diff options
518 files changed, 26303 insertions, 11733 deletions
diff --git a/.gitignore b/.gitignore index 9096ff228a..19490b9878 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ project.properties platform/android/java/lib/.cxx/ platform/android/java/libs/* platform/android/java/app/libs/* +platform/android/java/lib/.cxx/* # General c++ generated files *.lib @@ -26,6 +26,7 @@ Clay John <claynjohn@gmail.com> <clayjohn@shaw.ca> Dana Olson <dana@shineuponthee.com> <adolson@gmail.com> dankan1890 <mewuidev2@gmail.com> Daniel J. Ramirez <djrmuv@gmail.com> +Dominik 'dreamsComeTrue' Jasiński <dominikjasinski@o2.pl> Emmanuel Barroga <emmanuelbarroga@gmail.com> Erik Selecký <35656626+rxlecky@users.noreply.github.com> Erik Selecký <35656626+rxlecky@users.noreply.github.com> <35656626+SeleckyErik@users.noreply.github.com> @@ -75,6 +76,7 @@ Mariano Javier Suligoy <marianognu.easyrpg@gmail.com> Mario Schlack <m4r10.5ch14ck@gmail.com> marxin <mliska@suse.cz> marynate <mary.w.nate@gmail.com> <marynate@github.com> +Mateo Kuruk Miccino <mateomiccino@gmail.com> Max Hilbrunner <m.hilbrunner@gmail.com> Max Hilbrunner <m.hilbrunner@gmail.com> <mhilbrunner@users.noreply.github.com> Michael Alexsander <michaelalexsander@protonmail.com> diff --git a/.travis.yml b/.travis.yml index 14ee95e77e..8cfd7a1a7f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -55,17 +55,15 @@ matrix: packages: - *linux_deps -# TODO: Android support - -# - name: Android export template (release_debug, Clang) -# stage: build -# env: PLATFORM=android TOOLS=no TARGET=release_debug CACHE_NAME=${PLATFORM}-clang EXTRA_ARGS="warnings=extra werror=yes" -# os: linux -# compiler: clang -# addons: -# apt: -# packages: -# - openjdk-8-jdk + - name: Android export template (release_debug, Clang) + stage: build + env: PLATFORM=android TOOLS=no TARGET=release_debug CACHE_NAME=${PLATFORM}-clang EXTRA_ARGS="warnings=extra werror=yes" + os: linux + compiler: clang + addons: + apt: + packages: + - openjdk-8-jdk - name: macOS editor (debug, Clang) stage: build @@ -92,21 +90,6 @@ matrix: # packages: # - scons -# TODO: Dummy/Offscreen rasterizer - -# - name: Linux headless editor (release_debug, GCC 9, testing project exporting and script running) -# stage: build -# env: PLATFORM=server TOOLS=yes TARGET=release_debug CACHE_NAME=${PLATFORM}-tools-gcc-9 MATRIX_EVAL="CC=gcc-9 && CXX=g++-9" EXTRA_ARGS="warnings=extra werror=yes" TEST_PROJECT=yes -# os: linux -# compiler: gcc-9 -# addons: -# apt: -# sources: -# - sourceline: "ppa:ubuntu-toolchain-r/test" -# packages: -# - *gcc9_deps -# - *linux_deps - - name: Linux export template (release_debug, GCC 7, without 3D support) stage: build env: PLATFORM=linuxbsd TOOLS=no TARGET=release_debug CACHE_NAME=${PLATFORM}-gcc-7 EXTRA_ARGS="disable_3d=yes" diff --git a/AUTHORS.md b/AUTHORS.md index a3269a73f7..0f002cfaed 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -61,6 +61,7 @@ name is available. David Sichma (DavidSichma) Dharkael (lupoDharkael) Dmitry Koteroff (Krakean) + Dominik Jasiński (dreamsComeTrue) DualMatrix Emmanuel Barroga (codecustard) Emmanuel Leblond (touilleMan) @@ -104,6 +105,7 @@ name is available. Kelly Thomas (KellyThomas) Kostadin Damyanov (Max-Might) K. S. Ernest (iFire) Lee (fire) + lawnjelly Leon Krause (eska014) Lucien Menassol (Kanabenki) m4nu3lf @@ -118,6 +120,7 @@ name is available. Martin Sjursen (binbitten) marynate Masoud BH (masoudbh3) + Mateo Kuruk Miccino (kuruk-mm) Matthias Hölzl (hoelzl) Max Hilbrunner (mhilbrunner) merumelu @@ -157,6 +160,7 @@ name is available. Shiqing (kawa-yoiko) Simon Wenner (swenner) Swarnim Arun (minraws) + Thakee Nathees (ThakeeNathees) Theo Hallenius (TheoXD) Thomas Herzog (karroffel) Timo Schwarzer (timoschwarzer) @@ -40,6 +40,7 @@ generous deed immortalized in the next stable release of Godot Engine. Grady Hein-Pieter van Braam Jacob McKenney + Jasper Brooks Javary Co. Jeffery Chiu Justin Arnold @@ -62,6 +63,7 @@ generous deed immortalized in the next stable release of Godot Engine. Andrei Dave David Gehrig + David Graham David Snopek Ed Morley Florian Krick @@ -69,7 +71,6 @@ generous deed immortalized in the next stable release of Godot Engine. Jakub Grzesik Manuele Finocchiaro Officine Pixel S.n.c. - Retro Village Ronan Zeegers Sofox Taylor Ritenour @@ -99,6 +100,7 @@ generous deed immortalized in the next stable release of Godot Engine. Matthew Hillier Mohamed Ikbel Boulabiar Mored4u + Retro Village Rob Messick Ryan Badour Sandro Jenny @@ -106,10 +108,12 @@ generous deed immortalized in the next stable release of Godot Engine. Sergey thechris Tom Langwaldt + Tricky Fat Cat tukon William Wold Alex Khayrullin + alice gambrell Chris Goddard Chris Serino Christian Padilla @@ -151,6 +155,7 @@ generous deed immortalized in the next stable release of Godot Engine. Charlie Whitfield Chase Taranto Chris Petrich + Christian Alexander Bjørklund Bøhler Christian Leth Jeppesen Christoph Schröder Cody Parker @@ -186,6 +191,7 @@ generous deed immortalized in the next stable release of Godot Engine. Joshua Lesperance Juan Velandia Juraj Móza + Kelteseth kinfox Marcelo Dornbusch Lopes Markus Fehr @@ -193,9 +199,11 @@ generous deed immortalized in the next stable release of Godot Engine. Martin Eigel Matt Eunson Max Bulai + m kaersten MuffinManKen Nick Nikitin Oliver Dick + Oscar Campos Patrick Ting Paul Hocker Paul Von Zimmerman @@ -205,9 +213,12 @@ generous deed immortalized in the next stable release of Godot Engine. Robert Larnach Rocknight Studios Romildo Franco + Ryan Samuel Judd Scott Pilet Sean Morgan + Serban Serafimescu + Sindre Sømme SleepCircle spilldata Steve Hyatt @@ -216,7 +227,6 @@ generous deed immortalized in the next stable release of Godot Engine. Thomas Krampl Thomas Kurz Tobias Bocanegra - Tricky Fat Cat Urho William Foster Zhou Tuizhi @@ -232,6 +242,7 @@ generous deed immortalized in the next stable release of Godot Engine. Adam Carr Adam Long Adam McCurdy + Adam Netzel Adam N Webber Adam Smeltzer Adam Szymański @@ -244,6 +255,7 @@ generous deed immortalized in the next stable release of Godot Engine. Alan Stice Albin Jonasson Svärdsby Alder Stefano + AleMax Alessandro Senese Alexander Erlemann alex clavelle @@ -253,6 +265,7 @@ generous deed immortalized in the next stable release of Godot Engine. Andreas Krampitz André Simões Andrew Thomas + Anthony Avina Anthony Staunton AP Condomines Arda Erol @@ -260,6 +273,7 @@ generous deed immortalized in the next stable release of Godot Engine. Arseniy M Arthur S. Muszynski Asger + Ashley Claymore Aubrey Falconer Avencherus B A @@ -269,6 +283,7 @@ generous deed immortalized in the next stable release of Godot Engine. Ben Phelan Ben Vercammen Bernd Jänichen + Bjarne Black Block Blair Allen Bobby CC Wong @@ -276,6 +291,7 @@ generous deed immortalized in the next stable release of Godot Engine. bugcaptor Burney Waring Cameron Meyer + Carlo Sitaro Carl van der Geest Carwyn Edwards Cassidy James @@ -284,11 +300,11 @@ generous deed immortalized in the next stable release of Godot Engine. Christian Winter Christoffer Sundbom Christoph Brodmann + Christophe Gagnier Christopher Schmitt Christoph Woinke Clay Heaton Curt King - Dancin Liao Daniel Johnson Daniel Kimblad Daniel Pontillo @@ -328,7 +344,6 @@ generous deed immortalized in the next stable release of Godot Engine. Gary Thomas George Marques GiulianoB - Gordian Arragon Greg Olson GREGORY C FEIN Greg P @@ -337,13 +352,13 @@ generous deed immortalized in the next stable release of Godot Engine. Guldoman Hal A Heribert Hirth - Hudson Thorpe-Doubble Hunter Jones Hylpher Ichiro Dohi Iiari iKlem IndustrialRobot + Jacob Jaiden Gerig Jaime Ruiz-Borau Vizárraga Jako Danar @@ -351,7 +366,6 @@ generous deed immortalized in the next stable release of Godot Engine. Janders Jannik Gröger JARKKO PARVIAINEN - Jarrod Davis Jeff Hungerford Jennifer Graves Jeremy Kahn @@ -362,8 +376,10 @@ generous deed immortalized in the next stable release of Godot Engine. Johannes Wuensch John Gabriel Jomei Jackson + Jonas Bernemann Jonas Rudlang Jonas Yamazaki + Jonatan R Jonathan G Jonathon Jon Bonazza @@ -376,6 +392,7 @@ generous deed immortalized in the next stable release of Godot Engine. Judd Julian Murgia JungleRobba + Justin Hamilton Justin Spedding KaDokta Kauzig @@ -383,6 +400,7 @@ generous deed immortalized in the next stable release of Godot Engine. Keith Bradner Kevin McPhillips kickmaniac + Kiri Jolly Kiyohiro Kawamura (kyorohiro) Kjetil Haugland Klagsam @@ -394,6 +412,7 @@ generous deed immortalized in the next stable release of Godot Engine. Laurent Tréguier Leonardo Dimano Levi Lindsey + Lin Chear Linus Lind Lundgren Lionel Gaillard Luigi Renna @@ -418,8 +437,10 @@ generous deed immortalized in the next stable release of Godot Engine. Melissa Mears mewin mhilbrunner + Michael Dürwald Michael Haney Michael Labbe + Michał Skwarek Mikael Olsson Mikayla Mike Birkhead @@ -479,6 +500,7 @@ generous deed immortalized in the next stable release of Godot Engine. Scott D. Yelich Scott Longley Sebastian Michailidis + Sebastian Vetter Sergio Mello-Grand sgnsajgon Shane @@ -489,6 +511,7 @@ generous deed immortalized in the next stable release of Godot Engine. SK smbe19 smo1704 + Stefano Caronia Svenne Krap Terry tezuvholovdr @@ -498,7 +521,10 @@ generous deed immortalized in the next stable release of Godot Engine. Thomas Kelly Tim Drumheller Timothy B. MacDonald + tinyBigGames LLC + Title Plinsut Tobbun + Tom Glenn Torgeir Lilleskog Torsten Crass Travis O'Brien diff --git a/SConstruct b/SConstruct index 8fc333a8fa..e866a4c998 100644 --- a/SConstruct +++ b/SConstruct @@ -12,6 +12,7 @@ import sys # Local import methods import gles_builders +import version from platform_methods import run_in_subprocess # Scan possible build platforms @@ -72,6 +73,7 @@ env_base.disabled_modules = [] env_base.use_ptrcall = False env_base.module_version_string = "" env_base.msvc = False +env_base.stable_release = version.status == "stable" env_base.__class__.disable_module = methods.disable_module @@ -126,7 +128,7 @@ opts.Add(BoolVariable("xaudio2", "Enable the XAudio2 audio driver", False)) opts.Add(BoolVariable("verbose", "Enable verbose output for the compilation", False)) opts.Add(BoolVariable("progress", "Show a progress indicator during compilation", True)) opts.Add(EnumVariable("warnings", "Level of compilation warnings", "all", ("extra", "all", "moderate", "no"))) -opts.Add(BoolVariable("werror", "Treat compiler warnings as errors", True)) +opts.Add(BoolVariable("werror", "Treat compiler warnings as errors", not env_base.stable_release)) opts.Add(BoolVariable("dev", "If yes, alias for verbose=yes warnings=extra werror=yes", False)) opts.Add("extra_suffix", "Custom extra suffix added to the base filename of all generated binary files", "") opts.Add(BoolVariable("vsproj", "Generate a Visual Studio solution", False)) diff --git a/core/array.cpp b/core/array.cpp index d65bddae61..cd4e0fb4c8 100644 --- a/core/array.cpp +++ b/core/array.cpp @@ -30,8 +30,10 @@ #include "array.h" +#include "container_type_validate.h" #include "core/hashfuncs.h" #include "core/object.h" +#include "core/script_language.h" #include "core/variant.h" #include "core/vector.h" @@ -39,6 +41,8 @@ class ArrayPrivate { public: SafeRefCount refcount; Vector<Variant> array; + + ContainerTypeValidate typed; }; void Array::_ref(const Array &p_from) const { @@ -108,12 +112,59 @@ uint32_t Array::hash() const { } return h; } -void Array::operator=(const Array &p_array) { - _ref(p_array); +void Array::_assign(const Array &p_array) { + + if (_p->typed.type != Variant::OBJECT && _p->typed.type == p_array._p->typed.type) { + //same type or untyped, just reference, shuold be fine + _ref(p_array); + } else if (_p->typed.type == Variant::NIL) { //from typed to untyped, must copy, but this is cheap anyway + _p->array = p_array._p->array; + } else if (p_array._p->typed.type == Variant::NIL) { //from untyped to typed, must try to check if they are all valid + if (_p->typed.type == Variant::OBJECT) { + //for objects, it needs full validation, either can be converted or fail + for (int i = 0; i < p_array._p->array.size(); i++) { + if (!_p->typed.validate(p_array._p->array[i], "assign")) { + return; + } + } + _p->array = p_array._p->array; //then just copy, which is cheap anyway + + } else { + //for non objects, we need to check if there is a valid conversion, which needs to happen one by one, so this is the worst case. + Vector<Variant> new_array; + new_array.resize(p_array._p->array.size()); + for (int i = 0; i < p_array._p->array.size(); i++) { + Variant src_val = p_array._p->array[i]; + if (src_val.get_type() == _p->typed.type) { + new_array.write[i] = src_val; + } else if (Variant::can_convert_strict(src_val.get_type(), _p->typed.type)) { + Variant *ptr = &src_val; + Callable::CallError ce; + new_array.write[i] = Variant::construct(_p->typed.type, (const Variant **)&ptr, 1, ce, true); + if (ce.error != Callable::CallError::CALL_OK) { + ERR_FAIL_MSG("Unable to convert array index " + itos(i) + " from '" + Variant::get_type_name(src_val.get_type()) + "' to '" + Variant::get_type_name(_p->typed.type) + "'."); + } + } else { + ERR_FAIL_MSG("Unable to convert array index " + itos(i) + " from '" + Variant::get_type_name(src_val.get_type()) + "' to '" + Variant::get_type_name(_p->typed.type) + "'."); + } + } + + _p->array = new_array; + } + } else if (_p->typed.can_reference(p_array._p->typed)) { //same type or compatible + _ref(p_array); + } else { + ERR_FAIL_MSG("Assignment of arrays of incompatible types."); + } +} + +void Array::operator=(const Array &p_array) { + _assign(p_array); } void Array::push_back(const Variant &p_value) { + ERR_FAIL_COND(!_p->typed.validate(p_value, "push_back")); _p->array.push_back(p_value); } @@ -124,11 +175,13 @@ Error Array::resize(int p_new_size) { void Array::insert(int p_pos, const Variant &p_value) { + ERR_FAIL_COND(!_p->typed.validate(p_value, "insert")); _p->array.insert(p_pos, p_value); } void Array::erase(const Variant &p_value) { + ERR_FAIL_COND(!_p->typed.validate(p_value, "erase")); _p->array.erase(p_value); } @@ -144,6 +197,7 @@ Variant Array::back() const { int Array::find(const Variant &p_value, int p_from) const { + ERR_FAIL_COND_V(!_p->typed.validate(p_value, "find"), -1); return _p->array.find(p_value, p_from); } @@ -151,6 +205,7 @@ int Array::rfind(const Variant &p_value, int p_from) const { if (_p->array.size() == 0) return -1; + ERR_FAIL_COND_V(!_p->typed.validate(p_value, "rfind"), -1); if (p_from < 0) { // Relative offset from the end @@ -173,11 +228,13 @@ int Array::rfind(const Variant &p_value, int p_from) const { int Array::find_last(const Variant &p_value) const { + ERR_FAIL_COND_V(!_p->typed.validate(p_value, "find_last"), -1); return rfind(p_value); } int Array::count(const Variant &p_value) const { + ERR_FAIL_COND_V(!_p->typed.validate(p_value, "count"), 0); if (_p->array.size() == 0) return 0; @@ -193,6 +250,8 @@ int Array::count(const Variant &p_value) const { } bool Array::has(const Variant &p_value) const { + ERR_FAIL_COND_V(!_p->typed.validate(p_value, "use 'has'"), false); + return _p->array.find(p_value, 0) != -1; } @@ -203,6 +262,8 @@ void Array::remove(int p_pos) { void Array::set(int p_idx, const Variant &p_value) { + ERR_FAIL_COND(!_p->typed.validate(p_value, "set")); + operator[](p_idx) = p_value; } @@ -216,6 +277,7 @@ Array Array::duplicate(bool p_deep) const { Array new_arr; int element_count = size(); new_arr.resize(element_count); + new_arr._p->typed = _p->typed; for (int i = 0; i < element_count; i++) { new_arr[i] = p_deep ? get(i).duplicate(p_deep) : get(i); } @@ -369,11 +431,13 @@ _FORCE_INLINE_ int bisect(const Vector<Variant> &p_array, const Variant &p_value int Array::bsearch(const Variant &p_value, bool p_before) { + ERR_FAIL_COND_V(!_p->typed.validate(p_value, "binary search"), -1); return bisect(_p->array, p_value, p_before, _ArrayVariantSort()); } int Array::bsearch_custom(const Variant &p_value, Object *p_obj, const StringName &p_function, bool p_before) { + ERR_FAIL_COND_V(!_p->typed.validate(p_value, "custom binary search"), -1); ERR_FAIL_NULL_V(p_obj, 0); _ArrayVariantSortCustom less; @@ -391,6 +455,7 @@ Array &Array::invert() { void Array::push_front(const Variant &p_value) { + ERR_FAIL_COND(!_p->typed.validate(p_value, "push_front")); _p->array.insert(0, p_value); } @@ -465,6 +530,27 @@ const void *Array::id() const { return _p->array.ptr(); } +Array::Array(const Array &p_from, uint32_t p_type, const StringName &p_class_name, const Variant &p_script) { + _p = memnew(ArrayPrivate); + _p->refcount.init(); + set_typed(p_type, p_class_name, p_script); + _assign(p_from); +} + +void Array::set_typed(uint32_t p_type, const StringName &p_class_name, const Variant &p_script) { + ERR_FAIL_COND_MSG(_p->array.size() > 0, "Type can only be set when array is empty."); + ERR_FAIL_COND_MSG(_p->refcount.get() > 1, "Type can only be set when array has no more than one user."); + ERR_FAIL_COND_MSG(_p->typed.type != Variant::NIL, "Type can only be set once."); + ERR_FAIL_COND_MSG(p_class_name != StringName() && p_type != Variant::OBJECT, "Class names can only be set for type OBJECT"); + Ref<Script> script = p_script; + ERR_FAIL_COND_MSG(script.is_valid() && p_class_name == StringName(), "Script class can only be set together with base class name"); + + _p->typed.type = Variant::Type(p_type); + _p->typed.class_name = p_class_name; + _p->typed.script = script; + _p->typed.where = "TypedArray"; +} + Array::Array(const Array &p_from) { _p = nullptr; diff --git a/core/array.h b/core/array.h index 3b14bdb9fe..2840ce199c 100644 --- a/core/array.h +++ b/core/array.h @@ -47,6 +47,10 @@ class Array { int _clamp_index(int p_index) const; static int _fix_slice_index(int p_index, int p_arr_len, int p_top_mod); +protected: + Array(const Array &p_base, uint32_t p_type, const StringName &p_class_name, const Variant &p_script); + void _assign(const Array &p_array); + public: Variant &operator[](int p_idx); const Variant &operator[](int p_idx) const; @@ -101,6 +105,7 @@ public: const void *id() const; + void set_typed(uint32_t p_type, const StringName &p_class_name, const Variant &p_script); Array(const Array &p_from); Array(); ~Array(); diff --git a/core/callable_method_pointer.h b/core/callable_method_pointer.h index a931a344e6..fb809c2b44 100644 --- a/core/callable_method_pointer.h +++ b/core/callable_method_pointer.h @@ -34,6 +34,7 @@ #include "core/callable.h" #include "core/hashfuncs.h" #include "core/object.h" +#include "core/os/copymem.h" #include "core/simple_type.h" class CallableCustomMethodPointerBase : public CallableCustom { diff --git a/core/class_db.cpp b/core/class_db.cpp index 691b5a20fd..5e49688e9b 100644 --- a/core/class_db.cpp +++ b/core/class_db.cpp @@ -930,6 +930,15 @@ void ClassDB::add_property_group(StringName p_class, const String &p_name, const type->property_list.push_back(PropertyInfo(Variant::NIL, p_name, PROPERTY_HINT_NONE, p_prefix, PROPERTY_USAGE_GROUP)); } +void ClassDB::add_property_subgroup(StringName p_class, const String &p_name, const String &p_prefix) { + + OBJTYPE_WLOCK; + ClassInfo *type = classes.getptr(p_class); + ERR_FAIL_COND(!type); + + type->property_list.push_back(PropertyInfo(Variant::NIL, p_name, PROPERTY_HINT_NONE, p_prefix, PROPERTY_USAGE_SUBGROUP)); +} + void ClassDB::add_property(StringName p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index) { lock->read_lock(); diff --git a/core/class_db.h b/core/class_db.h index 1cbff34ea1..f760aa1738 100644 --- a/core/class_db.h +++ b/core/class_db.h @@ -349,6 +349,7 @@ public: static void get_signal_list(StringName p_class, List<MethodInfo> *p_signals, bool p_no_inheritance = false); static void add_property_group(StringName p_class, const String &p_name, const String &p_prefix = ""); + static void add_property_subgroup(StringName p_class, const String &p_name, const String &p_prefix = ""); static void add_property(StringName p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index = -1); static void set_property_default_value(StringName p_class, const StringName &p_name, const Variant &p_default); static void get_property_list(StringName p_class, List<PropertyInfo> *p_list, bool p_no_inheritance = false, const Object *p_validator = nullptr); diff --git a/core/container_type_validate.h b/core/container_type_validate.h new file mode 100644 index 0000000000..3721668033 --- /dev/null +++ b/core/container_type_validate.h @@ -0,0 +1,98 @@ +#ifndef CONTAINER_TYPE_VALIDATE_H +#define CONTAINER_TYPE_VALIDATE_H + +#include "core/script_language.h" +#include "core/variant.h" + +struct ContainerTypeValidate { + + Variant::Type type = Variant::NIL; + StringName class_name; + Ref<Script> script; + const char *where = "conatiner"; + + _FORCE_INLINE_ bool can_reference(const ContainerTypeValidate &p_type) const { + if (type == p_type.type) { + if (type != Variant::OBJECT) { + return true; //nothing else to check + } + } else { + return false; + } + + //both are object + + if ((class_name != StringName()) != (p_type.class_name != StringName())) { + return false; //both need to have class or none + } + + if (class_name != p_type.class_name) { + if (!ClassDB::is_parent_class(p_type.class_name, class_name)) { + return false; + } + } + + if (script.is_null() != p_type.script.is_null()) { + return false; + } + + if (script != p_type.script) { + if (!p_type.script->inherits_script(script)) { + return false; + } + } + + return true; + } + + _FORCE_INLINE_ bool validate(const Variant &p_variant, const char *p_operation = "use") { + + if (type == Variant::NIL) { + return true; + } + + ERR_FAIL_COND_V_MSG(type != p_variant.get_type(), false, "Attempted to " + String(p_operation) + " a variable of type '" + Variant::get_type_name(p_variant.get_type()) + "' into a " + where + " of type '" + Variant::get_type_name(type) + "'."); + if (type != p_variant.get_type()) { + return false; + } + + if (type != Variant::OBJECT) { + return true; + } +#ifdef DEBUG_ENABLED + ObjectID object_id = p_variant; + if (object_id == ObjectID()) { + return true; //fine its null; + } + Object *object = ObjectDB::get_instance(object_id); + ERR_FAIL_COND_V_MSG(object == nullptr, false, "Attempted to " + String(p_operation) + " an invalid (previously freed?) object instance into a '" + String(where) + "."); +#else + Object *object = p_variant; + if (object == nullptr) { + return true; //fine + } +#endif + if (class_name == StringName()) { + return true; //all good, no class type requested + } + + StringName obj_class = object->get_class_name(); + if (obj_class != class_name) { + ERR_FAIL_COND_V_MSG(!ClassDB::is_parent_class(object->get_class_name(), class_name), false, "Attempted to " + String(p_operation) + " an object of type '" + object->get_class() + "' into a " + where + ", which does not inherit from '" + String(class_name) + "'."); + } + + if (script.is_null()) { + return true; //all good + } + + Ref<Script> other_script = object->get_script(); + + //check base script.. + ERR_FAIL_COND_V_MSG(other_script.is_null(), false, "Attempted to " + String(p_operation) + " an object into a " + String(where) + ", that does not inherit from '" + String(script->get_class_name()) + "'."); + ERR_FAIL_COND_V_MSG(!other_script->inherits_script(script), false, "Attempted to " + String(p_operation) + " an object into a " + String(where) + ", that does not inherit from '" + String(script->get_class_name()) + "'."); + + return true; + } +}; + +#endif // CONTAINER_TYPE_VALIDATE_H diff --git a/core/crypto/crypto.cpp b/core/crypto/crypto.cpp index ab8548e3ba..233f62bd15 100644 --- a/core/crypto/crypto.cpp +++ b/core/crypto/crypto.cpp @@ -99,7 +99,7 @@ Crypto::Crypto() { /// Resource loader/saver -RES ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { String el = p_path.get_extension().to_lower(); if (el == "crt") { diff --git a/core/crypto/crypto.h b/core/crypto/crypto.h index e515367de5..d9becab958 100644 --- a/core/crypto/crypto.h +++ b/core/crypto/crypto.h @@ -84,18 +84,14 @@ public: }; class ResourceFormatLoaderCrypto : public ResourceFormatLoader { - GDCLASS(ResourceFormatLoaderCrypto, ResourceFormatLoader); - public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; }; class ResourceFormatSaverCrypto : public ResourceFormatSaver { - GDCLASS(ResourceFormatSaverCrypto, ResourceFormatSaver); - public: virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0); virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const; diff --git a/core/debugger/remote_debugger.cpp b/core/debugger/remote_debugger.cpp index c2996e552f..e6bcc5f77e 100644 --- a/core/debugger/remote_debugger.cpp +++ b/core/debugger/remote_debugger.cpp @@ -318,7 +318,7 @@ struct RemoteDebugger::ServersProfiler { void _send_frame_data(bool p_final) { DebuggerMarshalls::ServersProfilerFrame frame; - frame.frame_number = Engine::get_singleton()->get_frames_drawn(); + frame.frame_number = Engine::get_singleton()->get_idle_frames(); frame.frame_time = frame_time; frame.idle_time = idle_time; frame.physics_time = physics_time; diff --git a/core/engine.cpp b/core/engine.cpp index 36987eab31..5361e09a8a 100644 --- a/core/engine.cpp +++ b/core/engine.cpp @@ -60,7 +60,7 @@ void Engine::set_target_fps(int p_fps) { _target_fps = p_fps > 0 ? p_fps : 0; } -float Engine::get_target_fps() const { +int Engine::get_target_fps() const { return _target_fps; } diff --git a/core/engine.h b/core/engine.h index 4cfdeffa82..8512779d4c 100644 --- a/core/engine.h +++ b/core/engine.h @@ -86,7 +86,7 @@ public: float get_physics_jitter_fix() const; virtual void set_target_fps(int p_fps); - virtual float get_target_fps() const; + virtual int get_target_fps() const; virtual float get_frames_per_second() const { return _fps; } diff --git a/core/global_constants.cpp b/core/global_constants.cpp index 8706a38453..afcb283e05 100644 --- a/core/global_constants.cpp +++ b/core/global_constants.cpp @@ -568,9 +568,7 @@ void register_global_constants() { BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_INTERNATIONALIZED); BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_GROUP); BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_CATEGORY); - //deprecated, replaced by ClassDB function to check default value - //BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_STORE_IF_NONZERO); - //BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_STORE_IF_NONONE); + BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_SUBGROUP); BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_NO_INSTANCE_STATE); BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_RESTART_IF_CHANGED); BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_SCRIPT_VARIABLE); diff --git a/core/hashfuncs.h b/core/hashfuncs.h index 219b8b2658..a41a034843 100644 --- a/core/hashfuncs.h +++ b/core/hashfuncs.h @@ -35,10 +35,10 @@ #include "core/math/math_funcs.h" #include "core/node_path.h" #include "core/object_id.h" +#include "core/rid.h" #include "core/string_name.h" #include "core/typedefs.h" #include "core/ustring.h" - /** * Hashing functions */ @@ -150,6 +150,7 @@ struct HashMapHasherDefault { static _FORCE_INLINE_ uint32_t hash(const uint8_t p_int) { return p_int; } static _FORCE_INLINE_ uint32_t hash(const int8_t p_int) { return (uint32_t)p_int; } static _FORCE_INLINE_ uint32_t hash(const wchar_t p_wchar) { return (uint32_t)p_wchar; } + static _FORCE_INLINE_ uint32_t hash(const RID &p_rid) { return hash_one_uint64(p_rid.get_id()); } static _FORCE_INLINE_ uint32_t hash(const StringName &p_string_name) { return p_string_name.hash(); } static _FORCE_INLINE_ uint32_t hash(const NodePath &p_path) { return p_path.hash(); } diff --git a/core/image.cpp b/core/image.cpp index 2097f27b01..58351ae2e5 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -879,6 +879,9 @@ void Image::resize_to_po2(bool p_square) { int w = next_power_of_2(width); int h = next_power_of_2(height); + if (p_square) { + w = h = MAX(w, h); + } if (w == width && h == height) { diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp index 2770adbd36..01e6bb5618 100644 --- a/core/io/image_loader.cpp +++ b/core/io/image_loader.cpp @@ -129,7 +129,7 @@ void ImageLoader::cleanup() { ///////////////// -RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ); if (!f) { diff --git a/core/io/image_loader.h b/core/io/image_loader.h index 18b4df98f7..15ce6031d7 100644 --- a/core/io/image_loader.h +++ b/core/io/image_loader.h @@ -73,7 +73,7 @@ public: class ResourceFormatLoaderImage : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index a640565ecf..8c7559479b 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -337,12 +337,16 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { } break; case OBJECT_INTERNAL_RESOURCE: { uint32_t index = f->get_32(); - String path = res_path + "::" + itos(index); - RES res = ResourceLoader::load(path); - if (res.is_null()) { - WARN_PRINT(String("Couldn't load resource: " + path).utf8().get_data()); + if (use_nocache) { + r_v = internal_resources[index].cache; + } else { + String path = res_path + "::" + itos(index); + RES res = ResourceLoader::load(path); + if (res.is_null()) { + WARN_PRINT(String("Couldn't load resource: " + path).utf8().get_data()); + } + r_v = res; } - r_v = res; } break; case OBJECT_EXTERNAL_RESOURCE: { @@ -716,22 +720,24 @@ Error ResourceLoaderBinary::load() { if (!main) { - path = internal_resources[i].path; - if (path.begins_with("local://")) { - path = path.replace_first("local://", ""); - subindex = path.to_int(); - path = res_path + "::" + path; - } + if (!use_nocache) { + path = internal_resources[i].path; + if (path.begins_with("local://")) { + path = path.replace_first("local://", ""); + subindex = path.to_int(); + path = res_path + "::" + path; + } - if (ResourceCache::has(path)) { - //already loaded, don't do anything - stage++; - error = OK; - continue; + if (ResourceCache::has(path)) { + //already loaded, don't do anything + stage++; + error = OK; + continue; + } } } else { - if (!ResourceCache::has(res_path)) + if (!use_nocache && !ResourceCache::has(res_path)) path = res_path; } @@ -757,9 +763,15 @@ Error ResourceLoaderBinary::load() { RES res = RES(r); - r->set_path(path); + if (path != String()) { + r->set_path(path); + } r->set_subindex(subindex); + if (!main) { + internal_resources.write[i].cache = res; + } + int pc = f->get_32(); //set properties @@ -1013,6 +1025,7 @@ ResourceLoaderBinary::ResourceLoaderBinary() : importmd_ofs(0), error(OK) { + use_nocache = false; progress = nullptr; use_sub_threads = false; } @@ -1023,7 +1036,7 @@ ResourceLoaderBinary::~ResourceLoaderBinary() { memdelete(f); } -RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) *r_error = ERR_FILE_CANT_OPEN; @@ -1034,6 +1047,7 @@ RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_origi ERR_FAIL_COND_V_MSG(err != OK, RES(), "Cannot open file '" + p_path + "'."); ResourceLoaderBinary loader; + loader.use_nocache = p_no_cache; loader.use_sub_threads = p_use_sub_threads; loader.progress = r_progress; String path = p_original_path != "" ? p_original_path : p_path; diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index da67e1e648..0f8fc9445b 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -68,6 +68,7 @@ class ResourceLoaderBinary { struct IntResource { String path; uint64_t offset; + RES cache; }; Vector<IntResource> internal_resources; @@ -78,6 +79,8 @@ class ResourceLoaderBinary { Map<String, String> remaps; Error error; + bool use_nocache; + friend class ResourceFormatLoaderBinary; Error parse_variant(Variant &r_v); @@ -101,7 +104,7 @@ public: class ResourceFormatLoaderBinary : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp index ceb73cab77..643df53f8c 100644 --- a/core/io/resource_importer.cpp +++ b/core/io/resource_importer.cpp @@ -117,7 +117,7 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy return OK; } -RES ResourceFormatImporter::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatImporter::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { PathAndType pat; Error err = _get_path_and_type(p_path, pat); @@ -130,7 +130,7 @@ RES ResourceFormatImporter::load(const String &p_path, const String &p_original_ return RES(); } - RES res = ResourceLoader::_load(pat.path, p_path, pat.type, false, r_error, p_use_sub_threads, r_progress); + RES res = ResourceLoader::_load(pat.path, p_path, pat.type, p_no_cache, r_error, p_use_sub_threads, r_progress); #ifdef TOOLS_ENABLED if (res.is_valid()) { diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h index dbac80599a..6b76912494 100644 --- a/core/io/resource_importer.h +++ b/core/io/resource_importer.h @@ -58,7 +58,7 @@ class ResourceFormatImporter : public ResourceFormatLoader { public: static ResourceFormatImporter *get_singleton() { return singleton; } - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; virtual bool recognize_path(const String &p_path, const String &p_for_type = String()) const; diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 05a41013c2..d90802d7e2 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -119,7 +119,7 @@ void ResourceFormatLoader::get_recognized_extensions(List<String> *p_extensions) } } -RES ResourceFormatLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (get_script_instance() && get_script_instance()->has_method("load")) { Variant res = get_script_instance()->call("load", p_path, p_original_path, p_use_sub_threads); @@ -200,7 +200,7 @@ RES ResourceLoader::_load(const String &p_path, const String &p_original_path, c continue; } found = true; - RES res = loader[i]->load(p_path, p_original_path != String() ? p_original_path : p_path, r_error, p_use_sub_threads, r_progress); + RES res = loader[i]->load(p_path, p_original_path != String() ? p_original_path : p_path, r_error, p_use_sub_threads, r_progress, p_no_cache); if (res.is_null()) { continue; } diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index be4adf9091..2d95d5545f 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -43,7 +43,7 @@ protected: static void _bind_methods(); public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual bool exists(const String &p_path) const; virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; diff --git a/core/io/translation_loader_po.cpp b/core/io/translation_loader_po.cpp index 5da236d029..bce5361c76 100644 --- a/core/io/translation_loader_po.cpp +++ b/core/io/translation_loader_po.cpp @@ -185,7 +185,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) { return translation; } -RES TranslationLoaderPO::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES TranslationLoaderPO::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) *r_error = ERR_CANT_OPEN; diff --git a/core/io/translation_loader_po.h b/core/io/translation_loader_po.h index 9d3117b630..137dfd1768 100644 --- a/core/io/translation_loader_po.h +++ b/core/io/translation_loader_po.h @@ -38,7 +38,7 @@ class TranslationLoaderPO : public ResourceFormatLoader { public: static RES load_translation(FileAccess *f, Error *r_error = nullptr); - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/core/math/basis.cpp b/core/math/basis.cpp index 14079f811d..0f519a20d8 100644 --- a/core/math/basis.cpp +++ b/core/math/basis.cpp @@ -77,10 +77,6 @@ void Basis::invert() { void Basis::orthonormalize() { -#ifdef MATH_CHECKS - ERR_FAIL_COND(determinant() == 0); -#endif - // Gram-Schmidt Process Vector3 x = get_axis(0); diff --git a/core/method_bind.h b/core/method_bind.h index 588b472b62..d39f107ba6 100644 --- a/core/method_bind.h +++ b/core/method_bind.h @@ -39,6 +39,7 @@ #include "core/method_ptrcall.h" #include "core/object.h" #include "core/type_info.h" +#include "core/typedefs.h" #include "core/variant.h" #include <stdio.h> diff --git a/core/object.h b/core/object.h index 40032de271..b40aef2a42 100644 --- a/core/object.h +++ b/core/object.h @@ -60,7 +60,6 @@ enum PropertyHint { PROPERTY_HINT_ENUM, ///< hint_text= "val1,val2,val3,etc" PROPERTY_HINT_EXP_EASING, /// exponential easing function (Math::ease) use "attenuation" hint string to revert (flip h), "full" to also include in/out. (ie: "attenuation,inout") PROPERTY_HINT_LENGTH, ///< hint_text= "length" (as integer) - PROPERTY_HINT_SPRITE_FRAME, // FIXME: Obsolete: drop whenever we can break compat. Keeping now for GDNative compat. PROPERTY_HINT_KEY_ACCEL, ///< hint_text= "length" (as integer) PROPERTY_HINT_FLAGS, ///< hint_text= "flag1,flag2,etc" (as bit flags) PROPERTY_HINT_LAYERS_2D_RENDER, @@ -92,6 +91,7 @@ enum PropertyHint { PROPERTY_HINT_NODE_PATH_VALID_TYPES, PROPERTY_HINT_SAVE_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,". This opens a save dialog PROPERTY_HINT_INT_IS_OBJECTID, + PROPERTY_HINT_ARRAY_TYPE, PROPERTY_HINT_MAX, // When updating PropertyHint, also sync the hardcoded list in VisualScriptEditorVariableEdit }; @@ -107,10 +107,7 @@ enum PropertyUsageFlags { PROPERTY_USAGE_INTERNATIONALIZED = 64, //hint for internationalized strings PROPERTY_USAGE_GROUP = 128, //used for grouping props in the editor PROPERTY_USAGE_CATEGORY = 256, - // FIXME: Drop in 4.0, possibly reorder other flags? - // Those below are deprecated thanks to ClassDB's now class value cache - //PROPERTY_USAGE_STORE_IF_NONZERO = 512, //only store if nonzero - //PROPERTY_USAGE_STORE_IF_NONONE = 1024, //only store if false + PROPERTY_USAGE_SUBGROUP = 512, PROPERTY_USAGE_NO_INSTANCE_STATE = 2048, PROPERTY_USAGE_RESTART_IF_CHANGED = 4096, PROPERTY_USAGE_SCRIPT_VARIABLE = 8192, @@ -138,6 +135,7 @@ enum PropertyUsageFlags { #define ADD_PROPERTYI(m_property, m_setter, m_getter, m_index) ClassDB::add_property(get_class_static(), m_property, _scs_create(m_setter), _scs_create(m_getter), m_index) #define ADD_PROPERTY_DEFAULT(m_property, m_default) ClassDB::set_property_default_value(get_class_static(), m_property, m_default) #define ADD_GROUP(m_name, m_prefix) ClassDB::add_property_group(get_class_static(), m_name, m_prefix) +#define ADD_SUBGROUP(m_name, m_prefix) ClassDB::add_property_subgroup(get_class_static(), m_name, m_prefix) struct PropertyInfo { diff --git a/core/resource.cpp b/core/resource.cpp index d1883d8043..8d5c441b21 100644 --- a/core/resource.cpp +++ b/core/resource.cpp @@ -477,6 +477,9 @@ void ResourceCache::clear() { resources.clear(); memdelete(lock); +#ifdef TOOLS_ENABLED + memdelete(path_cache_lock); +#endif } void ResourceCache::reload_externals() { diff --git a/core/rid.h b/core/rid.h index 3cc0ee3084..a2f73423a3 100644 --- a/core/rid.h +++ b/core/rid.h @@ -31,11 +31,6 @@ #ifndef RID_H #define RID_H -#include "core/list.h" -#include "core/oa_hash_map.h" -#include "core/os/memory.h" -#include "core/safe_refcount.h" -#include "core/set.h" #include "core/typedefs.h" class RID_AllocBase; diff --git a/core/rid_owner.h b/core/rid_owner.h index 946b2e396c..ad6996b9a7 100644 --- a/core/rid_owner.h +++ b/core/rid_owner.h @@ -31,8 +31,13 @@ #ifndef RID_OWNER_H #define RID_OWNER_H +#include "core/list.h" +#include "core/oa_hash_map.h" +#include "core/os/memory.h" #include "core/print_string.h" #include "core/rid.h" +#include "core/safe_refcount.h" +#include "core/set.h" #include "core/spin_lock.h" #include <stdio.h> #include <typeinfo> diff --git a/core/script_language.h b/core/script_language.h index 2d86c5166d..5cc240efcb 100644 --- a/core/script_language.h +++ b/core/script_language.h @@ -135,6 +135,8 @@ public: virtual Ref<Script> get_base_script() const = 0; //for script inheritance + virtual bool inherits_script(const Ref<Script> &p_script) const = 0; + virtual StringName get_instance_base_type() const = 0; // this may not work in all scripts, will return empty if so virtual ScriptInstance *instance_create(Object *p_this) = 0; virtual PlaceHolderScriptInstance *placeholder_instance_create(Object *p_this) { return nullptr; } diff --git a/core/typed_array.cpp b/core/typed_array.cpp new file mode 100644 index 0000000000..55e45f0b3f --- /dev/null +++ b/core/typed_array.cpp @@ -0,0 +1 @@ +#include "typed_array.h" diff --git a/core/typed_array.h b/core/typed_array.h new file mode 100644 index 0000000000..5e95e81ea3 --- /dev/null +++ b/core/typed_array.h @@ -0,0 +1,202 @@ +#ifndef TYPED_ARRAY_H +#define TYPED_ARRAY_H + +#include "core/array.h" +#include "core/method_ptrcall.h" +#include "core/variant.h" + +template <class T> +class TypedArray : public Array { +public: + template <class U> + _FORCE_INLINE_ void operator=(const TypedArray<U> &p_array) { + static_assert(__is_base_of(T, U)); + _assign(p_array); + } + + _FORCE_INLINE_ void operator=(const Array &p_array) { + _assign(p_array); + } + _FORCE_INLINE_ TypedArray(const Variant &p_variant) : + Array(Array(p_variant), Variant::OBJECT, T::get_class_static(), Variant()) { + } + _FORCE_INLINE_ TypedArray(const Array &p_array) : + Array(p_array, Variant::OBJECT, T::get_class_static(), Variant()) { + } + _FORCE_INLINE_ TypedArray() { + set_typed(Variant::OBJECT, T::get_class_static(), Variant()); + } +}; + +//specialization for the rest of variant types + +#define MAKE_TYPED_ARRAY(m_type, m_variant_type) \ + template <> \ + class TypedArray<m_type> : public Array { \ + public: \ + _FORCE_INLINE_ void operator=(const Array &p_array) { \ + _assign(p_array); \ + } \ + _FORCE_INLINE_ TypedArray(const Variant &p_variant) : \ + Array(Array(p_variant), m_variant_type, StringName(), Variant()) { \ + } \ + _FORCE_INLINE_ TypedArray(const Array &p_array) : \ + Array(p_array, m_variant_type, StringName(), Variant()) { \ + } \ + _FORCE_INLINE_ TypedArray() { \ + set_typed(m_variant_type, StringName(), Variant()); \ + } \ + }; + +MAKE_TYPED_ARRAY(bool, Variant::BOOL) +MAKE_TYPED_ARRAY(uint8_t, Variant::INT) +MAKE_TYPED_ARRAY(int8_t, Variant::INT) +MAKE_TYPED_ARRAY(uint16_t, Variant::INT) +MAKE_TYPED_ARRAY(int16_t, Variant::INT) +MAKE_TYPED_ARRAY(uint32_t, Variant::INT) +MAKE_TYPED_ARRAY(int32_t, Variant::INT) +MAKE_TYPED_ARRAY(uint64_t, Variant::INT) +MAKE_TYPED_ARRAY(int64_t, Variant::INT) +MAKE_TYPED_ARRAY(float, Variant::FLOAT) +MAKE_TYPED_ARRAY(double, Variant::FLOAT) +MAKE_TYPED_ARRAY(String, Variant::STRING) +MAKE_TYPED_ARRAY(Vector2, Variant::VECTOR2) +MAKE_TYPED_ARRAY(Vector2i, Variant::VECTOR2I) +MAKE_TYPED_ARRAY(Rect2, Variant::RECT2) +MAKE_TYPED_ARRAY(Rect2i, Variant::RECT2I) +MAKE_TYPED_ARRAY(Vector3, Variant::VECTOR3) +MAKE_TYPED_ARRAY(Vector3i, Variant::VECTOR3I) +MAKE_TYPED_ARRAY(Transform2D, Variant::TRANSFORM2D) +MAKE_TYPED_ARRAY(Plane, Variant::PLANE) +MAKE_TYPED_ARRAY(Quat, Variant::QUAT) +MAKE_TYPED_ARRAY(AABB, Variant::AABB) +MAKE_TYPED_ARRAY(Basis, Variant::BASIS) +MAKE_TYPED_ARRAY(Transform, Variant::TRANSFORM) +MAKE_TYPED_ARRAY(Color, Variant::COLOR) +MAKE_TYPED_ARRAY(StringName, Variant::STRING_NAME) +MAKE_TYPED_ARRAY(NodePath, Variant::NODE_PATH) +MAKE_TYPED_ARRAY(RID, Variant::_RID) +MAKE_TYPED_ARRAY(Callable, Variant::CALLABLE) +MAKE_TYPED_ARRAY(Signal, Variant::SIGNAL) +MAKE_TYPED_ARRAY(Dictionary, Variant::DICTIONARY) +MAKE_TYPED_ARRAY(Array, Variant::ARRAY) +MAKE_TYPED_ARRAY(Vector<uint8_t>, Variant::PACKED_BYTE_ARRAY) +MAKE_TYPED_ARRAY(Vector<int32_t>, Variant::PACKED_INT32_ARRAY) +MAKE_TYPED_ARRAY(Vector<int64_t>, Variant::PACKED_INT64_ARRAY) +MAKE_TYPED_ARRAY(Vector<float>, Variant::PACKED_FLOAT32_ARRAY) +MAKE_TYPED_ARRAY(Vector<double>, Variant::PACKED_FLOAT64_ARRAY) +MAKE_TYPED_ARRAY(Vector<String>, Variant::PACKED_STRING_ARRAY) +MAKE_TYPED_ARRAY(Vector<Vector2>, Variant::PACKED_VECTOR2_ARRAY) +MAKE_TYPED_ARRAY(Vector<Vector3>, Variant::PACKED_VECTOR3_ARRAY) +MAKE_TYPED_ARRAY(Vector<Color>, Variant::PACKED_COLOR_ARRAY) + +#ifdef PTRCALL_ENABLED + +template <class T> +struct PtrToArg<TypedArray<T>> { + + _FORCE_INLINE_ static TypedArray<T> convert(const void *p_ptr) { + + return TypedArray<T>(*reinterpret_cast<const Array *>(p_ptr)); + } + + _FORCE_INLINE_ static void encode(TypedArray<T> p_val, void *p_ptr) { + + *(Array *)p_ptr = p_val; + } +}; + +template <class T> +struct PtrToArg<const TypedArray<T> &> { + + _FORCE_INLINE_ static TypedArray<T> convert(const void *p_ptr) { + + return TypedArray<T>(*reinterpret_cast<const Array *>(p_ptr)); + } +}; + +#endif // PTRCALL_ENABLED + +#ifdef DEBUG_METHODS_ENABLED + +template <class T> +struct GetTypeInfo<TypedArray<T>> { + static const Variant::Type VARIANT_TYPE = Variant::ARRAY; + static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; + static inline PropertyInfo get_class_info() { + return PropertyInfo(Variant::ARRAY, String(), PROPERTY_HINT_ARRAY_TYPE, T::get_class_static()); + } +}; + +template <class T> +struct GetTypeInfo<const TypedArray<T> &> { + static const Variant::Type VARIANT_TYPE = Variant::ARRAY; + static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; + static inline PropertyInfo get_class_info() { + return PropertyInfo(Variant::ARRAY, String(), PROPERTY_HINT_ARRAY_TYPE, T::get_class_static()); + } +}; + +#define MAKE_TYPED_ARRAY_INFO(m_type, m_variant_type) \ + template <> \ + struct GetTypeInfo<TypedArray<m_type>> { \ + static const Variant::Type VARIANT_TYPE = Variant::ARRAY; \ + static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \ + static inline PropertyInfo get_class_info() { \ + return PropertyInfo(Variant::ARRAY, String(), PROPERTY_HINT_ARRAY_TYPE, Variant::get_type_name(m_variant_type)); \ + } \ + }; \ + template <> \ + struct GetTypeInfo<const TypedArray<m_type> &> { \ + static const Variant::Type VARIANT_TYPE = Variant::ARRAY; \ + static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \ + static inline PropertyInfo get_class_info() { \ + return PropertyInfo(Variant::ARRAY, String(), PROPERTY_HINT_ARRAY_TYPE, Variant::get_type_name(m_variant_type)); \ + } \ + }; + +MAKE_TYPED_ARRAY_INFO(bool, Variant::BOOL) +MAKE_TYPED_ARRAY_INFO(uint8_t, Variant::INT) +MAKE_TYPED_ARRAY_INFO(int8_t, Variant::INT) +MAKE_TYPED_ARRAY_INFO(uint16_t, Variant::INT) +MAKE_TYPED_ARRAY_INFO(int16_t, Variant::INT) +MAKE_TYPED_ARRAY_INFO(uint32_t, Variant::INT) +MAKE_TYPED_ARRAY_INFO(int32_t, Variant::INT) +MAKE_TYPED_ARRAY_INFO(uint64_t, Variant::INT) +MAKE_TYPED_ARRAY_INFO(int64_t, Variant::INT) +MAKE_TYPED_ARRAY_INFO(float, Variant::FLOAT) +MAKE_TYPED_ARRAY_INFO(double, Variant::FLOAT) +MAKE_TYPED_ARRAY_INFO(String, Variant::STRING) +MAKE_TYPED_ARRAY_INFO(Vector2, Variant::VECTOR2) +MAKE_TYPED_ARRAY_INFO(Vector2i, Variant::VECTOR2I) +MAKE_TYPED_ARRAY_INFO(Rect2, Variant::RECT2) +MAKE_TYPED_ARRAY_INFO(Rect2i, Variant::RECT2I) +MAKE_TYPED_ARRAY_INFO(Vector3, Variant::VECTOR3) +MAKE_TYPED_ARRAY_INFO(Vector3i, Variant::VECTOR3I) +MAKE_TYPED_ARRAY_INFO(Transform2D, Variant::TRANSFORM2D) +MAKE_TYPED_ARRAY_INFO(Plane, Variant::PLANE) +MAKE_TYPED_ARRAY_INFO(Quat, Variant::QUAT) +MAKE_TYPED_ARRAY_INFO(AABB, Variant::AABB) +MAKE_TYPED_ARRAY_INFO(Basis, Variant::BASIS) +MAKE_TYPED_ARRAY_INFO(Transform, Variant::TRANSFORM) +MAKE_TYPED_ARRAY_INFO(Color, Variant::COLOR) +MAKE_TYPED_ARRAY_INFO(StringName, Variant::STRING_NAME) +MAKE_TYPED_ARRAY_INFO(NodePath, Variant::NODE_PATH) +MAKE_TYPED_ARRAY_INFO(RID, Variant::_RID) +MAKE_TYPED_ARRAY_INFO(Callable, Variant::CALLABLE) +MAKE_TYPED_ARRAY_INFO(Signal, Variant::SIGNAL) +MAKE_TYPED_ARRAY_INFO(Dictionary, Variant::DICTIONARY) +MAKE_TYPED_ARRAY_INFO(Array, Variant::ARRAY) +MAKE_TYPED_ARRAY_INFO(Vector<uint8_t>, Variant::PACKED_BYTE_ARRAY) +MAKE_TYPED_ARRAY_INFO(Vector<int32_t>, Variant::PACKED_INT32_ARRAY) +MAKE_TYPED_ARRAY_INFO(Vector<int64_t>, Variant::PACKED_INT64_ARRAY) +MAKE_TYPED_ARRAY_INFO(Vector<float>, Variant::PACKED_FLOAT32_ARRAY) +MAKE_TYPED_ARRAY_INFO(Vector<double>, Variant::PACKED_FLOAT64_ARRAY) +MAKE_TYPED_ARRAY_INFO(Vector<String>, Variant::PACKED_STRING_ARRAY) +MAKE_TYPED_ARRAY_INFO(Vector<Vector2>, Variant::PACKED_VECTOR2_ARRAY) +MAKE_TYPED_ARRAY_INFO(Vector<Vector3>, Variant::PACKED_VECTOR3_ARRAY) +MAKE_TYPED_ARRAY_INFO(Vector<Color>, Variant::PACKED_COLOR_ARRAY) + +#endif + +#endif // TYPED_ARRAY_H diff --git a/core/undo_redo.cpp b/core/undo_redo.cpp index 8bd5a4915d..62ad3e9f98 100644 --- a/core/undo_redo.cpp +++ b/core/undo_redo.cpp @@ -511,8 +511,7 @@ void UndoRedo::_bind_methods() { ClassDB::bind_method(D_METHOD("create_action", "name", "merge_mode"), &UndoRedo::create_action, DEFVAL(MERGE_DISABLE)); ClassDB::bind_method(D_METHOD("commit_action"), &UndoRedo::commit_action); - // FIXME: Typo in "commiting", fix in 4.0 when breaking compat. - ClassDB::bind_method(D_METHOD("is_commiting_action"), &UndoRedo::is_committing_action); + ClassDB::bind_method(D_METHOD("is_committing_action"), &UndoRedo::is_committing_action); { MethodInfo mi; diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index 8c6821eaac..71bbc271e2 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -12,9 +12,6 @@ <methods> </methods> <members> - <member name="ARVRServer" type="ARVRServer" setter="" getter=""> - The [ARVRServer] singleton. - </member> <member name="AudioServer" type="AudioServer" setter="" getter=""> The [AudioServer] singleton. </member> @@ -30,9 +27,6 @@ <member name="Geometry" type="Geometry" setter="" getter=""> The [Geometry] singleton. </member> - <member name="GodotSharp" type="GodotSharp" setter="" getter=""> - The [GodotSharp] singleton. Only available when using Godot's Mono build. - </member> <member name="IP" type="IP" setter="" getter=""> The [IP] singleton. </member> @@ -95,6 +89,9 @@ <member name="VisualScriptEditor" type="VisualScriptEditor" setter="" getter=""> The [VisualScriptEditor] singleton. </member> + <member name="XRServer" type="XRServer" setter="" getter=""> + The [XRServer] singleton. + </member> </members> <constants> <constant name="MARGIN_LEFT" value="0" enum="Margin"> @@ -1345,52 +1342,52 @@ <constant name="PROPERTY_HINT_LENGTH" value="5" enum="PropertyHint"> Deprecated hint, unused. </constant> - <constant name="PROPERTY_HINT_KEY_ACCEL" value="7" enum="PropertyHint"> + <constant name="PROPERTY_HINT_KEY_ACCEL" value="6" enum="PropertyHint"> Deprecated hint, unused. </constant> - <constant name="PROPERTY_HINT_FLAGS" value="8" enum="PropertyHint"> + <constant name="PROPERTY_HINT_FLAGS" value="7" enum="PropertyHint"> Hints that an integer property is a bitmask with named bit flags. For example, to allow toggling bits 0, 1, 2 and 4, the hint could be something like [code]"Bit0,Bit1,Bit2,,Bit4"[/code]. </constant> - <constant name="PROPERTY_HINT_LAYERS_2D_RENDER" value="9" enum="PropertyHint"> + <constant name="PROPERTY_HINT_LAYERS_2D_RENDER" value="8" enum="PropertyHint"> Hints that an integer property is a bitmask using the optionally named 2D render layers. </constant> - <constant name="PROPERTY_HINT_LAYERS_2D_PHYSICS" value="10" enum="PropertyHint"> + <constant name="PROPERTY_HINT_LAYERS_2D_PHYSICS" value="9" enum="PropertyHint"> Hints that an integer property is a bitmask using the optionally named 2D physics layers. </constant> - <constant name="PROPERTY_HINT_LAYERS_3D_RENDER" value="11" enum="PropertyHint"> + <constant name="PROPERTY_HINT_LAYERS_3D_RENDER" value="10" enum="PropertyHint"> Hints that an integer property is a bitmask using the optionally named 3D render layers. </constant> - <constant name="PROPERTY_HINT_LAYERS_3D_PHYSICS" value="12" enum="PropertyHint"> + <constant name="PROPERTY_HINT_LAYERS_3D_PHYSICS" value="11" enum="PropertyHint"> Hints that an integer property is a bitmask using the optionally named 3D physics layers. </constant> - <constant name="PROPERTY_HINT_FILE" value="13" enum="PropertyHint"> + <constant name="PROPERTY_HINT_FILE" value="12" enum="PropertyHint"> Hints that a string property is a path to a file. Editing it will show a file dialog for picking the path. The hint string can be a set of filters with wildcards like [code]"*.png,*.jpg"[/code]. </constant> - <constant name="PROPERTY_HINT_DIR" value="14" enum="PropertyHint"> + <constant name="PROPERTY_HINT_DIR" value="13" enum="PropertyHint"> Hints that a string property is a path to a directory. Editing it will show a file dialog for picking the path. </constant> - <constant name="PROPERTY_HINT_GLOBAL_FILE" value="15" enum="PropertyHint"> + <constant name="PROPERTY_HINT_GLOBAL_FILE" value="14" enum="PropertyHint"> Hints that a string property is an absolute path to a file outside the project folder. Editing it will show a file dialog for picking the path. The hint string can be a set of filters with wildcards like [code]"*.png,*.jpg"[/code]. </constant> - <constant name="PROPERTY_HINT_GLOBAL_DIR" value="16" enum="PropertyHint"> + <constant name="PROPERTY_HINT_GLOBAL_DIR" value="15" enum="PropertyHint"> Hints that a string property is an absolute path to a directory outside the project folder. Editing it will show a file dialog for picking the path. </constant> - <constant name="PROPERTY_HINT_RESOURCE_TYPE" value="17" enum="PropertyHint"> + <constant name="PROPERTY_HINT_RESOURCE_TYPE" value="16" enum="PropertyHint"> Hints that a property is an instance of a [Resource]-derived type, optionally specified via the hint string (e.g. [code]"Texture2D"[/code]). Editing it will show a popup menu of valid resource types to instantiate. </constant> - <constant name="PROPERTY_HINT_MULTILINE_TEXT" value="18" enum="PropertyHint"> + <constant name="PROPERTY_HINT_MULTILINE_TEXT" value="17" enum="PropertyHint"> Hints that a string property is text with line breaks. Editing it will show a text input field where line breaks can be typed. </constant> - <constant name="PROPERTY_HINT_PLACEHOLDER_TEXT" value="19" enum="PropertyHint"> + <constant name="PROPERTY_HINT_PLACEHOLDER_TEXT" value="18" enum="PropertyHint"> Hints that a string property should have a placeholder text visible on its input field, whenever the property is empty. The hint string is the placeholder text to use. </constant> - <constant name="PROPERTY_HINT_COLOR_NO_ALPHA" value="20" enum="PropertyHint"> + <constant name="PROPERTY_HINT_COLOR_NO_ALPHA" value="19" enum="PropertyHint"> Hints that a color property should be edited without changing its alpha component, i.e. only R, G and B channels are edited. </constant> - <constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSY" value="21" enum="PropertyHint"> + <constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSY" value="20" enum="PropertyHint"> Hints that an image is compressed using lossy compression. </constant> - <constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS" value="22" enum="PropertyHint"> + <constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS" value="21" enum="PropertyHint"> Hints that an image is compressed using lossless compression. </constant> <constant name="PROPERTY_USAGE_STORAGE" value="1" enum="PropertyUsageFlags"> @@ -1420,6 +1417,9 @@ <constant name="PROPERTY_USAGE_CATEGORY" value="256" enum="PropertyUsageFlags"> Used to categorize properties together in the editor. </constant> + <constant name="PROPERTY_USAGE_SUBGROUP" value="512" enum="PropertyUsageFlags"> + Used to group properties together in the editor in a subgroup (under a group). + </constant> <constant name="PROPERTY_USAGE_NO_INSTANCE_STATE" value="2048" enum="PropertyUsageFlags"> The property does not save its state in [PackedScene]. </constant> diff --git a/doc/classes/AudioStreamSample.xml b/doc/classes/AudioStreamSample.xml index 6d99433c90..c12e1bd05c 100644 --- a/doc/classes/AudioStreamSample.xml +++ b/doc/classes/AudioStreamSample.xml @@ -30,13 +30,13 @@ Audio format. See [enum Format] constants for values. </member> <member name="loop_begin" type="int" setter="set_loop_begin" getter="get_loop_begin" default="0"> - Loop start in bytes. + The loop start point (in number of samples, relative to the beginning of the sample). This information will be imported automatically from the WAV file if present. </member> <member name="loop_end" type="int" setter="set_loop_end" getter="get_loop_end" default="0"> - Loop end in bytes. + The loop end point (in number of samples, relative to the beginning of the sample). This information will be imported automatically from the WAV file if present. </member> <member name="loop_mode" type="int" setter="set_loop_mode" getter="get_loop_mode" enum="AudioStreamSample.LoopMode" default="0"> - Loop mode. See [enum LoopMode] constants for values. + The loop mode. This information will be imported automatically from the WAV file if present. See [enum LoopMode] constants for values. </member> <member name="mix_rate" type="int" setter="set_mix_rate" getter="get_mix_rate" default="44100"> The sample rate for mixing this audio. @@ -59,13 +59,13 @@ Audio does not loop. </constant> <constant name="LOOP_FORWARD" value="1" enum="LoopMode"> - Audio loops the data between [member loop_begin] and [member loop_end] playing forward only. + Audio loops the data between [member loop_begin] and [member loop_end], playing forward only. </constant> <constant name="LOOP_PING_PONG" value="2" enum="LoopMode"> - Audio loops the data between [member loop_begin] and [member loop_end] playing back and forth. + Audio loops the data between [member loop_begin] and [member loop_end], playing back and forth. </constant> <constant name="LOOP_BACKWARD" value="3" enum="LoopMode"> - Audio loops the data between [member loop_begin] and [member loop_end] playing backward only. + Audio loops the data between [member loop_begin] and [member loop_end], playing backward only. </constant> </constants> </class> diff --git a/doc/classes/BackBufferCopy.xml b/doc/classes/BackBufferCopy.xml index 1f7554f978..7cc6a5613b 100644 --- a/doc/classes/BackBufferCopy.xml +++ b/doc/classes/BackBufferCopy.xml @@ -5,6 +5,7 @@ </brief_description> <description> Node for back-buffering the currently-displayed screen. The region defined in the BackBufferCopy node is bufferized with the content of the screen it covers, or the entire screen according to the copy mode set. Use the [code]texture(SCREEN_TEXTURE, ...)[/code] function in your shader scripts to access the buffer. + [b]Note:[/b] Since this node inherits from [Node2D] (and not [Control]), anchors and margins won't apply to child [Control]-derived nodes. This can be problematic when resizing the window. To avoid this, add [Control]-derived nodes as [i]siblings[/i] to the BackBufferCopy node instead of adding them as children. </description> <tutorials> </tutorials> diff --git a/doc/classes/BaseButton.xml b/doc/classes/BaseButton.xml index 2147b2b4b0..5e908b0e53 100644 --- a/doc/classes/BaseButton.xml +++ b/doc/classes/BaseButton.xml @@ -60,6 +60,7 @@ </member> <member name="keep_pressed_outside" type="bool" setter="set_keep_pressed_outside" getter="is_keep_pressed_outside" default="false"> If [code]true[/code], the button stays pressed when moving the cursor outside the button while pressing it. + [b]Note:[/b] This property only affects the button's visual appearance. Signals will be emitted at the same moment regardless of this property's value. </member> <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). diff --git a/doc/classes/BaseMaterial3D.xml b/doc/classes/BaseMaterial3D.xml index 5bb94d2858..76abc31451 100644 --- a/doc/classes/BaseMaterial3D.xml +++ b/doc/classes/BaseMaterial3D.xml @@ -108,6 +108,15 @@ <member name="ao_texture_channel" type="int" setter="set_ao_texture_channel" getter="get_ao_texture_channel" enum="BaseMaterial3D.TextureChannel"> Specifies the channel of the [member ao_texture] in which the ambient occlusion information is stored. This is useful when you store the information for multiple effects in a single texture. For example if you stored metallic in the red channel, roughness in the blue, and ambient occlusion in the green you could reduce the number of textures you use. </member> + <member name="backlight" type="Color" setter="set_backlight" getter="get_backlight"> + The color used by the backlight effect. Represents the light passing through an object. + </member> + <member name="backlight_enabled" type="bool" setter="set_feature" getter="get_feature" default="false"> + If [code]true[/code], the backlight effect is enabled. + </member> + <member name="backlight_texture" type="Texture2D" setter="set_texture" getter="get_texture"> + Texture used to control the backlight effect per-pixel. Added to [member backlight]. + </member> <member name="billboard_keep_scale" type="bool" setter="set_flag" getter="get_flag" default="false"> If [code]true[/code], the shader will keep the scale set for the mesh. Otherwise the scale is lost when billboarding. Only applies when [member billboard_mode] is [constant BILLBOARD_ENABLED]. </member> @@ -296,6 +305,7 @@ Specifies the channel of the [member ao_texture] in which the ambient occlusion information is stored. This is useful when you store the information for multiple effects in a single texture. For example if you stored metallic in the red channel, roughness in the blue, and ambient occlusion in the green you could reduce the number of textures you use. </member> <member name="shading_mode" type="int" setter="set_shading_mode" getter="get_shading_mode" enum="BaseMaterial3D.ShadingMode" default="1"> + Sets whether the shading takes place per-pixel or per-vertex. Per-vertex lighting is faster, making it the best choice for mobile applications, however it looks considerably worse than per-pixel. </member> <member name="shadow_to_opacity" type="bool" setter="set_flag" getter="get_flag" default="false"> If [code]true[/code], enables the "shadow to opacity" render mode where lighting modifies the alpha so shadowed areas are opaque and non-shadowed areas are transparent. Useful for overlaying shadows onto a camera feed in AR. @@ -307,6 +317,7 @@ If [code]true[/code], subsurface scattering is enabled. Emulates light that penetrates an object's surface, is scattered, and then emerges. </member> <member name="subsurf_scatter_skin_mode" type="bool" setter="set_flag" getter="get_flag"> + If [code]true[/code], subsurface scattering will use a special mode optimized for the color and density of human skin. </member> <member name="subsurf_scatter_strength" type="float" setter="set_subsurface_scattering_strength" getter="get_subsurface_scattering_strength"> The strength of the subsurface scattering effect. @@ -314,21 +325,24 @@ <member name="subsurf_scatter_texture" type="Texture2D" setter="set_texture" getter="get_texture"> Texture used to control the subsurface scattering strength. Stored in the red texture channel. Multiplied by [member subsurf_scatter_strength]. </member> + <member name="subsurf_scatter_transmittance_boost" type="float" setter="set_transmittance_boost" getter="get_transmittance_boost"> + </member> + <member name="subsurf_scatter_transmittance_color" type="Color" setter="set_transmittance_color" getter="get_transmittance_color"> + </member> + <member name="subsurf_scatter_transmittance_curve" type="float" setter="set_transmittance_curve" getter="get_transmittance_curve"> + </member> + <member name="subsurf_scatter_transmittance_depth" type="float" setter="set_transmittance_depth" getter="get_transmittance_depth"> + </member> + <member name="subsurf_scatter_transmittance_enabled" type="bool" setter="set_feature" getter="get_feature"> + </member> + <member name="subsurf_scatter_transmittance_texture" type="Texture2D" setter="set_texture" getter="get_texture"> + </member> <member name="texture_filter" type="int" setter="set_texture_filter" getter="get_texture_filter" enum="BaseMaterial3D.TextureFilter" default="3"> Filter flags for the texture. See [enum TextureFilter] for options. </member> <member name="texture_repeat" type="bool" setter="set_flag" getter="get_flag" default="true"> Repeat flags for the texture. See [enum TextureFilter] for options. </member> - <member name="transmission" type="Color" setter="set_transmission" getter="get_transmission"> - The color used by the transmission effect. Represents the light passing through an object. - </member> - <member name="transmission_enabled" type="bool" setter="set_feature" getter="get_feature" default="false"> - If [code]true[/code], the transmission effect is enabled. - </member> - <member name="transmission_texture" type="Texture2D" setter="set_texture" getter="get_texture"> - Texture used to control the transmission effect per-pixel. Added to [member transmission]. - </member> <member name="transparency" type="int" setter="set_transparency" getter="get_transparency" enum="BaseMaterial3D.Transparency" default="0"> If [code]true[/code], transparency is enabled on the body. See also [member blend_mode]. </member> @@ -407,39 +421,47 @@ <constant name="TEXTURE_SUBSURFACE_SCATTERING" value="10" enum="TextureParam"> Texture specifying per-pixel subsurface scattering. </constant> - <constant name="TEXTURE_TRANSMISSION" value="11" enum="TextureParam"> - Texture specifying per-pixel transmission color. + <constant name="TEXTURE_SUBSURFACE_TRANSMITTANCE" value="11" enum="TextureParam"> + Texture specifying per-pixel transmittance for subsurface scattering. + </constant> + <constant name="TEXTURE_BACKLIGHT" value="12" enum="TextureParam"> + Texture specifying per-pixel backlight color. </constant> - <constant name="TEXTURE_REFRACTION" value="12" enum="TextureParam"> + <constant name="TEXTURE_REFRACTION" value="13" enum="TextureParam"> Texture specifying per-pixel refraction strength. </constant> - <constant name="TEXTURE_DETAIL_MASK" value="13" enum="TextureParam"> + <constant name="TEXTURE_DETAIL_MASK" value="14" enum="TextureParam"> Texture specifying per-pixel detail mask blending value. </constant> - <constant name="TEXTURE_DETAIL_ALBEDO" value="14" enum="TextureParam"> + <constant name="TEXTURE_DETAIL_ALBEDO" value="15" enum="TextureParam"> Texture specifying per-pixel detail color. </constant> - <constant name="TEXTURE_DETAIL_NORMAL" value="15" enum="TextureParam"> + <constant name="TEXTURE_DETAIL_NORMAL" value="16" enum="TextureParam"> Texture specifying per-pixel detail normal. </constant> - <constant name="TEXTURE_ORM" value="16" enum="TextureParam"> + <constant name="TEXTURE_ORM" value="17" enum="TextureParam"> + Texture holding ambient occlusion, roughness, and metallic. </constant> - <constant name="TEXTURE_MAX" value="17" enum="TextureParam"> + <constant name="TEXTURE_MAX" value="18" enum="TextureParam"> Represents the size of the [enum TextureParam] enum. </constant> <constant name="TEXTURE_FILTER_NEAREST" value="0" enum="TextureFilter"> The texture filter reads from the nearest pixel only. The simplest and fastest method of filtering, but the texture will look pixelized. </constant> <constant name="TEXTURE_FILTER_LINEAR" value="1" enum="TextureFilter"> - The texture filter blends between the nearest four pixels. Use this for most cases where you want to avoid a pixelated style. + The texture filter blends between the nearest 4 pixels. Use this when you want to avoid a pixelated style, but do not want mipmaps. </constant> <constant name="TEXTURE_FILTER_NEAREST_WITH_MIPMAPS" value="2" enum="TextureFilter"> + The texture filter reads from the nearest pixel in the nearest mipmap. The fastest way to read from textures with mipmaps. </constant> <constant name="TEXTURE_FILTER_LINEAR_WITH_MIPMAPS" value="3" enum="TextureFilter"> + The texture filter blends between the nearest 4 pixels and between the nearest 2 mipmaps. Use this for most cases as mipmaps are important to smooth out pixels that are far from the camera. </constant> <constant name="TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC" value="4" enum="TextureFilter"> + The texture filter reads from the nearest pixel, but selects a mipmap based on the angle between the surface and the camera view. This reduces artifacts on surfaces that are almost in line with the camera. </constant> <constant name="TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC" value="5" enum="TextureFilter"> + The texture filter blends between the nearest 4 pixels and selects a mipmap based on the angle between the surface and the camera view. This reduces artifacts on surfaces that are almost in line with the camera. This is the slowest of the filtering options, but results in the highest quality texturing. </constant> <constant name="TEXTURE_FILTER_MAX" value="6" enum="TextureFilter"> Represents the size of the [enum TextureFilter] enum. @@ -457,8 +479,10 @@ The material will use the texture's alpha values for transparency. </constant> <constant name="TRANSPARENCY_ALPHA_SCISSOR" value="2" enum="Transparency"> + The material will cut off all values below a threshold, the rest will remain opaque. </constant> <constant name="TRANSPARENCY_ALPHA_DEPTH_PRE_PASS" value="3" enum="Transparency"> + The material will use the texture's alpha value for transparency, but will still be rendered in the pre-pass. </constant> <constant name="TRANSPARENCY_MAX" value="4" enum="Transparency"> Represents the size of the [enum Transparency] enum. @@ -494,20 +518,24 @@ Constant for setting [member ao_enabled]. </constant> <constant name="FEATURE_HEIGHT_MAPPING" value="6" enum="Feature"> + Constant for setting [member heightmap_enabled]. </constant> - <constant name="FEATURE_SUBSURACE_SCATTERING" value="7" enum="Feature"> + <constant name="FEATURE_SUBSURFACE_SCATTERING" value="7" enum="Feature"> Constant for setting [member subsurf_scatter_enabled]. </constant> - <constant name="FEATURE_TRANSMISSION" value="8" enum="Feature"> - Constant for setting [member transmission_enabled]. + <constant name="FEATURE_SUBSURFACE_TRANSMITTANCE" value="8" enum="Feature"> + Constant for setting [member subsurf_scatter_transmittance_enabled]. + </constant> + <constant name="FEATURE_BACKLIGHT" value="9" enum="Feature"> + Constant for setting [member backlight_enabled]. </constant> - <constant name="FEATURE_REFRACTION" value="9" enum="Feature"> + <constant name="FEATURE_REFRACTION" value="10" enum="Feature"> Constant for setting [member refraction_enabled]. </constant> - <constant name="FEATURE_DETAIL" value="10" enum="Feature"> + <constant name="FEATURE_DETAIL" value="11" enum="Feature"> Constant for setting [member detail_enabled]. </constant> - <constant name="FEATURE_MAX" value="11" enum="Feature"> + <constant name="FEATURE_MAX" value="12" enum="Feature"> Represents the size of the [enum Feature] enum. </constant> <constant name="BLEND_MODE_MIX" value="0" enum="BlendMode"> @@ -589,11 +617,13 @@ Enables the shadow to opacity feature. </constant> <constant name="FLAG_USE_TEXTURE_REPEAT" value="16" enum="Flags"> + Enables the texture to repeat when UV coordinates are outside the 0-1 range. If using one of the linear filtering modes, this can result in artifacts at the edges of a texture when the sampler filters across the edges of the texture. </constant> <constant name="FLAG_INVERT_HEIGHTMAP" value="17" enum="Flags"> Invert values read from a depth texture to convert them to height values (heightmap). </constant> <constant name="FLAG_SUBSURFACE_MODE_SKIN" value="18" enum="Flags"> + Enables the skin mode for subsurface scattering which is used to improve the look of subsurface scattering when used for human skin. </constant> <constant name="FLAG_MAX" value="19" enum="Flags"> Represents the size of the [enum Flags] enum. diff --git a/doc/classes/Camera2D.xml b/doc/classes/Camera2D.xml index 73892481e6..ad49216b34 100644 --- a/doc/classes/Camera2D.xml +++ b/doc/classes/Camera2D.xml @@ -5,7 +5,8 @@ </brief_description> <description> Camera node for 2D scenes. It forces the screen (current layer) to scroll following this node. This makes it easier (and faster) to program scrollable scenes than manually changing the position of [CanvasItem]-based nodes. - This node is intended to be a simple helper to get things going quickly and it may happen that more functionality is desired to change how the camera works. To make your own custom camera node, simply inherit from [Node2D] and change the transform of the canvas by calling get_viewport().set_canvas_transform(m) in [Viewport]. + This node is intended to be a simple helper to get things going quickly and it may happen that more functionality is desired to change how the camera works. To make your own custom camera node, inherit from [Node2D] and change the transform of the canvas by setting [member Viewport.canvas_transform] in [Viewport] (you can obtain the current [Viewport] by using [method Node.get_viewport]). + Note that the [Camera2D] node's [code]position[/code] doesn't represent the actual position of the screen, which may differ due to applied smoothing or limits. You can use [method get_camera_screen_center] to get the real position. </description> <tutorials> </tutorials> diff --git a/doc/classes/CameraFeed.xml b/doc/classes/CameraFeed.xml index 3232f5970c..4fc124592f 100644 --- a/doc/classes/CameraFeed.xml +++ b/doc/classes/CameraFeed.xml @@ -4,7 +4,7 @@ A camera feed gives you access to a single physical camera attached to your device. </brief_description> <description> - A camera feed gives you access to a single physical camera attached to your device. When enabled, Godot will start capturing frames from the camera which can then be used. + A camera feed gives you access to a single physical camera attached to your device. When enabled, Godot will start capturing frames from the camera which can then be used. See also [CameraServer]. [b]Note:[/b] Many cameras will return YCbCr images which are split into two textures and need to be combined in a shader. Godot does this automatically for you if you set the environment to show the camera image in the background. </description> <tutorials> diff --git a/doc/classes/CameraServer.xml b/doc/classes/CameraServer.xml index 82d1faf716..e00dc031dc 100644 --- a/doc/classes/CameraServer.xml +++ b/doc/classes/CameraServer.xml @@ -6,6 +6,7 @@ <description> The [CameraServer] keeps track of different cameras accessible in Godot. These are external cameras such as webcams or the cameras on your phone. It is notably used to provide AR modules with a video feed from the camera. + [b]Note:[/b] This class is currently only implemented on macOS and iOS. On other platforms, no [CameraFeed]s will be available. </description> <tutorials> </tutorials> @@ -16,7 +17,7 @@ <argument index="0" name="feed" type="CameraFeed"> </argument> <description> - Adds a camera feed to the camera server. + Adds the camera [code]feed[/code] to the camera server. </description> </method> <method name="feeds"> @@ -32,7 +33,7 @@ <argument index="0" name="index" type="int"> </argument> <description> - Returns the [CameraFeed] with this id. + Returns the [CameraFeed] corresponding to the camera with the given [code]index[/code]. </description> </method> <method name="get_feed_count"> @@ -48,7 +49,7 @@ <argument index="0" name="feed" type="CameraFeed"> </argument> <description> - Removes a [CameraFeed]. + Removes the specified camera [code]feed[/code]. </description> </method> </methods> @@ -57,14 +58,14 @@ <argument index="0" name="id" type="int"> </argument> <description> - Emitted when a [CameraFeed] is added (e.g. webcam is plugged in). + Emitted when a [CameraFeed] is added (e.g. a webcam is plugged in). </description> </signal> <signal name="camera_feed_removed"> <argument index="0" name="id" type="int"> </argument> <description> - Emitted when a [CameraFeed] is removed (e.g. webcam is unplugged). + Emitted when a [CameraFeed] is removed (e.g. a webcam is unplugged). </description> </signal> </signals> @@ -73,7 +74,7 @@ The RGBA camera image. </constant> <constant name="FEED_YCBCR_IMAGE" value="0" enum="FeedImage"> - The YCbCr camera image. + The [url=https://en.wikipedia.org/wiki/YCbCr]YCbCr[/url] camera image. </constant> <constant name="FEED_Y_IMAGE" value="0" enum="FeedImage"> The Y component camera image. diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml index f2ce2a6fb9..38e4453cf2 100644 --- a/doc/classes/CanvasItem.xml +++ b/doc/classes/CanvasItem.xml @@ -9,6 +9,7 @@ Canvas items are drawn in tree order. By default, children are on top of their parents so a root [CanvasItem] will be drawn behind everything. This behavior can be changed on a per-item basis. A [CanvasItem] can also be hidden, which will also hide its children. It provides many ways to change parameters such as modulation (for itself and its children) and self modulation (only for itself), as well as its blend mode. Ultimately, a transform notification can be requested, which will notify the node that its global position changed in case the parent tree changed. + [b]Note:[/b] Unless otherwise specified, all methods that have angle parameters must have angles specified as [i]radians[/i]. To convert degrees to radians, use [method @GDScript.deg2rad]. </description> <tutorials> <link>https://docs.godotengine.org/en/latest/tutorials/2d/2d_transforms.html</link> diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml index 85a75fda37..0c8d42021a 100644 --- a/doc/classes/Control.xml +++ b/doc/classes/Control.xml @@ -838,7 +838,7 @@ Controls whether the control will be able to receive mouse button input events through [method _gui_input] and how these events should be handled. Also controls whether the control can receive the [signal mouse_entered], and [signal mouse_exited] signals. See the constants to learn what each does. </member> <member name="rect_clip_content" type="bool" setter="set_clip_contents" getter="is_clipping_contents" default="false"> - Enables whether rendering of children should be clipped to this control's rectangle. If [code]true[/code], parts of a child which would be visibly outside of this control's rectangle will not be rendered. + Enables whether rendering of [CanvasItem] based children should be clipped to this control's rectangle. If [code]true[/code], parts of a child which would be visibly outside of this control's rectangle will not be rendered. </member> <member name="rect_global_position" type="Vector2" setter="_set_global_position" getter="get_global_position"> The node's global position, relative to the world (usually to the top-left corner of the window). diff --git a/doc/classes/Decal.xml b/doc/classes/Decal.xml new file mode 100644 index 0000000000..f7329d1537 --- /dev/null +++ b/doc/classes/Decal.xml @@ -0,0 +1,111 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="Decal" inherits="VisualInstance3D" version="4.0"> + <brief_description> + Node that projects a texture onto a [MeshInstance3D]. + </brief_description> + <description> + [Decal]s are used to project a texture onto a [Mesh] in the scene. Use Decals to add detail to a scene without affecting the underlying [Mesh]. They are often used to add weathering to building, add dirt or mud to the ground, or add variety to props. Decals can be moved at any time, making them suitable for things like blob shadows or laser sight dots. + They are made of an [AABB] and a group of [Texture2D]s specifying [Color], normal, ORM (ambient occlusion, roughness, metallic), and emission. Decals are projected within their [AABB] so altering the orientation of the Decal affects the direction in which they are projected. By default, Decals are projected down (i.e. from positive Y to negative Y). + The [Texture2D]s associated with the Decal are automatically stored in a texture atlas which is used for drawing the decals so all decals can be drawn at once. Godot uses clustered decals, meaning they are stored in cluster data and drawn when the mesh is drawn, they are not drawn as a postprocessing effect after. + </description> + <tutorials> + </tutorials> + <methods> + <method name="get_texture" qualifiers="const"> + <return type="Texture2D"> + </return> + <argument index="0" name="type" type="int" enum="Decal.DecalTexture"> + </argument> + <description> + Returns the [Texture2D] associated with the specified [enum DecalTexture]. This is a convenience method, in most cases you should access the texture directly. + For example, instead of [code]albedo_tex = $Decal.get_texture(Decal.TEXTURE_ALBEDO)[/code], use [code]albedo_tex = $Decal.texture_albedo[/code]. + One case where this is better than accessing the texture directly is when you want to copy one Decal's textures to another. For example: + [codeblock] + for i in Decal.TEXTURE_MAX: + $NewDecal.set_texture(i, $OldDecal.get_texture(i)) + [/codeblock] + </description> + </method> + <method name="set_texture"> + <return type="void"> + </return> + <argument index="0" name="type" type="int" enum="Decal.DecalTexture"> + </argument> + <argument index="1" name="texture" type="Texture2D"> + </argument> + <description> + Sets the [Texture2D] associated with the specified [enum DecalTexture]. This is a convenience method, in most cases you should access the texture directly. + For example, instead of [code]$Decal.set_texture(Decal.TEXTURE_ALBEDO, albedo_tex)[/code], use [code]$Decal.texture_albedo = albedo_tex[/code]. + One case where this is better than accessing the texture directly is when you want to copy one Decal's textures to another. For example: + [codeblock] + for i in Decal.TEXTURE_MAX: + $NewDecal.set_texture(i, $OldDecal.get_texture(i)) + [/codeblock] + </description> + </method> + </methods> + <members> + <member name="albedo_mix" type="float" setter="set_albedo_mix" getter="get_albedo_mix" default="1.0"> + Blends the albedo [Color] of the decal with albedo [Color] of the underlying mesh. + </member> + <member name="cull_mask" type="int" setter="set_cull_mask" getter="get_cull_mask" default="1048575"> + Specifies which [member VisualInstance3D.layers] this decal will project on. By default, Decals affect all layers. This is used so you can specify which types of objects receive the Decal and which do not. This is especially useful so you an ensure that dynamic objects don't accidentally receive a Decal intended for the terrain under them. + </member> + <member name="distance_fade_begin" type="float" setter="set_distance_fade_begin" getter="get_distance_fade_begin" default="10.0"> + Distance from the camera at which the Decal begins to fade away. + </member> + <member name="distance_fade_enabled" type="bool" setter="set_enable_distance_fade" getter="is_distance_fade_enabled" default="false"> + If [code]true[/code], decals will smoothly fade away when far from the active [Camera3D] starting at [member distance_fade_begin]. The Decal will fade out over [member distance_fade_length], after which it will be culled and not sent to the shader at all. Use this to reduce the number of active Decals in a scene and thus improve performance. + </member> + <member name="distance_fade_length" type="float" setter="set_distance_fade_length" getter="get_distance_fade_length" default="1.0"> + Distance over which the Decal fades. The Decal becomes slowly more transparent over this distance and is completely invisible at the end. + </member> + <member name="emission_energy" type="float" setter="set_emission_energy" getter="get_emission_energy" default="1.0"> + Energy multiplier for the emission texture. This will make the decal emit light at a higher intensity. + </member> + <member name="extents" type="Vector3" setter="set_extents" getter="get_extents" default="Vector3( 1, 1, 1 )"> + Sets the size of the [AABB] used by the decal. The AABB goes from [code]-extents[/code] to [code]extents[/code]. + </member> + <member name="lower_fade" type="float" setter="set_lower_fade" getter="get_lower_fade" default="0.3"> + Sets the curve over which the decal will fade as the surface gets further from the center of the [AABB]. + </member> + <member name="modulate" type="Color" setter="set_modulate" getter="get_modulate" default="Color( 1, 1, 1, 1 )"> + Changes the [Color] of the Decal by multiplying it with this value. + </member> + <member name="normal_fade" type="float" setter="set_normal_fade" getter="get_normal_fade" default="0.0"> + Fades the Decal if the angle between the Decal's [AABB] and the target surface becomes too large. A value of [code]0[/code] projects the Decal regardless of angle, a value of [code]1[/code] limits the Decal to surfaces that are nearly perpendicular. + </member> + <member name="texture_albedo" type="Texture2D" setter="set_texture" getter="get_texture"> + [Texture2D] with the base [Color] of the Decal. Either this or the [member texture_emission] must be set for the Decal to be visible. Use the alpha channel like a mask to smoothly blend the edges of the decal with the underlying object. + </member> + <member name="texture_emission" type="Texture2D" setter="set_texture" getter="get_texture"> + [Texture2D] with the emission [Color] of the Decal. Either this or the [member texture_emission] must be set for the Decal to be visible. Use the alpha channel like a mask to smoothly blend the edges of the decal with the underlying object. + </member> + <member name="texture_normal" type="Texture2D" setter="set_texture" getter="get_texture"> + [Texture2D] with the per-pixel normalmap for the decal. Use this to add extra detail to decals. + </member> + <member name="texture_orm" type="Texture2D" setter="set_texture" getter="get_texture"> + [Texture2D] storing ambient occlusion, roughness, and metallic for the decal. Use this to add extra detail to decals. + </member> + <member name="upper_fade" type="float" setter="set_upper_fade" getter="get_upper_fade" default="0.3"> + Sets the curve over which the decal will fade as the surface gets further from the center of the [AABB]. + </member> + </members> + <constants> + <constant name="TEXTURE_ALBEDO" value="0" enum="DecalTexture"> + [Texture2D] corresponding to [member texture_albedo]. + </constant> + <constant name="TEXTURE_NORMAL" value="1" enum="DecalTexture"> + [Texture2D] corresponding to [member texture_normal]. + </constant> + <constant name="TEXTURE_ORM" value="2" enum="DecalTexture"> + [Texture2D] corresponding to [member texture_orm]. + </constant> + <constant name="TEXTURE_EMISSION" value="3" enum="DecalTexture"> + [Texture2D] corresponding to [member texture_emission]. + </constant> + <constant name="TEXTURE_MAX" value="4" enum="DecalTexture"> + Max size of [enum DecalTexture] enum. + </constant> + </constants> +</class> diff --git a/doc/classes/Dictionary.xml b/doc/classes/Dictionary.xml index 540ebf3931..e982e00d6d 100644 --- a/doc/classes/Dictionary.xml +++ b/doc/classes/Dictionary.xml @@ -4,27 +4,29 @@ Dictionary type. </brief_description> <description> - Dictionary type. Associative container which contains values referenced by unique keys. Dictionary are composed of pairs of keys (which must be unique) and values. You can define a dictionary by placing a comma separated list of [code]key: value[/code] pairs in curly braces [code]{}[/code]. - Erasing elements while iterating over them [b]is not supported[/b]. + Dictionary type. Associative container which contains values referenced by unique keys. Dictionaries are composed of pairs of keys (which must be unique) and values. Dictionaries will preserve the insertion order when adding elements, even though this may not be reflected when printing the dictionary. In other programming languages, this data structure is sometimes referred to as an hash map or associative array. + You can define a dictionary by placing a comma-separated list of [code]key: value[/code] pairs in curly braces [code]{}[/code]. + Erasing elements while iterating over them [b]is not supported[/b] and will result in undefined behavior. Creating a dictionary: [codeblock] var my_dir = {} # Creates an empty dictionary. var points_dir = {"White": 50, "Yellow": 75, "Orange": 100} - var my_dir = { + var another_dir = { key1: value1, key2: value2, key3: value3, } [/codeblock] - You can access values of a dictionary by referencing appropriate key in above example [code]points_dir["White"][/code] would return value of 50. + You can access a dictionary's values by referencing the appropriate key. In the above example, [code]points_dir["White"][/code] will return [code]50[/code]. You can also write [code]points_dir.White[/code], which is equivalent. However, you'll have to use the bracket syntax if the key you're accessing the dictionary with isn't a fixed string (such as a number or variable). [codeblock] export(String, "White", "Yellow", "Orange") var my_color var points_dir = {"White": 50, "Yellow": 75, "Orange": 100} func _ready(): + # We can't use dot syntax here as `my_color` is a variable. var points = points_dir[my_color] [/codeblock] - In the above code [code]points[/code] will be assigned the value that is paired with the appropriate color selected in [code]my_color[/code]. + In the above code, [code]points[/code] will be assigned the value that is paired with the appropriate color selected in [code]my_color[/code]. Dictionaries can contain more complex data: [codeblock] my_dir = {"First Array": [1, 2, 3, 4]} # Assigns an Array to a String key. @@ -32,13 +34,21 @@ To add a key to an existing dictionary, access it like an existing key and assign to it: [codeblock] var points_dir = {"White": 50, "Yellow": 75, "Orange": 100} - var points_dir["Blue"] = 150 # Add "Blue" as a key and assign 150 as its value. + points_dir["Blue"] = 150 # Add "Blue" as a key and assign 150 as its value. [/codeblock] Finally, dictionaries can contain different types of keys and values in the same dictionary: [codeblock] - var my_dir = {"String Key": 5, 4: [1, 2, 3], 7: "Hello"} # This is a valid dictionary. + # This is a valid dictionary. + # To access the string "Nested value" below, use `my_dir.sub_dir.sub_key` or `my_dir["sub_dir"]["sub_key"]`. + # Indexing styles can be mixed and matched depending on your needs. + var my_dir = { + "String Key": 5, + 4: [1, 2, 3], + 7: "Hello", + "sub_dir": {"sub_key": "Nested value"}, + } [/codeblock] - [b]Note:[/b] Unlike [Array]s you can't compare dictionaries directly: + [b]Note:[/b] Unlike [Array]s, you can't compare dictionaries directly: [codeblock] array1 = [1, 2, 3] array2 = [1, 2, 3] @@ -78,7 +88,7 @@ <argument index="0" name="deep" type="bool" default="false"> </argument> <description> - Creates a copy of the dictionary, and returns it. + Creates a copy of the dictionary, and returns it. The [code]deep[/code] parameter causes inner dictionaries and arrays to be copied recursively, but does not apply to objects. </description> </method> <method name="empty"> diff --git a/doc/classes/DirectionalLight3D.xml b/doc/classes/DirectionalLight3D.xml index a5d476f5c8..6c88dcf42e 100644 --- a/doc/classes/DirectionalLight3D.xml +++ b/doc/classes/DirectionalLight3D.xml @@ -12,9 +12,6 @@ <methods> </methods> <members> - <member name="directional_shadow_bias_split_scale" type="float" setter="set_param" getter="get_param" default="0.25"> - Amount of extra bias for shadow splits that are far away. If self-shadowing occurs only on the splits far away, increasing this value can fix them. - </member> <member name="directional_shadow_blend_splits" type="bool" setter="set_blend_splits" getter="is_blend_splits_enabled" default="false"> If [code]true[/code], shadow detail is sacrificed in exchange for smoother transitions between splits. </member> @@ -22,6 +19,7 @@ Optimizes shadow rendering for detail versus movement. See [enum ShadowDepthRange]. </member> <member name="directional_shadow_fade_start" type="float" setter="set_param" getter="get_param" default="0.8"> + Proportion of [member directional_shadow_max_distance] at which point the shadow starts to fade. At [member directional_shadow_max_distance] the shadow will disappear. </member> <member name="directional_shadow_max_distance" type="float" setter="set_param" getter="get_param" default="100.0"> The maximum distance for shadow splits. @@ -29,8 +27,8 @@ <member name="directional_shadow_mode" type="int" setter="set_shadow_mode" getter="get_shadow_mode" enum="DirectionalLight3D.ShadowMode" default="2"> The light's shadow rendering algorithm. See [enum ShadowMode]. </member> - <member name="directional_shadow_normal_bias" type="float" setter="set_param" getter="get_param" default="0.8"> - Can be used to fix special cases of self shadowing when objects are perpendicular to the light. + <member name="directional_shadow_pancake_size" type="float" setter="set_param" getter="get_param" default="20.0"> + Sets the size of the directional shadow pancake. The pancake offsets the start of the shadow's camera frustum to provide a higher effective depth resolution for the shadow. However, a high pancake size can cause artifacts in the shadows of large objects that are close to the edge of the frustum. Reducing the pancake size can help. Setting the size to [code]0[/code] turns off the pancaking effect. </member> <member name="directional_shadow_split_1" type="float" setter="set_param" getter="get_param" default="0.1"> The distance from camera to shadow split 1. Relative to [member directional_shadow_max_distance]. Only used when [member directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or [code]SHADOW_PARALLEL_4_SPLITS[/code]. @@ -41,7 +39,6 @@ <member name="directional_shadow_split_3" type="float" setter="set_param" getter="get_param" default="0.5"> The distance from shadow split 2 to split 3. Relative to [member directional_shadow_max_distance]. Only used when [member directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]. </member> - <member name="shadow_bias" type="float" setter="set_param" getter="get_param" override="true" default="0.1" /> </members> <constants> <constant name="SHADOW_ORTHOGONAL" value="0" enum="ShadowMode"> diff --git a/doc/classes/DynamicFont.xml b/doc/classes/DynamicFont.xml index 29e430b14d..0864c3ba36 100644 --- a/doc/classes/DynamicFont.xml +++ b/doc/classes/DynamicFont.xml @@ -12,6 +12,7 @@ dynamic_font.size = 64 $"Label".set("custom_fonts/font", dynamic_font) [/codeblock] + [b]Note:[/b] DynamicFont doesn't support features such as right-to-left typesetting, ligatures, text shaping, variable fonts and optional font features yet. If you wish to "bake" an optional font feature into a TTF font file, you can use [url=https://fontforge.org/]FontForge[/url] to do so. In FontForge, use [b]File > Generate Fonts[/b], click [b]Options[/b], choose the desired features then generate the font. </description> <tutorials> </tutorials> diff --git a/doc/classes/EditorFeatureProfile.xml b/doc/classes/EditorFeatureProfile.xml index 53db8dd293..eb03d3010f 100644 --- a/doc/classes/EditorFeatureProfile.xml +++ b/doc/classes/EditorFeatureProfile.xml @@ -72,7 +72,7 @@ <argument index="0" name="path" type="String"> </argument> <description> - Saves the editor feature profile to a file in JSON format. It can then be imported using the feature profile manager's [b]Import[/b] button or the [method load_from_file] button. + Saves the editor feature profile to a file in JSON format. It can then be imported using the feature profile manager's [b]Import[/b] button or the [method load_from_file] button. </description> </method> <method name="set_disable_class"> diff --git a/doc/classes/EditorInspector.xml b/doc/classes/EditorInspector.xml index 61d240c1dc..99a78d147c 100644 --- a/doc/classes/EditorInspector.xml +++ b/doc/classes/EditorInspector.xml @@ -26,6 +26,12 @@ <description> </description> </signal> + <signal name="property_deleted"> + <argument index="0" name="property" type="String"> + </argument> + <description> + </description> + </signal> <signal name="property_edited"> <argument index="0" name="property" type="String"> </argument> diff --git a/doc/classes/EditorProperty.xml b/doc/classes/EditorProperty.xml index 3216541b20..4da3b58b94 100644 --- a/doc/classes/EditorProperty.xml +++ b/doc/classes/EditorProperty.xml @@ -78,6 +78,8 @@ <member name="checked" type="bool" setter="set_checked" getter="is_checked" default="false"> Used by the inspector, when the property is checked. </member> + <member name="deletable" type="bool" setter="set_deletable" getter="is_deletable" default="false"> + </member> <member name="draw_red" type="bool" setter="set_draw_red" getter="is_draw_red" default="false"> Used by the inspector, when the property must draw with error color. </member> @@ -128,6 +130,12 @@ Emitted when a property was checked. Used internally. </description> </signal> + <signal name="property_deleted"> + <argument index="0" name="property" type="StringName"> + </argument> + <description> + </description> + </signal> <signal name="property_keyed"> <argument index="0" name="property" type="StringName"> </argument> diff --git a/doc/classes/Environment.xml b/doc/classes/Environment.xml index 6f55bfc229..3642d92771 100644 --- a/doc/classes/Environment.xml +++ b/doc/classes/Environment.xml @@ -265,18 +265,25 @@ Represents the size of the [enum BGMode] enum. </constant> <constant name="AMBIENT_SOURCE_BG" value="0" enum="AmbientSource"> + Gather ambient light from whichever source is specified as the background. </constant> <constant name="AMBIENT_SOURCE_DISABLED" value="1" enum="AmbientSource"> + Disable ambient light. </constant> <constant name="AMBIENT_SOURCE_COLOR" value="2" enum="AmbientSource"> + Specify a specific [Color] for ambient light. </constant> <constant name="AMBIENT_SOURCE_SKY" value="3" enum="AmbientSource"> + Gather ambient light from the [Sky] regardless of what the background is. </constant> <constant name="REFLECTION_SOURCE_BG" value="0" enum="ReflectionSource"> + Use the background for reflections. </constant> <constant name="REFLECTION_SOURCE_DISABLED" value="1" enum="ReflectionSource"> + Disable reflections. </constant> <constant name="REFLECTION_SOURCE_SKY" value="2" enum="ReflectionSource"> + Use the [Sky] for reflections regardless of what the background is. </constant> <constant name="GLOW_BLEND_MODE_ADDITIVE" value="0" enum="GlowBlendMode"> Additive glow blending mode. Mostly used for particles, glows (bloom), lens flare, bright sources. @@ -291,6 +298,7 @@ Replace glow blending mode. Replaces all pixels' color by the glow value. This can be used to simulate a full-screen blur effect by tweaking the glow parameters to match the original image's brightness. </constant> <constant name="GLOW_BLEND_MODE_MIX" value="4" enum="GlowBlendMode"> + Mixes the glow with the underlying color to avoid increasing brightness as much while still maintaining a glow effect. </constant> <constant name="TONE_MAPPER_LINEAR" value="0" enum="ToneMapper"> Linear tonemapper operator. Reads the linear data and passes it on unmodified. @@ -314,7 +322,7 @@ 2×2 blur for the screen-space ambient occlusion effect. </constant> <constant name="SSAO_BLUR_3x3" value="3" enum="SSAOBlur"> - 3×3 blur for the screen-space ambient occlusion effect (slowest). + 3×3 blur for the screen-space ambient occlusion effect. Increases the radius of the blur for a smoother look, but can result in checkerboard-like artifacts. </constant> </constants> </class> diff --git a/doc/classes/File.xml b/doc/classes/File.xml index e9477517cf..17c65731ff 100644 --- a/doc/classes/File.xml +++ b/doc/classes/File.xml @@ -297,6 +297,7 @@ </argument> <description> Stores an integer as 16 bits in the file. + [b]Note:[/b] The [code]value[/code] should lie in the interval [code][0, 2^16 - 1][/code]. </description> </method> <method name="store_32"> @@ -306,6 +307,7 @@ </argument> <description> Stores an integer as 32 bits in the file. + [b]Note:[/b] The [code]value[/code] should lie in the interval [code][0, 2^32 - 1][/code]. </description> </method> <method name="store_64"> @@ -315,6 +317,7 @@ </argument> <description> Stores an integer as 64 bits in the file. + [b]Note:[/b] The [code]value[/code] must lie in the interval [code][-2^63, 2^63 - 1][/code] (i.e. be a valid [int] value). </description> </method> <method name="store_8"> @@ -324,6 +327,7 @@ </argument> <description> Stores an integer as 8 bits in the file. + [b]Note:[/b] The [code]value[/code] should lie in the interval [code][0, 255][/code]. </description> </method> <method name="store_buffer"> diff --git a/doc/classes/GeometryInstance3D.xml b/doc/classes/GeometryInstance3D.xml index 7df5f0ea50..518a172973 100644 --- a/doc/classes/GeometryInstance3D.xml +++ b/doc/classes/GeometryInstance3D.xml @@ -18,6 +18,14 @@ Returns the [enum GeometryInstance3D.Flags] that have been set for this object. </description> </method> + <method name="get_shader_instance_uniform" qualifiers="const"> + <return type="Variant"> + </return> + <argument index="0" name="uniform" type="StringName"> + </argument> + <description> + </description> + </method> <method name="set_custom_aabb"> <return type="void"> </return> @@ -38,6 +46,16 @@ Sets the [enum GeometryInstance3D.Flags] specified. See [enum GeometryInstance3D.Flags] for options. </description> </method> + <method name="set_shader_instance_uniform"> + <return type="void"> + </return> + <argument index="0" name="uniform" type="StringName"> + </argument> + <argument index="1" name="value" type="Variant"> + </argument> + <description> + </description> + </method> </methods> <members> <member name="cast_shadow" type="int" setter="set_cast_shadows_setting" getter="get_cast_shadows_setting" enum="GeometryInstance3D.ShadowCastingSetting" default="1"> diff --git a/doc/classes/GraphEdit.xml b/doc/classes/GraphEdit.xml index c41ffd4bff..750ac8085c 100644 --- a/doc/classes/GraphEdit.xml +++ b/doc/classes/GraphEdit.xml @@ -273,6 +273,12 @@ Emitted when a GraphNode is selected. </description> </signal> + <signal name="node_unselected"> + <argument index="0" name="node" type="Node"> + </argument> + <description> + </description> + </signal> <signal name="paste_nodes_request"> <description> Emitted when the user presses [code]Ctrl + V[/code]. diff --git a/doc/classes/HSlider.xml b/doc/classes/HSlider.xml index 2738958058..afe9d10d2e 100644 --- a/doc/classes/HSlider.xml +++ b/doc/classes/HSlider.xml @@ -19,6 +19,8 @@ <theme_item name="grabber_area" type="StyleBox"> The background of the area to the left of the grabber. </theme_item> + <theme_item name="grabber_area_highlight" type="StyleBox"> + </theme_item> <theme_item name="grabber_disabled" type="Texture2D"> The texture for the grabber when it's disabled. </theme_item> diff --git a/doc/classes/IP_Unix.xml b/doc/classes/IP_Unix.xml deleted file mode 100644 index 79cdf2ce08..0000000000 --- a/doc/classes/IP_Unix.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="IP_Unix" inherits="IP" version="4.0"> - <brief_description> - UNIX IP support. See [IP]. - </brief_description> - <description> - UNIX-specific implementation of IP support functions. See [IP]. - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/Image.xml b/doc/classes/Image.xml index f541b0ae66..8cffe07fc0 100644 --- a/doc/classes/Image.xml +++ b/doc/classes/Image.xml @@ -5,6 +5,7 @@ </brief_description> <description> Native image datatype. Contains image data, which can be converted to a [Texture2D], and several functions to interact with it. The maximum width and height for an [Image] are [constant MAX_WIDTH] and [constant MAX_HEIGHT]. + [b]Note:[/b] The maximum image size is 16384×16384 pixels due to graphics hardware limitations. Larger images will fail to import. </description> <tutorials> </tutorials> diff --git a/doc/classes/ImageTexture.xml b/doc/classes/ImageTexture.xml index 1578783b8b..d122d74e85 100644 --- a/doc/classes/ImageTexture.xml +++ b/doc/classes/ImageTexture.xml @@ -5,6 +5,7 @@ </brief_description> <description> A [Texture2D] based on an [Image]. Can be created from an [Image] with [method create_from_image]. + [b]Note:[/b] The maximum image size is 16384×16384 pixels due to graphics hardware limitations. Larger images will fail to import. </description> <tutorials> </tutorials> diff --git a/doc/classes/MonoGCHandle.xml b/doc/classes/JNISingleton.xml index 1e33dd1359..84ab1a49c1 100644 --- a/doc/classes/MonoGCHandle.xml +++ b/doc/classes/JNISingleton.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="MonoGCHandle" inherits="Reference" version="4.0"> +<class name="JNISingleton" inherits="Object" version="4.0"> <brief_description> </brief_description> <description> diff --git a/doc/classes/Light3D.xml b/doc/classes/Light3D.xml index 4e48a24951..cb21db2d00 100644 --- a/doc/classes/Light3D.xml +++ b/doc/classes/Light3D.xml @@ -35,6 +35,9 @@ <member name="editor_only" type="bool" setter="set_editor_only" getter="is_editor_only" default="false"> If [code]true[/code], the light only appears in the editor and will not be visible at runtime. </member> + <member name="light_angular_distance" type="float" setter="set_param" getter="get_param" default="0.0"> + Angular size of the light in degrees. Only available for [DirectionalLight3D]s. For reference, the sun from earth is approximately [code]0.5[/code]. + </member> <member name="light_bake_mode" type="int" setter="set_bake_mode" getter="get_bake_mode" enum="Light3D.BakeMode" default="1"> The light's bake mode. See [enum BakeMode]. </member> @@ -53,24 +56,35 @@ <member name="light_negative" type="bool" setter="set_negative" getter="is_negative" default="false"> If [code]true[/code], the light's effect is reversed, darkening areas and casting bright shadows. </member> + <member name="light_projector" type="Texture2D" setter="set_projector" getter="get_projector"> + [Texture2D] projected by light. [member shadow_enabled] must be on for the projector to work. Light projectors make the light appear as if it is shining through a colored but transparent object, almost like light shining through stained glass. + </member> + <member name="light_size" type="float" setter="set_param" getter="get_param" default="0.0"> + The size of the light in Godot units. Only available for [OmniLight3D]s and [SpotLight3D]s. + </member> <member name="light_specular" type="float" setter="set_param" getter="get_param" default="0.5"> The intensity of the specular blob in objects affected by the light. At [code]0[/code] the light becomes a pure diffuse light. </member> - <member name="shadow_bias" type="float" setter="set_param" getter="get_param" default="0.15"> + <member name="shadow_bias" type="float" setter="set_param" getter="get_param" default="0.02"> Used to adjust shadow appearance. Too small a value results in self-shadowing, while too large a value causes shadows to separate from casters. Adjust as needed. </member> + <member name="shadow_blur" type="float" setter="set_param" getter="get_param" default="1.0"> + Blurs the edges of the shadow. Can be used to hide pixel artifacts in low resolution shadow maps. A high value can make shadows appear grainy and can cause other unwanted artifacts. Try to keep as near default as possible. + </member> <member name="shadow_color" type="Color" setter="set_shadow_color" getter="get_shadow_color" default="Color( 0, 0, 0, 1 )"> The color of shadows cast by this light. </member> - <member name="shadow_contact" type="float" setter="set_param" getter="get_param" default="0.0"> - Attempts to reduce [member shadow_bias] gap. - </member> <member name="shadow_enabled" type="bool" setter="set_shadow" getter="has_shadow" default="false"> If [code]true[/code], the light will cast shadows. </member> + <member name="shadow_normal_bias" type="float" setter="set_param" getter="get_param" default="1.0"> + Offsets the lookup into the shadow map by the objects normal. This can be used reduce self-shadowing artifacts without using [member shadow_bias]. In practice, this value should be tweaked along with [member shadow_bias] to reduce artifacts as much as possible. + </member> <member name="shadow_reverse_cull_face" type="bool" setter="set_shadow_reverse_cull_face" getter="get_shadow_reverse_cull_face" default="false"> If [code]true[/code], reverses the backface culling of the mesh. This can be useful when you have a flat mesh that has a light behind it. If you need to cast a shadow on both sides of the mesh, set the mesh to use double-sided shadows with [constant GeometryInstance3D.SHADOW_CASTING_SETTING_DOUBLE_SIDED]. </member> + <member name="shadow_transmittance_bias" type="float" setter="set_param" getter="get_param" default="0.05"> + </member> </members> <constants> <constant name="PARAM_ENERGY" value="0" enum="Param"> @@ -85,18 +99,18 @@ <constant name="PARAM_RANGE" value="3" enum="Param"> Constant for accessing [member OmniLight3D.omni_range] or [member SpotLight3D.spot_range]. </constant> - <constant name="PARAM_ATTENUATION" value="4" enum="Param"> + <constant name="PARAM_SIZE" value="4" enum="Param"> + Constant for accessing [member light_size]. + </constant> + <constant name="PARAM_ATTENUATION" value="5" enum="Param"> Constant for accessing [member OmniLight3D.omni_attenuation] or [member SpotLight3D.spot_attenuation]. </constant> - <constant name="PARAM_SPOT_ANGLE" value="5" enum="Param"> + <constant name="PARAM_SPOT_ANGLE" value="6" enum="Param"> Constant for accessing [member SpotLight3D.spot_angle]. </constant> - <constant name="PARAM_SPOT_ATTENUATION" value="6" enum="Param"> + <constant name="PARAM_SPOT_ATTENUATION" value="7" enum="Param"> Constant for accessing [member SpotLight3D.spot_angle_attenuation]. </constant> - <constant name="PARAM_CONTACT_SHADOW_SIZE" value="7" enum="Param"> - Constant for accessing [member shadow_contact]. - </constant> <constant name="PARAM_SHADOW_MAX_DISTANCE" value="8" enum="Param"> Constant for accessing [member DirectionalLight3D.directional_shadow_max_distance]. </constant> @@ -110,17 +124,24 @@ Constant for accessing [member DirectionalLight3D.directional_shadow_split_3]. </constant> <constant name="PARAM_SHADOW_FADE_START" value="12" enum="Param"> + Constant for accessing [member DirectionalLight3D.directional_shadow_fade_start]. </constant> <constant name="PARAM_SHADOW_NORMAL_BIAS" value="13" enum="Param"> - Constant for accessing [member DirectionalLight3D.directional_shadow_normal_bias]. + Constant for accessing [member shadow_normal_bias]. </constant> <constant name="PARAM_SHADOW_BIAS" value="14" enum="Param"> Constant for accessing [member shadow_bias]. </constant> - <constant name="PARAM_SHADOW_BIAS_SPLIT_SCALE" value="15" enum="Param"> - Constant for accessing [member DirectionalLight3D.directional_shadow_bias_split_scale]. + <constant name="PARAM_SHADOW_PANCAKE_SIZE" value="15" enum="Param"> + Constant for accessing [member DirectionalLight3D.directional_shadow_pancake_size]. + </constant> + <constant name="PARAM_SHADOW_BLUR" value="16" enum="Param"> + Constant for accessing [member shadow_blur]. + </constant> + <constant name="PARAM_TRANSMITTANCE_BIAS" value="17" enum="Param"> + Constant for accessing [member shadow_transmittance_bias]. </constant> - <constant name="PARAM_MAX" value="16" enum="Param"> + <constant name="PARAM_MAX" value="18" enum="Param"> Represents the size of the [enum Param] enum. </constant> <constant name="BAKE_DISABLED" value="0" enum="BakeMode"> diff --git a/doc/classes/Node3D.xml b/doc/classes/Node3D.xml index ef24f638fb..3e7d4d4c05 100644 --- a/doc/classes/Node3D.xml +++ b/doc/classes/Node3D.xml @@ -6,6 +6,7 @@ <description> Most basic 3D game object, with a 3D [Transform] and visibility settings. All other 3D game objects inherit from Node3D. Use [Node3D] as a parent node to move, scale, rotate and show/hide children in a 3D project. Affine operations (rotate, scale, translate) happen in parent's local coordinate system, unless the [Node3D] object is set as top-level. Affine operations in this coordinate system correspond to direct affine operations on the [Node3D]'s transform. The word local below refers to this coordinate system. The coordinate system that is attached to the [Node3D] object itself is referred to as object-local coordinate system. + [b]Note:[/b] Unless otherwise specified, all methods that have angle parameters must have angles specified as [i]radians[/i]. To convert degrees to radians, use [method @GDScript.deg2rad]. </description> <tutorials> <link>https://docs.godotengine.org/en/latest/tutorials/3d/introduction_to_3d.html</link> diff --git a/doc/classes/OptionButton.xml b/doc/classes/OptionButton.xml index 5cb2aaf314..39d974ec47 100644 --- a/doc/classes/OptionButton.xml +++ b/doc/classes/OptionButton.xml @@ -214,14 +214,14 @@ </members> <signals> <signal name="item_focused"> - <argument index="0" name="id" type="int"> + <argument index="0" name="index" type="int"> </argument> <description> Emitted the when user navigates to an item using the [code]ui_up[/code] or [code]ui_down[/code] actions. The index of the item selected is passed as argument. </description> </signal> <signal name="item_selected"> - <argument index="0" name="id" type="int"> + <argument index="0" name="index" type="int"> </argument> <description> Emitted when the current item has been changed by the user. The index of the item selected is passed as argument. diff --git a/doc/classes/PackedScene.xml b/doc/classes/PackedScene.xml index e422545b7b..2d70dea012 100644 --- a/doc/classes/PackedScene.xml +++ b/doc/classes/PackedScene.xml @@ -9,23 +9,25 @@ [b]Note:[/b] The node doesn't need to own itself. [b]Example of saving a node with different owners:[/b] The following example creates 3 objects: [code]Node2D[/code] ([code]node[/code]), [code]RigidBody2D[/code] ([code]rigid[/code]) and [code]CollisionObject2D[/code] ([code]collision[/code]). [code]collision[/code] is a child of [code]rigid[/code] which is a child of [code]node[/code]. Only [code]rigid[/code] is owned by [code]node[/code] and [code]pack[/code] will therefore only save those two nodes, but not [code]collision[/code]. [codeblock] - # Create the objects + # Create the objects. var node = Node2D.new() var rigid = RigidBody2D.new() var collision = CollisionShape2D.new() - # Create the object hierarchy + # Create the object hierarchy. rigid.add_child(collision) node.add_child(rigid) - # Change owner of rigid, but not of collision + # Change owner of `rigid`, but not of `collision`. rigid.owner = node var scene = PackedScene.new() - # Only node and rigid are now packed + # Only `node` and `rigid` are now packed. var result = scene.pack(node) if result == OK: - ResourceSaver.save("res://path/name.scn", scene) # Or "user://..." + var error = ResourceSaver.save("res://path/name.scn", scene) # Or "user://..." + if error != OK: + push_error("An error occurred while saving the scene to disk.") [/codeblock] </description> <tutorials> diff --git a/doc/classes/PhysicalBone3D.xml b/doc/classes/PhysicalBone3D.xml index d45c72ee87..58930aae37 100644 --- a/doc/classes/PhysicalBone3D.xml +++ b/doc/classes/PhysicalBone3D.xml @@ -25,6 +25,14 @@ <description> </description> </method> + <method name="get_axis_lock" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="axis" type="int" enum="PhysicsServer3D.BodyAxis"> + </argument> + <description> + </description> + </method> <method name="get_bone_id" qualifiers="const"> <return type="int"> </return> @@ -43,23 +51,74 @@ <description> </description> </method> + <method name="set_axis_lock"> + <return type="void"> + </return> + <argument index="0" name="axis" type="int" enum="PhysicsServer3D.BodyAxis"> + </argument> + <argument index="1" name="lock" type="bool"> + </argument> + <description> + </description> + </method> </methods> <members> + <member name="angular_damp" type="float" setter="set_angular_damp" getter="get_angular_damp" default="-1.0"> + Damps the body's rotation if greater than [code]0[/code]. + </member> + <member name="axis_lock_angular_x" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false"> + Lock the body's rotation in the X axis. + </member> + <member name="axis_lock_angular_y" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false"> + Lock the body's rotation in the Y axis. + </member> + <member name="axis_lock_angular_z" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false"> + Lock the body's rotation in the Z axis. + </member> + <member name="axis_lock_linear_x" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false"> + Lock the body's movement in the X axis. + </member> + <member name="axis_lock_linear_y" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false"> + Lock the body's movement in the Y axis. + </member> + <member name="axis_lock_linear_z" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false"> + Lock the body's movement in the Z axis. + </member> <member name="body_offset" type="Transform" setter="set_body_offset" getter="get_body_offset" default="Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> + Sets the body's transform. </member> <member name="bounce" type="float" setter="set_bounce" getter="get_bounce" default="0.0"> + The body's bounciness. Values range from [code]0[/code] (no bounce) to [code]1[/code] (full bounciness). + </member> + <member name="can_sleep" type="bool" setter="set_can_sleep" getter="is_able_to_sleep" default="true"> + If [code]true[/code], the body is deactivated when there is no movement, so it will not take part in the simulation until it is awaken by an external force. </member> <member name="friction" type="float" setter="set_friction" getter="get_friction" default="1.0"> + The body's friction, from [code]0[/code] (frictionless) to [code]1[/code] (max friction). </member> <member name="gravity_scale" type="float" setter="set_gravity_scale" getter="get_gravity_scale" default="1.0"> + This is multiplied by the global 3D gravity setting found in [b]Project > Project Settings > Physics > 3d[/b] to produce the body's gravity. For example, a value of 1 will be normal gravity, 2 will apply double gravity, and 0.5 will apply half gravity to this object. </member> <member name="joint_offset" type="Transform" setter="set_joint_offset" getter="get_joint_offset" default="Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> + Sets the joint's transform. + </member> + <member name="joint_rotation" type="Vector3" setter="set_joint_rotation" getter="get_joint_rotation"> + Sets the joint's rotation in radians. + </member> + <member name="joint_rotation_degrees" type="Vector3" setter="set_joint_rotation_degrees" getter="get_joint_rotation_degrees" default="Vector3( 0, 0, 0 )"> + Sets the joint's rotation in degrees. </member> <member name="joint_type" type="int" setter="set_joint_type" getter="get_joint_type" enum="PhysicalBone3D.JointType" default="0"> + Sets the joint type. See [enum JointType] for possible values. + </member> + <member name="linear_damp" type="float" setter="set_linear_damp" getter="get_linear_damp" default="-1.0"> + Damps the body's movement if greater than [code]0[/code]. </member> <member name="mass" type="float" setter="set_mass" getter="get_mass" default="1.0"> + The body's mass. </member> <member name="weight" type="float" setter="set_weight" getter="get_weight" default="9.8"> + The body's weight based on its mass and the global 3D gravity. Global values are set in [b]Project > Project Settings > Physics > 3d[/b]. </member> </members> <constants> diff --git a/doc/classes/PhysicsDirectBodyState2DSW.xml b/doc/classes/PhysicsDirectBodyState2DSW.xml deleted file mode 100644 index 94fc4213b7..0000000000 --- a/doc/classes/PhysicsDirectBodyState2DSW.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="PhysicsDirectBodyState2DSW" inherits="PhysicsDirectBodyState2D" version="4.0"> - <brief_description> - Software implementation of [PhysicsDirectBodyState2D]. - </brief_description> - <description> - Software implementation of [PhysicsDirectBodyState2D]. This object exposes no new methods or properties and should not be used, as [PhysicsDirectBodyState2D] selects the best implementation available. - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/PhysicsDirectSpaceState3D.xml b/doc/classes/PhysicsDirectSpaceState3D.xml index 09ee93732d..ea094dcd90 100644 --- a/doc/classes/PhysicsDirectSpaceState3D.xml +++ b/doc/classes/PhysicsDirectSpaceState3D.xml @@ -19,7 +19,7 @@ </argument> <description> Checks whether the shape can travel to a point. The method will return an array with two floats between 0 and 1, both representing a fraction of [code]motion[/code]. The first is how far the shape can move without triggering a collision, and the second is the point at which a collision will occur. If no collision is detected, the returned array will be [code][1, 1][/code]. - If the shape can not move, the returned array will be [code][0, 0][/code] under Bullet, and empty under GodotPhysics. + If the shape can not move, the returned array will be [code][0, 0][/code] under Bullet, and empty under GodotPhysics3D. </description> </method> <method name="collide_shape"> diff --git a/doc/classes/PhysicsServer2DSW.xml b/doc/classes/PhysicsServer2DSW.xml deleted file mode 100644 index dac5e360f0..0000000000 --- a/doc/classes/PhysicsServer2DSW.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="PhysicsServer2DSW" inherits="PhysicsServer2D" version="4.0"> - <brief_description> - Software implementation of [PhysicsServer2D]. - </brief_description> - <description> - This class exposes no new methods or properties and should not be used, as [PhysicsServer2D] automatically selects the best implementation available. - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/ProceduralSkyMaterial.xml b/doc/classes/ProceduralSkyMaterial.xml index 70e82d248c..d3e1dbca27 100644 --- a/doc/classes/ProceduralSkyMaterial.xml +++ b/doc/classes/ProceduralSkyMaterial.xml @@ -40,11 +40,8 @@ <member name="sun_angle_max" type="float" setter="set_sun_angle_max" getter="get_sun_angle_max" default="100.0"> Distance from center of sun where it fades out completely. </member> - <member name="sun_angle_min" type="float" setter="set_sun_angle_min" getter="get_sun_angle_min" default="1.0"> - Distance from sun where it goes from solid to starting to fade. - </member> <member name="sun_curve" type="float" setter="set_sun_curve" getter="get_sun_curve" default="0.05"> - How quickly the sun fades away between [member sun_angle_min] and [member sun_angle_max]. + How quickly the sun fades away between the edge of the sun disk and [member sun_angle_max]. </member> </members> <constants> diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 3a4e516d86..4eb089e511 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -806,18 +806,6 @@ <member name="memory/limits/multithreaded_server/rid_pool_prealloc" type="int" setter="" getter="" default="60"> This is used by servers when used in multi-threading mode (servers and visual). RIDs are preallocated to avoid stalling the server requesting them on threads. If servers get stalled too often when loading resources in a thread, increase this number. </member> - <member name="mono/debugger_agent/port" type="int" setter="" getter="" default="23685"> - </member> - <member name="mono/debugger_agent/wait_for_debugger" type="bool" setter="" getter="" default="false"> - </member> - <member name="mono/debugger_agent/wait_timeout" type="int" setter="" getter="" default="3000"> - </member> - <member name="mono/profiler/args" type="String" setter="" getter="" default=""log:calls,alloc,sample,output=output.mlpd""> - </member> - <member name="mono/profiler/enabled" type="bool" setter="" getter="" default="false"> - </member> - <member name="mono/unhandled_exception_policy" type="int" setter="" getter="" default="0"> - </member> <member name="network/limits/debugger/max_chars_per_second" type="int" setter="" getter="" default="32768"> Maximum amount of characters allowed to send as output from the debugger. Over this value, content is dropped. This helps not to stall the debugger connection. </member> @@ -911,7 +899,7 @@ </member> <member name="physics/2d/physics_engine" type="String" setter="" getter="" default=""DEFAULT""> Sets which physics engine to use for 2D physics. - "DEFAULT" and "GodotPhysics" are the same, as there is currently no alternative 2D physics server implemented. + "DEFAULT" and "GodotPhysics2D" are the same, as there is currently no alternative 2D physics server implemented. </member> <member name="physics/2d/sleep_threshold_angular" type="float" setter="" getter="" default="0.139626"> Threshold angular velocity under which a 2D physics body will be considered inactive. See [constant PhysicsServer2D.SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD]. @@ -953,7 +941,7 @@ </member> <member name="physics/3d/physics_engine" type="String" setter="" getter="" default=""DEFAULT""> Sets which physics engine to use for 3D physics. - "DEFAULT" is currently the [url=https://bulletphysics.org]Bullet[/url] physics engine. The "GodotPhysics" engine is still supported as an alternative. + "DEFAULT" is currently the [url=https://bulletphysics.org]Bullet[/url] physics engine. The "GodotPhysics3D" engine is still supported as an alternative. </member> <member name="physics/common/enable_object_picking" type="bool" setter="" getter="" default="true"> Enables [member Viewport.physics_object_picking] on the root viewport. @@ -972,6 +960,8 @@ <member name="rendering/environment/default_environment" type="String" setter="" getter="" default=""""> [Environment] that will be used as a fallback environment in case a scene does not specify its own environment. The default environment is loaded in at scene load time regardless of whether you have set an environment or not. If you do not rely on the fallback environment, it is best to delete [code]default_env.tres[/code], or to specify a different default environment here. </member> + <member name="rendering/high_end/global_shader_variables_buffer_size" type="int" setter="" getter="" default="65536"> + </member> <member name="rendering/limits/rendering/max_renderable_elements" type="int" setter="" getter="" default="128000"> Max amount of elements renderable in a frame. If more than this are visible per frame, they will be dropped. Keep in mind elements refer to mesh surfaces and not meshes themselves. </member> @@ -982,6 +972,15 @@ <member name="rendering/quality/2d/use_pixel_snap" type="bool" setter="" getter="" default="false"> If [code]true[/code], forces snapping of polygons to pixels in 2D rendering. May help in some pixel art styles. </member> + <member name="rendering/quality/depth_of_field/depth_of_field_bokeh_quality" type="int" setter="" getter="" default="2"> + Sets the quality of the depth of field effect. Higher quality takes more samples, which is slower but looks smoother. + </member> + <member name="rendering/quality/depth_of_field/depth_of_field_bokeh_shape" type="int" setter="" getter="" default="1"> + Sets the depth of field shape. Can be Box, Hexagon, or Circle. Box is the fastest. Circle is the most realistic, but also the most expensive to compute. + </member> + <member name="rendering/quality/depth_of_field/depth_of_field_use_jitter" type="bool" setter="" getter="" default="false"> + If [code]true[/code], jitters DOF samples to make effect slightly blurrier and hide lines created from low sample rates. This can result in a slightly grainy appearance when used with a low number of samples. + </member> <member name="rendering/quality/depth_prepass/disable_for_vendors" type="String" setter="" getter="" default=""PowerVR,Mali,Adreno,Apple""> Disables depth pre-pass for some GPU vendors (usually mobile), as their architecture already does this. </member> @@ -994,38 +993,29 @@ <member name="rendering/quality/directional_shadow/size.mobile" type="int" setter="" getter="" default="2048"> Lower-end override for [member rendering/quality/directional_shadow/size] on mobile devices, due to performance concerns or driver support. </member> + <member name="rendering/quality/directional_shadow/soft_shadow_quality" type="int" setter="" getter="" default="2"> + Quality setting for shadows cast by [DirectionalLight3D]s. Higher quality settings use more samples when reading from shadow maps and are thus slower. Low quality settings may result in shadows looking grainy. + </member> + <member name="rendering/quality/directional_shadow/soft_shadow_quality.mobile" type="int" setter="" getter="" default="0"> + Lower-end override for [member rendering/quality/directional_shadow/soft_shadow_quality] on mobile devices, due to performance concerns or driver support. + </member> <member name="rendering/quality/driver/driver_name" type="String" setter="" getter="" default=""Vulkan""> The video driver to use ("GLES2" or "Vulkan"). [b]Note:[/b] The backend in use can be overridden at runtime via the [code]--rendering-driver[/code] command line argument. [b]FIXME:[/b] No longer valid after DisplayServer split: In such cases, this property is not updated, so use [code]OS.get_current_video_driver[/code] to query it at run-time. </member> - <member name="rendering/quality/filters/depth_of_field_bokeh_quality" type="int" setter="" getter="" default="2"> - </member> - <member name="rendering/quality/filters/depth_of_field_bokeh_shape" type="int" setter="" getter="" default="1"> - </member> - <member name="rendering/quality/filters/depth_of_field_use_jitter" type="bool" setter="" getter="" default="false"> - </member> - <member name="rendering/quality/filters/max_anisotropy" type="int" setter="" getter="" default="4"> - </member> - <member name="rendering/quality/filters/msaa" type="int" setter="" getter="" default="0"> - Sets the number of MSAA samples to use. MSAA is used to reduce aliasing around the edges of polygons. A higher MSAA value results in smoother edges but can be significantly slower on some hardware. - [b]Note:[/b] MSAA is not available on HTML5 export using the GLES2 backend. - </member> - <member name="rendering/quality/filters/screen_space_roughness_limiter" type="int" setter="" getter="" default="0"> - </member> - <member name="rendering/quality/filters/screen_space_roughness_limiter_curve" type="float" setter="" getter="" default="1.0"> - </member> - <member name="rendering/quality/filters/use_nearest_mipmap_filter" type="bool" setter="" getter="" default="false"> - If [code]true[/code], uses nearest-neighbor mipmap filtering when using mipmaps (also called "bilinear filtering"), which will result in visible seams appearing between mipmap stages. This may increase performance in mobile as less memory bandwidth is used. If [code]false[/code], linear mipmap filtering (also called "trilinear filtering") is used. - </member> <member name="rendering/quality/gi_probes/anisotropic" type="bool" setter="" getter="" default="false"> + If [code]true[/code], take additional samples when rendering objects affected by a [GIProbe] to reduce artifacts from only sampling in one direction. </member> <member name="rendering/quality/gi_probes/quality" type="int" setter="" getter="" default="1"> + Sets the number of cone samples taken when rendering objects affected by [GIProbe]s. </member> <member name="rendering/quality/glow/upscale_mode" type="int" setter="" getter="" default="1"> + Sets how the glow effect is upscaled before being copied onto the screen. Linear is faster, but looks blocky. Bicubic is slower but looks smooth. </member> <member name="rendering/quality/glow/upscale_mode.mobile" type="int" setter="" getter="" default="0"> + Lower-end override for [member rendering/quality/glow/upscale_mode] on mobile devices, due to performance concerns or driver support. </member> <member name="rendering/quality/intended_usage/framebuffer_allocation" type="int" setter="" getter="" default="2"> Strategy used for framebuffer allocation. The simpler it is, the less resources it uses (but the less features it supports). If set to "2D Without Sampling" or "3D Without Effects", sample buffers will not be allocated. This means [code]SCREEN_TEXTURE[/code] and [code]DEPTH_TEXTURE[/code] will not be available in shaders and post-processing effects will not be available in the [Environment]. @@ -1060,7 +1050,22 @@ <member name="rendering/quality/reflections/texture_array_reflections.mobile" type="bool" setter="" getter="" default="false"> Lower-end override for [member rendering/quality/reflections/texture_array_reflections] on mobile devices, due to performance concerns or driver support. </member> + <member name="rendering/quality/screen_filters/msaa" type="int" setter="" getter="" default="0"> + Sets the number of MSAA samples to use. MSAA is used to reduce aliasing around the edges of polygons. A higher MSAA value results in smoother edges but can be significantly slower on some hardware. + [b]Note:[/b] MSAA is not available on HTML5 export using the GLES2 backend. + </member> + <member name="rendering/quality/screen_filters/screen_space_aa" type="int" setter="" getter="" default="0"> + Sets the screen-space antialiasing mode for the default screen [Viewport]. Screen-space antialiasing works by selectively blurring edges in a post-process shader. It differs from MSAA which takes multiple coverage samples while rendering objects. Screen-space AA methods are typically faster than MSAA and will smooth out specular aliasing, but tend to make scenes appear blurry. + Another way to combat specular aliasing is to enable [member rendering/quality/screen_filters/screen_space_roughness_limiter]. + </member> + <member name="rendering/quality/screen_filters/screen_space_roughness_limiter" type="int" setter="" getter="" default="0"> + Enables the screen-space roughness limiter which increases material roughness in areas with a high normal frequency (i.e. when normals change a lot from pixel to pixel). This helps to reduce the amount of specular aliasing in a scene. Specular aliasing looks like random bright pixels that occur in reflections. + </member> + <member name="rendering/quality/screen_filters/screen_space_roughness_limiter_curve" type="float" setter="" getter="" default="1.0"> + Curves the amount of the roughness limited effect. A higher value limits the effect to very sharply curved surfaces, while a lower threshold extends the effect to smoother surfaces. + </member> <member name="rendering/quality/screen_space_reflection/roughness_quality" type="int" setter="" getter="" default="1"> + Sets the quality for rough screen-space reflections. Turning off will make all screen space reflections sharp, while higher values make rough reflections look better. </member> <member name="rendering/quality/shading/force_blinn_over_ggx" type="bool" setter="" getter="" default="false"> If [code]true[/code], uses faster but lower-quality Blinn model to generate blurred reflections instead of the GGX model. @@ -1098,21 +1103,33 @@ <member name="rendering/quality/shadow_atlas/size.mobile" type="int" setter="" getter="" default="2048"> Lower-end override for [member rendering/quality/shadow_atlas/size] on mobile devices, due to performance concerns or driver support. </member> - <member name="rendering/quality/shadows/filter_mode" type="int" setter="" getter="" default="1"> - Shadow filter mode. Higher-quality settings result in smoother shadows that flicker less when moving. "Disabled" is the fastest option, but also has the lowest quality. "PCF5" is smoother but is also slower. "PCF13" is the smoothest option, but is also the slowest. + <member name="rendering/quality/shadows/soft_shadow_quality" type="int" setter="" getter="" default="2"> + Quality setting for shadows cast by [OmniLight3D]s and [SpotLight3D]s. Higher quality settings use more samples when reading from shadow maps and are thus slower. Low quality settings may result in shadows looking grainy. </member> - <member name="rendering/quality/shadows/filter_mode.mobile" type="int" setter="" getter="" default="0"> - Lower-end override for [member rendering/quality/shadows/filter_mode] on mobile devices, due to performance concerns or driver support. + <member name="rendering/quality/shadows/soft_shadow_quality.mobile" type="int" setter="" getter="" default="0"> + Lower-end override for [member rendering/quality/shadows/soft_shadow_quality] on mobile devices, due to performance concerns or driver support. </member> <member name="rendering/quality/ssao/half_size" type="bool" setter="" getter="" default="false"> + If [code]true[/code], screen-space ambient occlusion will be rendered at half size and then upscaled before being added to the scene. This is significantly faster but may miss small details. </member> <member name="rendering/quality/ssao/quality" type="int" setter="" getter="" default="1"> + Sets the quality of the screen-space ambient occlusion effect. Higher values take more samples and so will result in better quality, at the cost of performance. </member> <member name="rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale" type="float" setter="" getter="" default="0.01"> + Scales the depth over which the subsurface scattering effect is applied. A high value may allow light to scatter into a part of the mesh or another mesh that is close in screen space but far in depth. </member> <member name="rendering/quality/subsurface_scattering/subsurface_scattering_quality" type="int" setter="" getter="" default="1"> + Sets the quality of the subsurface scattering effect. Higher values are slower but look nicer. </member> <member name="rendering/quality/subsurface_scattering/subsurface_scattering_scale" type="float" setter="" getter="" default="0.05"> + Scales the distance over which samples are taken for subsurface scattering effect. Changing this does not impact performance, but higher values will result in significant artifacts as the samples will become obviously spread out. A lower value results in a smaller spread of scattered light. + </member> + <member name="rendering/quality/texture_filters/max_anisotropy" type="int" setter="" getter="" default="4"> + Sets the maximum number of samples to take when using anisotropic filtering on textures. A higher sample count will result in sharper textures at oblique angles, but is more expensive to compute. + Only power of two values are valid ([code]1[/code], [code]2[/code], [code]4[/code], [code]8[/code], [code]16[/code]). A value of [code]1[/code] forcibly disables anisotropic filtering, even on materials where it is enabled. + </member> + <member name="rendering/quality/texture_filters/use_nearest_mipmap_filter" type="bool" setter="" getter="" default="false"> + If [code]true[/code], uses nearest-neighbor mipmap filtering when using mipmaps (also called "bilinear filtering"), which will result in visible seams appearing between mipmap stages. This may increase performance in mobile as less memory bandwidth is used. If [code]false[/code], linear mipmap filtering (also called "trilinear filtering") is used. </member> <member name="rendering/threads/thread_model" type="int" setter="" getter="" default="1"> Thread model for rendering. Rendering on a thread can vastly improve performance, but synchronizing to the main thread can cause a bit more jitter. diff --git a/doc/classes/RDAttachmentFormat.xml b/doc/classes/RDAttachmentFormat.xml new file mode 100644 index 0000000000..4ee7b9b28e --- /dev/null +++ b/doc/classes/RDAttachmentFormat.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="RDAttachmentFormat" inherits="Reference" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="format" type="int" setter="set_format" getter="get_format" enum="RenderingDevice.DataFormat" default="36"> + </member> + <member name="samples" type="int" setter="set_samples" getter="get_samples" enum="RenderingDevice.TextureSamples" default="0"> + </member> + <member name="usage_flags" type="int" setter="set_usage_flags" getter="get_usage_flags" default="0"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/RDPipelineColorBlendState.xml b/doc/classes/RDPipelineColorBlendState.xml new file mode 100644 index 0000000000..7cb31f6986 --- /dev/null +++ b/doc/classes/RDPipelineColorBlendState.xml @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="RDPipelineColorBlendState" inherits="Reference" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + <method name="add_attachment"> + <return type="void"> + </return> + <argument index="0" name="atachment" type="RDPipelineColorBlendStateAttachment"> + </argument> + <description> + </description> + </method> + <method name="add_blend_mix_attachment"> + <return type="void"> + </return> + <description> + </description> + </method> + <method name="add_no_blend_attachment"> + <return type="void"> + </return> + <description> + </description> + </method> + <method name="clear_attachments"> + <return type="void"> + </return> + <description> + </description> + </method> + <method name="get_attachments" qualifiers="const"> + <return type="Array"> + </return> + <description> + </description> + </method> + </methods> + <members> + <member name="blend_constant" type="Color" setter="set_blend_constant" getter="get_blend_constant" default="Color( 0, 0, 0, 1 )"> + </member> + <member name="enable_logic_op" type="bool" setter="set_enable_logic_op" getter="get_enable_logic_op" default="false"> + </member> + <member name="logic_op" type="int" setter="set_logic_op" getter="get_logic_op" enum="RenderingDevice.LogicOperation" default="0"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/RDPipelineColorBlendStateAttachment.xml b/doc/classes/RDPipelineColorBlendStateAttachment.xml new file mode 100644 index 0000000000..a4caa622aa --- /dev/null +++ b/doc/classes/RDPipelineColorBlendStateAttachment.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="RDPipelineColorBlendStateAttachment" inherits="Reference" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="alpha_blend_op" type="int" setter="set_alpha_blend_op" getter="get_alpha_blend_op" enum="RenderingDevice.BlendOperation" default="0"> + </member> + <member name="color_blend_op" type="int" setter="set_color_blend_op" getter="get_color_blend_op" enum="RenderingDevice.BlendOperation" default="0"> + </member> + <member name="dst_alpha_blend_factor" type="int" setter="set_dst_alpha_blend_factor" getter="get_dst_alpha_blend_factor" enum="RenderingDevice.BlendFactor" default="0"> + </member> + <member name="dst_color_blend_factor" type="int" setter="set_dst_color_blend_factor" getter="get_dst_color_blend_factor" enum="RenderingDevice.BlendFactor" default="0"> + </member> + <member name="enable_blend" type="bool" setter="set_enable_blend" getter="get_enable_blend" default="false"> + </member> + <member name="src_alpha_blend_factor" type="int" setter="set_src_alpha_blend_factor" getter="get_src_alpha_blend_factor" enum="RenderingDevice.BlendFactor" default="0"> + </member> + <member name="src_color_blend_factor" type="int" setter="set_src_color_blend_factor" getter="get_src_color_blend_factor" enum="RenderingDevice.BlendFactor" default="0"> + </member> + <member name="write_a" type="bool" setter="set_write_a" getter="get_write_a" default="true"> + </member> + <member name="write_b" type="bool" setter="set_write_b" getter="get_write_b" default="true"> + </member> + <member name="write_g" type="bool" setter="set_write_g" getter="get_write_g" default="true"> + </member> + <member name="write_r" type="bool" setter="set_write_r" getter="get_write_r" default="true"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/RDPipelineDepthStencilState.xml b/doc/classes/RDPipelineDepthStencilState.xml new file mode 100644 index 0000000000..562ff52819 --- /dev/null +++ b/doc/classes/RDPipelineDepthStencilState.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="RDPipelineDepthStencilState" inherits="Reference" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="back_op_compare" type="int" setter="set_back_op_compare" getter="get_back_op_compare" enum="RenderingDevice.CompareOperator" default="7"> + </member> + <member name="back_op_compare_mask" type="int" setter="set_back_op_compare_mask" getter="get_back_op_compare_mask" default="0"> + </member> + <member name="back_op_depth_fail" type="int" setter="set_back_op_depth_fail" getter="get_back_op_depth_fail" enum="RenderingDevice.StencilOperation" default="1"> + </member> + <member name="back_op_fail" type="int" setter="set_back_op_fail" getter="get_back_op_fail" enum="RenderingDevice.StencilOperation" default="1"> + </member> + <member name="back_op_pass" type="int" setter="set_back_op_pass" getter="get_back_op_pass" enum="RenderingDevice.StencilOperation" default="1"> + </member> + <member name="back_op_reference" type="int" setter="set_back_op_reference" getter="get_back_op_reference" default="0"> + </member> + <member name="back_op_write_mask" type="int" setter="set_back_op_write_mask" getter="get_back_op_write_mask" default="0"> + </member> + <member name="depth_compare_operator" type="int" setter="set_depth_compare_operator" getter="get_depth_compare_operator" enum="RenderingDevice.CompareOperator" default="7"> + </member> + <member name="depth_range_max" type="float" setter="set_depth_range_max" getter="get_depth_range_max" default="0.0"> + </member> + <member name="depth_range_min" type="float" setter="set_depth_range_min" getter="get_depth_range_min" default="0.0"> + </member> + <member name="enable_depth_range" type="bool" setter="set_enable_depth_range" getter="get_enable_depth_range" default="false"> + </member> + <member name="enable_depth_test" type="bool" setter="set_enable_depth_test" getter="get_enable_depth_test" default="false"> + </member> + <member name="enable_depth_write" type="bool" setter="set_enable_depth_write" getter="get_enable_depth_write" default="false"> + </member> + <member name="enable_stencil" type="bool" setter="set_enable_stencil" getter="get_enable_stencil" default="false"> + </member> + <member name="front_op_compare" type="int" setter="set_front_op_compare" getter="get_front_op_compare" enum="RenderingDevice.CompareOperator" default="7"> + </member> + <member name="front_op_compare_mask" type="int" setter="set_front_op_compare_mask" getter="get_front_op_compare_mask" default="0"> + </member> + <member name="front_op_depth_fail" type="int" setter="set_front_op_depth_fail" getter="get_front_op_depth_fail" enum="RenderingDevice.StencilOperation" default="1"> + </member> + <member name="front_op_fail" type="int" setter="set_front_op_fail" getter="get_front_op_fail" enum="RenderingDevice.StencilOperation" default="1"> + </member> + <member name="front_op_pass" type="int" setter="set_front_op_pass" getter="get_front_op_pass" enum="RenderingDevice.StencilOperation" default="1"> + </member> + <member name="front_op_reference" type="int" setter="set_front_op_reference" getter="get_front_op_reference" default="0"> + </member> + <member name="front_op_write_mask" type="int" setter="set_front_op_write_mask" getter="get_front_op_write_mask" default="0"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/RDPipelineMultisampleState.xml b/doc/classes/RDPipelineMultisampleState.xml new file mode 100644 index 0000000000..b936ded4fe --- /dev/null +++ b/doc/classes/RDPipelineMultisampleState.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="RDPipelineMultisampleState" inherits="Reference" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + <method name="add_sample_mask"> + <return type="void"> + </return> + <argument index="0" name="mask" type="int"> + </argument> + <description> + </description> + </method> + <method name="clear_sample_masks"> + <return type="void"> + </return> + <description> + </description> + </method> + <method name="get_sample_masks" qualifiers="const"> + <return type="PackedInt64Array"> + </return> + <description> + </description> + </method> + </methods> + <members> + <member name="enable_alpha_to_coverage" type="bool" setter="set_enable_alpha_to_coverage" getter="get_enable_alpha_to_coverage" default="false"> + </member> + <member name="enable_alpha_to_one" type="bool" setter="set_enable_alpha_to_one" getter="get_enable_alpha_to_one" default="false"> + </member> + <member name="enable_sample_shading" type="bool" setter="set_enable_sample_shading" getter="get_enable_sample_shading" default="false"> + </member> + <member name="min_sample_shading" type="float" setter="set_min_sample_shading" getter="get_min_sample_shading" default="0.0"> + </member> + <member name="sample_count" type="int" setter="set_sample_count" getter="get_sample_count" enum="RenderingDevice.TextureSamples" default="0"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/RDPipelineRasterizationState.xml b/doc/classes/RDPipelineRasterizationState.xml new file mode 100644 index 0000000000..5064dd6deb --- /dev/null +++ b/doc/classes/RDPipelineRasterizationState.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="RDPipelineRasterizationState" inherits="Reference" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="cull_mode" type="int" setter="set_cull_mode" getter="get_cull_mode" enum="RenderingDevice.PolygonCullMode" default="0"> + </member> + <member name="depth_bias_clamp" type="float" setter="set_depth_bias_clamp" getter="get_depth_bias_clamp" default="0.0"> + </member> + <member name="depth_bias_constant_factor" type="float" setter="set_depth_bias_constant_factor" getter="get_depth_bias_constant_factor" default="0.0"> + </member> + <member name="depth_bias_enable" type="bool" setter="set_depth_bias_enable" getter="get_depth_bias_enable" default="false"> + </member> + <member name="depth_bias_slope_factor" type="float" setter="set_depth_bias_slope_factor" getter="get_depth_bias_slope_factor" default="0.0"> + </member> + <member name="discard_primitives" type="bool" setter="set_discard_primitives" getter="get_discard_primitives" default="false"> + </member> + <member name="enable_depth_clamp" type="bool" setter="set_enable_depth_clamp" getter="get_enable_depth_clamp" default="false"> + </member> + <member name="front_face" type="int" setter="set_front_face" getter="get_front_face" enum="RenderingDevice.PolygonFrontFace" default="0"> + </member> + <member name="line_width" type="float" setter="set_line_width" getter="get_line_width" default="1.0"> + </member> + <member name="patch_control_points" type="int" setter="set_patch_control_points" getter="get_patch_control_points" default="1"> + </member> + <member name="wireframe" type="bool" setter="set_wireframe" getter="get_wireframe" default="false"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/RDSamplerState.xml b/doc/classes/RDSamplerState.xml new file mode 100644 index 0000000000..ab31960b7c --- /dev/null +++ b/doc/classes/RDSamplerState.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="RDSamplerState" inherits="Reference" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="anisotropy_max" type="float" setter="set_anisotropy_max" getter="get_anisotropy_max" default="1.0"> + </member> + <member name="border_color" type="int" setter="set_border_color" getter="get_border_color" enum="RenderingDevice.SamplerBorderColor" default="2"> + </member> + <member name="compare_op" type="int" setter="set_compare_op" getter="get_compare_op" enum="RenderingDevice.CompareOperator" default="7"> + </member> + <member name="enable_compare" type="bool" setter="set_enable_compare" getter="get_enable_compare" default="false"> + </member> + <member name="lod_bias" type="float" setter="set_lod_bias" getter="get_lod_bias" default="0.0"> + </member> + <member name="mag_filter" type="int" setter="set_mag_filter" getter="get_mag_filter" enum="RenderingDevice.SamplerFilter" default="0"> + </member> + <member name="max_lod" type="float" setter="set_max_lod" getter="get_max_lod" default="1e+20"> + </member> + <member name="min_filter" type="int" setter="set_min_filter" getter="get_min_filter" enum="RenderingDevice.SamplerFilter" default="0"> + </member> + <member name="min_lod" type="float" setter="set_min_lod" getter="get_min_lod" default="0.0"> + </member> + <member name="mip_filter" type="int" setter="set_mip_filter" getter="get_mip_filter" enum="RenderingDevice.SamplerFilter" default="0"> + </member> + <member name="repeat_u" type="int" setter="set_repeat_u" getter="get_repeat_u" enum="RenderingDevice.SamplerRepeatMode" default="2"> + </member> + <member name="repeat_v" type="int" setter="set_repeat_v" getter="get_repeat_v" enum="RenderingDevice.SamplerRepeatMode" default="2"> + </member> + <member name="repeat_w" type="int" setter="set_repeat_w" getter="get_repeat_w" enum="RenderingDevice.SamplerRepeatMode" default="2"> + </member> + <member name="unnormalized_uvw" type="bool" setter="set_unnormalized_uvw" getter="get_unnormalized_uvw" default="false"> + </member> + <member name="use_anisotropy" type="bool" setter="set_use_anisotropy" getter="get_use_anisotropy" default="false"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/RDShaderBytecode.xml b/doc/classes/RDShaderBytecode.xml new file mode 100644 index 0000000000..7a3501004e --- /dev/null +++ b/doc/classes/RDShaderBytecode.xml @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="RDShaderBytecode" inherits="Resource" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + <method name="get_stage_bytecode" qualifiers="const"> + <return type="PackedByteArray"> + </return> + <argument index="0" name="stage" type="int" enum="RenderingDevice.ShaderStage"> + </argument> + <description> + </description> + </method> + <method name="get_stage_compile_error" qualifiers="const"> + <return type="String"> + </return> + <argument index="0" name="stage" type="int" enum="RenderingDevice.ShaderStage"> + </argument> + <description> + </description> + </method> + <method name="set_stage_bytecode"> + <return type="void"> + </return> + <argument index="0" name="stage" type="int" enum="RenderingDevice.ShaderStage"> + </argument> + <argument index="1" name="bytecode" type="PackedByteArray"> + </argument> + <description> + </description> + </method> + <method name="set_stage_compile_error"> + <return type="void"> + </return> + <argument index="0" name="stage" type="int" enum="RenderingDevice.ShaderStage"> + </argument> + <argument index="1" name="compile_error" type="String"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="bytecode_compute" type="PackedByteArray" setter="set_stage_bytecode" getter="get_stage_bytecode" default="PackedByteArray( )"> + </member> + <member name="bytecode_fragment" type="PackedByteArray" setter="set_stage_bytecode" getter="get_stage_bytecode" default="PackedByteArray( )"> + </member> + <member name="bytecode_tesselation_control" type="PackedByteArray" setter="set_stage_bytecode" getter="get_stage_bytecode" default="PackedByteArray( )"> + </member> + <member name="bytecode_tesselation_evaluation" type="PackedByteArray" setter="set_stage_bytecode" getter="get_stage_bytecode" default="PackedByteArray( )"> + </member> + <member name="bytecode_vertex" type="PackedByteArray" setter="set_stage_bytecode" getter="get_stage_bytecode" default="PackedByteArray( )"> + </member> + <member name="compile_error_compute" type="String" setter="set_stage_compile_error" getter="get_stage_compile_error" default=""""> + </member> + <member name="compile_error_fragment" type="String" setter="set_stage_compile_error" getter="get_stage_compile_error" default=""""> + </member> + <member name="compile_error_tesselation_control" type="String" setter="set_stage_compile_error" getter="get_stage_compile_error" default=""""> + </member> + <member name="compile_error_tesselation_evaluation" type="String" setter="set_stage_compile_error" getter="get_stage_compile_error" default=""""> + </member> + <member name="compile_error_vertex" type="String" setter="set_stage_compile_error" getter="get_stage_compile_error" default=""""> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/RDShaderFile.xml b/doc/classes/RDShaderFile.xml new file mode 100644 index 0000000000..14e70d53ea --- /dev/null +++ b/doc/classes/RDShaderFile.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="RDShaderFile" inherits="Resource" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + <method name="get_bytecode" qualifiers="const"> + <return type="RDShaderBytecode"> + </return> + <argument index="0" name="version" type="StringName" default="@"""> + </argument> + <description> + </description> + </method> + <method name="get_version_list" qualifiers="const"> + <return type="PackedStringArray"> + </return> + <description> + </description> + </method> + <method name="set_bytecode"> + <return type="void"> + </return> + <argument index="0" name="bytecode" type="RDShaderBytecode"> + </argument> + <argument index="1" name="version" type="StringName" default="@"""> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="base_error" type="String" setter="set_base_error" getter="get_base_error" default=""""> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/RDShaderSource.xml b/doc/classes/RDShaderSource.xml new file mode 100644 index 0000000000..c1cfd34bb7 --- /dev/null +++ b/doc/classes/RDShaderSource.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="RDShaderSource" inherits="Reference" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + <method name="get_stage_source" qualifiers="const"> + <return type="String"> + </return> + <argument index="0" name="stage" type="int" enum="RenderingDevice.ShaderStage"> + </argument> + <description> + </description> + </method> + <method name="set_stage_source"> + <return type="void"> + </return> + <argument index="0" name="stage" type="int" enum="RenderingDevice.ShaderStage"> + </argument> + <argument index="1" name="source" type="String"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="language" type="int" setter="set_language" getter="get_language" enum="RenderingDevice.ShaderLanguage" default="0"> + </member> + <member name="source_compute" type="String" setter="set_stage_source" getter="get_stage_source" default=""""> + </member> + <member name="source_fragment" type="String" setter="set_stage_source" getter="get_stage_source" default=""""> + </member> + <member name="source_tesselation_control" type="String" setter="set_stage_source" getter="get_stage_source" default=""""> + </member> + <member name="source_tesselation_evaluation" type="String" setter="set_stage_source" getter="get_stage_source" default=""""> + </member> + <member name="source_vertex" type="String" setter="set_stage_source" getter="get_stage_source" default=""""> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/RDTextureFormat.xml b/doc/classes/RDTextureFormat.xml new file mode 100644 index 0000000000..664d4cadff --- /dev/null +++ b/doc/classes/RDTextureFormat.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="RDTextureFormat" inherits="Reference" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + <method name="add_shareable_format"> + <return type="void"> + </return> + <argument index="0" name="format" type="int" enum="RenderingDevice.DataFormat"> + </argument> + <description> + </description> + </method> + <method name="remove_shareable_format"> + <return type="void"> + </return> + <argument index="0" name="format" type="int" enum="RenderingDevice.DataFormat"> + </argument> + <description> + </description> + </method> + </methods> + <members> + <member name="array_layers" type="int" setter="set_array_layers" getter="get_array_layers" default="1"> + </member> + <member name="depth" type="int" setter="set_depth" getter="get_depth" default="1"> + </member> + <member name="format" type="int" setter="set_format" getter="get_format" enum="RenderingDevice.DataFormat" default="8"> + </member> + <member name="height" type="int" setter="set_height" getter="get_height" default="1"> + </member> + <member name="mipmaps" type="int" setter="set_mipmaps" getter="get_mipmaps" default="1"> + </member> + <member name="samples" type="int" setter="set_samples" getter="get_samples" enum="RenderingDevice.TextureSamples" default="0"> + </member> + <member name="type" type="int" setter="set_type" getter="get_type" enum="RenderingDevice.TextureType" default="1"> + </member> + <member name="usage_bits" type="int" setter="set_usage_bits" getter="get_usage_bits" default="0"> + </member> + <member name="width" type="int" setter="set_width" getter="get_width" default="1"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/RDTextureView.xml b/doc/classes/RDTextureView.xml new file mode 100644 index 0000000000..73b2a7ae4a --- /dev/null +++ b/doc/classes/RDTextureView.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="RDTextureView" inherits="Reference" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="format_override" type="int" setter="set_format_override" getter="get_format_override" enum="RenderingDevice.DataFormat" default="226"> + </member> + <member name="swizzle_a" type="int" setter="set_swizzle_a" getter="get_swizzle_a" enum="RenderingDevice.TextureSwizzle" default="6"> + </member> + <member name="swizzle_b" type="int" setter="set_swizzle_b" getter="get_swizzle_b" enum="RenderingDevice.TextureSwizzle" default="5"> + </member> + <member name="swizzle_g" type="int" setter="set_swizzle_g" getter="get_swizzle_g" enum="RenderingDevice.TextureSwizzle" default="4"> + </member> + <member name="swizzle_r" type="int" setter="set_swizzle_r" getter="get_swizzle_r" enum="RenderingDevice.TextureSwizzle" default="3"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/RDUniform.xml b/doc/classes/RDUniform.xml new file mode 100644 index 0000000000..e5bace32af --- /dev/null +++ b/doc/classes/RDUniform.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="RDUniform" inherits="Reference" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + <method name="add_id"> + <return type="void"> + </return> + <argument index="0" name="id" type="RID"> + </argument> + <description> + </description> + </method> + <method name="clear_ids"> + <return type="void"> + </return> + <description> + </description> + </method> + <method name="get_ids" qualifiers="const"> + <return type="Array"> + </return> + <description> + </description> + </method> + </methods> + <members> + <member name="binding" type="int" setter="set_binding" getter="get_binding" default="0"> + </member> + <member name="type" type="int" setter="set_type" getter="get_type" enum="RenderingDevice.UniformType" default="3"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/RDVertexDescription.xml b/doc/classes/RDVertexDescription.xml new file mode 100644 index 0000000000..90e37ee023 --- /dev/null +++ b/doc/classes/RDVertexDescription.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="RDVertexDescription" inherits="Reference" version="4.0"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="format" type="int" setter="set_format" getter="get_format" enum="RenderingDevice.DataFormat" default="226"> + </member> + <member name="frequency" type="int" setter="set_frequency" getter="get_frequency" enum="RenderingDevice.VertexFrequency" default="0"> + </member> + <member name="location" type="int" setter="set_location" getter="get_location" default="0"> + </member> + <member name="offset" type="int" setter="set_offset" getter="get_offset" default="0"> + </member> + <member name="stride" type="int" setter="set_stride" getter="get_stride" default="0"> + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/RenderingDevice.xml b/doc/classes/RenderingDevice.xml index 2615f0a2e9..6d68eafc70 100644 --- a/doc/classes/RenderingDevice.xml +++ b/doc/classes/RenderingDevice.xml @@ -7,7 +7,1593 @@ <tutorials> </tutorials> <methods> + <method name="buffer_get_data"> + <return type="PackedByteArray"> + </return> + <argument index="0" name="buffer" type="RID"> + </argument> + <description> + </description> + </method> + <method name="buffer_update"> + <return type="int" enum="Error"> + </return> + <argument index="0" name="buffer" type="RID"> + </argument> + <argument index="1" name="offset" type="int"> + </argument> + <argument index="2" name="size_bytes" type="int"> + </argument> + <argument index="3" name="data" type="PackedByteArray"> + </argument> + <argument index="4" name="sync_with_draw" type="bool" default="true"> + </argument> + <description> + </description> + </method> + <method name="capture_timestamp"> + <return type="void"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <argument index="1" name="sync_to_draw" type="bool"> + </argument> + <description> + </description> + </method> + <method name="compute_list_add_barrier"> + <return type="void"> + </return> + <argument index="0" name="compute_list" type="int"> + </argument> + <description> + </description> + </method> + <method name="compute_list_begin"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="compute_list_bind_compute_pipeline"> + <return type="void"> + </return> + <argument index="0" name="compute_list" type="int"> + </argument> + <argument index="1" name="compute_pipeline" type="RID"> + </argument> + <description> + </description> + </method> + <method name="compute_list_bind_uniform_set"> + <return type="void"> + </return> + <argument index="0" name="compute_list" type="int"> + </argument> + <argument index="1" name="uniform_set" type="RID"> + </argument> + <argument index="2" name="set_index" type="int"> + </argument> + <description> + </description> + </method> + <method name="compute_list_dispatch"> + <return type="void"> + </return> + <argument index="0" name="compute_list" type="int"> + </argument> + <argument index="1" name="x_groups" type="int"> + </argument> + <argument index="2" name="y_groups" type="int"> + </argument> + <argument index="3" name="z_groups" type="int"> + </argument> + <description> + </description> + </method> + <method name="compute_list_end"> + <return type="void"> + </return> + <description> + </description> + </method> + <method name="compute_list_set_push_constant"> + <return type="void"> + </return> + <argument index="0" name="compute_list" type="int"> + </argument> + <argument index="1" name="buffer" type="PackedByteArray"> + </argument> + <argument index="2" name="size_bytes" type="int"> + </argument> + <description> + </description> + </method> + <method name="compute_pipeline_create"> + <return type="RID"> + </return> + <argument index="0" name="shader" type="RID"> + </argument> + <description> + </description> + </method> + <method name="compute_pipeline_is_valid"> + <return type="bool"> + </return> + <argument index="0" name="compute_pieline" type="RID"> + </argument> + <description> + </description> + </method> + <method name="create_local_device"> + <return type="RenderingDevice"> + </return> + <description> + </description> + </method> + <method name="draw_list_begin"> + <return type="int"> + </return> + <argument index="0" name="framebuffer" type="RID"> + </argument> + <argument index="1" name="initial_color_action" type="int" enum="RenderingDevice.InitialAction"> + </argument> + <argument index="2" name="final_color_action" type="int" enum="RenderingDevice.FinalAction"> + </argument> + <argument index="3" name="initial_depth_action" type="int" enum="RenderingDevice.InitialAction"> + </argument> + <argument index="4" name="final_depth_action" type="int" enum="RenderingDevice.FinalAction"> + </argument> + <argument index="5" name="clear_color_values" type="PackedColorArray" default="PackedColorArray( )"> + </argument> + <argument index="6" name="clear_depth" type="float" default="1.0"> + </argument> + <argument index="7" name="clear_stencil" type="int" default="0"> + </argument> + <argument index="8" name="region" type="Rect2" default="Rect2i( 0, 0, 0, 0 )"> + </argument> + <description> + </description> + </method> + <method name="draw_list_begin_for_screen"> + <return type="int"> + </return> + <argument index="0" name="screen" type="int" default="0"> + </argument> + <argument index="1" name="clear_color" type="Color" default="Color( 0, 0, 0, 1 )"> + </argument> + <description> + </description> + </method> + <method name="draw_list_begin_split"> + <return type="PackedInt64Array"> + </return> + <argument index="0" name="framebuffer" type="RID"> + </argument> + <argument index="1" name="splits" type="int"> + </argument> + <argument index="2" name="initial_color_action" type="int" enum="RenderingDevice.InitialAction"> + </argument> + <argument index="3" name="final_color_action" type="int" enum="RenderingDevice.FinalAction"> + </argument> + <argument index="4" name="initial_depth_action" type="int" enum="RenderingDevice.InitialAction"> + </argument> + <argument index="5" name="final_depth_action" type="int" enum="RenderingDevice.FinalAction"> + </argument> + <argument index="6" name="clear_color_values" type="PackedColorArray" default="PackedColorArray( )"> + </argument> + <argument index="7" name="clear_depth" type="float" default="1.0"> + </argument> + <argument index="8" name="clear_stencil" type="int" default="0"> + </argument> + <argument index="9" name="region" type="Rect2" default="Rect2i( 0, 0, 0, 0 )"> + </argument> + <description> + </description> + </method> + <method name="draw_list_bind_index_array"> + <return type="void"> + </return> + <argument index="0" name="draw_list" type="int"> + </argument> + <argument index="1" name="index_array" type="RID"> + </argument> + <description> + </description> + </method> + <method name="draw_list_bind_render_pipeline"> + <return type="void"> + </return> + <argument index="0" name="draw_list" type="int"> + </argument> + <argument index="1" name="render_pipeline" type="RID"> + </argument> + <description> + </description> + </method> + <method name="draw_list_bind_uniform_set"> + <return type="void"> + </return> + <argument index="0" name="draw_list" type="int"> + </argument> + <argument index="1" name="uniform_set" type="RID"> + </argument> + <argument index="2" name="set_index" type="int"> + </argument> + <description> + </description> + </method> + <method name="draw_list_bind_vertex_array"> + <return type="void"> + </return> + <argument index="0" name="draw_list" type="int"> + </argument> + <argument index="1" name="vertex_array" type="RID"> + </argument> + <description> + </description> + </method> + <method name="draw_list_disable_scissor"> + <return type="void"> + </return> + <argument index="0" name="draw_list" type="int"> + </argument> + <description> + </description> + </method> + <method name="draw_list_draw"> + <return type="void"> + </return> + <argument index="0" name="draw_list" type="int"> + </argument> + <argument index="1" name="use_indices" type="bool"> + </argument> + <argument index="2" name="instances" type="int"> + </argument> + <argument index="3" name="procedural_vertex_count" type="int" default="0"> + </argument> + <description> + </description> + </method> + <method name="draw_list_enable_scissor"> + <return type="void"> + </return> + <argument index="0" name="draw_list" type="int"> + </argument> + <argument index="1" name="rect" type="Rect2" default="Rect2i( 0, 0, 0, 0 )"> + </argument> + <description> + </description> + </method> + <method name="draw_list_end"> + <return type="void"> + </return> + <description> + </description> + </method> + <method name="draw_list_set_push_constant"> + <return type="void"> + </return> + <argument index="0" name="draw_list" type="int"> + </argument> + <argument index="1" name="buffer" type="PackedByteArray"> + </argument> + <argument index="2" name="size_bytes" type="int"> + </argument> + <description> + </description> + </method> + <method name="framebuffer_create"> + <return type="RID"> + </return> + <argument index="0" name="textures" type="Array"> + </argument> + <argument index="1" name="validate_with_format" type="int" default="-1"> + </argument> + <description> + </description> + </method> + <method name="framebuffer_format_create"> + <return type="int"> + </return> + <argument index="0" name="attachments" type="Array"> + </argument> + <description> + </description> + </method> + <method name="framebuffer_format_get_texture_samples"> + <return type="int" enum="RenderingDevice.TextureSamples"> + </return> + <argument index="0" name="format" type="int"> + </argument> + <description> + </description> + </method> + <method name="framebuffer_get_format"> + <return type="int"> + </return> + <argument index="0" name="framebuffer" type="RID"> + </argument> + <description> + </description> + </method> + <method name="free"> + <return type="void"> + </return> + <argument index="0" name="rid" type="RID"> + </argument> + <description> + </description> + </method> + <method name="get_captured_timestamp_cpu_time" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="index" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_captured_timestamp_gpu_time" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="index" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_captured_timestamp_name" qualifiers="const"> + <return type="String"> + </return> + <argument index="0" name="index" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_captured_timestamps_count" qualifiers="const"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="get_captured_timestamps_frame" qualifiers="const"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="get_frame_delay" qualifiers="const"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="index_array_create"> + <return type="RID"> + </return> + <argument index="0" name="index_buffer" type="RID"> + </argument> + <argument index="1" name="index_offset" type="int"> + </argument> + <argument index="2" name="index_count" type="int"> + </argument> + <description> + </description> + </method> + <method name="index_buffer_create"> + <return type="RID"> + </return> + <argument index="0" name="size_indices" type="int"> + </argument> + <argument index="1" name="format" type="int" enum="RenderingDevice.IndexBufferFormat"> + </argument> + <argument index="2" name="data" type="PackedByteArray"> + </argument> + <argument index="3" name="arg3" type="bool" default="PackedByteArray( )"> + </argument> + <description> + </description> + </method> + <method name="limit_get"> + <return type="int"> + </return> + <argument index="0" name="limit" type="int" enum="RenderingDevice.Limit"> + </argument> + <description> + </description> + </method> + <method name="render_pipeline_create"> + <return type="RID"> + </return> + <argument index="0" name="shader" type="RID"> + </argument> + <argument index="1" name="framebuffer_format" type="int"> + </argument> + <argument index="2" name="vertex_format" type="int"> + </argument> + <argument index="3" name="primitive" type="int" enum="RenderingDevice.RenderPrimitive"> + </argument> + <argument index="4" name="rasterization_state" type="RDPipelineRasterizationState"> + </argument> + <argument index="5" name="multisample_state" type="RDPipelineMultisampleState"> + </argument> + <argument index="6" name="stencil_state" type="RDPipelineDepthStencilState"> + </argument> + <argument index="7" name="color_blend_state" type="RDPipelineColorBlendState"> + </argument> + <argument index="8" name="dynamic_state_flags" type="int" default="0"> + </argument> + <description> + </description> + </method> + <method name="render_pipeline_is_valid"> + <return type="bool"> + </return> + <argument index="0" name="render_pipeline" type="RID"> + </argument> + <description> + </description> + </method> + <method name="sampler_create"> + <return type="RID"> + </return> + <argument index="0" name="state" type="RDSamplerState"> + </argument> + <description> + </description> + </method> + <method name="screen_get_framebuffer_format" qualifiers="const"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="screen_get_height" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="screen" type="int" default="0"> + </argument> + <description> + </description> + </method> + <method name="screen_get_width" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="screen" type="int" default="0"> + </argument> + <description> + </description> + </method> + <method name="shader_compile_from_source"> + <return type="RDShaderBytecode"> + </return> + <argument index="0" name="shader_source" type="RDShaderSource"> + </argument> + <argument index="1" name="allow_cache" type="bool" default="true"> + </argument> + <description> + </description> + </method> + <method name="shader_create"> + <return type="RID"> + </return> + <argument index="0" name="shader_data" type="RDShaderBytecode"> + </argument> + <description> + </description> + </method> + <method name="shader_get_vertex_input_attribute_mask"> + <return type="int"> + </return> + <argument index="0" name="shader" type="RID"> + </argument> + <description> + </description> + </method> + <method name="storage_buffer_create"> + <return type="RID"> + </return> + <argument index="0" name="size_bytes" type="int"> + </argument> + <argument index="1" name="data" type="PackedByteArray" default="PackedByteArray( )"> + </argument> + <description> + </description> + </method> + <method name="submit"> + <return type="void"> + </return> + <description> + </description> + </method> + <method name="sync"> + <return type="void"> + </return> + <description> + </description> + </method> + <method name="texture_buffer_create"> + <return type="RID"> + </return> + <argument index="0" name="size_bytes" type="int"> + </argument> + <argument index="1" name="format" type="int" enum="RenderingDevice.DataFormat"> + </argument> + <argument index="2" name="data" type="PackedByteArray" default="PackedByteArray( )"> + </argument> + <description> + </description> + </method> + <method name="texture_clear"> + <return type="int" enum="Error"> + </return> + <argument index="0" name="texture" type="RID"> + </argument> + <argument index="1" name="color" type="Color"> + </argument> + <argument index="2" name="base_mipmap" type="int"> + </argument> + <argument index="3" name="mipmap_count" type="int"> + </argument> + <argument index="4" name="base_layer" type="int"> + </argument> + <argument index="5" name="layer_count" type="int"> + </argument> + <argument index="6" name="sync_with_draw" type="bool" default="false"> + </argument> + <description> + </description> + </method> + <method name="texture_copy"> + <return type="int" enum="Error"> + </return> + <argument index="0" name="from_texture" type="RID"> + </argument> + <argument index="1" name="to_texture" type="RID"> + </argument> + <argument index="2" name="from_pos" type="Vector3"> + </argument> + <argument index="3" name="to_pos" type="Vector3"> + </argument> + <argument index="4" name="size" type="Vector3"> + </argument> + <argument index="5" name="src_mipmap" type="int"> + </argument> + <argument index="6" name="dst_mipmap" type="int"> + </argument> + <argument index="7" name="src_layer" type="int"> + </argument> + <argument index="8" name="dst_layer" type="int"> + </argument> + <argument index="9" name="sync_with_draw" type="bool" default="false"> + </argument> + <description> + </description> + </method> + <method name="texture_create"> + <return type="RID"> + </return> + <argument index="0" name="format" type="RDTextureFormat"> + </argument> + <argument index="1" name="view" type="RDTextureView"> + </argument> + <argument index="2" name="data" type="Array" default="[ ]"> + </argument> + <description> + </description> + </method> + <method name="texture_create_shared"> + <return type="RID"> + </return> + <argument index="0" name="view" type="RDTextureView"> + </argument> + <argument index="1" name="with_texture" type="RID"> + </argument> + <description> + </description> + </method> + <method name="texture_create_shared_from_slice"> + <return type="RID"> + </return> + <argument index="0" name="view" type="RDTextureView"> + </argument> + <argument index="1" name="with_texture" type="RID"> + </argument> + <argument index="2" name="layer" type="int"> + </argument> + <argument index="3" name="mipmap" type="int"> + </argument> + <argument index="4" name="slice_type" type="int" enum="RenderingDevice.TextureSliceType" default="0"> + </argument> + <description> + </description> + </method> + <method name="texture_get_data"> + <return type="PackedByteArray"> + </return> + <argument index="0" name="texture" type="RID"> + </argument> + <argument index="1" name="layer" type="int"> + </argument> + <description> + </description> + </method> + <method name="texture_is_format_supported_for_usage" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="format" type="int" enum="RenderingDevice.DataFormat"> + </argument> + <argument index="1" name="usage_flags" type="int"> + </argument> + <description> + </description> + </method> + <method name="texture_is_shared"> + <return type="bool"> + </return> + <argument index="0" name="texture" type="RID"> + </argument> + <description> + </description> + </method> + <method name="texture_is_valid"> + <return type="bool"> + </return> + <argument index="0" name="texture" type="RID"> + </argument> + <description> + </description> + </method> + <method name="texture_resolve_multisample"> + <return type="int" enum="Error"> + </return> + <argument index="0" name="from_texture" type="RID"> + </argument> + <argument index="1" name="to_texture" type="RID"> + </argument> + <argument index="2" name="sync_with_draw" type="bool" default="false"> + </argument> + <description> + </description> + </method> + <method name="texture_update"> + <return type="int" enum="Error"> + </return> + <argument index="0" name="texture" type="RID"> + </argument> + <argument index="1" name="layer" type="int"> + </argument> + <argument index="2" name="data" type="PackedByteArray"> + </argument> + <argument index="3" name="sync_with_draw" type="bool" default="false"> + </argument> + <description> + </description> + </method> + <method name="uniform_buffer_create"> + <return type="RID"> + </return> + <argument index="0" name="size_bytes" type="int"> + </argument> + <argument index="1" name="data" type="PackedByteArray" default="PackedByteArray( )"> + </argument> + <description> + </description> + </method> + <method name="uniform_set_create"> + <return type="RID"> + </return> + <argument index="0" name="uniforms" type="Array"> + </argument> + <argument index="1" name="shader" type="RID"> + </argument> + <argument index="2" name="shader_set" type="int"> + </argument> + <description> + </description> + </method> + <method name="uniform_set_is_valid"> + <return type="bool"> + </return> + <argument index="0" name="uniform_set" type="RID"> + </argument> + <description> + </description> + </method> + <method name="vertex_buffer_create"> + <return type="RID"> + </return> + <argument index="0" name="size_bytes" type="int"> + </argument> + <argument index="1" name="data" type="PackedByteArray" default="PackedByteArray( )"> + </argument> + <description> + </description> + </method> + <method name="vertex_format_create"> + <return type="int"> + </return> + <argument index="0" name="vertex_descriptions" type="Array"> + </argument> + <description> + </description> + </method> </methods> <constants> + <constant name="DATA_FORMAT_R4G4_UNORM_PACK8" value="0" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R4G4B4A4_UNORM_PACK16" value="1" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B4G4R4A4_UNORM_PACK16" value="2" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R5G6B5_UNORM_PACK16" value="3" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B5G6R5_UNORM_PACK16" value="4" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R5G5B5A1_UNORM_PACK16" value="5" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B5G5R5A1_UNORM_PACK16" value="6" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A1R5G5B5_UNORM_PACK16" value="7" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8_UNORM" value="8" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8_SNORM" value="9" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8_USCALED" value="10" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8_SSCALED" value="11" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8_UINT" value="12" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8_SINT" value="13" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8_SRGB" value="14" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8_UNORM" value="15" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8_SNORM" value="16" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8_USCALED" value="17" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8_SSCALED" value="18" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8_UINT" value="19" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8_SINT" value="20" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8_SRGB" value="21" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8B8_UNORM" value="22" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8B8_SNORM" value="23" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8B8_USCALED" value="24" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8B8_SSCALED" value="25" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8B8_UINT" value="26" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8B8_SINT" value="27" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8B8_SRGB" value="28" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B8G8R8_UNORM" value="29" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B8G8R8_SNORM" value="30" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B8G8R8_USCALED" value="31" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B8G8R8_SSCALED" value="32" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B8G8R8_UINT" value="33" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B8G8R8_SINT" value="34" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B8G8R8_SRGB" value="35" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8B8A8_UNORM" value="36" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8B8A8_SNORM" value="37" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8B8A8_USCALED" value="38" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8B8A8_SSCALED" value="39" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8B8A8_UINT" value="40" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8B8A8_SINT" value="41" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R8G8B8A8_SRGB" value="42" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B8G8R8A8_UNORM" value="43" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B8G8R8A8_SNORM" value="44" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B8G8R8A8_USCALED" value="45" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B8G8R8A8_SSCALED" value="46" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B8G8R8A8_UINT" value="47" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B8G8R8A8_SINT" value="48" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B8G8R8A8_SRGB" value="49" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A8B8G8R8_UNORM_PACK32" value="50" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A8B8G8R8_SNORM_PACK32" value="51" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A8B8G8R8_USCALED_PACK32" value="52" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A8B8G8R8_SSCALED_PACK32" value="53" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A8B8G8R8_UINT_PACK32" value="54" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A8B8G8R8_SINT_PACK32" value="55" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A8B8G8R8_SRGB_PACK32" value="56" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A2R10G10B10_UNORM_PACK32" value="57" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A2R10G10B10_SNORM_PACK32" value="58" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A2R10G10B10_USCALED_PACK32" value="59" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A2R10G10B10_SSCALED_PACK32" value="60" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A2R10G10B10_UINT_PACK32" value="61" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A2R10G10B10_SINT_PACK32" value="62" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A2B10G10R10_UNORM_PACK32" value="63" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A2B10G10R10_SNORM_PACK32" value="64" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A2B10G10R10_USCALED_PACK32" value="65" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A2B10G10R10_SSCALED_PACK32" value="66" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A2B10G10R10_UINT_PACK32" value="67" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_A2B10G10R10_SINT_PACK32" value="68" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16_UNORM" value="69" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16_SNORM" value="70" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16_USCALED" value="71" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16_SSCALED" value="72" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16_UINT" value="73" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16_SINT" value="74" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16_SFLOAT" value="75" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16_UNORM" value="76" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16_SNORM" value="77" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16_USCALED" value="78" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16_SSCALED" value="79" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16_UINT" value="80" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16_SINT" value="81" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16_SFLOAT" value="82" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16B16_UNORM" value="83" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16B16_SNORM" value="84" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16B16_USCALED" value="85" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16B16_SSCALED" value="86" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16B16_UINT" value="87" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16B16_SINT" value="88" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16B16_SFLOAT" value="89" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16B16A16_UNORM" value="90" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16B16A16_SNORM" value="91" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16B16A16_USCALED" value="92" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16B16A16_SSCALED" value="93" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16B16A16_UINT" value="94" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16B16A16_SINT" value="95" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R16G16B16A16_SFLOAT" value="96" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R32_UINT" value="97" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R32_SINT" value="98" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R32_SFLOAT" value="99" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R32G32_UINT" value="100" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R32G32_SINT" value="101" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R32G32_SFLOAT" value="102" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R32G32B32_UINT" value="103" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R32G32B32_SINT" value="104" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R32G32B32_SFLOAT" value="105" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R32G32B32A32_UINT" value="106" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R32G32B32A32_SINT" value="107" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R32G32B32A32_SFLOAT" value="108" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R64_UINT" value="109" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R64_SINT" value="110" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R64_SFLOAT" value="111" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R64G64_UINT" value="112" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R64G64_SINT" value="113" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R64G64_SFLOAT" value="114" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R64G64B64_UINT" value="115" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R64G64B64_SINT" value="116" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R64G64B64_SFLOAT" value="117" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R64G64B64A64_UINT" value="118" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R64G64B64A64_SINT" value="119" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R64G64B64A64_SFLOAT" value="120" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B10G11R11_UFLOAT_PACK32" value="121" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32" value="122" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_D16_UNORM" value="123" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_X8_D24_UNORM_PACK32" value="124" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_D32_SFLOAT" value="125" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_S8_UINT" value="126" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_D16_UNORM_S8_UINT" value="127" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_D24_UNORM_S8_UINT" value="128" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_D32_SFLOAT_S8_UINT" value="129" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC1_RGB_UNORM_BLOCK" value="130" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC1_RGB_SRGB_BLOCK" value="131" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC1_RGBA_UNORM_BLOCK" value="132" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC1_RGBA_SRGB_BLOCK" value="133" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC2_UNORM_BLOCK" value="134" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC2_SRGB_BLOCK" value="135" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC3_UNORM_BLOCK" value="136" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC3_SRGB_BLOCK" value="137" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC4_UNORM_BLOCK" value="138" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC4_SNORM_BLOCK" value="139" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC5_UNORM_BLOCK" value="140" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC5_SNORM_BLOCK" value="141" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC6H_UFLOAT_BLOCK" value="142" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC6H_SFLOAT_BLOCK" value="143" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC7_UNORM_BLOCK" value="144" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_BC7_SRGB_BLOCK" value="145" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK" value="146" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK" value="147" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK" value="148" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK" value="149" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK" value="150" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK" value="151" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_EAC_R11_UNORM_BLOCK" value="152" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_EAC_R11_SNORM_BLOCK" value="153" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_EAC_R11G11_UNORM_BLOCK" value="154" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_EAC_R11G11_SNORM_BLOCK" value="155" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_4x4_UNORM_BLOCK" value="156" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_4x4_SRGB_BLOCK" value="157" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_5x4_UNORM_BLOCK" value="158" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_5x4_SRGB_BLOCK" value="159" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_5x5_UNORM_BLOCK" value="160" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_5x5_SRGB_BLOCK" value="161" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_6x5_UNORM_BLOCK" value="162" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_6x5_SRGB_BLOCK" value="163" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_6x6_UNORM_BLOCK" value="164" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_6x6_SRGB_BLOCK" value="165" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_8x5_UNORM_BLOCK" value="166" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_8x5_SRGB_BLOCK" value="167" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_8x6_UNORM_BLOCK" value="168" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_8x6_SRGB_BLOCK" value="169" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_8x8_UNORM_BLOCK" value="170" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_8x8_SRGB_BLOCK" value="171" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_10x5_UNORM_BLOCK" value="172" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_10x5_SRGB_BLOCK" value="173" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_10x6_UNORM_BLOCK" value="174" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_10x6_SRGB_BLOCK" value="175" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_10x8_UNORM_BLOCK" value="176" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_10x8_SRGB_BLOCK" value="177" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_10x10_UNORM_BLOCK" value="178" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_10x10_SRGB_BLOCK" value="179" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_12x10_UNORM_BLOCK" value="180" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_12x10_SRGB_BLOCK" value="181" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_12x12_UNORM_BLOCK" value="182" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_ASTC_12x12_SRGB_BLOCK" value="183" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G8B8G8R8_422_UNORM" value="184" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B8G8R8G8_422_UNORM" value="185" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G8_B8_R8_3PLANE_420_UNORM" value="186" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G8_B8R8_2PLANE_420_UNORM" value="187" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G8_B8_R8_3PLANE_422_UNORM" value="188" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G8_B8R8_2PLANE_422_UNORM" value="189" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G8_B8_R8_3PLANE_444_UNORM" value="190" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R10X6_UNORM_PACK16" value="191" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R10X6G10X6_UNORM_2PACK16" value="192" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16" value="193" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16" value="194" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16" value="195" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16" value="196" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16" value="197" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16" value="198" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16" value="199" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16" value="200" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R12X4_UNORM_PACK16" value="201" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R12X4G12X4_UNORM_2PACK16" value="202" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16" value="203" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16" value="204" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16" value="205" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16" value="206" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16" value="207" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16" value="208" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16" value="209" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16" value="210" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G16B16G16R16_422_UNORM" value="211" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_B16G16R16G16_422_UNORM" value="212" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G16_B16_R16_3PLANE_420_UNORM" value="213" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G16_B16R16_2PLANE_420_UNORM" value="214" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G16_B16_R16_3PLANE_422_UNORM" value="215" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G16_B16R16_2PLANE_422_UNORM" value="216" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_G16_B16_R16_3PLANE_444_UNORM" value="217" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG" value="218" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG" value="219" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG" value="220" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG" value="221" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG" value="222" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG" value="223" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG" value="224" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG" value="225" enum="DataFormat"> + </constant> + <constant name="DATA_FORMAT_MAX" value="226" enum="DataFormat"> + </constant> + <constant name="TEXTURE_TYPE_1D" value="0" enum="TextureType"> + </constant> + <constant name="TEXTURE_TYPE_2D" value="1" enum="TextureType"> + </constant> + <constant name="TEXTURE_TYPE_3D" value="2" enum="TextureType"> + </constant> + <constant name="TEXTURE_TYPE_CUBE" value="3" enum="TextureType"> + </constant> + <constant name="TEXTURE_TYPE_1D_ARRAY" value="4" enum="TextureType"> + </constant> + <constant name="TEXTURE_TYPE_2D_ARRAY" value="5" enum="TextureType"> + </constant> + <constant name="TEXTURE_TYPE_CUBE_ARRAY" value="6" enum="TextureType"> + </constant> + <constant name="TEXTURE_TYPE_MAX" value="7" enum="TextureType"> + </constant> + <constant name="TEXTURE_SAMPLES_1" value="0" enum="TextureSamples"> + </constant> + <constant name="TEXTURE_SAMPLES_2" value="1" enum="TextureSamples"> + </constant> + <constant name="TEXTURE_SAMPLES_4" value="2" enum="TextureSamples"> + </constant> + <constant name="TEXTURE_SAMPLES_8" value="3" enum="TextureSamples"> + </constant> + <constant name="TEXTURE_SAMPLES_16" value="4" enum="TextureSamples"> + </constant> + <constant name="TEXTURE_SAMPLES_32" value="5" enum="TextureSamples"> + </constant> + <constant name="TEXTURE_SAMPLES_64" value="6" enum="TextureSamples"> + </constant> + <constant name="TEXTURE_SAMPLES_MAX" value="7" enum="TextureSamples"> + </constant> + <constant name="TEXTURE_USAGE_SAMPLING_BIT" value="1" enum="TextureUsageBits"> + </constant> + <constant name="TEXTURE_USAGE_COLOR_ATTACHMENT_BIT" value="2" enum="TextureUsageBits"> + </constant> + <constant name="TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT" value="4" enum="TextureUsageBits"> + </constant> + <constant name="TEXTURE_USAGE_STORAGE_BIT" value="8" enum="TextureUsageBits"> + </constant> + <constant name="TEXTURE_USAGE_STORAGE_ATOMIC_BIT" value="16" enum="TextureUsageBits"> + </constant> + <constant name="TEXTURE_USAGE_CPU_READ_BIT" value="32" enum="TextureUsageBits"> + </constant> + <constant name="TEXTURE_USAGE_CAN_UPDATE_BIT" value="64" enum="TextureUsageBits"> + </constant> + <constant name="TEXTURE_USAGE_CAN_COPY_FROM_BIT" value="128" enum="TextureUsageBits"> + </constant> + <constant name="TEXTURE_USAGE_CAN_COPY_TO_BIT" value="256" enum="TextureUsageBits"> + </constant> + <constant name="TEXTURE_USAGE_RESOLVE_ATTACHMENT_BIT" value="512" enum="TextureUsageBits"> + </constant> + <constant name="TEXTURE_SWIZZLE_IDENTITY" value="0" enum="TextureSwizzle"> + </constant> + <constant name="TEXTURE_SWIZZLE_ZERO" value="1" enum="TextureSwizzle"> + </constant> + <constant name="TEXTURE_SWIZZLE_ONE" value="2" enum="TextureSwizzle"> + </constant> + <constant name="TEXTURE_SWIZZLE_R" value="3" enum="TextureSwizzle"> + </constant> + <constant name="TEXTURE_SWIZZLE_G" value="4" enum="TextureSwizzle"> + </constant> + <constant name="TEXTURE_SWIZZLE_B" value="5" enum="TextureSwizzle"> + </constant> + <constant name="TEXTURE_SWIZZLE_A" value="6" enum="TextureSwizzle"> + </constant> + <constant name="TEXTURE_SWIZZLE_MAX" value="7" enum="TextureSwizzle"> + </constant> + <constant name="TEXTURE_SLICE_2D" value="0" enum="TextureSliceType"> + </constant> + <constant name="TEXTURE_SLICE_CUBEMAP" value="1" enum="TextureSliceType"> + </constant> + <constant name="TEXTURE_SLICE_3D" value="2" enum="TextureSliceType"> + </constant> + <constant name="SAMPLER_FILTER_NEAREST" value="0" enum="SamplerFilter"> + </constant> + <constant name="SAMPLER_FILTER_LINEAR" value="1" enum="SamplerFilter"> + </constant> + <constant name="SAMPLER_REPEAT_MODE_REPEAT" value="0" enum="SamplerRepeatMode"> + </constant> + <constant name="SAMPLER_REPEAT_MODE_MIRRORED_REPEAT" value="1" enum="SamplerRepeatMode"> + </constant> + <constant name="SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE" value="2" enum="SamplerRepeatMode"> + </constant> + <constant name="SAMPLER_REPEAT_MODE_CLAMP_TO_BORDER" value="3" enum="SamplerRepeatMode"> + </constant> + <constant name="SAMPLER_REPEAT_MODE_MIRROR_CLAMP_TO_EDGE" value="4" enum="SamplerRepeatMode"> + </constant> + <constant name="SAMPLER_REPEAT_MODE_MAX" value="5" enum="SamplerRepeatMode"> + </constant> + <constant name="SAMPLER_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK" value="0" enum="SamplerBorderColor"> + </constant> + <constant name="SAMPLER_BORDER_COLOR_INT_TRANSPARENT_BLACK" value="1" enum="SamplerBorderColor"> + </constant> + <constant name="SAMPLER_BORDER_COLOR_FLOAT_OPAQUE_BLACK" value="2" enum="SamplerBorderColor"> + </constant> + <constant name="SAMPLER_BORDER_COLOR_INT_OPAQUE_BLACK" value="3" enum="SamplerBorderColor"> + </constant> + <constant name="SAMPLER_BORDER_COLOR_FLOAT_OPAQUE_WHITE" value="4" enum="SamplerBorderColor"> + </constant> + <constant name="SAMPLER_BORDER_COLOR_INT_OPAQUE_WHITE" value="5" enum="SamplerBorderColor"> + </constant> + <constant name="SAMPLER_BORDER_COLOR_MAX" value="6" enum="SamplerBorderColor"> + </constant> + <constant name="VERTEX_FREQUENCY_VERTEX" value="0" enum="VertexFrequency"> + </constant> + <constant name="VERTEX_FREQUENCY_INSTANCE" value="1" enum="VertexFrequency"> + </constant> + <constant name="INDEX_BUFFER_FORMAT_UINT16" value="0" enum="IndexBufferFormat"> + </constant> + <constant name="INDEX_BUFFER_FORMAT_UINT32" value="1" enum="IndexBufferFormat"> + </constant> + <constant name="UNIFORM_TYPE_SAMPLER" value="0" enum="UniformType"> + </constant> + <constant name="UNIFORM_TYPE_SAMPLER_WITH_TEXTURE" value="1" enum="UniformType"> + </constant> + <constant name="UNIFORM_TYPE_TEXTURE" value="2" enum="UniformType"> + </constant> + <constant name="UNIFORM_TYPE_IMAGE" value="3" enum="UniformType"> + </constant> + <constant name="UNIFORM_TYPE_TEXTURE_BUFFER" value="4" enum="UniformType"> + </constant> + <constant name="UNIFORM_TYPE_SAMPLER_WITH_TEXTURE_BUFFER" value="5" enum="UniformType"> + </constant> + <constant name="UNIFORM_TYPE_IMAGE_BUFFER" value="6" enum="UniformType"> + </constant> + <constant name="UNIFORM_TYPE_UNIFORM_BUFFER" value="7" enum="UniformType"> + </constant> + <constant name="UNIFORM_TYPE_STORAGE_BUFFER" value="8" enum="UniformType"> + </constant> + <constant name="UNIFORM_TYPE_INPUT_ATTACHMENT" value="9" enum="UniformType"> + </constant> + <constant name="UNIFORM_TYPE_MAX" value="10" enum="UniformType"> + </constant> + <constant name="RENDER_PRIMITIVE_POINTS" value="0" enum="RenderPrimitive"> + </constant> + <constant name="RENDER_PRIMITIVE_LINES" value="1" enum="RenderPrimitive"> + </constant> + <constant name="RENDER_PRIMITIVE_LINES_WITH_ADJACENCY" value="2" enum="RenderPrimitive"> + </constant> + <constant name="RENDER_PRIMITIVE_LINESTRIPS" value="3" enum="RenderPrimitive"> + </constant> + <constant name="RENDER_PRIMITIVE_LINESTRIPS_WITH_ADJACENCY" value="4" enum="RenderPrimitive"> + </constant> + <constant name="RENDER_PRIMITIVE_TRIANGLES" value="5" enum="RenderPrimitive"> + </constant> + <constant name="RENDER_PRIMITIVE_TRIANGLES_WITH_ADJACENCY" value="6" enum="RenderPrimitive"> + </constant> + <constant name="RENDER_PRIMITIVE_TRIANGLE_STRIPS" value="7" enum="RenderPrimitive"> + </constant> + <constant name="RENDER_PRIMITIVE_TRIANGLE_STRIPS_WITH_AJACENCY" value="8" enum="RenderPrimitive"> + </constant> + <constant name="RENDER_PRIMITIVE_TRIANGLE_STRIPS_WITH_RESTART_INDEX" value="9" enum="RenderPrimitive"> + </constant> + <constant name="RENDER_PRIMITIVE_TESSELATION_PATCH" value="10" enum="RenderPrimitive"> + </constant> + <constant name="RENDER_PRIMITIVE_MAX" value="11" enum="RenderPrimitive"> + </constant> + <constant name="POLYGON_CULL_DISABLED" value="0" enum="PolygonCullMode"> + </constant> + <constant name="POLYGON_CULL_FRONT" value="1" enum="PolygonCullMode"> + </constant> + <constant name="POLYGON_CULL_BACK" value="2" enum="PolygonCullMode"> + </constant> + <constant name="POLYGON_FRONT_FACE_CLOCKWISE" value="0" enum="PolygonFrontFace"> + </constant> + <constant name="POLYGON_FRONT_FACE_COUNTER_CLOCKWISE" value="1" enum="PolygonFrontFace"> + </constant> + <constant name="STENCIL_OP_KEEP" value="0" enum="StencilOperation"> + </constant> + <constant name="STENCIL_OP_ZERO" value="1" enum="StencilOperation"> + </constant> + <constant name="STENCIL_OP_REPLACE" value="2" enum="StencilOperation"> + </constant> + <constant name="STENCIL_OP_INCREMENT_AND_CLAMP" value="3" enum="StencilOperation"> + </constant> + <constant name="STENCIL_OP_DECREMENT_AND_CLAMP" value="4" enum="StencilOperation"> + </constant> + <constant name="STENCIL_OP_INVERT" value="5" enum="StencilOperation"> + </constant> + <constant name="STENCIL_OP_INCREMENT_AND_WRAP" value="6" enum="StencilOperation"> + </constant> + <constant name="STENCIL_OP_DECREMENT_AND_WRAP" value="7" enum="StencilOperation"> + </constant> + <constant name="STENCIL_OP_MAX" value="8" enum="StencilOperation"> + </constant> + <constant name="COMPARE_OP_NEVER" value="0" enum="CompareOperator"> + </constant> + <constant name="COMPARE_OP_LESS" value="1" enum="CompareOperator"> + </constant> + <constant name="COMPARE_OP_EQUAL" value="2" enum="CompareOperator"> + </constant> + <constant name="COMPARE_OP_LESS_OR_EQUAL" value="3" enum="CompareOperator"> + </constant> + <constant name="COMPARE_OP_GREATER" value="4" enum="CompareOperator"> + </constant> + <constant name="COMPARE_OP_NOT_EQUAL" value="5" enum="CompareOperator"> + </constant> + <constant name="COMPARE_OP_GREATER_OR_EQUAL" value="6" enum="CompareOperator"> + </constant> + <constant name="COMPARE_OP_ALWAYS" value="7" enum="CompareOperator"> + </constant> + <constant name="COMPARE_OP_MAX" value="8" enum="CompareOperator"> + </constant> + <constant name="LOGIC_OP_CLEAR" value="0" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_AND" value="1" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_AND_REVERSE" value="2" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_COPY" value="3" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_AND_INVERTED" value="4" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_NO_OP" value="5" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_XOR" value="6" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_OR" value="7" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_NOR" value="8" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_EQUIVALENT" value="9" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_INVERT" value="10" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_OR_REVERSE" value="11" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_COPY_INVERTED" value="12" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_OR_INVERTED" value="13" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_NAND" value="14" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_SET" value="15" enum="LogicOperation"> + </constant> + <constant name="LOGIC_OP_MAX" value="16" enum="LogicOperation"> + </constant> + <constant name="BLEND_FACTOR_ZERO" value="0" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_ONE" value="1" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_SRC_COLOR" value="2" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_ONE_MINUS_SRC_COLOR" value="3" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_DST_COLOR" value="4" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_ONE_MINUS_DST_COLOR" value="5" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_SRC_ALPHA" value="6" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_ONE_MINUS_SRC_ALPHA" value="7" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_DST_ALPHA" value="8" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_ONE_MINUS_DST_ALPHA" value="9" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_CONSTANT_COLOR" value="10" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR" value="11" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_CONSTANT_ALPHA" value="12" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA" value="13" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_SRC_ALPHA_SATURATE" value="14" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_SRC1_COLOR" value="15" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_ONE_MINUS_SRC1_COLOR" value="16" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_SRC1_ALPHA" value="17" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA" value="18" enum="BlendFactor"> + </constant> + <constant name="BLEND_FACTOR_MAX" value="19" enum="BlendFactor"> + </constant> + <constant name="BLEND_OP_ADD" value="0" enum="BlendOperation"> + </constant> + <constant name="BLEND_OP_SUBTRACT" value="1" enum="BlendOperation"> + </constant> + <constant name="BLEND_OP_REVERSE_SUBTRACT" value="2" enum="BlendOperation"> + </constant> + <constant name="BLEND_OP_MINIMUM" value="3" enum="BlendOperation"> + </constant> + <constant name="BLEND_OP_MAXIMUM" value="4" enum="BlendOperation"> + </constant> + <constant name="BLEND_OP_MAX" value="5" enum="BlendOperation"> + </constant> + <constant name="DYNAMIC_STATE_LINE_WIDTH" value="1" enum="PipelineDynamicStateFlags"> + </constant> + <constant name="DYNAMIC_STATE_DEPTH_BIAS" value="2" enum="PipelineDynamicStateFlags"> + </constant> + <constant name="DYNAMIC_STATE_BLEND_CONSTANTS" value="4" enum="PipelineDynamicStateFlags"> + </constant> + <constant name="DYNAMIC_STATE_DEPTH_BOUNDS" value="8" enum="PipelineDynamicStateFlags"> + </constant> + <constant name="DYNAMIC_STATE_STENCIL_COMPARE_MASK" value="16" enum="PipelineDynamicStateFlags"> + </constant> + <constant name="DYNAMIC_STATE_STENCIL_WRITE_MASK" value="32" enum="PipelineDynamicStateFlags"> + </constant> + <constant name="DYNAMIC_STATE_STENCIL_REFERENCE" value="64" enum="PipelineDynamicStateFlags"> + </constant> + <constant name="INITIAL_ACTION_CLEAR" value="0" enum="InitialAction"> + </constant> + <constant name="INITIAL_ACTION_KEEP" value="1" enum="InitialAction"> + </constant> + <constant name="INITIAL_ACTION_DROP" value="2" enum="InitialAction"> + </constant> + <constant name="INITIAL_ACTION_CONTINUE" value="3" enum="InitialAction"> + </constant> + <constant name="INITIAL_ACTION_MAX" value="4" enum="InitialAction"> + </constant> + <constant name="FINAL_ACTION_READ" value="0" enum="FinalAction"> + </constant> + <constant name="FINAL_ACTION_DISCARD" value="1" enum="FinalAction"> + </constant> + <constant name="FINAL_ACTION_CONTINUE" value="2" enum="FinalAction"> + </constant> + <constant name="FINAL_ACTION_MAX" value="3" enum="FinalAction"> + </constant> + <constant name="SHADER_STAGE_VERTEX" value="0" enum="ShaderStage"> + </constant> + <constant name="SHADER_STAGE_FRAGMENT" value="1" enum="ShaderStage"> + </constant> + <constant name="SHADER_STAGE_TESSELATION_CONTROL" value="2" enum="ShaderStage"> + </constant> + <constant name="SHADER_STAGE_TESSELATION_EVALUATION" value="3" enum="ShaderStage"> + </constant> + <constant name="SHADER_STAGE_COMPUTE" value="4" enum="ShaderStage"> + </constant> + <constant name="SHADER_STAGE_MAX" value="5" enum="ShaderStage"> + </constant> + <constant name="SHADER_STAGE_VERTEX_BIT" value="1" enum="ShaderStage"> + </constant> + <constant name="SHADER_STAGE_FRAGMENT_BIT" value="2" enum="ShaderStage"> + </constant> + <constant name="SHADER_STAGE_TESSELATION_CONTROL_BIT" value="4" enum="ShaderStage"> + </constant> + <constant name="SHADER_STAGE_TESSELATION_EVALUATION_BIT" value="8" enum="ShaderStage"> + </constant> + <constant name="SHADER_STAGE_COMPUTE_BIT" value="16" enum="ShaderStage"> + </constant> + <constant name="SHADER_LANGUAGE_GLSL" value="0" enum="ShaderLanguage"> + </constant> + <constant name="SHADER_LANGUAGE_HLSL" value="1" enum="ShaderLanguage"> + </constant> + <constant name="LIMIT_MAX_BOUND_UNIFORM_SETS" value="0" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_FRAMEBUFFER_COLOR_ATTACHMENTS" value="1" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_TEXTURES_PER_UNIFORM_SET" value="2" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_SAMPLERS_PER_UNIFORM_SET" value="3" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_STORAGE_BUFFERS_PER_UNIFORM_SET" value="4" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_STORAGE_IMAGES_PER_UNIFORM_SET" value="5" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_UNIFORM_BUFFERS_PER_UNIFORM_SET" value="6" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_DRAW_INDEXED_INDEX" value="7" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_FRAMEBUFFER_HEIGHT" value="8" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_FRAMEBUFFER_WIDTH" value="9" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_TEXTURE_ARRAY_LAYERS" value="10" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_TEXTURE_SIZE_1D" value="11" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_TEXTURE_SIZE_2D" value="12" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_TEXTURE_SIZE_3D" value="13" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_TEXTURE_SIZE_CUBE" value="14" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_TEXTURES_PER_SHADER_STAGE" value="15" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_SAMPLERS_PER_SHADER_STAGE" value="16" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_STORAGE_BUFFERS_PER_SHADER_STAGE" value="17" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_STORAGE_IMAGES_PER_SHADER_STAGE" value="18" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_UNIFORM_BUFFERS_PER_SHADER_STAGE" value="19" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_PUSH_CONSTANT_SIZE" value="20" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_UNIFORM_BUFFER_SIZE" value="21" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_VERTEX_INPUT_ATTRIBUTE_OFFSET" value="22" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_VERTEX_INPUT_ATTRIBUTES" value="23" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_VERTEX_INPUT_BINDINGS" value="24" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_VERTEX_INPUT_BINDING_STRIDE" value="25" enum="Limit"> + </constant> + <constant name="LIMIT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT" value="26" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_COMPUTE_SHARED_MEMORY_SIZE" value="27" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_X" value="28" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Y" value="29" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Z" value="30" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_COMPUTE_WORKGROUP_INVOCATIONS" value="31" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_X" value="32" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Y" value="33" enum="Limit"> + </constant> + <constant name="LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z" value="34" enum="Limit"> + </constant> + <constant name="INVALID_ID" value="-1"> + </constant> + <constant name="INVALID_FORMAT_ID" value="-1"> + </constant> </constants> </class> diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index d2d13fe406..4e0762a68b 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -4,12 +4,12 @@ Server for anything visible. </brief_description> <description> - Server for anything visible. The visual server is the API backend for everything visible. The whole scene system mounts on it to display. - The visual server is completely opaque, the internals are entirely implementation specific and cannot be accessed. - The visual server can be used to bypass the scene system entirely. + Server for anything visible. The rendering server is the API backend for everything visible. The whole scene system mounts on it to display. + The rendering server is completely opaque, the internals are entirely implementation specific and cannot be accessed. + The rendering server can be used to bypass the scene system entirely. Resources are created using the [code]*_create[/code] functions. All objects are drawn to a viewport. You can use the [Viewport] attached to the [SceneTree] or you can create one yourself with [method viewport_create]. When using a custom scenario or canvas, the scenario or canvas needs to be attached to the viewport using [method viewport_set_scenario] or [method viewport_attach_canvas]. - In 3D, all visual objects must be associated with a scenario. The scenario is a visual representation of the world. If accessing the visual server from a running game, the scenario can be accessed from the scene tree from any [Node3D] node with [method Node3D.get_world]. Otherwise, a scenario can be created with [method scenario_create]. + In 3D, all visual objects must be associated with a scenario. The scenario is a visual representation of the world. If accessing the rendering server from a running game, the scenario can be accessed from the scene tree from any [Node3D] node with [method Node3D.get_world]. Otherwise, a scenario can be created with [method scenario_create]. Similarly in 2D, a canvas is needed to draw all canvas items. In 3D, all visible objects are comprised of a resource and an instance. A resource can be a mesh, a particle system, a light, or any other 3D object. In order to be visible resources must be attached to an instance using [method instance_set_base]. The instance must also be attached to the scenario using [method instance_set_scenario] in order to be visible. In 2D, all visible objects are some form of canvas item. In order to be visible, a canvas item needs to be the child of a canvas attached to a viewport, or it needs to be the child of another canvas item that is eventually attached to the canvas. @@ -947,6 +947,58 @@ Returns the id of a white texture. Creates one if none exists. </description> </method> + <method name="global_variable_add"> + <return type="void"> + </return> + <argument index="0" name="name" type="StringName"> + </argument> + <argument index="1" name="type" type="int" enum="RenderingServer.GlobalVariableType"> + </argument> + <argument index="2" name="default_value" type="Variant"> + </argument> + <description> + </description> + </method> + <method name="global_variable_get" qualifiers="const"> + <return type="Variant"> + </return> + <argument index="0" name="name" type="StringName"> + </argument> + <description> + </description> + </method> + <method name="global_variable_get_list" qualifiers="const"> + <return type="PackedStringArray"> + </return> + <description> + </description> + </method> + <method name="global_variable_get_type" qualifiers="const"> + <return type="int" enum="RenderingServer.GlobalVariableType"> + </return> + <argument index="0" name="name" type="StringName"> + </argument> + <description> + </description> + </method> + <method name="global_variable_remove"> + <return type="void"> + </return> + <argument index="0" name="name" type="StringName"> + </argument> + <description> + </description> + </method> + <method name="global_variable_set"> + <return type="void"> + </return> + <argument index="0" name="name" type="StringName"> + </argument> + <argument index="1" name="value" type="Variant"> + </argument> + <description> + </description> + </method> <method name="has_changed" qualifiers="const"> <return type="bool"> </return> @@ -1113,7 +1165,7 @@ <return type="void"> </return> <description> - Initializes the visual server. This function is called internally by platform-dependent code during engine initialization. If called from a running game, it will not do anything. + Initializes the rendering server. This function is called internally by platform-dependent code during engine initialization. If called from a running game, it will not do anything. </description> </method> <method name="instance_attach_object_instance_id"> @@ -3067,15 +3119,15 @@ Sets when the viewport should be updated. See [enum ViewportUpdateMode] constants for options. </description> </method> - <method name="viewport_set_use_arvr"> + <method name="viewport_set_use_xr"> <return type="void"> </return> <argument index="0" name="viewport" type="RID"> </argument> - <argument index="1" name="use_arvr" type="bool"> + <argument index="1" name="use_xr" type="bool"> </argument> <description> - If [code]true[/code], the viewport uses augmented or virtual reality technologies. See [ARVRInterface]. + If [code]true[/code], the viewport uses augmented or virtual reality technologies. See [XRInterface]. </description> </method> </methods> @@ -3110,12 +3162,6 @@ <constant name="MAX_CURSORS" value="8"> Unused enum in Godot 3.x. </constant> - <constant name="MATERIAL_RENDER_PRIORITY_MIN" value="-128"> - The minimum renderpriority of all materials. - </constant> - <constant name="MATERIAL_RENDER_PRIORITY_MAX" value="127"> - The maximum renderpriority of all materials. - </constant> <constant name="TEXTURE_LAYERED_2D_ARRAY" value="0" enum="TextureLayeredType"> </constant> <constant name="TEXTURE_LAYERED_CUBEMAP" value="1" enum="TextureLayeredType"> @@ -3149,6 +3195,12 @@ <constant name="SHADER_MAX" value="4" enum="ShaderMode"> Represents the size of the [enum ShaderMode] enum. </constant> + <constant name="MATERIAL_RENDER_PRIORITY_MIN" value="-128"> + The minimum renderpriority of all materials. + </constant> + <constant name="MATERIAL_RENDER_PRIORITY_MAX" value="127"> + The maximum renderpriority of all materials. + </constant> <constant name="ARRAY_VERTEX" value="0" enum="ArrayType"> Array is a vertex array. </constant> @@ -3224,14 +3276,14 @@ <constant name="ARRAY_COMPRESS_INDEX" value="131072" enum="ArrayFormat"> Flag used to mark a compressed index array. </constant> + <constant name="ARRAY_COMPRESS_DEFAULT" value="31744" enum="ArrayFormat"> + Used to set flags [constant ARRAY_COMPRESS_NORMAL], [constant ARRAY_COMPRESS_TANGENT], [constant ARRAY_COMPRESS_COLOR], [constant ARRAY_COMPRESS_TEX_UV] and [constant ARRAY_COMPRESS_TEX_UV2] quickly. + </constant> <constant name="ARRAY_FLAG_USE_2D_VERTICES" value="262144" enum="ArrayFormat"> Flag used to mark that the array contains 2D vertices. </constant> <constant name="ARRAY_FLAG_USE_DYNAMIC_UPDATE" value="1048576" enum="ArrayFormat"> </constant> - <constant name="ARRAY_COMPRESS_DEFAULT" value="31744" enum="ArrayFormat"> - Used to set flags [constant ARRAY_COMPRESS_NORMAL], [constant ARRAY_COMPRESS_TANGENT], [constant ARRAY_COMPRESS_COLOR], [constant ARRAY_COMPRESS_TEX_UV] and [constant ARRAY_COMPRESS_TEX_UV2] quickly. - </constant> <constant name="PRIMITIVE_POINTS" value="0" enum="PrimitiveType"> Primitive to draw consists of points. </constant> @@ -3282,18 +3334,18 @@ <constant name="LIGHT_PARAM_RANGE" value="3" enum="LightParam"> The light's range. </constant> - <constant name="LIGHT_PARAM_ATTENUATION" value="4" enum="LightParam"> + <constant name="LIGHT_PARAM_SIZE" value="4" enum="LightParam"> + The size of the light when using spot light or omni light. The angular size of the light when using directional light. + </constant> + <constant name="LIGHT_PARAM_ATTENUATION" value="5" enum="LightParam"> The light's attenuation. </constant> - <constant name="LIGHT_PARAM_SPOT_ANGLE" value="5" enum="LightParam"> + <constant name="LIGHT_PARAM_SPOT_ANGLE" value="6" enum="LightParam"> The spotlight's angle. </constant> - <constant name="LIGHT_PARAM_SPOT_ATTENUATION" value="6" enum="LightParam"> + <constant name="LIGHT_PARAM_SPOT_ATTENUATION" value="7" enum="LightParam"> The spotlight's attenuation. </constant> - <constant name="LIGHT_PARAM_CONTACT_SHADOW_SIZE" value="7" enum="LightParam"> - Scales the shadow color. - </constant> <constant name="LIGHT_PARAM_SHADOW_MAX_DISTANCE" value="8" enum="LightParam"> Max distance that shadows will be rendered. </constant> @@ -3307,6 +3359,7 @@ Proportion of shadow atlas occupied by the third split. The fourth split occupies the rest. </constant> <constant name="LIGHT_PARAM_SHADOW_FADE_START" value="12" enum="LightParam"> + Proportion of shadow max distance where the shadow will start to fade out. </constant> <constant name="LIGHT_PARAM_SHADOW_NORMAL_BIAS" value="13" enum="LightParam"> Normal bias used to offset shadow lookup by object normal. Can be used to fix self-shadowing artifacts. @@ -3314,10 +3367,15 @@ <constant name="LIGHT_PARAM_SHADOW_BIAS" value="14" enum="LightParam"> Bias the shadow lookup to fix self-shadowing artifacts. </constant> - <constant name="LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE" value="15" enum="LightParam"> - Increases bias on further splits to fix self-shadowing that only occurs far away from the camera. + <constant name="LIGHT_PARAM_SHADOW_PANCAKE_SIZE" value="15" enum="LightParam"> + Sets the size of the directional shadow pancake. The pancake offsets the start of the shadow's camera frustum to provide a higher effective depth resolution for the shadow. However, a high pancake size can cause artifacts in the shadows of large objects that are close to the edge of the frustum. Reducing the pancake size can help. Setting the size to [code]0[/code] turns off the pancaking effect. + </constant> + <constant name="LIGHT_PARAM_SHADOW_BLUR" value="16" enum="LightParam"> + Blurs the edges of the shadow. Can be used to hide pixel artifacts in low resolution shadow maps. A high value can make shadows appear grainy and can cause other unwanted artifacts. Try to keep as near default as possible. </constant> - <constant name="LIGHT_PARAM_MAX" value="16" enum="LightParam"> + <constant name="LIGHT_PARAM_TRANSMITTANCE_BIAS" value="17" enum="LightParam"> + </constant> + <constant name="LIGHT_PARAM_MAX" value="18" enum="LightParam"> Represents the size of the [enum LightParam] enum. </constant> <constant name="LIGHT_OMNI_SHADOW_DUAL_PARABOLOID" value="0" enum="LightOmniShadowMode"> @@ -3347,6 +3405,16 @@ <constant name="REFLECTION_PROBE_UPDATE_ALWAYS" value="1" enum="ReflectionProbeUpdateMode"> Reflection probe will update each frame. This mode is necessary to capture moving objects. </constant> + <constant name="DECAL_TEXTURE_ALBEDO" value="0" enum="DecalTexture"> + </constant> + <constant name="DECAL_TEXTURE_NORMAL" value="1" enum="DecalTexture"> + </constant> + <constant name="DECAL_TEXTURE_ORM" value="2" enum="DecalTexture"> + </constant> + <constant name="DECAL_TEXTURE_EMISSION" value="3" enum="DecalTexture"> + </constant> + <constant name="DECAL_TEXTURE_MAX" value="4" enum="DecalTexture"> + </constant> <constant name="PARTICLES_DRAW_ORDER_INDEX" value="0" enum="ParticlesDrawOrder"> Draw particles in the order that they appear in the particles array. </constant> @@ -3383,22 +3451,24 @@ Multisample antialiasing is disabled. </constant> <constant name="VIEWPORT_MSAA_2X" value="1" enum="ViewportMSAA"> - Multisample antialiasing is set to 2×. + Multisample antialiasing uses 2 samples per pixel. </constant> <constant name="VIEWPORT_MSAA_4X" value="2" enum="ViewportMSAA"> - Multisample antialiasing is set to 4×. + Multisample antialiasing uses 4 samples per pixel. </constant> <constant name="VIEWPORT_MSAA_8X" value="3" enum="ViewportMSAA"> - Multisample antialiasing is set to 8×. + Multisample antialiasing uses 8 samples per pixel. </constant> <constant name="VIEWPORT_MSAA_16X" value="4" enum="ViewportMSAA"> - Multisample antialiasing is set to 16×. + Multisample antialiasing uses 16 samples per pixel. + </constant> + <constant name="VIEWPORT_MSAA_MAX" value="5" enum="ViewportMSAA"> </constant> - <constant name="VIEWPORT_MSAA_EXT_2X" value="5" enum="ViewportMSAA"> - Multisample antialiasing is set to 2× on external texture. Special mode for GLES2 Android VR (Oculus Quest and Go). + <constant name="VIEWPORT_SCREEN_SPACE_AA_DISABLED" value="0" enum="ViewportScreenSpaceAA"> </constant> - <constant name="VIEWPORT_MSAA_EXT_4X" value="6" enum="ViewportMSAA"> - Multisample antialiasing is set to 4× on external texture. Special mode for GLES2 Android VR (Oculus Quest and Go). + <constant name="VIEWPORT_SCREEN_SPACE_AA_FXAA" value="1" enum="ViewportScreenSpaceAA"> + </constant> + <constant name="VIEWPORT_SCREEN_SPACE_AA_MAX" value="2" enum="ViewportScreenSpaceAA"> </constant> <constant name="VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME" value="0" enum="ViewportRenderInfo"> Number of objects drawn in a single frame. @@ -3425,37 +3495,54 @@ Debug draw is disabled. Default setting. </constant> <constant name="VIEWPORT_DEBUG_DRAW_UNSHADED" value="1" enum="ViewportDebugDraw"> - Debug draw sets objects to unshaded. + Objects are displayed without light information. </constant> <constant name="VIEWPORT_DEBUG_DRAW_LIGHTING" value="2" enum="ViewportDebugDraw"> + Objects are displayed with only light information. </constant> <constant name="VIEWPORT_DEBUG_DRAW_OVERDRAW" value="3" enum="ViewportDebugDraw"> - Overwrites clear color to [code](0,0,0,0)[/code]. + Objects are displayed semi-transparent with additive blending so you can see where they are drawing over top of one another. A higher overdraw means you are wasting performance on drawing pixels that are being hidden behind others. </constant> <constant name="VIEWPORT_DEBUG_DRAW_WIREFRAME" value="4" enum="ViewportDebugDraw"> Debug draw draws objects in wireframe. </constant> <constant name="VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER" value="5" enum="ViewportDebugDraw"> + Normal buffer is drawn instead of regular scene so you can see the per-pixel normals that will be used by post-processing effects. </constant> <constant name="VIEWPORT_DEBUG_DRAW_GI_PROBE_ALBEDO" value="6" enum="ViewportDebugDraw"> + Objects are displayed with only the albedo value from [GIProbe]s. </constant> <constant name="VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING" value="7" enum="ViewportDebugDraw"> + Objects are displayed with only the lighting value from [GIProbe]s. </constant> <constant name="VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION" value="8" enum="ViewportDebugDraw"> + Objects are displayed with only the emission color from [GIProbe]s. </constant> <constant name="VIEWPORT_DEBUG_DRAW_SHADOW_ATLAS" value="9" enum="ViewportDebugDraw"> + Draws the shadow atlas that stores shadows from [OmniLight3D]s and [SpotLight3D]s in the upper left quadrant of the [Viewport]. </constant> <constant name="VIEWPORT_DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS" value="10" enum="ViewportDebugDraw"> + Draws the shadow atlas that stores shadows from [DirectionalLight3D]s in the upper left quadrant of the [Viewport]. </constant> <constant name="VIEWPORT_DEBUG_DRAW_SCENE_LUMINANCE" value="11" enum="ViewportDebugDraw"> </constant> <constant name="VIEWPORT_DEBUG_DRAW_SSAO" value="12" enum="ViewportDebugDraw"> + Draws the screen space ambient occlusion texture instead of the scene so that you can clearly see how it is affecting objects. In order for this display mode to work, you must have [member Environment.ssao_enabled] set in your [WorldEnvironment]. </constant> <constant name="VIEWPORT_DEBUG_DRAW_ROUGHNESS_LIMITER" value="13" enum="ViewportDebugDraw"> + Draws the roughness limiter post process over the Viewport so you can see where it has an effect. It must be enabled in [member ProjectSettings.rendering/quality/screen_filters/screen_space_roughness_limiter] to work. + </constant> + <constant name="VIEWPORT_DEBUG_DRAW_PSSM_SPLITS" value="14" enum="ViewportDebugDraw"> + Colors each PSSM split for the [DirectionalLight3D]s in the scene a different color so you can see where the splits are. In order they will be colored red, green, blue, yellow. + </constant> + <constant name="VIEWPORT_DEBUG_DRAW_DECAL_ATLAS" value="15" enum="ViewportDebugDraw"> </constant> <constant name="SKY_MODE_QUALITY" value="0" enum="SkyMode"> + Uses high quality importance sampling to process the radiance map. In general, this results in much higher quality than [constant Sky.PROCESS_MODE_REALTIME] but takes much longer to generate. This should not be used if you plan on changing the sky at runtime. If you are finding that the reflection is not blurry enough and is showing sparkles or fireflies, try increasing [member ProjectSettings.rendering/quality/reflections/ggx_samples]. </constant> <constant name="SKY_MODE_REALTIME" value="1" enum="SkyMode"> + Uses the fast filtering algorithm to process the radiance map. In general this results in lower quality, but substantially faster run times. + [b]Note:[/b] The fast filtering algorithm is limited to 256x256 cubemaps, so [member Sky.radiance_size] must be set to [constant Sky.RADIANCE_SIZE_256]. </constant> <constant name="ENV_BG_CLEAR_COLOR" value="0" enum="EnvironmentBG"> Use the clear color as background. @@ -3479,28 +3566,40 @@ Represents the size of the [enum EnvironmentBG] enum. </constant> <constant name="ENV_AMBIENT_SOURCE_BG" value="0" enum="EnvironmentAmbientSource"> + Gather ambient light from whichever source is specified as the background. </constant> <constant name="ENV_AMBIENT_SOURCE_DISABLED" value="1" enum="EnvironmentAmbientSource"> + Disable ambient light. </constant> <constant name="ENV_AMBIENT_SOURCE_COLOR" value="2" enum="EnvironmentAmbientSource"> + Specify a specific [Color] for ambient light. </constant> <constant name="ENV_AMBIENT_SOURCE_SKY" value="3" enum="EnvironmentAmbientSource"> + Gather ambient light from the [Sky] regardless of what the background is. </constant> <constant name="ENV_REFLECTION_SOURCE_BG" value="0" enum="EnvironmentReflectionSource"> + Use the background for reflections. </constant> <constant name="ENV_REFLECTION_SOURCE_DISABLED" value="1" enum="EnvironmentReflectionSource"> + Disable reflections. </constant> <constant name="ENV_REFLECTION_SOURCE_SKY" value="2" enum="EnvironmentReflectionSource"> + Use the [Sky] for reflections regardless of what the background is. </constant> <constant name="ENV_GLOW_BLEND_MODE_ADDITIVE" value="0" enum="EnvironmentGlowBlendMode"> + Additive glow blending mode. Mostly used for particles, glows (bloom), lens flare, bright sources. </constant> <constant name="ENV_GLOW_BLEND_MODE_SCREEN" value="1" enum="EnvironmentGlowBlendMode"> + Screen glow blending mode. Increases brightness, used frequently with bloom. </constant> <constant name="ENV_GLOW_BLEND_MODE_SOFTLIGHT" value="2" enum="EnvironmentGlowBlendMode"> + Soft light glow blending mode. Modifies contrast, exposes shadows and highlights (vivid bloom). </constant> <constant name="ENV_GLOW_BLEND_MODE_REPLACE" value="3" enum="EnvironmentGlowBlendMode"> + Replace glow blending mode. Replaces all pixels' color by the glow value. This can be used to simulate a full-screen blur effect by tweaking the glow parameters to match the original image's brightness. </constant> <constant name="ENV_GLOW_BLEND_MODE_MIX" value="4" enum="EnvironmentGlowBlendMode"> + Mixes the glow with the underlying color to avoid increasing brightness as much while still maintaining a glow effect. </constant> <constant name="ENV_TONE_MAPPER_LINEAR" value="0" enum="EnvironmentToneMapper"> Output color as they came in. @@ -3514,6 +3613,14 @@ <constant name="ENV_TONE_MAPPER_ACES" value="3" enum="EnvironmentToneMapper"> Use the ACES tonemapper. </constant> + <constant name="ENV_SSR_ROUGNESS_QUALITY_DISABLED" value="0" enum="EnvironmentSSRRoughnessQuality"> + </constant> + <constant name="ENV_SSR_ROUGNESS_QUALITY_LOW" value="1" enum="EnvironmentSSRRoughnessQuality"> + </constant> + <constant name="ENV_SSR_ROUGNESS_QUALITY_MEDIUM" value="2" enum="EnvironmentSSRRoughnessQuality"> + </constant> + <constant name="ENV_SSR_ROUGNESS_QUALITY_HIGH" value="3" enum="EnvironmentSSRRoughnessQuality"> + </constant> <constant name="ENV_SSAO_BLUR_DISABLED" value="0" enum="EnvironmentSSAOBlur"> Disables the blur set for SSAO. Will make SSAO look noisier. </constant> @@ -3533,23 +3640,51 @@ Medium quality screen space ambient occlusion. </constant> <constant name="ENV_SSAO_QUALITY_HIGH" value="2" enum="EnvironmentSSAOQuality"> - Highest quality screen space ambient occlusion. + High quality screen space ambient occlusion. </constant> <constant name="ENV_SSAO_QUALITY_ULTRA" value="3" enum="EnvironmentSSAOQuality"> + Highest quality screen space ambient occlusion. + </constant> + <constant name="SUB_SURFACE_SCATTERING_QUALITY_DISABLED" value="0" enum="SubSurfaceScatteringQuality"> + </constant> + <constant name="SUB_SURFACE_SCATTERING_QUALITY_LOW" value="1" enum="SubSurfaceScatteringQuality"> + </constant> + <constant name="SUB_SURFACE_SCATTERING_QUALITY_MEDIUM" value="2" enum="SubSurfaceScatteringQuality"> + </constant> + <constant name="SUB_SURFACE_SCATTERING_QUALITY_HIGH" value="3" enum="SubSurfaceScatteringQuality"> </constant> <constant name="DOF_BLUR_QUALITY_VERY_LOW" value="0" enum="DOFBlurQuality"> + Lowest quality DOF blur. This is the fastest setting, but you may be able to see filtering artifacts. </constant> <constant name="DOF_BLUR_QUALITY_LOW" value="1" enum="DOFBlurQuality"> + Low quality DOF blur. </constant> <constant name="DOF_BLUR_QUALITY_MEDIUM" value="2" enum="DOFBlurQuality"> + Medium quality DOF blur. </constant> <constant name="DOF_BLUR_QUALITY_HIGH" value="3" enum="DOFBlurQuality"> + Highest quality DOF blur. Results in the smoothest looking blur by taking the most samples, but is also significantly slower. </constant> <constant name="DOF_BOKEH_BOX" value="0" enum="DOFBokehShape"> + Calculate the DOF blur using a box filter. The fastest option, but results in obvious lines in blur pattern. </constant> <constant name="DOF_BOKEH_HEXAGON" value="1" enum="DOFBokehShape"> + Calculates DOF blur using a hexagon shaped filter. </constant> <constant name="DOF_BOKEH_CIRCLE" value="2" enum="DOFBokehShape"> + Calculates DOF blur using a circle shaped filter. Best quality and most realistic, but slowest. Use only for areas where a lot of performance can be dedicated to post-processing (e.g. cutscenes). + </constant> + <constant name="SHADOW_QUALITY_HARD" value="0" enum="ShadowQuality"> + </constant> + <constant name="SHADOW_QUALITY_SOFT_LOW" value="1" enum="ShadowQuality"> + </constant> + <constant name="SHADOW_QUALITY_SOFT_MEDIUM" value="2" enum="ShadowQuality"> + </constant> + <constant name="SHADOW_QUALITY_SOFT_HIGH" value="3" enum="ShadowQuality"> + </constant> + <constant name="SHADOW_QUALITY_SOFT_ULTRA" value="4" enum="ShadowQuality"> + </constant> + <constant name="SHADOW_QUALITY_MAX" value="5" enum="ShadowQuality"> </constant> <constant name="SCENARIO_DEBUG_DISABLED" value="0" enum="ScenarioDebugMode"> Do not use a debug mode. @@ -3584,13 +3719,16 @@ <constant name="INSTANCE_REFLECTION_PROBE" value="6" enum="InstanceType"> The instance is a reflection probe. </constant> - <constant name="INSTANCE_GI_PROBE" value="7" enum="InstanceType"> + <constant name="INSTANCE_DECAL" value="7" enum="InstanceType"> + The instance is a decal. + </constant> + <constant name="INSTANCE_GI_PROBE" value="8" enum="InstanceType"> The instance is a GI probe. </constant> - <constant name="INSTANCE_LIGHTMAP_CAPTURE" value="8" enum="InstanceType"> + <constant name="INSTANCE_LIGHTMAP_CAPTURE" value="9" enum="InstanceType"> The instance is a lightmap capture. </constant> - <constant name="INSTANCE_MAX" value="9" enum="InstanceType"> + <constant name="INSTANCE_MAX" value="10" enum="InstanceType"> Represents the size of the [enum InstanceType] enum. </constant> <constant name="INSTANCE_GEOMETRY_MASK" value="30" enum="InstanceType"> @@ -3600,6 +3738,7 @@ Allows the instance to be used in baked lighting. </constant> <constant name="INSTANCE_FLAG_USE_DYNAMIC_GI" value="1" enum="InstanceFlags"> + Allows the instance to be used with dynamic global illumination. </constant> <constant name="INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE" value="2" enum="InstanceFlags"> When set, manually requests to draw geometry on next frame. @@ -3629,30 +3768,43 @@ The nine patch gets filled with tiles where needed and stretches them a bit if needed. </constant> <constant name="CANVAS_ITEM_TEXTURE_FILTER_DEFAULT" value="0" enum="CanvasItemTextureFilter"> + Uses the default filter mode for this [Viewport]. </constant> <constant name="CANVAS_ITEM_TEXTURE_FILTER_NEAREST" value="1" enum="CanvasItemTextureFilter"> + The texture filter reads from the nearest pixel only. The simplest and fastest method of filtering, but the texture will look pixelized. </constant> <constant name="CANVAS_ITEM_TEXTURE_FILTER_LINEAR" value="2" enum="CanvasItemTextureFilter"> + The texture filter blends between the nearest 4 pixels. Use this when you want to avoid a pixelated style, but do not want mipmaps. </constant> <constant name="CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS" value="3" enum="CanvasItemTextureFilter"> + The texture filter reads from the nearest pixel in the nearest mipmap. The fastest way to read from textures with mipmaps. </constant> <constant name="CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS" value="4" enum="CanvasItemTextureFilter"> + The texture filter blends between the nearest 4 pixels and between the nearest 2 mipmaps. </constant> <constant name="CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC" value="5" enum="CanvasItemTextureFilter"> + The texture filter reads from the nearest pixel, but selects a mipmap based on the angle between the surface and the camera view. This reduces artifacts on surfaces that are almost in line with the camera. </constant> <constant name="CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC" value="6" enum="CanvasItemTextureFilter"> + The texture filter blends between the nearest 4 pixels and selects a mipmap based on the angle between the surface and the camera view. This reduces artifacts on surfaces that are almost in line with the camera. This is the slowest of the filtering options, but results in the highest quality texturing. </constant> <constant name="CANVAS_ITEM_TEXTURE_FILTER_MAX" value="7" enum="CanvasItemTextureFilter"> + Max value for [enum CanvasItemTextureFilter] enum. </constant> <constant name="CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT" value="0" enum="CanvasItemTextureRepeat"> + Uses the default repeat mode for this [Viewport]. </constant> <constant name="CANVAS_ITEM_TEXTURE_REPEAT_DISABLED" value="1" enum="CanvasItemTextureRepeat"> + Disables textures repeating. Instead, when reading UVs outside the 0-1 range, the value will be clamped to the edge of the texture, resulting in a stretched out look at the borders of the texture. </constant> <constant name="CANVAS_ITEM_TEXTURE_REPEAT_ENABLED" value="2" enum="CanvasItemTextureRepeat"> + Enables the texture to repeat when UV coordinates are outside the 0-1 range. If using one of the linear filtering modes, this can result in artifacts at the edges of a texture when the sampler filters across the edges of the texture. </constant> <constant name="CANVAS_ITEM_TEXTURE_REPEAT_MIRROR" value="3" enum="CanvasItemTextureRepeat"> + Flip the texture when repeating so that the edge lines up instead of abruptly changing. </constant> <constant name="CANVAS_ITEM_TEXTURE_REPEAT_MAX" value="4" enum="CanvasItemTextureRepeat"> + Max value for [enum CanvasItemTextureRepeat] enum. </constant> <constant name="CANVAS_LIGHT_MODE_ADD" value="0" enum="CanvasLightMode"> Adds light color additive to the canvas. @@ -3676,6 +3828,7 @@ Use PCF13 filtering to filter canvas light shadows. </constant> <constant name="CANVAS_LIGHT_FILTER_MAX" value="3" enum="CanvasLightShadowFilter"> + Max value of the [enum CanvasLightShadowFilter] enum. </constant> <constant name="CANVAS_OCCLUDER_POLYGON_CULL_DISABLED" value="0" enum="CanvasOccluderPolygonCullMode"> Culling of the canvas occluder is disabled. @@ -3686,6 +3839,64 @@ <constant name="CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE" value="2" enum="CanvasOccluderPolygonCullMode"> Culling of the canvas occluder is counterclockwise. </constant> + <constant name="GLOBAL_VAR_TYPE_BOOL" value="0" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_BVEC2" value="1" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_BVEC3" value="2" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_BVEC4" value="3" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_INT" value="4" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_IVEC2" value="5" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_IVEC3" value="6" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_IVEC4" value="7" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_RECT2I" value="8" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_UINT" value="9" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_UVEC2" value="10" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_UVEC3" value="11" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_UVEC4" value="12" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_FLOAT" value="13" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_VEC2" value="14" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_VEC3" value="15" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_VEC4" value="16" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_COLOR" value="17" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_RECT2" value="18" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_MAT2" value="19" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_MAT3" value="20" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_MAT4" value="21" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_TRANSFORM_2D" value="22" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_TRANSFORM" value="23" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_SAMPLER2D" value="24" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_SAMPLER2DARRAY" value="25" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_SAMPLER3D" value="26" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_SAMPLERCUBE" value="27" enum="GlobalVariableType"> + </constant> + <constant name="GLOBAL_VAR_TYPE_MAX" value="28" enum="GlobalVariableType"> + </constant> <constant name="INFO_OBJECTS_IN_FRAME" value="0" enum="RenderInfo"> The amount of objects in the frame. </constant> diff --git a/doc/classes/ResourceFormatLoaderCrypto.xml b/doc/classes/ResourceFormatLoaderCrypto.xml deleted file mode 100644 index fda529fdbd..0000000000 --- a/doc/classes/ResourceFormatLoaderCrypto.xml +++ /dev/null @@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="ResourceFormatLoaderCrypto" inherits="ResourceFormatLoader" version="4.0"> - <brief_description> - </brief_description> - <description> - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/ResourceFormatSaverCrypto.xml b/doc/classes/ResourceFormatSaverCrypto.xml deleted file mode 100644 index 31db8ff4f5..0000000000 --- a/doc/classes/ResourceFormatSaverCrypto.xml +++ /dev/null @@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="ResourceFormatSaverCrypto" inherits="ResourceFormatSaver" version="4.0"> - <brief_description> - </brief_description> - <description> - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/RigidBody3D.xml b/doc/classes/RigidBody3D.xml index 829589f650..1db818d6af 100644 --- a/doc/classes/RigidBody3D.xml +++ b/doc/classes/RigidBody3D.xml @@ -28,7 +28,7 @@ <argument index="0" name="force" type="Vector3"> </argument> <description> - Adds a constant directional force without affecting rotation. + Adds a constant directional force (i.e. acceleration) without affecting rotation. This is equivalent to [code]add_force(force, Vector3(0,0,0))[/code]. </description> </method> @@ -40,7 +40,8 @@ <argument index="1" name="position" type="Vector3"> </argument> <description> - Adds a constant force (i.e. acceleration). + Adds a constant directional force (i.e. acceleration). + The position uses the rotation of the global coordinate system, but is centered at the object's origin. </description> </method> <method name="add_torque"> @@ -146,7 +147,7 @@ Lock the body's movement in the Z axis. </member> <member name="can_sleep" type="bool" setter="set_can_sleep" getter="is_able_to_sleep" default="true"> - If [code]true[/code], the RigidBody3D will not calculate forces and will act as a static body while there is no movement. It will wake up when forces are applied through other collisions or when the [code]apply_impulse[/code] method is used. + If [code]true[/code], the body is deactivated when there is no movement, so it will not take part in the simulation until it is awaken by an external force. </member> <member name="contact_monitor" type="bool" setter="set_contact_monitor" getter="is_contact_monitor_enabled" default="false"> If [code]true[/code], the RigidBody3D will emit signals when it collides with another RigidBody3D. diff --git a/modules/bullet/doc_classes/BulletPhysicsServer3D.xml b/doc/classes/ShaderGlobalsOverride.xml index b20595b4f6..2aa00aa5a9 100644 --- a/modules/bullet/doc_classes/BulletPhysicsServer3D.xml +++ b/doc/classes/ShaderGlobalsOverride.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="BulletPhysicsServer3D" inherits="PhysicsServer3D" version="4.0"> +<class name="ShaderGlobalsOverride" inherits="Node" version="4.0"> <brief_description> </brief_description> <description> diff --git a/doc/classes/Sky.xml b/doc/classes/Sky.xml index f574f42431..78c75d9c2b 100644 --- a/doc/classes/Sky.xml +++ b/doc/classes/Sky.xml @@ -49,7 +49,7 @@ Represents the size of the [enum RadianceSize] enum. </constant> <constant name="PROCESS_MODE_QUALITY" value="0" enum="ProcessMode"> - Uses high quality importance sampling to process the radiance map. In general, this results in much higher quality than [constant PROCESS_MODE_REALTIME] but takes much longer to generate. This should not be used if you plan on changing the sky at runtime. + Uses high quality importance sampling to process the radiance map. In general, this results in much higher quality than [constant PROCESS_MODE_REALTIME] but takes much longer to generate. This should not be used if you plan on changing the sky at runtime. If you are finding that the reflection is not blurry enough and is showing sparkles or fireflies, try increasing [member ProjectSettings.rendering/quality/reflections/ggx_samples]. </constant> <constant name="PROCESS_MODE_REALTIME" value="1" enum="ProcessMode"> Uses the fast filtering algorithm to process the radiance map. In general this results in lower quality, but substantially faster run times. diff --git a/doc/classes/SubViewport.xml b/doc/classes/SubViewport.xml index dc3d748496..6014762e3d 100644 --- a/doc/classes/SubViewport.xml +++ b/doc/classes/SubViewport.xml @@ -9,9 +9,6 @@ <methods> </methods> <members> - <member name="arvr" type="bool" setter="set_use_arvr" getter="is_using_arvr" default="false"> - If [code]true[/code], the sub-viewport will be used in AR/VR process. - </member> <member name="render_target_clear_mode" type="int" setter="set_clear_mode" getter="get_clear_mode" enum="SubViewport.ClearMode" default="0"> The clear mode when the sub-viewport is used as a render target. </member> @@ -27,8 +24,20 @@ <member name="size_2d_override_stretch" type="bool" setter="set_size_2d_override_stretch" getter="is_size_2d_override_stretch_enabled" default="false"> If [code]true[/code], the 2D size override affects stretch as well. </member> + <member name="xr" type="bool" setter="set_use_xr" getter="is_using_xr" default="false"> + If [code]true[/code], the sub-viewport will be used in AR/VR process. + </member> </members> <constants> + <constant name="CLEAR_MODE_ALWAYS" value="0" enum="ClearMode"> + Always clear the render target before drawing. + </constant> + <constant name="CLEAR_MODE_NEVER" value="1" enum="ClearMode"> + Never clear the render target. + </constant> + <constant name="CLEAR_MODE_ONLY_NEXT_FRAME" value="2" enum="ClearMode"> + Clear the render target next frame, then switch to [constant CLEAR_MODE_NEVER]. + </constant> <constant name="UPDATE_DISABLED" value="0" enum="UpdateMode"> Do not update the render target. </constant> @@ -44,14 +53,5 @@ <constant name="UPDATE_ALWAYS" value="4" enum="UpdateMode"> Always update the render target. </constant> - <constant name="CLEAR_MODE_ALWAYS" value="0" enum="ClearMode"> - Always clear the render target before drawing. - </constant> - <constant name="CLEAR_MODE_NEVER" value="1" enum="ClearMode"> - Never clear the render target. - </constant> - <constant name="CLEAR_MODE_ONLY_NEXT_FRAME" value="2" enum="ClearMode"> - Clear the render target next frame, then switch to [constant CLEAR_MODE_NEVER]. - </constant> </constants> </class> diff --git a/doc/classes/TabContainer.xml b/doc/classes/TabContainer.xml index f7e94ad236..22e92ae5d9 100644 --- a/doc/classes/TabContainer.xml +++ b/doc/classes/TabContainer.xml @@ -36,10 +36,10 @@ <method name="get_tab_control" qualifiers="const"> <return type="Control"> </return> - <argument index="0" name="idx" type="int"> + <argument index="0" name="tab_idx" type="int"> </argument> <description> - Returns the currently visible tab's [Control] node. + Returns the [Control] node from the tab at index [code]tab_idx[/code]. </description> </method> <method name="get_tab_count" qualifiers="const"> diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml index b515b27b31..b7cf93d672 100644 --- a/doc/classes/TextEdit.xml +++ b/doc/classes/TextEdit.xml @@ -433,6 +433,7 @@ </member> <member name="mouse_default_cursor_shape" type="int" setter="set_default_cursor_shape" getter="get_default_cursor_shape" override="true" enum="Control.CursorShape" default="1" /> <member name="override_selected_font_color" type="bool" setter="set_override_selected_font_color" getter="is_overriding_selected_font_color" default="false"> + If [code]true[/code], custom [code]font_color_selected[/code] will be used for selected text. </member> <member name="readonly" type="bool" setter="set_readonly" getter="is_readonly" default="false"> If [code]true[/code], read-only mode is enabled. Existing text cannot be modified and new text cannot be added. @@ -611,6 +612,7 @@ <theme_item name="font_color_readonly" type="Color" default="Color( 0.88, 0.88, 0.88, 0.5 )"> </theme_item> <theme_item name="font_color_selected" type="Color" default="Color( 0, 0, 0, 1 )"> + Sets the [Color] of the selected text. [member override_selected_font_color] has to be enabled. </theme_item> <theme_item name="function_color" type="Color" default="Color( 0.4, 0.64, 0.81, 1 )"> </theme_item> diff --git a/doc/classes/TileMap.xml b/doc/classes/TileMap.xml index 1db1142aa0..5b7694b775 100644 --- a/doc/classes/TileMap.xml +++ b/doc/classes/TileMap.xml @@ -43,7 +43,7 @@ <argument index="1" name="y" type="int"> </argument> <description> - Returns the coordinate of the autotile variation in the tileset. Returns a zero vector if the cell doesn't have autotiling. + Returns the coordinate (subtile column and row) of the autotile variation in the tileset. Returns a zero vector if the cell doesn't have autotiling. </description> </method> <method name="get_cellv" qualifiers="const"> @@ -161,7 +161,7 @@ <description> Sets the tile index for the cell given by a Vector2. An index of [code]-1[/code] clears the cell. - Optionally, the tile can also be flipped, transposed, or given autotile coordinates. + Optionally, the tile can also be flipped, transposed, or given autotile coordinates. The autotile coordinate refers to the column and row of the subtile. [b]Note:[/b] Data such as navigation polygons and collision shapes are not immediately updated for performance reasons. If you need these to be immediately updated, you can call [method update_dirty_quadrants]. Overriding this method also overrides it internally, allowing custom logic to be implemented when tiles are placed/removed: diff --git a/doc/classes/UndoRedo.xml b/doc/classes/UndoRedo.xml index 766ebf7e32..2cc3e974e2 100644 --- a/doc/classes/UndoRedo.xml +++ b/doc/classes/UndoRedo.xml @@ -155,7 +155,7 @@ Returns [code]true[/code] if an "undo" action is available. </description> </method> - <method name="is_commiting_action" qualifiers="const"> + <method name="is_committing_action" qualifiers="const"> <return type="bool"> </return> <description> diff --git a/doc/classes/VSlider.xml b/doc/classes/VSlider.xml index 3faafdfe80..9394d6b430 100644 --- a/doc/classes/VSlider.xml +++ b/doc/classes/VSlider.xml @@ -23,6 +23,8 @@ <theme_item name="grabber_area" type="StyleBox"> The background of the area below the grabber. </theme_item> + <theme_item name="grabber_area_highlight" type="StyleBox"> + </theme_item> <theme_item name="grabber_disabled" type="Texture2D"> The texture for the grabber when it's disabled. </theme_item> diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml index 5826822c6e..a2d53f8e0c 100644 --- a/doc/classes/Viewport.xml +++ b/doc/classes/Viewport.xml @@ -192,8 +192,10 @@ If [code]true[/code], the viewport will process 3D audio streams. </member> <member name="canvas_item_default_texture_filter" type="int" setter="set_default_canvas_item_texture_filter" getter="get_default_canvas_item_texture_filter" enum="Viewport.DefaultCanvasItemTextureFilter" default="1"> + Sets the default filter mode used by [CanvasItem]s in this Viewport. See [enum DefaultCanvasItemTextureFilter] for options. </member> <member name="canvas_item_default_texture_repeat" type="int" setter="set_default_canvas_item_texture_repeat" getter="get_default_canvas_item_texture_repeat" enum="Viewport.DefaultCanvasItemTextureRepeat" default="0"> + Sets the default repeat mode used by [CanvasItem]s in this Viewport. See [enum DefaultCanvasItemTextureRepeat] for options. </member> <member name="canvas_transform" type="Transform2D" setter="set_canvas_transform" getter="get_canvas_transform"> The canvas transform of the viewport, useful for changing the on-screen positions of all child [CanvasItem]s. This is relative to the global canvas transform of the viewport. @@ -223,6 +225,9 @@ <member name="physics_object_picking" type="bool" setter="set_physics_object_picking" getter="get_physics_object_picking" default="false"> If [code]true[/code], the objects rendered by viewport become subjects of mouse picking process. </member> + <member name="screen_space_aa" type="int" setter="set_screen_space_aa" getter="get_screen_space_aa" enum="Viewport.ScreenSpaceAA" default="0"> + Sets the screen-space antialiasing method used. Screen-space antialiasing works by selectively blurring edges in a post-process shader. It differs from MSAA which takes multiple coverage samples while rendering objects. Screen-space AA methods are typically faster than MSAA and will smooth out specular aliasing, but tend to make scenes appear blurry. + </member> <member name="shadow_atlas_quad_0" type="int" setter="set_shadow_atlas_quadrant_subdiv" getter="get_shadow_atlas_quadrant_subdiv" enum="Viewport.ShadowAtlasQuadrantSubdiv" default="2"> The subdivision amount of the first quadrant on the shadow atlas. </member> @@ -288,6 +293,33 @@ <constant name="SHADOW_ATLAS_QUADRANT_SUBDIV_MAX" value="7" enum="ShadowAtlasQuadrantSubdiv"> Represents the size of the [enum ShadowAtlasQuadrantSubdiv] enum. </constant> + <constant name="MSAA_DISABLED" value="0" enum="MSAA"> + Multisample antialiasing mode disabled. This is the default value, and also the fastest setting. + </constant> + <constant name="MSAA_2X" value="1" enum="MSAA"> + Use 2x Multisample Antialiasing. + </constant> + <constant name="MSAA_4X" value="2" enum="MSAA"> + Use 4x Multisample Antialiasing. + </constant> + <constant name="MSAA_8X" value="3" enum="MSAA"> + Use 8x Multisample Antialiasing. Likely unsupported on low-end and older hardware. + </constant> + <constant name="MSAA_16X" value="4" enum="MSAA"> + Use 16x Multisample Antialiasing. Likely unsupported on medium and low-end hardware. + </constant> + <constant name="MSAA_MAX" value="5" enum="MSAA"> + Represents the size of the [enum MSAA] enum. + </constant> + <constant name="SCREEN_SPACE_AA_DISABLED" value="0" enum="ScreenSpaceAA"> + Do not perform any antialiasing in the full screen post-process. + </constant> + <constant name="SCREEN_SPACE_AA_FXAA" value="1" enum="ScreenSpaceAA"> + Use fast approximate antialiasing. FXAA is a popular screen-space antialising method, which is fast but will make the image look blurry, especially at lower resolutions. It can still work relatively well at large resolutions such as 1440p and 4K. + </constant> + <constant name="SCREEN_SPACE_AA_MAX" value="2" enum="ScreenSpaceAA"> + Represents the size of the [enum ScreenSpaceAA] enum. + </constant> <constant name="RENDER_INFO_OBJECTS_IN_FRAME" value="0" enum="RenderInfo"> Amount of objects in frame. </constant> @@ -315,58 +347,71 @@ <constant name="DEBUG_DRAW_UNSHADED" value="1" enum="DebugDraw"> Objects are displayed without light information. </constant> + <constant name="DEBUG_DRAW_LIGHTING" value="2" enum="DebugDraw"> + </constant> <constant name="DEBUG_DRAW_OVERDRAW" value="3" enum="DebugDraw"> - Objected are displayed semi-transparent with additive blending so you can see where they intersect. + Objects are displayed semi-transparent with additive blending so you can see where they are drawing over top of one another. A higher overdraw means you are wasting performance on drawing pixels that are being hidden behind others. </constant> <constant name="DEBUG_DRAW_WIREFRAME" value="4" enum="DebugDraw"> Objects are displayed in wireframe style. </constant> + <constant name="DEBUG_DRAW_NORMAL_BUFFER" value="5" enum="DebugDraw"> + </constant> <constant name="DEBUG_DRAW_GI_PROBE_ALBEDO" value="6" enum="DebugDraw"> + Objects are displayed with only the albedo value from [GIProbe]s. </constant> <constant name="DEBUG_DRAW_GI_PROBE_LIGHTING" value="7" enum="DebugDraw"> + Objects are displayed with only the lighting value from [GIProbe]s. </constant> <constant name="DEBUG_DRAW_GI_PROBE_EMISSION" value="8" enum="DebugDraw"> + Objects are displayed with only the emission color from [GIProbe]s. </constant> <constant name="DEBUG_DRAW_SHADOW_ATLAS" value="9" enum="DebugDraw"> + Draws the shadow atlas that stores shadows from [OmniLight3D]s and [SpotLight3D]s in the upper left quadrant of the [Viewport]. </constant> <constant name="DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS" value="10" enum="DebugDraw"> + Draws the shadow atlas that stores shadows from [DirectionalLight3D]s in the upper left quadrant of the [Viewport]. </constant> <constant name="DEBUG_DRAW_SCENE_LUMINANCE" value="11" enum="DebugDraw"> </constant> <constant name="DEBUG_DRAW_SSAO" value="12" enum="DebugDraw"> + Draws the screen-space ambient occlusion texture instead of the scene so that you can clearly see how it is affecting objects. In order for this display mode to work, you must have [member Environment.ssao_enabled] set in your [WorldEnvironment]. </constant> - <constant name="MSAA_DISABLED" value="0" enum="MSAA"> - Multisample anti-aliasing mode disabled. This is the default value. - </constant> - <constant name="MSAA_2X" value="1" enum="MSAA"> - Use 2x Multisample Antialiasing. - </constant> - <constant name="MSAA_4X" value="2" enum="MSAA"> - Use 4x Multisample Antialiasing. + <constant name="DEBUG_DRAW_ROUGHNESS_LIMITER" value="13" enum="DebugDraw"> + Draws the roughness limiter post process over the Viewport so you can see where it has an effect. It must be enabled in [member ProjectSettings.rendering/quality/screen_filters/screen_space_roughness_limiter] to work. </constant> - <constant name="MSAA_8X" value="3" enum="MSAA"> - Use 8x Multisample Antialiasing. Likely unsupported on low-end and older hardware. + <constant name="DEBUG_DRAW_PSSM_SPLITS" value="14" enum="DebugDraw"> + Colors each PSSM split for the [DirectionalLight3D]s in the scene a different color so you can see where the splits are. In order, they will be colored red, green, blue, and yellow. </constant> - <constant name="MSAA_16X" value="4" enum="MSAA"> - Use 16x Multisample Antialiasing. Likely unsupported on medium and low-end hardware. + <constant name="DEBUG_DRAW_DECAL_ATLAS" value="15" enum="DebugDraw"> + Draws the decal atlas used by [Decal]s and light projector textures in the upper left quadrant of the [Viewport]. </constant> <constant name="DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST" value="0" enum="DefaultCanvasItemTextureFilter"> + The texture filter reads from the nearest pixel only. The simplest and fastest method of filtering, but the texture will look pixelized. </constant> <constant name="DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR" value="1" enum="DefaultCanvasItemTextureFilter"> + The texture filter blends between the nearest 4 pixels. Use this when you want to avoid a pixelated style, but do not want mipmaps. </constant> <constant name="DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS" value="2" enum="DefaultCanvasItemTextureFilter"> + The texture filter reads from the nearest pixel in the nearest mipmap. The fastest way to read from textures with mipmaps. </constant> <constant name="DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS" value="3" enum="DefaultCanvasItemTextureFilter"> + The texture filter blends between the nearest 4 pixels and between the nearest 2 mipmaps. </constant> <constant name="DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_MAX" value="4" enum="DefaultCanvasItemTextureFilter"> + Max value for [enum DefaultCanvasItemTextureFilter] enum. </constant> <constant name="DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED" value="0" enum="DefaultCanvasItemTextureRepeat"> + Disables textures repeating. Instead, when reading UVs outside the 0-1 range, the value will be clamped to the edge of the texture, resulting in a stretched out look at the borders of the texture. </constant> <constant name="DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_ENABLED" value="1" enum="DefaultCanvasItemTextureRepeat"> + Enables the texture to repeat when UV coordinates are outside the 0-1 range. If using one of the linear filtering modes, this can result in artifacts at the edges of a texture when the sampler filters across the edges of the texture. </constant> <constant name="DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MIRROR" value="2" enum="DefaultCanvasItemTextureRepeat"> + Flip the texture when repeating so that the edge lines up instead of abruptly changing. </constant> <constant name="DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MAX" value="3" enum="DefaultCanvasItemTextureRepeat"> + Max value for [enum DefaultCanvasItemTextureRepeat] enum. </constant> </constants> </class> diff --git a/doc/classes/VisibilityEnabler2D.xml b/doc/classes/VisibilityEnabler2D.xml index 0bdecafbfa..f0e4c999ac 100644 --- a/doc/classes/VisibilityEnabler2D.xml +++ b/doc/classes/VisibilityEnabler2D.xml @@ -1,11 +1,12 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisibilityEnabler2D" inherits="VisibilityNotifier2D" version="4.0"> <brief_description> - Enables certain nodes only when visible. + Enables certain nodes only when approximately visible. </brief_description> <description> The VisibilityEnabler2D will disable [RigidBody2D], [AnimationPlayer], and other nodes when they are not visible. It will only affect nodes with the same root node as the VisibilityEnabler2D, and the root node itself. - Note that VisibilityEnabler2D will not affect nodes added after scene initialization. + [b]Note:[/b] VisibilityEnabler2D uses an approximate heuristic for performance reasons. If you need exact visibility checking, use another method such as adding an [Area2D] node as a child of a [Camera2D] node. + [b]Note:[/b] VisibilityEnabler2D will not affect nodes added after scene initialization. </description> <tutorials> </tutorials> diff --git a/doc/classes/VisibilityEnabler3D.xml b/doc/classes/VisibilityEnabler3D.xml index 9c25c6c7c8..342a37e7a4 100644 --- a/doc/classes/VisibilityEnabler3D.xml +++ b/doc/classes/VisibilityEnabler3D.xml @@ -1,11 +1,12 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisibilityEnabler3D" inherits="VisibilityNotifier3D" version="4.0"> <brief_description> - Enables certain nodes only when visible. + Enables certain nodes only when approximately visible. </brief_description> <description> The VisibilityEnabler3D will disable [RigidBody3D] and [AnimationPlayer] nodes when they are not visible. It will only affect other nodes within the same scene as the VisibilityEnabler3D itself. - Note that VisibilityEnabler3D will not affect nodes added after scene initialization. + [b]Note:[/b] VisibilityEnabler3D uses an approximate heuristic for performance reasons. It doesn't take walls and other occlusion into account. If you need exact visibility checking, use another method such as adding an [Area3D] node as a child of a [Camera3D] node. + [b]Note:[/b] VisibilityEnabler3D will not affect nodes added after scene initialization. </description> <tutorials> </tutorials> diff --git a/doc/classes/VisibilityNotifier2D.xml b/doc/classes/VisibilityNotifier2D.xml index f2a4a59d77..813f74f404 100644 --- a/doc/classes/VisibilityNotifier2D.xml +++ b/doc/classes/VisibilityNotifier2D.xml @@ -1,10 +1,11 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisibilityNotifier2D" inherits="Node2D" version="4.0"> <brief_description> - Detects when the node is visible on screen. + Detects approximately when the node is visible on screen. </brief_description> <description> The VisibilityNotifier2D detects when it is visible on the screen. It also notifies when its bounding rectangle enters or exits the screen or a viewport. + [b]Note:[/b] VisibilityNotifier2D uses an approximate heuristic for performance reasons. If you need exact visibility checking, use another method such as adding an [Area2D] node as a child of a [Camera2D] node. </description> <tutorials> </tutorials> diff --git a/doc/classes/VisibilityNotifier3D.xml b/doc/classes/VisibilityNotifier3D.xml index d8a605c69c..eb7bb91f26 100644 --- a/doc/classes/VisibilityNotifier3D.xml +++ b/doc/classes/VisibilityNotifier3D.xml @@ -1,10 +1,11 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisibilityNotifier3D" inherits="Node3D" version="4.0"> <brief_description> - Detects when the node is visible on screen. + Detects approximately when the node is visible on screen. </brief_description> <description> The VisibilityNotifier3D detects when it is visible on the screen. It also notifies when its bounding rectangle enters or exits the screen or a [Camera3D]'s view. + [b]Note:[/b] VisibilityNotifier3D uses an approximate heuristic for performance reasons. It doesn't take walls and other occlusion into account. If you need exact visibility checking, use another method such as adding an [Area3D] node as a child of a [Camera3D] node. </description> <tutorials> </tutorials> diff --git a/doc/classes/ARVRAnchor.xml b/doc/classes/XRAnchor3D.xml index 82575ce7cb..a409c79230 100644 --- a/doc/classes/ARVRAnchor.xml +++ b/doc/classes/XRAnchor3D.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ARVRAnchor" inherits="Node3D" version="4.0"> +<class name="XRAnchor3D" inherits="Node3D" version="4.0"> <brief_description> An anchor point in AR space. </brief_description> <description> - The [ARVRAnchor] point is a spatial node that maps a real world location identified by the AR platform to a position within the game world. For example, as long as plane detection in ARKit is on, ARKit will identify and update the position of planes (tables, floors, etc) and create anchors for them. + The [XRAnchor3D] point is a spatial node that maps a real world location identified by the AR platform to a position within the game world. For example, as long as plane detection in ARKit is on, ARKit will identify and update the position of planes (tables, floors, etc) and create anchors for them. This node is mapped to one of the anchors through its unique ID. When you receive a signal that a new anchor is available, you should add this node to your scene for that anchor. You can predefine nodes and set the ID; the nodes will simply remain on 0,0,0 until a plane is recognized. Keep in mind that, as long as plane detection is enabled, the size, placing and orientation of an anchor will be updated as the detection logic learns more about the real world out there especially if only part of the surface is in view. </description> @@ -29,7 +29,7 @@ <return type="Mesh"> </return> <description> - If provided by the [ARVRInterface], this returns a mesh object for the anchor. For an anchor, this can be a shape related to the object being tracked or it can be a mesh that provides topology related to the anchor and can be used to create shadows/reflections on surfaces or for generating collision shapes. + If provided by the [XRInterface], this returns a mesh object for the anchor. For an anchor, this can be a shape related to the object being tracked or it can be a mesh that provides topology related to the anchor and can be used to create shadows/reflections on surfaces or for generating collision shapes. </description> </method> <method name="get_plane" qualifiers="const"> diff --git a/doc/classes/ARVRCamera.xml b/doc/classes/XRCamera3D.xml index c97d5cf1d8..4d86e24daa 100644 --- a/doc/classes/ARVRCamera.xml +++ b/doc/classes/XRCamera3D.xml @@ -1,11 +1,11 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ARVRCamera" inherits="Camera3D" version="4.0"> +<class name="XRCamera3D" inherits="Camera3D" version="4.0"> <brief_description> A camera node with a few overrules for AR/VR applied, such as location tracking. </brief_description> <description> This is a helper spatial node for our camera; note that, if stereoscopic rendering is applicable (VR-HMD), most of the camera properties are ignored, as the HMD information overrides them. The only properties that can be trusted are the near and far planes. - The position and orientation of this node is automatically updated by the ARVR Server to represent the location of the HMD if such tracking is available and can thus be used by game logic. Note that, in contrast to the ARVR Controller, the render thread has access to the most up-to-date tracking data of the HMD and the location of the ARVRCamera can lag a few milliseconds behind what is used for rendering as a result. + The position and orientation of this node is automatically updated by the XR Server to represent the location of the HMD if such tracking is available and can thus be used by game logic. Note that, in contrast to the XR Controller, the render thread has access to the most up-to-date tracking data of the HMD and the location of the XRCamera3D can lag a few milliseconds behind what is used for rendering as a result. </description> <tutorials> <link>https://docs.godotengine.org/en/latest/tutorials/vr/index.html</link> diff --git a/doc/classes/ARVRController.xml b/doc/classes/XRController3D.xml index 572b47ce6d..e4a06a80db 100644 --- a/doc/classes/ARVRController.xml +++ b/doc/classes/XRController3D.xml @@ -1,12 +1,12 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ARVRController" inherits="Node3D" version="4.0"> +<class name="XRController3D" inherits="Node3D" version="4.0"> <brief_description> A spatial node representing a spatially-tracked controller. </brief_description> <description> This is a helper spatial node that is linked to the tracking of controllers. It also offers several handy passthroughs to the state of buttons and such on the controllers. - Controllers are linked by their ID. You can create controller nodes before the controllers are available. If your game always uses two controllers (one for each hand), you can predefine the controllers with ID 1 and 2; they will become active as soon as the controllers are identified. If you expect additional controllers to be used, you should react to the signals and add ARVRController nodes to your scene. - The position of the controller node is automatically updated by the [ARVRServer]. This makes this node ideal to add child nodes to visualize the controller. + Controllers are linked by their ID. You can create controller nodes before the controllers are available. If your game always uses two controllers (one for each hand), you can predefine the controllers with ID 1 and 2; they will become active as soon as the controllers are identified. If you expect additional controllers to be used, you should react to the signals and add XRController3D nodes to your scene. + The position of the controller node is automatically updated by the [XRServer]. This makes this node ideal to add child nodes to visualize the controller. </description> <tutorials> <link>https://docs.godotengine.org/en/latest/tutorials/vr/index.html</link> @@ -20,17 +20,17 @@ </description> </method> <method name="get_hand" qualifiers="const"> - <return type="int" enum="ARVRPositionalTracker.TrackerHand"> + <return type="int" enum="XRPositionalTracker.TrackerHand"> </return> <description> - Returns the hand holding this controller, if known. See [enum ARVRPositionalTracker.TrackerHand]. + Returns the hand holding this controller, if known. See [enum XRPositionalTracker.TrackerHand]. </description> </method> <method name="get_is_active" qualifiers="const"> <return type="bool"> </return> <description> - Returns [code]true[/code] if the bound controller is active. ARVR systems attempt to track active controllers. + Returns [code]true[/code] if the bound controller is active. XR systems attempt to track active controllers. </description> </method> <method name="get_joystick_axis" qualifiers="const"> @@ -46,14 +46,14 @@ <return type="int"> </return> <description> - Returns the ID of the joystick object bound to this. Every controller tracked by the [ARVRServer] that has buttons and axis will also be registered as a joystick within Godot. This means that all the normal joystick tracking and input mapping will work for buttons and axis found on the AR/VR controllers. This ID is purely offered as information so you can link up the controller with its joystick entry. + Returns the ID of the joystick object bound to this. Every controller tracked by the [XRServer] that has buttons and axis will also be registered as a joystick within Godot. This means that all the normal joystick tracking and input mapping will work for buttons and axis found on the AR/VR controllers. This ID is purely offered as information so you can link up the controller with its joystick entry. </description> </method> <method name="get_mesh" qualifiers="const"> <return type="Mesh"> </return> <description> - If provided by the [ARVRInterface], this returns a mesh associated with the controller. This can be used to visualize the controller. + If provided by the [XRInterface], this returns a mesh associated with the controller. This can be used to visualize the controller. </description> </method> <method name="is_button_pressed" qualifiers="const"> @@ -70,11 +70,11 @@ <member name="controller_id" type="int" setter="set_controller_id" getter="get_controller_id" default="1"> The controller's ID. A controller ID of 0 is unbound and will always result in an inactive node. Controller ID 1 is reserved for the first controller that identifies itself as the left-hand controller and ID 2 is reserved for the first controller that identifies itself as the right-hand controller. - For any other controller that the [ARVRServer] detects, we continue with controller ID 3. + For any other controller that the [XRServer] detects, we continue with controller ID 3. When a controller is turned off, its slot is freed. This ensures controllers will keep the same ID even when controllers with lower IDs are turned off. </member> <member name="rumble" type="float" setter="set_rumble" getter="get_rumble" default="0.0"> - The degree to which the controller vibrates. Ranges from [code]0.0[/code] to [code]1.0[/code] with precision [code].01[/code]. If changed, updates [member ARVRPositionalTracker.rumble] accordingly. + The degree to which the controller vibrates. Ranges from [code]0.0[/code] to [code]1.0[/code] with precision [code].01[/code]. If changed, updates [member XRPositionalTracker.rumble] accordingly. This is a useful property to animate if you want the controller to vibrate for a limited duration. </member> </members> diff --git a/doc/classes/ARVRInterface.xml b/doc/classes/XRInterface.xml index 0727bda668..1985010223 100644 --- a/doc/classes/ARVRInterface.xml +++ b/doc/classes/XRInterface.xml @@ -1,11 +1,11 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ARVRInterface" inherits="Reference" version="4.0"> +<class name="XRInterface" inherits="Reference" version="4.0"> <brief_description> Base class for an AR/VR interface implementation. </brief_description> <description> - This class needs to be implemented to make an AR or VR platform available to Godot and these should be implemented as C++ modules or GDNative modules (note that for GDNative the subclass ARVRScriptInterface should be used). Part of the interface is exposed to GDScript so you can detect, enable and configure an AR or VR platform. - Interfaces should be written in such a way that simply enabling them will give us a working setup. You can query the available interfaces through [ARVRServer]. + This class needs to be implemented to make an AR or VR platform available to Godot and these should be implemented as C++ modules or GDNative modules (note that for GDNative the subclass XRScriptInterface should be used). Part of the interface is exposed to GDScript so you can detect, enable and configure an AR or VR platform. + Interfaces should be written in such a way that simply enabling them will give us a working setup. You can query the available interfaces through [XRServer]. </description> <tutorials> <link>https://docs.godotengine.org/en/latest/tutorials/vr/index.html</link> @@ -40,7 +40,7 @@ </description> </method> <method name="get_tracking_status" qualifiers="const"> - <return type="int" enum="ARVRInterface.Tracking_status"> + <return type="int" enum="XRInterface.Tracking_status"> </return> <description> If supported, returns the status of our tracking. This will allow you to provide feedback to the user whether there are issues with positional tracking. @@ -84,19 +84,19 @@ </member> </members> <constants> - <constant name="ARVR_NONE" value="0" enum="Capabilities"> - No ARVR capabilities. + <constant name="XR_NONE" value="0" enum="Capabilities"> + No XR capabilities. </constant> - <constant name="ARVR_MONO" value="1" enum="Capabilities"> + <constant name="XR_MONO" value="1" enum="Capabilities"> This interface can work with normal rendering output (non-HMD based AR). </constant> - <constant name="ARVR_STEREO" value="2" enum="Capabilities"> + <constant name="XR_STEREO" value="2" enum="Capabilities"> This interface supports stereoscopic rendering. </constant> - <constant name="ARVR_AR" value="4" enum="Capabilities"> + <constant name="XR_AR" value="4" enum="Capabilities"> This interface supports AR (video background and real world tracking). </constant> - <constant name="ARVR_EXTERNAL" value="8" enum="Capabilities"> + <constant name="XR_EXTERNAL" value="8" enum="Capabilities"> This interface outputs to an external device. If the main viewport is used, the on screen output is an unmodified buffer of either the left or right eye (stretched if the viewport size is not changed to the same aspect ratio of [method get_render_targetsize]). Using a separate viewport node frees up the main viewport for other purposes. </constant> <constant name="EYE_MONO" value="0" enum="Eyes"> @@ -108,19 +108,19 @@ <constant name="EYE_RIGHT" value="2" enum="Eyes"> Right eye output, this is mostly used internally when rendering the image for the right eye and obtaining positioning and projection information. </constant> - <constant name="ARVR_NORMAL_TRACKING" value="0" enum="Tracking_status"> + <constant name="XR_NORMAL_TRACKING" value="0" enum="Tracking_status"> Tracking is behaving as expected. </constant> - <constant name="ARVR_EXCESSIVE_MOTION" value="1" enum="Tracking_status"> + <constant name="XR_EXCESSIVE_MOTION" value="1" enum="Tracking_status"> Tracking is hindered by excessive motion (the player is moving faster than tracking can keep up). </constant> - <constant name="ARVR_INSUFFICIENT_FEATURES" value="2" enum="Tracking_status"> + <constant name="XR_INSUFFICIENT_FEATURES" value="2" enum="Tracking_status"> Tracking is hindered by insufficient features, it's too dark (for camera-based tracking), player is blocked, etc. </constant> - <constant name="ARVR_UNKNOWN_TRACKING" value="3" enum="Tracking_status"> + <constant name="XR_UNKNOWN_TRACKING" value="3" enum="Tracking_status"> We don't know the status of the tracking or this interface does not provide feedback. </constant> - <constant name="ARVR_NOT_TRACKING" value="4" enum="Tracking_status"> + <constant name="XR_NOT_TRACKING" value="4" enum="Tracking_status"> Tracking is not functional (camera not plugged in or obscured, lighthouses turned off, etc.). </constant> </constants> diff --git a/doc/classes/ARVROrigin.xml b/doc/classes/XROrigin3D.xml index a88a89c927..57cf673d30 100644 --- a/doc/classes/ARVROrigin.xml +++ b/doc/classes/XROrigin3D.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ARVROrigin" inherits="Node3D" version="4.0"> +<class name="XROrigin3D" inherits="Node3D" version="4.0"> <brief_description> The origin point in AR/VR. </brief_description> <description> This is a special node within the AR/VR system that maps the physical location of the center of our tracking space to the virtual location within our game world. - There should be only one of these nodes in your scene and you must have one. All the ARVRCamera, ARVRController and ARVRAnchor nodes should be direct children of this node for spatial tracking to work correctly. + There should be only one of these nodes in your scene and you must have one. All the XRCamera3D, XRController3D and XRAnchor3D nodes should be direct children of this node for spatial tracking to work correctly. It is the position of this node that you update when your character needs to move through your game world while we're not moving in the real world. Movement in the real world is always in relation to this origin point. - For example, if your character is driving a car, the ARVROrigin node should be a child node of this car. Or, if you're implementing a teleport system to move your character, you should change the position of this node. + For example, if your character is driving a car, the XROrigin3D node should be a child node of this car. Or, if you're implementing a teleport system to move your character, you should change the position of this node. </description> <tutorials> <link>https://docs.godotengine.org/en/latest/tutorials/vr/index.html</link> @@ -17,7 +17,7 @@ <members> <member name="world_scale" type="float" setter="set_world_scale" getter="get_world_scale" default="1.0"> Allows you to adjust the scale to your game's units. Most AR/VR platforms assume a scale of 1 game world unit = 1 real world meter. - [b]Note:[/b] This method is a passthrough to the [ARVRServer] itself. + [b]Note:[/b] This method is a passthrough to the [XRServer] itself. </member> </members> <constants> diff --git a/doc/classes/ARVRPositionalTracker.xml b/doc/classes/XRPositionalTracker.xml index 640b721d37..2f7cc21703 100644 --- a/doc/classes/ARVRPositionalTracker.xml +++ b/doc/classes/XRPositionalTracker.xml @@ -1,19 +1,19 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ARVRPositionalTracker" inherits="Object" version="4.0"> +<class name="XRPositionalTracker" inherits="Object" version="4.0"> <brief_description> A tracked object. </brief_description> <description> An instance of this object represents a device that is tracked, such as a controller or anchor point. HMDs aren't represented here as they are handled internally. - As controllers are turned on and the AR/VR interface detects them, instances of this object are automatically added to this list of active tracking objects accessible through the [ARVRServer]. - The [ARVRController] and [ARVRAnchor] both consume objects of this type and should be used in your project. The positional trackers are just under-the-hood objects that make this all work. These are mostly exposed so that GDNative-based interfaces can interact with them. + As controllers are turned on and the AR/VR interface detects them, instances of this object are automatically added to this list of active tracking objects accessible through the [XRServer]. + The [XRController3D] and [XRAnchor3D] both consume objects of this type and should be used in your project. The positional trackers are just under-the-hood objects that make this all work. These are mostly exposed so that GDNative-based interfaces can interact with them. </description> <tutorials> <link>https://docs.godotengine.org/en/latest/tutorials/vr/index.html</link> </tutorials> <methods> <method name="get_hand" qualifiers="const"> - <return type="int" enum="ARVRPositionalTracker.TrackerHand"> + <return type="int" enum="XRPositionalTracker.TrackerHand"> </return> <description> Returns the hand holding this tracker, if known. See [enum TrackerHand] constants. @@ -58,7 +58,7 @@ <return type="int"> </return> <description> - Returns the internal tracker ID. This uniquely identifies the tracker per tracker type and matches the ID you need to specify for nodes such as the [ARVRController] and [ARVRAnchor] nodes. + Returns the internal tracker ID. This uniquely identifies the tracker per tracker type and matches the ID you need to specify for nodes such as the [XRController3D] and [XRAnchor3D] nodes. </description> </method> <method name="get_tracks_orientation" qualifiers="const"> @@ -85,7 +85,7 @@ </description> </method> <method name="get_type" qualifiers="const"> - <return type="int" enum="ARVRServer.TrackerType"> + <return type="int" enum="XRServer.TrackerType"> </return> <description> Returns the tracker's type. diff --git a/doc/classes/ARVRServer.xml b/doc/classes/XRServer.xml index d8d069c048..5e6002aee3 100644 --- a/doc/classes/ARVRServer.xml +++ b/doc/classes/XRServer.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="ARVRServer" inherits="Object" version="4.0"> +<class name="XRServer" inherits="Object" version="4.0"> <brief_description> Server for AR and VR features. </brief_description> @@ -13,7 +13,7 @@ <method name="center_on_hmd"> <return type="void"> </return> - <argument index="0" name="rotation_mode" type="int" enum="ARVRServer.RotationMode"> + <argument index="0" name="rotation_mode" type="int" enum="XRServer.RotationMode"> </argument> <argument index="1" name="keep_height" type="bool"> </argument> @@ -27,7 +27,7 @@ </description> </method> <method name="find_interface" qualifiers="const"> - <return type="ARVRInterface"> + <return type="XRInterface"> </return> <argument index="0" name="name" type="String"> </argument> @@ -43,7 +43,7 @@ </description> </method> <method name="get_interface" qualifiers="const"> - <return type="ARVRInterface"> + <return type="XRInterface"> </return> <argument index="0" name="idx" type="int"> </argument> @@ -69,7 +69,7 @@ <return type="int"> </return> <description> - Returns the absolute timestamp (in μs) of the last [ARVRServer] commit of the AR/VR eyes to [RenderingServer]. The value comes from an internal call to [method OS.get_ticks_usec]. + Returns the absolute timestamp (in μs) of the last [XRServer] commit of the AR/VR eyes to [RenderingServer]. The value comes from an internal call to [method OS.get_ticks_usec]. </description> </method> <method name="get_last_frame_usec"> @@ -83,7 +83,7 @@ <return type="int"> </return> <description> - Returns the absolute timestamp (in μs) of the last [ARVRServer] process callback. The value comes from an internal call to [method OS.get_ticks_usec]. + Returns the absolute timestamp (in μs) of the last [XRServer] process callback. The value comes from an internal call to [method OS.get_ticks_usec]. </description> </method> <method name="get_reference_frame" qualifiers="const"> @@ -94,7 +94,7 @@ </description> </method> <method name="get_tracker" qualifiers="const"> - <return type="ARVRPositionalTracker"> + <return type="XRPositionalTracker"> </return> <argument index="0" name="idx" type="int"> </argument> @@ -111,8 +111,8 @@ </method> </methods> <members> - <member name="primary_interface" type="ARVRInterface" setter="set_primary_interface" getter="get_primary_interface"> - The primary [ARVRInterface] currently bound to the [ARVRServer]. + <member name="primary_interface" type="XRInterface" setter="set_primary_interface" getter="get_primary_interface"> + The primary [XRInterface] currently bound to the [XRServer]. </member> <member name="world_scale" type="float" setter="set_world_scale" getter="get_world_scale" default="1.0"> Allows you to adjust the scale to your game's units. Most AR/VR platforms assume a scale of 1 game world unit = 1 real world meter. @@ -141,7 +141,7 @@ <argument index="2" name="id" type="int"> </argument> <description> - Emitted when a new tracker has been added. If you don't use a fixed number of controllers or if you're using [ARVRAnchor]s for an AR solution, it is important to react to this signal to add the appropriate [ARVRController] or [ARVRAnchor] nodes related to this new tracker. + Emitted when a new tracker has been added. If you don't use a fixed number of controllers or if you're using [XRAnchor3D]s for an AR solution, it is important to react to this signal to add the appropriate [XRController3D] or [XRAnchor3D] nodes related to this new tracker. </description> </signal> <signal name="tracker_removed"> @@ -152,7 +152,7 @@ <argument index="2" name="id" type="int"> </argument> <description> - Emitted when a tracker is removed. You should remove any [ARVRController] or [ARVRAnchor] points if applicable. This is not mandatory, the nodes simply become inactive and will be made active again when a new tracker becomes available (i.e. a new controller is switched on that takes the place of the previous one). + Emitted when a tracker is removed. You should remove any [XRController3D] or [XRAnchor3D] points if applicable. This is not mandatory, the nodes simply become inactive and will be made active again when a new tracker becomes available (i.e. a new controller is switched on that takes the place of the previous one). </description> </signal> </signals> diff --git a/doc/tools/makerst.py b/doc/tools/makerst.py index 9de5eac31d..c6c6cae6c0 100755 --- a/doc/tools/makerst.py +++ b/doc/tools/makerst.py @@ -424,7 +424,7 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S type_rst = property_def.type_name.to_rst(state) default = property_def.default_value if property_def.overridden: - ml.append((type_rst, property_def.name, "**O:** " + default)) + ml.append((type_rst, property_def.name, default + " *(parent override)*")) else: ref = ":ref:`{0}<class_{1}_property_{0}>`".format(property_def.name, class_name) ml.append((type_rst, ref, default)) diff --git a/drivers/dummy/texture_loader_dummy.cpp b/drivers/dummy/texture_loader_dummy.cpp index 92919f25c8..ddd2943720 100644 --- a/drivers/dummy/texture_loader_dummy.cpp +++ b/drivers/dummy/texture_loader_dummy.cpp @@ -35,7 +35,7 @@ #include <string.h> -RES ResourceFormatDummyTexture::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatDummyTexture::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { unsigned int width = 8; unsigned int height = 8; diff --git a/drivers/dummy/texture_loader_dummy.h b/drivers/dummy/texture_loader_dummy.h index 2a7d01dd78..ef9f3b13b6 100644 --- a/drivers/dummy/texture_loader_dummy.h +++ b/drivers/dummy/texture_loader_dummy.h @@ -36,7 +36,7 @@ class ResourceFormatDummyTexture : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp index 2ba2147de9..bdf0559f58 100644 --- a/drivers/gles2/rasterizer_scene_gles2.cpp +++ b/drivers/gles2/rasterizer_scene_gles2.cpp @@ -4045,7 +4045,7 @@ void RasterizerSceneGLES2::initialize() { //maximum compatibility, renderbuffer and RGBA shadow glGenRenderbuffers(1, &directional_shadow.depth); glBindRenderbuffer(GL_RENDERBUFFER, directional_shadow.depth); - glRenderbufferStorage(GL_RENDERBUFFER, storage->config.depth_internalformat, directional_shadow.size, directional_shadow.size); + glRenderbufferStorage(GL_RENDERBUFFER, storage->config.depth_buffer_internalformat, directional_shadow.size, directional_shadow.size); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, directional_shadow.depth); glGenTextures(1, &directional_shadow.color); diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp index 409722ff82..b8c7815f6a 100644 --- a/drivers/gles2/rasterizer_storage_gles2.cpp +++ b/drivers/gles2/rasterizer_storage_gles2.cpp @@ -6252,7 +6252,7 @@ void RasterizerStorageGLES2::initialize() { #endif config.force_vertex_shading = GLOBAL_GET("rendering/quality/shading/force_vertex_shading"); - config.use_fast_texture_filter = GLOBAL_GET("rendering/quality/filters/use_nearest_mipmap_filter"); + config.use_fast_texture_filter = GLOBAL_GET("rendering/quality/texture_filters/use_nearest_mipmap_filter"); } void RasterizerStorageGLES2::finalize() { diff --git a/drivers/vulkan/SCsub b/drivers/vulkan/SCsub index 7ffdac27d5..91d0e42f80 100644 --- a/drivers/vulkan/SCsub +++ b/drivers/vulkan/SCsub @@ -4,7 +4,25 @@ Import("env") env.add_source_files(env.drivers_sources, "*.cpp") -if env["builtin_vulkan"]: +if env["platform"] == "android": + # Use NDK Vulkan headers + thirdparty_dir = env["ANDROID_NDK_ROOT"] + "/sources/third_party/vulkan/src" + thirdparty_includes = [ + thirdparty_dir, + thirdparty_dir + "/include", + thirdparty_dir + "/layers", + thirdparty_dir + "/layers/generated", + ] + env.Prepend(CPPPATH=thirdparty_includes) + + # Build Vulkan memory allocator + env_thirdparty = env.Clone() + env_thirdparty.disable_warnings() + + thirdparty_dir = "#thirdparty/vulkan" + vma_sources = [thirdparty_dir + "/android/vk_mem_alloc.cpp"] + env_thirdparty.add_source_files(env.drivers_sources, vma_sources) +elif env["builtin_vulkan"]: # Use bundled Vulkan headers thirdparty_dir = "#thirdparty/vulkan" env.Prepend(CPPPATH=[thirdparty_dir, thirdparty_dir + "/include", thirdparty_dir + "/loader"]) diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index 01da97cfd5..23e9227a39 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -1565,11 +1565,21 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T image_create_info.pNext = nullptr; image_create_info.flags = 0; - VkImageFormatListCreateInfoKHR format_list_create_info; - Vector<VkFormat> allowed_formats; +#ifndef _MSC_VER +#warning TODO check for support via RenderingDevice to enable on mobile when possible +#endif + +#ifndef ANDROID_ENABLED + // vkCreateImage fails with format list on Android (VK_ERROR_OUT_OF_HOST_MEMORY) + VkImageFormatListCreateInfoKHR format_list_create_info; //keep out of the if, needed for creation + Vector<VkFormat> allowed_formats; //keep out of the if, needed for creation +#endif if (p_format.shareable_formats.size()) { image_create_info.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; + +#ifndef ANDROID_ENABLED + for (int i = 0; i < p_format.shareable_formats.size(); i++) { allowed_formats.push_back(vulkan_formats[p_format.shareable_formats[i]]); } @@ -1584,7 +1594,9 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T "If supplied a list of shareable formats, the current format must be present in the list"); ERR_FAIL_COND_V_MSG(p_view.format_override != DATA_FORMAT_MAX && p_format.shareable_formats.find(p_view.format_override) == -1, RID(), "If supplied a list of shareable formats, the current view format override must be present in the list"); +#endif } + if (p_format.type == TEXTURE_TYPE_CUBE || p_format.type == TEXTURE_TYPE_CUBE_ARRAY) { image_create_info.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; } @@ -1760,6 +1772,8 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T texture.depth = image_create_info.extent.depth; texture.layers = image_create_info.arrayLayers; texture.mipmaps = image_create_info.mipLevels; + texture.base_mipmap = 0; + texture.base_layer = 0; texture.usage_flags = p_format.usage_bits; texture.samples = p_format.samples; texture.allowed_shared_formats = p_format.shareable_formats; @@ -2000,6 +2014,8 @@ RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p get_image_format_required_size(texture.format, texture.width, texture.height, texture.depth, p_mipmap + 1, &texture.width, &texture.height); texture.mipmaps = 1; texture.layers = p_slice_type == TEXTURE_SLICE_CUBEMAP ? 6 : 1; + texture.base_mipmap = p_mipmap; + texture.base_layer = p_layer; VkImageViewCreateInfo image_view_create_info; image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; @@ -2660,6 +2676,159 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture, return OK; } +Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID p_to_texture, bool p_sync_with_draw) { + _THREAD_SAFE_METHOD_ + + Texture *src_tex = texture_owner.getornull(p_from_texture); + ERR_FAIL_COND_V(!src_tex, ERR_INVALID_PARAMETER); + + ERR_FAIL_COND_V_MSG(p_sync_with_draw && src_tex->bound, ERR_INVALID_PARAMETER, + "Source texture can't be copied while a render pass that uses it is being created. Ensure render pass is finalized (and that it was created with RENDER_PASS_CONTENTS_FINISH) to unbind this texture."); + ERR_FAIL_COND_V_MSG(!(src_tex->usage_flags & TEXTURE_USAGE_CAN_COPY_FROM_BIT), ERR_INVALID_PARAMETER, + "Source texture requires the TEXTURE_USAGE_CAN_COPY_FROM_BIT in order to be retrieved."); + + ERR_FAIL_COND_V_MSG(src_tex->type != TEXTURE_TYPE_2D, ERR_INVALID_PARAMETER, "Source texture must be 2D (or a slice of a 3D/Cube texture)"); + ERR_FAIL_COND_V_MSG(src_tex->samples == TEXTURE_SAMPLES_1, ERR_INVALID_PARAMETER, "Source texture must be multisampled."); + + Texture *dst_tex = texture_owner.getornull(p_to_texture); + ERR_FAIL_COND_V(!dst_tex, ERR_INVALID_PARAMETER); + + ERR_FAIL_COND_V_MSG(p_sync_with_draw && dst_tex->bound, ERR_INVALID_PARAMETER, + "Destination texture can't be copied while a render pass that uses it is being created. Ensure render pass is finalized (and that it was created with RENDER_PASS_CONTENTS_FINISH) to unbind this texture."); + ERR_FAIL_COND_V_MSG(!(dst_tex->usage_flags & TEXTURE_USAGE_CAN_COPY_TO_BIT), ERR_INVALID_PARAMETER, + "Destination texture requires the TEXTURE_USAGE_CAN_COPY_TO_BIT in order to be retrieved."); + + ERR_FAIL_COND_V_MSG(dst_tex->type != TEXTURE_TYPE_2D, ERR_INVALID_PARAMETER, "Destination texture must be 2D (or a slice of a 3D/Cube texture)."); + ERR_FAIL_COND_V_MSG(dst_tex->samples != TEXTURE_SAMPLES_1, ERR_INVALID_PARAMETER, "Destination texture must not be multisampled."); + + ERR_FAIL_COND_V_MSG(src_tex->format != dst_tex->format, ERR_INVALID_PARAMETER, "Source and Destionation textures must be the same format."); + ERR_FAIL_COND_V_MSG(src_tex->width != dst_tex->width && src_tex->height != dst_tex->height && src_tex->depth != dst_tex->depth, ERR_INVALID_PARAMETER, "Source and Destionation textures must have the same dimensions."); + + ERR_FAIL_COND_V_MSG(src_tex->read_aspect_mask != dst_tex->read_aspect_mask, ERR_INVALID_PARAMETER, + "Source and destination texture must be of the same type (color or depth)."); + + VkCommandBuffer command_buffer = p_sync_with_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer; + + { + + //PRE Copy the image + + { //Source + VkImageMemoryBarrier image_memory_barrier; + image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + image_memory_barrier.pNext = nullptr; + image_memory_barrier.srcAccessMask = 0; + image_memory_barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + image_memory_barrier.oldLayout = src_tex->layout; + image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + + image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + image_memory_barrier.image = src_tex->image; + image_memory_barrier.subresourceRange.aspectMask = src_tex->barrier_aspect_mask; + image_memory_barrier.subresourceRange.baseMipLevel = src_tex->base_mipmap; + image_memory_barrier.subresourceRange.levelCount = 1; + image_memory_barrier.subresourceRange.baseArrayLayer = src_tex->base_layer; + image_memory_barrier.subresourceRange.layerCount = 1; + + vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); + } + { //Dest + VkImageMemoryBarrier image_memory_barrier; + image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + image_memory_barrier.pNext = nullptr; + image_memory_barrier.srcAccessMask = 0; + image_memory_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + image_memory_barrier.oldLayout = dst_tex->layout; + image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + + image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + image_memory_barrier.image = dst_tex->image; + image_memory_barrier.subresourceRange.aspectMask = dst_tex->read_aspect_mask; + image_memory_barrier.subresourceRange.baseMipLevel = dst_tex->base_mipmap; + image_memory_barrier.subresourceRange.levelCount = 1; + image_memory_barrier.subresourceRange.baseArrayLayer = dst_tex->base_layer; + image_memory_barrier.subresourceRange.layerCount = 1; + + vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); + } + + //COPY + + { + + VkImageResolve image_copy_region; + image_copy_region.srcSubresource.aspectMask = src_tex->read_aspect_mask; + image_copy_region.srcSubresource.baseArrayLayer = src_tex->base_layer; + image_copy_region.srcSubresource.layerCount = 1; + image_copy_region.srcSubresource.mipLevel = src_tex->base_mipmap; + image_copy_region.srcOffset.x = 0; + image_copy_region.srcOffset.y = 0; + image_copy_region.srcOffset.z = 0; + + image_copy_region.dstSubresource.aspectMask = dst_tex->read_aspect_mask; + image_copy_region.dstSubresource.baseArrayLayer = dst_tex->base_layer; + image_copy_region.dstSubresource.layerCount = 1; + image_copy_region.dstSubresource.mipLevel = dst_tex->base_mipmap; + image_copy_region.dstOffset.x = 0; + image_copy_region.dstOffset.y = 0; + image_copy_region.dstOffset.z = 0; + + image_copy_region.extent.width = src_tex->width; + image_copy_region.extent.height = src_tex->height; + image_copy_region.extent.depth = src_tex->depth; + + vkCmdResolveImage(command_buffer, src_tex->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst_tex->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &image_copy_region); + } + + // RESTORE LAYOUT for SRC and DST + + { //restore src + VkImageMemoryBarrier image_memory_barrier; + image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + image_memory_barrier.pNext = nullptr; + image_memory_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + image_memory_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + image_memory_barrier.newLayout = src_tex->layout; + image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + image_memory_barrier.image = src_tex->image; + image_memory_barrier.subresourceRange.aspectMask = src_tex->barrier_aspect_mask; + image_memory_barrier.subresourceRange.baseMipLevel = src_tex->base_mipmap; + image_memory_barrier.subresourceRange.levelCount = 1; + image_memory_barrier.subresourceRange.baseArrayLayer = src_tex->base_layer; + image_memory_barrier.subresourceRange.layerCount = 1; + + vkCmdPipelineBarrier(command_buffer, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); + } + + { //make dst readable + + VkImageMemoryBarrier image_memory_barrier; + image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + image_memory_barrier.pNext = nullptr; + image_memory_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + image_memory_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + image_memory_barrier.newLayout = dst_tex->layout; + + image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + image_memory_barrier.image = dst_tex->image; + image_memory_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + image_memory_barrier.subresourceRange.baseMipLevel = dst_tex->base_mipmap; + image_memory_barrier.subresourceRange.levelCount = 1; + image_memory_barrier.subresourceRange.baseArrayLayer = dst_tex->base_layer; + image_memory_barrier.subresourceRange.layerCount = 1; + + vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); + } + } + + return OK; +} Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, bool p_sync_with_draw) { @@ -2702,9 +2871,9 @@ Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color, image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; image_memory_barrier.image = src_tex->image; image_memory_barrier.subresourceRange.aspectMask = src_tex->read_aspect_mask; - image_memory_barrier.subresourceRange.baseMipLevel = p_base_mipmap; + image_memory_barrier.subresourceRange.baseMipLevel = src_tex->base_mipmap + p_base_mipmap; image_memory_barrier.subresourceRange.levelCount = p_mipmaps; - image_memory_barrier.subresourceRange.baseArrayLayer = p_base_layer; + image_memory_barrier.subresourceRange.baseArrayLayer = src_tex->base_layer + p_base_layer; image_memory_barrier.subresourceRange.layerCount = p_layers; layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; @@ -2719,9 +2888,9 @@ Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color, VkImageSubresourceRange range; range.aspectMask = src_tex->read_aspect_mask; - range.baseArrayLayer = p_base_layer; + range.baseArrayLayer = src_tex->base_layer + p_base_layer; range.layerCount = p_layers; - range.baseMipLevel = p_base_mipmap; + range.baseMipLevel = src_tex->base_mipmap + p_base_mipmap; range.levelCount = p_mipmaps; vkCmdClearColorImage(command_buffer, src_tex->image, layout, &clear_color, 1, &range); @@ -2740,9 +2909,9 @@ Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color, image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; image_memory_barrier.image = src_tex->image; image_memory_barrier.subresourceRange.aspectMask = src_tex->read_aspect_mask; - image_memory_barrier.subresourceRange.baseMipLevel = p_base_mipmap; + image_memory_barrier.subresourceRange.baseMipLevel = src_tex->base_mipmap + p_base_mipmap; image_memory_barrier.subresourceRange.levelCount = p_mipmaps; - image_memory_barrier.subresourceRange.baseArrayLayer = p_base_layer; + image_memory_barrier.subresourceRange.baseArrayLayer = src_tex->base_layer + p_base_layer; image_memory_barrier.subresourceRange.layerCount = p_layers; vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); @@ -2840,6 +3009,21 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there } } break; + case INITIAL_ACTION_DROP: { + if (p_format[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) { + description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + } else if (p_format[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { + description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there + description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + } else { + description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there + } + } break; case INITIAL_ACTION_CONTINUE: { if (p_format[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) { description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; @@ -3143,7 +3327,7 @@ RID RenderingDeviceVulkan::vertex_buffer_create(uint32_t p_size_bytes, const Vec } // Internally reference counted, this ID is warranted to be unique for the same description, but needs to be freed as many times as it was allocated -RenderingDevice::VertexFormatID RenderingDeviceVulkan::vertex_format_create(const Vector<VertexDescription> &p_vertex_formats) { +RenderingDevice::VertexFormatID RenderingDeviceVulkan::vertex_format_create(const Vector<VertexAttribute> &p_vertex_formats) { _THREAD_SAFE_METHOD_ @@ -3218,7 +3402,7 @@ RID RenderingDeviceVulkan::vertex_array_create(uint32_t p_vertex_count, VertexFo //validate with buffer { - const VertexDescription &atf = vd.vertex_formats[i]; + const VertexAttribute &atf = vd.vertex_formats[i]; uint32_t element_size = get_format_vertex_size(atf.format); ERR_FAIL_COND_V(element_size == 0, RID()); //should never happens since this was prevalidated @@ -4319,6 +4503,10 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, attachable_textures.push_back(texture->owner.is_valid() ? texture->owner : uniform.ids[j + 1]); } + if (texture->usage_flags & TEXTURE_USAGE_STORAGE_BIT) { + //can also be used as storage, add to mutable sampled + mutable_sampled_textures.push_back(texture); + } if (texture->owner.is_valid()) { texture = texture_owner.getornull(texture->owner); ERR_FAIL_COND_V(!texture, RID()); //bug, should never happen @@ -4327,11 +4515,6 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; image_info.push_back(img_info); - - if (texture->usage_flags & TEXTURE_USAGE_STORAGE_BIT) { - //can also be used as storage, add to mutable sampled - mutable_sampled_textures.push_back(texture); - } } write.dstArrayElement = 0; @@ -4371,6 +4554,11 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, attachable_textures.push_back(texture->owner.is_valid() ? texture->owner : uniform.ids[j]); } + if (texture->usage_flags & TEXTURE_USAGE_STORAGE_BIT) { + //can also be used as storage, add to mutable sampled + mutable_sampled_textures.push_back(texture); + } + if (texture->owner.is_valid()) { texture = texture_owner.getornull(texture->owner); ERR_FAIL_COND_V(!texture, RID()); //bug, should never happen @@ -4379,11 +4567,6 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; image_info.push_back(img_info); - - if (texture->usage_flags & TEXTURE_USAGE_STORAGE_BIT) { - //can also be used as storage, add to mutable sampled - mutable_sampled_textures.push_back(texture); - } } write.dstArrayElement = 0; @@ -4420,6 +4603,11 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, img_info.sampler = VK_NULL_HANDLE; img_info.imageView = texture->view; + if (texture->usage_flags & TEXTURE_USAGE_SAMPLING_BIT) { + //can also be used as storage, add to mutable sampled + mutable_storage_textures.push_back(texture); + } + if (texture->owner.is_valid()) { texture = texture_owner.getornull(texture->owner); ERR_FAIL_COND_V(!texture, RID()); //bug, should never happen @@ -4428,11 +4616,6 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, img_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL; image_info.push_back(img_info); - - if (texture->usage_flags & TEXTURE_USAGE_SAMPLING_BIT) { - //can also be used as storage, add to mutable sampled - mutable_storage_textures.push_back(texture); - } } write.dstArrayElement = 0; @@ -4902,29 +5085,29 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma depth_stencil_state_create_info.depthBoundsTestEnable = p_depth_stencil_state.enable_depth_range; depth_stencil_state_create_info.stencilTestEnable = p_depth_stencil_state.enable_stencil; - ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_front.fail, STENCIL_OP_MAX, RID()); - depth_stencil_state_create_info.front.failOp = stencil_operations[p_depth_stencil_state.stencil_operation_front.fail]; - ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_front.pass, STENCIL_OP_MAX, RID()); - depth_stencil_state_create_info.front.passOp = stencil_operations[p_depth_stencil_state.stencil_operation_front.pass]; - ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_front.depth_fail, STENCIL_OP_MAX, RID()); - depth_stencil_state_create_info.front.depthFailOp = stencil_operations[p_depth_stencil_state.stencil_operation_front.depth_fail]; - ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_front.compare, COMPARE_OP_MAX, RID()); - depth_stencil_state_create_info.front.compareOp = compare_operators[p_depth_stencil_state.stencil_operation_front.compare]; - depth_stencil_state_create_info.front.compareMask = p_depth_stencil_state.stencil_operation_front.compare_mask; - depth_stencil_state_create_info.front.writeMask = p_depth_stencil_state.stencil_operation_front.write_mask; - depth_stencil_state_create_info.front.reference = p_depth_stencil_state.stencil_operation_front.reference; - - ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_back.fail, STENCIL_OP_MAX, RID()); - depth_stencil_state_create_info.back.failOp = stencil_operations[p_depth_stencil_state.stencil_operation_back.fail]; - ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_back.pass, STENCIL_OP_MAX, RID()); - depth_stencil_state_create_info.back.passOp = stencil_operations[p_depth_stencil_state.stencil_operation_back.pass]; - ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_back.depth_fail, STENCIL_OP_MAX, RID()); - depth_stencil_state_create_info.back.depthFailOp = stencil_operations[p_depth_stencil_state.stencil_operation_back.depth_fail]; - ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_back.compare, COMPARE_OP_MAX, RID()); - depth_stencil_state_create_info.back.compareOp = compare_operators[p_depth_stencil_state.stencil_operation_back.compare]; - depth_stencil_state_create_info.back.compareMask = p_depth_stencil_state.stencil_operation_back.compare_mask; - depth_stencil_state_create_info.back.writeMask = p_depth_stencil_state.stencil_operation_back.write_mask; - depth_stencil_state_create_info.back.reference = p_depth_stencil_state.stencil_operation_back.reference; + ERR_FAIL_INDEX_V(p_depth_stencil_state.front_op.fail, STENCIL_OP_MAX, RID()); + depth_stencil_state_create_info.front.failOp = stencil_operations[p_depth_stencil_state.front_op.fail]; + ERR_FAIL_INDEX_V(p_depth_stencil_state.front_op.pass, STENCIL_OP_MAX, RID()); + depth_stencil_state_create_info.front.passOp = stencil_operations[p_depth_stencil_state.front_op.pass]; + ERR_FAIL_INDEX_V(p_depth_stencil_state.front_op.depth_fail, STENCIL_OP_MAX, RID()); + depth_stencil_state_create_info.front.depthFailOp = stencil_operations[p_depth_stencil_state.front_op.depth_fail]; + ERR_FAIL_INDEX_V(p_depth_stencil_state.front_op.compare, COMPARE_OP_MAX, RID()); + depth_stencil_state_create_info.front.compareOp = compare_operators[p_depth_stencil_state.front_op.compare]; + depth_stencil_state_create_info.front.compareMask = p_depth_stencil_state.front_op.compare_mask; + depth_stencil_state_create_info.front.writeMask = p_depth_stencil_state.front_op.write_mask; + depth_stencil_state_create_info.front.reference = p_depth_stencil_state.front_op.reference; + + ERR_FAIL_INDEX_V(p_depth_stencil_state.back_op.fail, STENCIL_OP_MAX, RID()); + depth_stencil_state_create_info.back.failOp = stencil_operations[p_depth_stencil_state.back_op.fail]; + ERR_FAIL_INDEX_V(p_depth_stencil_state.back_op.pass, STENCIL_OP_MAX, RID()); + depth_stencil_state_create_info.back.passOp = stencil_operations[p_depth_stencil_state.back_op.pass]; + ERR_FAIL_INDEX_V(p_depth_stencil_state.back_op.depth_fail, STENCIL_OP_MAX, RID()); + depth_stencil_state_create_info.back.depthFailOp = stencil_operations[p_depth_stencil_state.back_op.depth_fail]; + ERR_FAIL_INDEX_V(p_depth_stencil_state.back_op.compare, COMPARE_OP_MAX, RID()); + depth_stencil_state_create_info.back.compareOp = compare_operators[p_depth_stencil_state.back_op.compare]; + depth_stencil_state_create_info.back.compareMask = p_depth_stencil_state.back_op.compare_mask; + depth_stencil_state_create_info.back.writeMask = p_depth_stencil_state.back_op.write_mask; + depth_stencil_state_create_info.back.reference = p_depth_stencil_state.back_op.reference; depth_stencil_state_create_info.minDepthBounds = p_depth_stencil_state.depth_range_min; depth_stencil_state_create_info.maxDepthBounds = p_depth_stencil_state.depth_range_max; @@ -5153,17 +5336,19 @@ bool RenderingDeviceVulkan::compute_pipeline_is_valid(RID p_pipeline) { int RenderingDeviceVulkan::screen_get_width(DisplayServer::WindowID p_screen) const { _THREAD_SAFE_METHOD_ - + ERR_FAIL_COND_V_MSG(local_device.is_valid(), -1, "Local devices have no screen"); return context->window_get_width(p_screen); } int RenderingDeviceVulkan::screen_get_height(DisplayServer::WindowID p_screen) const { _THREAD_SAFE_METHOD_ + ERR_FAIL_COND_V_MSG(local_device.is_valid(), -1, "Local devices have no screen"); return context->window_get_height(p_screen); } RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::screen_get_framebuffer_format() const { _THREAD_SAFE_METHOD_ + ERR_FAIL_COND_V_MSG(local_device.is_valid(), INVALID_ID, "Local devices have no screen"); //very hacky, but not used often per frame so I guess ok VkFormat vkformat = context->get_screen_format(); @@ -5193,6 +5378,7 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::screen_get_framebuff RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin_for_screen(DisplayServer::WindowID p_screen, const Color &p_clear_color) { _THREAD_SAFE_METHOD_ + ERR_FAIL_COND_V_MSG(local_device.is_valid(), INVALID_ID, "Local devices have no screen"); ERR_FAIL_COND_V_MSG(draw_list != nullptr, INVALID_ID, "Only one draw list can be active at the same time."); ERR_FAIL_COND_V_MSG(compute_list != nullptr, INVALID_ID, "Only one draw/compute list can be active at the same time."); @@ -5857,7 +6043,7 @@ void RenderingDeviceVulkan::draw_list_set_line_width(DrawListID p_list, float p_ vkCmdSetLineWidth(dl->command_buffer, p_width); } -void RenderingDeviceVulkan::draw_list_set_push_constant(DrawListID p_list, void *p_data, uint32_t p_data_size) { +void RenderingDeviceVulkan::draw_list_set_push_constant(DrawListID p_list, const void *p_data, uint32_t p_data_size) { DrawList *dl = _get_draw_list_ptr(p_list); ERR_FAIL_COND(!dl); @@ -6200,9 +6386,9 @@ void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list, image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; image_memory_barrier.image = textures_to_sampled[i]->image; image_memory_barrier.subresourceRange.aspectMask = textures_to_sampled[i]->read_aspect_mask; - image_memory_barrier.subresourceRange.baseMipLevel = 0; + image_memory_barrier.subresourceRange.baseMipLevel = textures_to_sampled[i]->base_mipmap; image_memory_barrier.subresourceRange.levelCount = textures_to_sampled[i]->mipmaps; - image_memory_barrier.subresourceRange.baseArrayLayer = 0; + image_memory_barrier.subresourceRange.baseArrayLayer = textures_to_sampled[i]->base_layer; image_memory_barrier.subresourceRange.layerCount = textures_to_sampled[i]->layers; vkCmdPipelineBarrier(cl->command_buffer, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); @@ -6231,9 +6417,9 @@ void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list, image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; image_memory_barrier.image = textures_to_storage[i]->image; image_memory_barrier.subresourceRange.aspectMask = textures_to_storage[i]->read_aspect_mask; - image_memory_barrier.subresourceRange.baseMipLevel = 0; + image_memory_barrier.subresourceRange.baseMipLevel = textures_to_storage[i]->base_mipmap; image_memory_barrier.subresourceRange.levelCount = textures_to_storage[i]->mipmaps; - image_memory_barrier.subresourceRange.baseArrayLayer = 0; + image_memory_barrier.subresourceRange.baseArrayLayer = textures_to_storage[i]->base_layer; image_memory_barrier.subresourceRange.layerCount = textures_to_storage[i]->layers; vkCmdPipelineBarrier(cl->command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); @@ -6260,7 +6446,7 @@ void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list, #endif } -void RenderingDeviceVulkan::compute_list_set_push_constant(ComputeListID p_list, void *p_data, uint32_t p_data_size) { +void RenderingDeviceVulkan::compute_list_set_push_constant(ComputeListID p_list, const void *p_data, uint32_t p_data_size) { ERR_FAIL_COND(p_list != ID_TYPE_COMPUTE_LIST); ERR_FAIL_COND(!compute_list); @@ -6363,9 +6549,9 @@ void RenderingDeviceVulkan::compute_list_end() { image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; image_memory_barrier.image = E->get()->image; image_memory_barrier.subresourceRange.aspectMask = E->get()->read_aspect_mask; - image_memory_barrier.subresourceRange.baseMipLevel = 0; + image_memory_barrier.subresourceRange.baseMipLevel = E->get()->base_mipmap; image_memory_barrier.subresourceRange.levelCount = E->get()->mipmaps; - image_memory_barrier.subresourceRange.baseArrayLayer = 0; + image_memory_barrier.subresourceRange.baseArrayLayer = E->get()->base_layer; image_memory_barrier.subresourceRange.layerCount = E->get()->layers; vkCmdPipelineBarrier(compute_list->command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier); @@ -6512,75 +6698,104 @@ void RenderingDeviceVulkan::free(RID p_id) { _free_dependencies(p_id); //recursively erase dependencies first, to avoid potential API problems _free_internal(p_id); } -void RenderingDeviceVulkan::swap_buffers() { - _THREAD_SAFE_METHOD_ +void RenderingDeviceVulkan::_finalize_command_bufers() { - { //finalize frame + if (draw_list) { + ERR_PRINT("Found open draw list at the end of the frame, this should never happen (further drawing will likely not work)."); + } - if (draw_list) { - ERR_PRINT("Found open draw list at the end of the frame, this should never happen (further drawing will likely not work)."); - } + if (compute_list) { + ERR_PRINT("Found open compute list at the end of the frame, this should never happen (further compute will likely not work)."); + } - if (compute_list) { - ERR_PRINT("Found open compute list at the end of the frame, this should never happen (further compute will likely not work)."); - } + { //complete the setup buffer (that needs to be processed before anything else) + vkEndCommandBuffer(frames[frame].setup_command_buffer); + vkEndCommandBuffer(frames[frame].draw_command_buffer); + } +} + +void RenderingDeviceVulkan::_begin_frame() { + + //erase pending resources + _free_pending_resources(frame); + + //create setup command buffer and set as the setup buffer + + { + VkCommandBufferBeginInfo cmdbuf_begin; + cmdbuf_begin.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + cmdbuf_begin.pNext = nullptr; + cmdbuf_begin.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + cmdbuf_begin.pInheritanceInfo = nullptr; - { //complete the setup buffer (that needs to be processed before anything else) - vkEndCommandBuffer(frames[frame].setup_command_buffer); - vkEndCommandBuffer(frames[frame].draw_command_buffer); + VkResult err = vkResetCommandBuffer(frames[frame].setup_command_buffer, 0); + ERR_FAIL_COND_MSG(err, "vkResetCommandBuffer failed with error " + itos(err) + "."); + + err = vkBeginCommandBuffer(frames[frame].setup_command_buffer, &cmdbuf_begin); + ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + "."); + err = vkBeginCommandBuffer(frames[frame].draw_command_buffer, &cmdbuf_begin); + ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + "."); + + if (local_device.is_null()) { + context->append_command_buffer(frames[frame].draw_command_buffer); + context->set_setup_buffer(frames[frame].setup_command_buffer); //append now so it's added before everything else } - screen_prepared = false; } - //swap buffers - context->swap_buffers(); + //advance current frame + frames_drawn++; + //advance staging buffer if used + if (staging_buffer_used) { + staging_buffer_current = (staging_buffer_current + 1) % staging_buffer_blocks.size(); + staging_buffer_used = false; + } - { //advance frame + if (frames[frame].timestamp_count) { + vkGetQueryPoolResults(device, frames[frame].timestamp_pool, 0, frames[frame].timestamp_count, sizeof(uint64_t) * max_timestamp_query_elements, frames[frame].timestamp_result_values, sizeof(uint64_t), VK_QUERY_RESULT_64_BIT); + SWAP(frames[frame].timestamp_names, frames[frame].timestamp_result_names); + SWAP(frames[frame].timestamp_cpu_values, frames[frame].timestamp_cpu_result_values); + } - frame = (frame + 1) % frame_count; + frames[frame].timestamp_result_count = frames[frame].timestamp_count; + frames[frame].timestamp_count = 0; + frames[frame].index = Engine::get_singleton()->get_frames_drawn(); +} - //erase pending resources - _free_pending_resources(frame); +void RenderingDeviceVulkan::swap_buffers() { - //create setup command buffer and set as the setup buffer + ERR_FAIL_COND_MSG(local_device.is_valid(), "Local devices can't swap buffers."); + _THREAD_SAFE_METHOD_ - { - VkCommandBufferBeginInfo cmdbuf_begin; - cmdbuf_begin.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - cmdbuf_begin.pNext = nullptr; - cmdbuf_begin.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - cmdbuf_begin.pInheritanceInfo = nullptr; + _finalize_command_bufers(); - VkResult err = vkResetCommandBuffer(frames[frame].setup_command_buffer, 0); - ERR_FAIL_COND_MSG(err, "vkResetCommandBuffer failed with error " + itos(err) + "."); + screen_prepared = false; + //swap buffers + context->swap_buffers(); - err = vkBeginCommandBuffer(frames[frame].setup_command_buffer, &cmdbuf_begin); - ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + "."); - context->set_setup_buffer(frames[frame].setup_command_buffer); //append now so it's added before everything else - err = vkBeginCommandBuffer(frames[frame].draw_command_buffer, &cmdbuf_begin); - ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + "."); - context->append_command_buffer(frames[frame].draw_command_buffer); - } + frame = (frame + 1) % frame_count; - //advance current frame - frames_drawn++; - //advance staging buffer if used - if (staging_buffer_used) { - staging_buffer_current = (staging_buffer_current + 1) % staging_buffer_blocks.size(); - staging_buffer_used = false; - } + _begin_frame(); +} - if (frames[frame].timestamp_count) { - vkGetQueryPoolResults(device, frames[frame].timestamp_pool, 0, frames[frame].timestamp_count, sizeof(uint64_t) * max_timestamp_query_elements, frames[frame].timestamp_result_values, sizeof(uint64_t), VK_QUERY_RESULT_64_BIT); - SWAP(frames[frame].timestamp_names, frames[frame].timestamp_result_names); - SWAP(frames[frame].timestamp_cpu_values, frames[frame].timestamp_cpu_result_values); - } +void RenderingDeviceVulkan::submit() { + ERR_FAIL_COND_MSG(local_device.is_null(), "Only local devices can submit and sync."); + ERR_FAIL_COND_MSG(local_device_processing, "device already submitted, call sync to wait until done."); - frames[frame].timestamp_result_count = frames[frame].timestamp_count; - frames[frame].timestamp_count = 0; - frames[frame].index = Engine::get_singleton()->get_frames_drawn(); - } + _finalize_command_bufers(); + + VkCommandBuffer command_buffers[2] = { frames[frame].setup_command_buffer, frames[frame].draw_command_buffer }; + context->local_device_push_command_buffers(local_device, command_buffers, 2); + local_device_processing = true; +} + +void RenderingDeviceVulkan::sync() { + + ERR_FAIL_COND_MSG(local_device.is_null(), "Only local devices can submit and sync."); + ERR_FAIL_COND_MSG(!local_device_processing, "sync can only be called after a submit"); + + context->local_device_sync(local_device); + _begin_frame(); } void RenderingDeviceVulkan::_free_pending_resources(int p_frame) { @@ -6699,14 +6914,21 @@ uint32_t RenderingDeviceVulkan::get_frame_delay() const { void RenderingDeviceVulkan::_flush(bool p_current_frame) { + if (local_device.is_valid() && !p_current_frame) { + return; //flushign previous frames has no effect with local device + } //not doing this crashes RADV (undefined behavior) if (p_current_frame) { vkEndCommandBuffer(frames[frame].setup_command_buffer); vkEndCommandBuffer(frames[frame].draw_command_buffer); } - context->flush(p_current_frame, p_current_frame); - //re-create the setup command - if (p_current_frame) { + + if (local_device.is_valid()) { + + VkCommandBuffer command_buffers[2] = { frames[frame].setup_command_buffer, frames[frame].draw_command_buffer }; + context->local_device_push_command_buffers(local_device, command_buffers, 2); + context->local_device_sync(local_device); + VkCommandBufferBeginInfo cmdbuf_begin; cmdbuf_begin.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; cmdbuf_begin.pNext = nullptr; @@ -6715,27 +6937,48 @@ void RenderingDeviceVulkan::_flush(bool p_current_frame) { VkResult err = vkBeginCommandBuffer(frames[frame].setup_command_buffer, &cmdbuf_begin); ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + "."); - context->set_setup_buffer(frames[frame].setup_command_buffer); //append now so it's added before everything else - } + err = vkBeginCommandBuffer(frames[frame].draw_command_buffer, &cmdbuf_begin); + ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + "."); - if (p_current_frame) { - VkCommandBufferBeginInfo cmdbuf_begin; - cmdbuf_begin.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - cmdbuf_begin.pNext = nullptr; - cmdbuf_begin.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - cmdbuf_begin.pInheritanceInfo = nullptr; + } else { + context->flush(p_current_frame, p_current_frame); + //re-create the setup command + if (p_current_frame) { + VkCommandBufferBeginInfo cmdbuf_begin; + cmdbuf_begin.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + cmdbuf_begin.pNext = nullptr; + cmdbuf_begin.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + cmdbuf_begin.pInheritanceInfo = nullptr; - VkResult err = vkBeginCommandBuffer(frames[frame].draw_command_buffer, &cmdbuf_begin); - ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + "."); - context->append_command_buffer(frames[frame].draw_command_buffer); + VkResult err = vkBeginCommandBuffer(frames[frame].setup_command_buffer, &cmdbuf_begin); + ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + "."); + context->set_setup_buffer(frames[frame].setup_command_buffer); //append now so it's added before everything else + } + + if (p_current_frame) { + VkCommandBufferBeginInfo cmdbuf_begin; + cmdbuf_begin.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + cmdbuf_begin.pNext = nullptr; + cmdbuf_begin.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + cmdbuf_begin.pInheritanceInfo = nullptr; + + VkResult err = vkBeginCommandBuffer(frames[frame].draw_command_buffer, &cmdbuf_begin); + ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + "."); + context->append_command_buffer(frames[frame].draw_command_buffer); + } } } -void RenderingDeviceVulkan::initialize(VulkanContext *p_context) { +void RenderingDeviceVulkan::initialize(VulkanContext *p_context, bool p_local_device) { context = p_context; device = p_context->get_device(); - frame_count = p_context->get_swapchain_image_count() + 1; //always need one extra to ensure it's unused at any time, without having to use a fence for this. + if (p_local_device) { + frame_count = 1; + local_device = p_context->local_device_create(); + } else { + frame_count = p_context->get_swapchain_image_count() + 1; //always need one extra to ensure it's unused at any time, without having to use a fence for this. + } limits = p_context->get_device_limits(); max_timestamp_query_elements = 256; @@ -6816,11 +7059,13 @@ void RenderingDeviceVulkan::initialize(VulkanContext *p_context) { VkResult err = vkBeginCommandBuffer(frames[0].setup_command_buffer, &cmdbuf_begin); ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + "."); - context->set_setup_buffer(frames[0].setup_command_buffer); //append now so it's added before everything else err = vkBeginCommandBuffer(frames[0].draw_command_buffer, &cmdbuf_begin); ERR_FAIL_COND_MSG(err, "vkBeginCommandBuffer failed with error " + itos(err) + "."); - context->append_command_buffer(frames[0].draw_command_buffer); + if (local_device.is_null()) { + context->set_setup_buffer(frames[0].setup_command_buffer); //append now so it's added before everything else + context->append_command_buffer(frames[0].draw_command_buffer); + } } staging_buffer_block_size = GLOBAL_DEF("rendering/vulkan/staging_buffer/block_size_kb", 256); @@ -6929,9 +7174,42 @@ uint64_t RenderingDeviceVulkan::get_captured_timestamps_frame() const { return frames[frame].index; } +static void mult64to128(uint64_t u, uint64_t v, uint64_t &h, uint64_t &l) { + uint64_t u1 = (u & 0xffffffff); + uint64_t v1 = (v & 0xffffffff); + uint64_t t = (u1 * v1); + uint64_t w3 = (t & 0xffffffff); + uint64_t k = (t >> 32); + + u >>= 32; + t = (u * v1) + k; + k = (t & 0xffffffff); + uint64_t w1 = (t >> 32); + + v >>= 32; + t = (u1 * v) + k; + k = (t >> 32); + + h = (u * v) + w1 + k; + l = (t << 32) + w3; +} + uint64_t RenderingDeviceVulkan::get_captured_timestamp_gpu_time(uint32_t p_index) const { ERR_FAIL_UNSIGNED_INDEX_V(p_index, frames[frame].timestamp_result_count, 0); - return frames[frame].timestamp_result_values[p_index] * limits.timestampPeriod; + + // this sucks because timestampPeriod multiplier is a float, while the timestamp is 64 bits nanosecs. + // so, in cases like nvidia which give you enormous numbers and 1 as multiplier, multiplying is next to impossible + // need to do 128 bits fixed point multiplication to get the rigth value + + uint64_t shift_bits = 16; + + uint64_t h, l; + + mult64to128(frames[frame].timestamp_result_values[p_index], uint64_t(double(limits.timestampPeriod) * double(1 << shift_bits)), h, l); + l >>= shift_bits; + l |= h << (64 - shift_bits); + + return l; } uint64_t RenderingDeviceVulkan::get_captured_timestamp_cpu_time(uint32_t p_index) const { ERR_FAIL_UNSIGNED_INDEX_V(p_index, frames[frame].timestamp_result_count, 0); @@ -7058,12 +7336,30 @@ void RenderingDeviceVulkan::finalize() { vertex_formats.erase(temp); } + for (int i = 0; i < framebuffer_formats.size(); i++) { + vkDestroyRenderPass(device, framebuffer_formats[i].render_pass, nullptr); + } + framebuffer_formats.clear(); + //all these should be clear at this point ERR_FAIL_COND(descriptor_pools.size()); ERR_FAIL_COND(dependency_map.size()); ERR_FAIL_COND(reverse_dependency_map.size()); } +RenderingDevice *RenderingDeviceVulkan::create_local_device() { + RenderingDeviceVulkan *rd = memnew(RenderingDeviceVulkan); + rd->initialize(context, true); + return rd; +} + RenderingDeviceVulkan::RenderingDeviceVulkan() { screen_prepared = false; } + +RenderingDeviceVulkan::~RenderingDeviceVulkan() { + if (local_device.is_valid()) { + finalize(); + context->local_device_free(local_device); + } +} diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h index a46b80e2f4..6432946fbe 100644 --- a/drivers/vulkan/rendering_device_vulkan.h +++ b/drivers/vulkan/rendering_device_vulkan.h @@ -37,8 +37,10 @@ #include "servers/rendering/rendering_device.h" #ifdef DEBUG_ENABLED +#ifndef _DEBUG #define _DEBUG #endif +#endif #include "vk_mem_alloc.h" #include <vulkan/vulkan.h> //todo: @@ -136,6 +138,8 @@ class RenderingDeviceVulkan : public RenderingDevice { uint32_t layers; uint32_t mipmaps; uint32_t usage_flags; + uint32_t base_mipmap; + uint32_t base_layer; Vector<DataFormat> allowed_shared_formats; @@ -328,7 +332,7 @@ class RenderingDeviceVulkan : public RenderingDevice { RID_Owner<Buffer, true> vertex_buffer_owner; struct VertexDescriptionKey { - Vector<VertexDescription> vertex_formats; + Vector<VertexAttribute> vertex_formats; bool operator==(const VertexDescriptionKey &p_key) const { int vdc = vertex_formats.size(); int vdck = p_key.vertex_formats.size(); @@ -336,11 +340,11 @@ class RenderingDeviceVulkan : public RenderingDevice { if (vdc != vdck) { return false; } else { - const VertexDescription *a_ptr = vertex_formats.ptr(); - const VertexDescription *b_ptr = p_key.vertex_formats.ptr(); + const VertexAttribute *a_ptr = vertex_formats.ptr(); + const VertexAttribute *b_ptr = p_key.vertex_formats.ptr(); for (int i = 0; i < vdc; i++) { - const VertexDescription &a = a_ptr[i]; - const VertexDescription &b = b_ptr[i]; + const VertexAttribute &a = a_ptr[i]; + const VertexAttribute &b = b_ptr[i]; if (a.location != b.location) { return false; @@ -365,9 +369,9 @@ class RenderingDeviceVulkan : public RenderingDevice { uint32_t hash() const { int vdc = vertex_formats.size(); uint32_t h = hash_djb2_one_32(vdc); - const VertexDescription *ptr = vertex_formats.ptr(); + const VertexAttribute *ptr = vertex_formats.ptr(); for (int i = 0; i < vdc; i++) { - const VertexDescription &vd = ptr[i]; + const VertexAttribute &vd = ptr[i]; h = hash_djb2_one_32(vd.location, h); h = hash_djb2_one_32(vd.offset, h); h = hash_djb2_one_32(vd.format, h); @@ -389,7 +393,7 @@ class RenderingDeviceVulkan : public RenderingDevice { HashMap<VertexDescriptionKey, VertexFormatID, VertexDescriptionHash> vertex_format_cache; struct VertexDescriptionCache { - Vector<VertexDescription> vertex_formats; + Vector<VertexAttribute> vertex_formats; VkVertexInputBindingDescription *bindings; VkVertexInputAttributeDescription *attributes; VkPipelineVertexInputStateCreateInfo create_info; @@ -948,10 +952,12 @@ class RenderingDeviceVulkan : public RenderingDevice { uint32_t max_timestamp_query_elements; - Frame *frames; //frames available, they are cycled (usually 3) + Frame *frames; //frames available, for main device they are cycled (usually 3), for local devices only 1 int frame; //current frame int frame_count; //total amount of frames uint64_t frames_drawn; + RID local_device; + bool local_device_processing = false; void _free_pending_resources(int p_frame); @@ -967,6 +973,9 @@ class RenderingDeviceVulkan : public RenderingDevice { template <class T> void _free_rids(T &p_owner, const char *p_type); + void _finalize_command_bufers(); + void _begin_frame(); + public: virtual RID texture_create(const TextureFormat &p_format, const TextureView &p_view, const Vector<Vector<uint8_t>> &p_data = Vector<Vector<uint8_t>>()); virtual RID texture_create_shared(const TextureView &p_view, RID p_with_texture); @@ -981,6 +990,7 @@ public: virtual Error texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, bool p_sync_with_draw = false); virtual Error texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, bool p_sync_with_draw = false); + virtual Error texture_resolve_multisample(RID p_from_texture, RID p_to_texture, bool p_sync_with_draw = false); /*********************/ /**** FRAMEBUFFER ****/ @@ -1006,7 +1016,7 @@ public: virtual RID vertex_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data = Vector<uint8_t>()); // Internally reference counted, this ID is warranted to be unique for the same description, but needs to be freed as many times as it was allocated - virtual VertexFormatID vertex_format_create(const Vector<VertexDescription> &p_vertex_formats); + virtual VertexFormatID vertex_format_create(const Vector<VertexAttribute> &p_vertex_formats); virtual RID vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const Vector<RID> &p_src_buffers); virtual RID index_buffer_create(uint32_t p_size_indices, IndexBufferFormat p_format, const Vector<uint8_t> &p_data = Vector<uint8_t>(), bool p_use_restart_indices = false); @@ -1070,7 +1080,7 @@ public: virtual void draw_list_bind_vertex_array(DrawListID p_list, RID p_vertex_array); virtual void draw_list_bind_index_array(DrawListID p_list, RID p_index_array); virtual void draw_list_set_line_width(DrawListID p_list, float p_width); - virtual void draw_list_set_push_constant(DrawListID p_list, void *p_data, uint32_t p_data_size); + virtual void draw_list_set_push_constant(DrawListID p_list, const void *p_data, uint32_t p_data_size); virtual void draw_list_draw(DrawListID p_list, bool p_use_indices, uint32_t p_instances = 1, uint32_t p_procedural_vertices = 0); @@ -1086,7 +1096,7 @@ public: virtual ComputeListID compute_list_begin(); virtual void compute_list_bind_compute_pipeline(ComputeListID p_list, RID p_compute_pipeline); virtual void compute_list_bind_uniform_set(ComputeListID p_list, RID p_uniform_set, uint32_t p_index); - virtual void compute_list_set_push_constant(ComputeListID p_list, void *p_data, uint32_t p_data_size); + virtual void compute_list_set_push_constant(ComputeListID p_list, const void *p_data, uint32_t p_data_size); virtual void compute_list_add_barrier(ComputeListID p_list); virtual void compute_list_dispatch(ComputeListID p_list, uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups); @@ -1116,14 +1126,20 @@ public: virtual int limit_get(Limit p_limit); virtual void prepare_screen_for_drawing(); - void initialize(VulkanContext *p_context); + void initialize(VulkanContext *p_context, bool p_local_device = false); void finalize(); - virtual void swap_buffers(); + virtual void swap_buffers(); //for main device + + virtual void submit(); //for local device + virtual void sync(); //for local device virtual uint32_t get_frame_delay() const; + virtual RenderingDevice *create_local_device(); + RenderingDeviceVulkan(); + ~RenderingDeviceVulkan(); }; #endif // RENDERING_DEVICE_VULKAN_H diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp index 68b4cdf4a4..083b822676 100644 --- a/drivers/vulkan/vulkan_context.cpp +++ b/drivers/vulkan/vulkan_context.cpp @@ -1499,8 +1499,100 @@ VulkanContext::VulkanContext() { swapchainImageCount = 0; } +RID VulkanContext::local_device_create() { + LocalDevice ld; + + { //create device + VkResult err; + float queue_priorities[1] = { 0.0 }; + VkDeviceQueueCreateInfo queues[2]; + queues[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queues[0].pNext = nullptr; + queues[0].queueFamilyIndex = graphics_queue_family_index; + queues[0].queueCount = 1; + queues[0].pQueuePriorities = queue_priorities; + queues[0].flags = 0; + + VkDeviceCreateInfo sdevice = { + /*sType =*/VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, + /*pNext */ nullptr, + /*flags */ 0, + /*queueCreateInfoCount */ 1, + /*pQueueCreateInfos */ queues, + /*enabledLayerCount */ 0, + /*ppEnabledLayerNames */ nullptr, + /*enabledExtensionCount */ enabled_extension_count, + /*ppEnabledExtensionNames */ (const char *const *)extension_names, + /*pEnabledFeatures */ &physical_device_features, // If specific features are required, pass them in here + }; + err = vkCreateDevice(gpu, &sdevice, nullptr, &ld.device); + ERR_FAIL_COND_V(err, RID()); + } + + { //create graphics queue + + vkGetDeviceQueue(ld.device, graphics_queue_family_index, 0, &ld.queue); + } + + return local_device_owner.make_rid(ld); +} + +VkDevice VulkanContext::local_device_get_vk_device(RID p_local_device) { + LocalDevice *ld = local_device_owner.getornull(p_local_device); + return ld->device; +} + +void VulkanContext::local_device_push_command_buffers(RID p_local_device, const VkCommandBuffer *p_buffers, int p_count) { + + LocalDevice *ld = local_device_owner.getornull(p_local_device); + ERR_FAIL_COND(ld->waiting); + + VkSubmitInfo submit_info; + submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submit_info.pNext = nullptr; + submit_info.pWaitDstStageMask = nullptr; + submit_info.waitSemaphoreCount = 0; + submit_info.pWaitSemaphores = nullptr; + submit_info.commandBufferCount = p_count; + submit_info.pCommandBuffers = p_buffers; + submit_info.signalSemaphoreCount = 0; + submit_info.pSignalSemaphores = nullptr; + + VkResult err = vkQueueSubmit(ld->queue, 1, &submit_info, VK_NULL_HANDLE); + ERR_FAIL_COND(err); + + ld->waiting = true; +} + +void VulkanContext::local_device_sync(RID p_local_device) { + + LocalDevice *ld = local_device_owner.getornull(p_local_device); + ERR_FAIL_COND(!ld->waiting); + + vkDeviceWaitIdle(ld->device); + ld->waiting = false; +} + +void VulkanContext::local_device_free(RID p_local_device) { + + LocalDevice *ld = local_device_owner.getornull(p_local_device); + vkDestroyDevice(ld->device, nullptr); + local_device_owner.free(p_local_device); +} + VulkanContext::~VulkanContext() { if (queue_props) { free(queue_props); } + for (uint32_t i = 0; i < FRAME_LAG; i++) { + vkDestroyFence(device, fences[i], nullptr); + vkDestroySemaphore(device, image_acquired_semaphores[i], nullptr); + vkDestroySemaphore(device, draw_complete_semaphores[i], nullptr); + if (separate_present_queue) { + vkDestroySemaphore(device, image_ownership_semaphores[i], nullptr); + } + } + DestroyDebugUtilsMessengerEXT(inst, dbg_messenger, nullptr); + vkDestroyDevice(device, nullptr); + vkDestroyInstance(inst, nullptr); } diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h index 2f10fbfdef..51c3febb47 100644 --- a/drivers/vulkan/vulkan_context.h +++ b/drivers/vulkan/vulkan_context.h @@ -33,6 +33,8 @@ #include "core/error_list.h" #include "core/map.h" +#include "core/os/mutex.h" +#include "core/rid_owner.h" #include "core/ustring.h" #include "servers/display_server.h" #include <vulkan/vulkan.h> @@ -45,8 +47,6 @@ class VulkanContext { FRAME_LAG = 2 }; - bool use_validation_layers; - VkInstance inst; VkSurfaceKHR surface; VkPhysicalDevice gpu; @@ -107,6 +107,14 @@ class VulkanContext { } }; + struct LocalDevice { + bool waiting = false; + VkDevice device; + VkQueue queue; + }; + + RID_Owner<LocalDevice, true> local_device_owner; + Map<DisplayServer::WindowID, Window> windows; uint32_t swapchainImageCount; @@ -181,6 +189,8 @@ protected: bool buffers_prepared; + bool use_validation_layers; + public: VkDevice get_device(); VkPhysicalDevice get_physical_device(); @@ -194,6 +204,12 @@ public: VkFramebuffer window_get_framebuffer(DisplayServer::WindowID p_window = 0); VkRenderPass window_get_render_pass(DisplayServer::WindowID p_window = 0); + RID local_device_create(); + VkDevice local_device_get_vk_device(RID p_local_device); + void local_device_push_command_buffers(RID p_local_device, const VkCommandBuffer *p_buffers, int p_count); + void local_device_sync(RID p_local_device); + void local_device_free(RID p_local_device); + VkFormat get_screen_format() const; VkPhysicalDeviceLimits get_device_limits() const; diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index b393ff5fd4..f10e439f10 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -1402,7 +1402,7 @@ void AnimationTimelineEdit::_zoom_changed(double) { float AnimationTimelineEdit::get_zoom_scale() const { - float zv = zoom->get_value(); + float zv = zoom->get_max() - zoom->get_value(); if (zv < 1) { zv = 1.0 - zv; return Math::pow(1.0f + zv, 8.0f) * 100; diff --git a/editor/doc_data.cpp b/editor/doc_data.cpp index 096be1fe4b..310e78ee60 100644 --- a/editor/doc_data.cpp +++ b/editor/doc_data.cpp @@ -40,6 +40,9 @@ #include "core/version.h" #include "scene/resources/theme.h" +// Used for a hack preserving Mono properties on non-Mono builds. +#include "modules/modules_enabled.gen.h" + void DocData::merge_from(const DocData &p_data) { for (Map<String, ClassDoc>::Element *E = class_list.front(); E; E = E->next()) { @@ -154,6 +157,23 @@ void DocData::merge_from(const DocData &p_data) { break; } } + +#ifndef MODULE_MONO_ENABLED + // The Mono module defines some properties that we want to keep when + // re-generating docs with a non-Mono build, to prevent pointless diffs + // (and loss of descriptions) depending on the config of the doc writer. + // We use a horrible hack to force keeping the relevant properties, + // hardcoded below. At least it's an ad hoc hack... ¯\_(ツ)_/¯ + // Don't show this to your kids. + if (c.name == "@GlobalScope") { + // Retrieve GodotSharp singleton. + for (int j = 0; j < cf.properties.size(); j++) { + if (cf.properties[j].name == "GodotSharp") { + c.properties.push_back(cf.properties[j]); + } + } + } +#endif } } @@ -173,6 +193,8 @@ static void return_doc_from_retinfo(DocData::MethodDoc &p_method, const Property p_method.return_type = "int"; } else if (p_retinfo.class_name != StringName()) { p_method.return_type = p_retinfo.class_name; + } else if (p_retinfo.type == Variant::ARRAY && p_retinfo.hint == PROPERTY_HINT_ARRAY_TYPE) { + p_method.return_type = p_retinfo.hint_string + "[]"; } else if (p_retinfo.hint == PROPERTY_HINT_RESOURCE_TYPE) { p_method.return_type = p_retinfo.hint_string; } else if (p_retinfo.type == Variant::NIL && p_retinfo.usage & PROPERTY_USAGE_NIL_IS_VARIANT) { @@ -195,6 +217,8 @@ static void argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const Pr p_argument.type = "int"; } else if (p_arginfo.class_name != StringName()) { p_argument.type = p_arginfo.class_name; + } else if (p_arginfo.type == Variant::ARRAY && p_arginfo.hint == PROPERTY_HINT_ARRAY_TYPE) { + p_argument.type = p_arginfo.hint_string + "[]"; } else if (p_arginfo.hint == PROPERTY_HINT_RESOURCE_TYPE) { p_argument.type = p_arginfo.hint_string; } else if (p_arginfo.type == Variant::NIL) { @@ -243,6 +267,12 @@ void DocData::generate(bool p_basic_types) { Set<StringName> setters_getters; String name = classes.front()->get(); + if (!ClassDB::is_class_exposed(name)) { + print_verbose(vformat("Class '%s' is not exposed, skipping.", name)); + classes.pop_front(); + continue; + } + String cname = name; if (cname.begins_with("_")) //proxy class cname = cname.substr(1, name.length()); @@ -271,7 +301,7 @@ void DocData::generate(bool p_basic_types) { EO = EO->next(); } - if (E->get().usage & PROPERTY_USAGE_GROUP || E->get().usage & PROPERTY_USAGE_CATEGORY || E->get().usage & PROPERTY_USAGE_INTERNAL) + if (E->get().usage & PROPERTY_USAGE_GROUP || E->get().usage & PROPERTY_USAGE_SUBGROUP || E->get().usage & PROPERTY_USAGE_CATEGORY || E->get().usage & PROPERTY_USAGE_INTERNAL) continue; PropertyDoc prop; @@ -328,6 +358,8 @@ void DocData::generate(bool p_basic_types) { prop.type = "int"; } else if (retinfo.class_name != StringName()) { prop.type = retinfo.class_name; + } else if (retinfo.type == Variant::ARRAY && retinfo.hint == PROPERTY_HINT_ARRAY_TYPE) { + prop.type = retinfo.hint_string + "[]"; } else if (retinfo.hint == PROPERTY_HINT_RESOURCE_TYPE) { prop.type = retinfo.hint_string; diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp index 942b4a8ee6..9c739474d1 100644 --- a/editor/editor_data.cpp +++ b/editor/editor_data.cpp @@ -1066,9 +1066,9 @@ Array EditorSelection::_get_transformable_selected_nodes() { return ret; } -Array EditorSelection::get_selected_nodes() { +TypedArray<Node> EditorSelection::get_selected_nodes() { - Array ret; + TypedArray<Node> ret; for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) { diff --git a/editor/editor_data.h b/editor/editor_data.h index 4f5d68bfed..e4f4c67c8e 100644 --- a/editor/editor_data.h +++ b/editor/editor_data.h @@ -257,7 +257,7 @@ protected: static void _bind_methods(); public: - Array get_selected_nodes(); + TypedArray<Node> get_selected_nodes(); void add_node(Node *p_node); void remove_node(Node *p_node); bool is_selected(Node *) const; diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index a36e2f360e..bad70d9714 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -198,7 +198,12 @@ void EditorHelp::_add_type(const String &p_type, const String &p_enum) { const Color text_color = get_theme_color("default_color", "RichTextLabel"); const Color type_color = get_theme_color("accent_color", "Editor").linear_interpolate(text_color, 0.5); class_desc->push_color(type_color); + bool add_array = false; if (can_ref) { + if (t.ends_with("[]")) { + add_array = true; + t = t.replace("[]", ""); + } if (p_enum.empty()) { class_desc->push_meta("#" + t); //class } else { @@ -206,8 +211,15 @@ void EditorHelp::_add_type(const String &p_type, const String &p_enum) { } } class_desc->add_text(t); - if (can_ref) + if (can_ref) { class_desc->pop(); + if (add_array) { + class_desc->add_text(" "); + class_desc->push_meta("#Array"); //class + class_desc->add_text("[]"); + class_desc->pop(); + } + } class_desc->pop(); } diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index c92d1d009d..8fcd5bacb6 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -66,6 +66,11 @@ Size2 EditorProperty::get_minimum_size() const { ms.width += key->get_width() + get_theme_constant("hseparator", "Tree"); } + if (deletable) { + Ref<Texture2D> key = get_theme_icon("Close", "EditorIcons"); + ms.width += key->get_width() + get_theme_constant("hseparator", "Tree"); + } + if (checkable) { Ref<Texture2D> check = get_theme_icon("checked", "CheckBox"); ms.width += check->get_width() + get_theme_constant("hseparation", "CheckBox") + get_theme_constant("hseparator", "Tree"); @@ -154,6 +159,18 @@ void EditorProperty::_notification(int p_what) { text_size -= key->get_width() + 4 * EDSCALE; } } + + if (deletable) { + Ref<Texture2D> close; + + close = get_theme_icon("Close", "EditorIcons"); + + rect.size.x -= close->get_width() + get_theme_constant("hseparator", "Tree"); + + if (no_children) { + text_size -= close->get_width() + 4 * EDSCALE; + } + } } //set children @@ -278,6 +295,25 @@ void EditorProperty::_notification(int p_what) { } else { keying_rect = Rect2(); } + + if (deletable) { + Ref<Texture2D> close; + + close = get_theme_icon("Close", "EditorIcons"); + + ofs = size.width - close->get_width() - get_theme_constant("hseparator", "Tree"); + + Color color2(1, 1, 1); + if (delete_hover) { + color2.r *= 1.2; + color2.g *= 1.2; + color2.b *= 1.2; + } + delete_rect = Rect2(ofs, ((size.height - close->get_height()) / 2), close->get_width(), close->get_height()); + draw_texture(close, delete_rect.position, color2); + } else { + delete_rect = Rect2(); + } } } @@ -547,6 +583,16 @@ void EditorProperty::set_keying(bool p_keying) { queue_sort(); } +void EditorProperty::set_deletable(bool p_deletable) { + deletable = p_deletable; + update(); + queue_sort(); +} + +bool EditorProperty::is_deletable() const { + return deletable; +} + bool EditorProperty::is_keying() const { return keying; } @@ -619,6 +665,12 @@ void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) { update(); } + bool new_delete_hover = delete_rect.has_point(me->get_position()) && !button_left; + if (new_delete_hover != delete_hover) { + delete_hover = new_delete_hover; + update(); + } + bool new_revert_hover = revert_rect.has_point(me->get_position()) && !button_left; if (new_revert_hover != revert_hover) { revert_hover = new_revert_hover; @@ -662,6 +714,9 @@ void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) { call_deferred("update_property"); } } + if (delete_rect.has_point(mb->get_position())) { + emit_signal("property_deleted", property); + } if (revert_rect.has_point(mb->get_position())) { @@ -821,6 +876,9 @@ void EditorProperty::_bind_methods() { ClassDB::bind_method(D_METHOD("set_keying", "keying"), &EditorProperty::set_keying); ClassDB::bind_method(D_METHOD("is_keying"), &EditorProperty::is_keying); + ClassDB::bind_method(D_METHOD("set_deletable", "deletable"), &EditorProperty::set_deletable); + ClassDB::bind_method(D_METHOD("is_deletable"), &EditorProperty::is_deletable); + ClassDB::bind_method(D_METHOD("get_edited_property"), &EditorProperty::get_edited_property); ClassDB::bind_method(D_METHOD("get_edited_object"), &EditorProperty::get_edited_object); @@ -839,9 +897,11 @@ void EditorProperty::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "checked"), "set_checked", "is_checked"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_red"), "set_draw_red", "is_draw_red"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keying"), "set_keying", "is_keying"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "deletable"), "set_deletable", "is_deletable"); ADD_SIGNAL(MethodInfo("property_changed", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::NIL, "value", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT))); ADD_SIGNAL(MethodInfo("multiple_properties_changed", PropertyInfo(Variant::PACKED_STRING_ARRAY, "properties"), PropertyInfo(Variant::ARRAY, "value"))); ADD_SIGNAL(MethodInfo("property_keyed", PropertyInfo(Variant::STRING_NAME, "property"))); + ADD_SIGNAL(MethodInfo("property_deleted", PropertyInfo(Variant::STRING_NAME, "property"))); ADD_SIGNAL(MethodInfo("property_keyed_with_value", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::NIL, "value", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT))); ADD_SIGNAL(MethodInfo("property_checked", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::STRING, "bool"))); ADD_SIGNAL(MethodInfo("resource_selected", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource"))); @@ -865,6 +925,7 @@ EditorProperty::EditorProperty() { checked = false; draw_red = false; keying = false; + deletable = false; keying_hover = false; revert_hover = false; check_hover = false; @@ -926,7 +987,7 @@ void EditorInspectorPlugin::parse_category(Object *p_object, const String &p_par } } -bool EditorInspectorPlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage) { +bool EditorInspectorPlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide) { if (get_script_instance()) { Variant arg[6] = { @@ -1276,11 +1337,11 @@ EditorInspectorSection::~EditorInspectorSection() { Ref<EditorInspectorPlugin> EditorInspector::inspector_plugins[MAX_PLUGINS]; int EditorInspector::inspector_plugin_count = 0; -EditorProperty *EditorInspector::instantiate_property_editor(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage) { +EditorProperty *EditorInspector::instantiate_property_editor(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide) { for (int i = inspector_plugin_count - 1; i >= 0; i--) { - inspector_plugins[i]->parse_property(p_object, p_type, p_path, p_hint, p_hint_text, p_usage); + inspector_plugins[i]->parse_property(p_object, p_type, p_path, p_hint, p_hint_text, p_usage, p_wide); if (inspector_plugins[i]->added_editors.size()) { for (int j = 1; j < inspector_plugins[i]->added_editors.size(); j++) { //only keep first one memdelete(inspector_plugins[i]->added_editors[j].property_editor); @@ -1362,6 +1423,7 @@ void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, Ref<Edit ep->object = object; ep->connect("property_changed", callable_mp(this, &EditorInspector::_property_changed)); ep->connect("property_keyed", callable_mp(this, &EditorInspector::_property_keyed)); + ep->connect("property_deleted", callable_mp(this, &EditorInspector::_property_deleted), varray(), CONNECT_DEFERRED); ep->connect("property_keyed_with_value", callable_mp(this, &EditorInspector::_property_keyed_with_value)); ep->connect("property_checked", callable_mp(this, &EditorInspector::_property_checked)); ep->connect("selected", callable_mp(this, &EditorInspector::_property_selected)); @@ -1394,6 +1456,7 @@ void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, Ref<Edit ep->set_read_only(read_only); ep->update_property(); ep->update_reload_status(); + ep->set_deletable(deletable_properties); } } ped->added_editors.clear(); @@ -1478,6 +1541,8 @@ void EditorInspector::update_tree() { String filter = search_box ? search_box->get_text() : ""; String group; String group_base; + String subgroup; + String subgroup_base; VBoxContainer *category_vbox = nullptr; List<PropertyInfo> @@ -1503,10 +1568,19 @@ void EditorInspector::update_tree() { //make sure the property can be edited - if (p.usage & PROPERTY_USAGE_GROUP) { + if (p.usage & PROPERTY_USAGE_SUBGROUP) { + + subgroup = p.name; + subgroup_base = p.hint_string; + + continue; + + } else if (p.usage & PROPERTY_USAGE_GROUP) { group = p.name; group_base = p.hint_string; + subgroup = ""; + subgroup_base = ""; continue; @@ -1514,6 +1588,8 @@ void EditorInspector::update_tree() { group = ""; group_base = ""; + subgroup = ""; + subgroup_base = ""; if (!show_categories) continue; @@ -1577,18 +1653,33 @@ void EditorInspector::update_tree() { } String basename = p.name; + + if (subgroup != "") { + if (subgroup_base != "") { + if (basename.begins_with(subgroup_base)) { + basename = basename.replace_first(subgroup_base, ""); + } else if (subgroup_base.begins_with(basename)) { + //keep it, this is used pretty often + } else { + subgroup = ""; //no longer using subgroup base, clear + } + } + } if (group != "") { - if (group_base != "") { + if (group_base != "" && subgroup == "") { if (basename.begins_with(group_base)) { basename = basename.replace_first(group_base, ""); } else if (group_base.begins_with(basename)) { //keep it, this is used pretty often } else { group = ""; //no longer using group base, clear + subgroup = ""; } } } - + if (subgroup != "") { + basename = subgroup + "/" + basename; + } if (group != "") { basename = group + "/" + basename; } @@ -1734,7 +1825,7 @@ void EditorInspector::update_tree() { for (List<Ref<EditorInspectorPlugin>>::Element *E = valid_plugins.front(); E; E = E->next()) { Ref<EditorInspectorPlugin> ped = E->get(); - bool exclusive = ped->parse_property(object, p.type, p.name, p.hint, p.hint_string, p.usage); + bool exclusive = ped->parse_property(object, p.type, p.name, p.hint, p.hint_string, p.usage, wide_editors); List<EditorInspectorPlugin::AddedEditor> editors = ped->added_editors; //make a copy, since plugins may be used again in a sub-inspector ped->added_editors.clear(); @@ -1778,6 +1869,7 @@ void EditorInspector::update_tree() { ep->set_keying(keying); ep->set_read_only(read_only); + ep->set_deletable(deletable_properties); } current_vbox->add_child(F->get().property_editor); @@ -1789,6 +1881,7 @@ void EditorInspector::update_tree() { ep->connect("property_changed", callable_mp(this, &EditorInspector::_property_changed_update_all), varray(), CONNECT_DEFERRED); } ep->connect("property_keyed", callable_mp(this, &EditorInspector::_property_keyed)); + ep->connect("property_deleted", callable_mp(this, &EditorInspector::_property_deleted), varray(), CONNECT_DEFERRED); ep->connect("property_keyed_with_value", callable_mp(this, &EditorInspector::_property_keyed_with_value)); ep->connect("property_checked", callable_mp(this, &EditorInspector::_property_checked)); ep->connect("selected", callable_mp(this, &EditorInspector::_property_selected)); @@ -1972,6 +2065,10 @@ int EditorInspector::get_scroll_offset() const { return get_v_scroll(); } +void EditorInspector::set_use_wide_editors(bool p_enable) { + wide_editors = p_enable; +} + void EditorInspector::set_sub_inspector(bool p_enable) { sub_inspector = p_enable; @@ -1985,6 +2082,10 @@ void EditorInspector::set_sub_inspector(bool p_enable) { } } +void EditorInspector::set_use_deletable_properties(bool p_enabled) { + deletable_properties = p_enabled; +} + void EditorInspector::_edit_request_change(Object *p_object, const String &p_property) { if (object != p_object) //may be undoing/redoing for a non edited object, so ignore @@ -2117,6 +2218,15 @@ void EditorInspector::_property_keyed(const String &p_path, bool p_advance) { emit_signal("property_keyed", p_path, object->get(p_path), p_advance); //second param is deprecated } +void EditorInspector::_property_deleted(const String &p_path) { + + print_line("deleted pressed?"); + if (!object) + return; + + emit_signal("property_deleted", p_path); //second param is deprecated +} + void EditorInspector::_property_keyed_with_value(const String &p_path, const Variant &p_value, bool p_advance) { if (!object) @@ -2320,6 +2430,7 @@ void EditorInspector::_bind_methods() { ADD_SIGNAL(MethodInfo("property_selected", PropertyInfo(Variant::STRING, "property"))); ADD_SIGNAL(MethodInfo("property_keyed", PropertyInfo(Variant::STRING, "property"))); + ADD_SIGNAL(MethodInfo("property_deleted", PropertyInfo(Variant::STRING, "property"))); ADD_SIGNAL(MethodInfo("resource_selected", PropertyInfo(Variant::OBJECT, "res"), PropertyInfo(Variant::STRING, "prop"))); ADD_SIGNAL(MethodInfo("object_id_selected", PropertyInfo(Variant::INT, "id"))); ADD_SIGNAL(MethodInfo("property_edited", PropertyInfo(Variant::STRING, "property"))); @@ -2337,6 +2448,7 @@ EditorInspector::EditorInspector() { set_enable_h_scroll(false); set_enable_v_scroll(true); + wide_editors = false; show_categories = false; hide_script = true; use_doc_hints = false; @@ -2355,6 +2467,7 @@ EditorInspector::EditorInspector() { set_process(true); property_focusable = -1; sub_inspector = false; + deletable_properties = false; get_v_scrollbar()->connect("value_changed", callable_mp(this, &EditorInspector::_vscroll_changed)); update_scroll_request = -1; diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h index b49a4424f6..c8c1ecc49a 100644 --- a/editor/editor_inspector.h +++ b/editor/editor_inspector.h @@ -64,6 +64,7 @@ private: bool checked; bool draw_red; bool keying; + bool deletable; Rect2 right_child_rect; Rect2 bottom_child_rect; @@ -74,6 +75,8 @@ private: bool revert_hover; Rect2 check_rect; bool check_hover; + Rect2 delete_rect; + bool delete_hover; bool can_revert; @@ -133,6 +136,8 @@ public: void set_keying(bool p_keying); bool is_keying() const; + void set_deletable(bool p_enable); + bool is_deletable() const; void add_focusable(Control *p_control); void select(int p_focusable = -1); void deselect(); @@ -190,7 +195,7 @@ public: virtual bool can_handle(Object *p_object); virtual void parse_begin(Object *p_object); virtual void parse_category(Object *p_object, const String &p_parse_category); - virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage); + virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide = false); virtual void parse_end(); }; @@ -283,6 +288,8 @@ class EditorInspector : public ScrollContainer { bool read_only; bool keying; bool sub_inspector; + bool wide_editors; + bool deletable_properties; float refresh_countdown; bool update_tree_pending; @@ -307,6 +314,7 @@ class EditorInspector : public ScrollContainer { void _multiple_properties_changed(Vector<String> p_paths, Array p_values); void _property_keyed(const String &p_path, bool p_advance); void _property_keyed_with_value(const String &p_path, const Variant &p_value, bool p_advance); + void _property_deleted(const String &p_path); void _property_checked(const String &p_path, bool p_checked); @@ -337,7 +345,7 @@ public: static void remove_inspector_plugin(const Ref<EditorInspectorPlugin> &p_plugin); static void cleanup_plugins(); - static EditorProperty *instantiate_property_editor(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage); + static EditorProperty *instantiate_property_editor(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide = false); void set_undo_redo(UndoRedo *p_undo_redo); @@ -380,8 +388,11 @@ public: void set_object_class(const String &p_class); String get_object_class() const; + void set_use_wide_editors(bool p_enable); void set_sub_inspector(bool p_enable); + void set_use_deletable_properties(bool p_enabled); + EditorInspector(); }; diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index e7c1eaf777..3569cd411d 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -64,6 +64,7 @@ #include "servers/navigation_server_2d.h" #include "servers/navigation_server_3d.h" #include "servers/physics_server_2d.h" +#include "servers/rendering/rendering_device.h" #include "editor/audio_stream_preview.h" #include "editor/debugger/editor_debugger_node.h" @@ -97,6 +98,7 @@ #include "editor/import/resource_importer_layered_texture.h" #include "editor/import/resource_importer_obj.h" #include "editor/import/resource_importer_scene.h" +#include "editor/import/resource_importer_shader_file.h" #include "editor/import/resource_importer_texture.h" #include "editor/import/resource_importer_texture_atlas.h" #include "editor/import/resource_importer_wav.h" @@ -147,6 +149,7 @@ #include "editor/plugins/script_editor_plugin.h" #include "editor/plugins/script_text_editor.h" #include "editor/plugins/shader_editor_plugin.h" +#include "editor/plugins/shader_file_editor_plugin.h" #include "editor/plugins/skeleton_2d_editor_plugin.h" #include "editor/plugins/skeleton_3d_editor_plugin.h" #include "editor/plugins/skeleton_ik_3d_editor_plugin.h" @@ -358,13 +361,13 @@ void EditorNode::_notification(int p_what) { scene_root->set_default_canvas_item_texture_repeat(tr); } - RS::DOFBokehShape dof_shape = RS::DOFBokehShape(int(GLOBAL_GET("rendering/quality/filters/depth_of_field_bokeh_shape"))); + RS::DOFBokehShape dof_shape = RS::DOFBokehShape(int(GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_bokeh_shape"))); RS::get_singleton()->camera_effects_set_dof_blur_bokeh_shape(dof_shape); - RS::DOFBlurQuality dof_quality = RS::DOFBlurQuality(int(GLOBAL_GET("rendering/quality/filters/depth_of_field_bokeh_quality"))); - bool dof_jitter = GLOBAL_GET("rendering/quality/filters/depth_of_field_use_jitter"); + RS::DOFBlurQuality dof_quality = RS::DOFBlurQuality(int(GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_bokeh_quality"))); + bool dof_jitter = GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_use_jitter"); RS::get_singleton()->camera_effects_set_dof_blur_quality(dof_quality, dof_jitter); RS::get_singleton()->environment_set_ssao_quality(RS::EnvironmentSSAOQuality(int(GLOBAL_GET("rendering/quality/ssao/quality"))), GLOBAL_GET("rendering/quality/ssao/half_size")); - RS::get_singleton()->screen_space_roughness_limiter_set_active(GLOBAL_GET("rendering/quality/filters/screen_space_roughness_limiter"), GLOBAL_GET("rendering/quality/filters/screen_space_roughness_limiter_curve")); + RS::get_singleton()->screen_space_roughness_limiter_set_active(GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter"), GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_curve")); bool glow_bicubic = int(GLOBAL_GET("rendering/quality/glow/upscale_mode")) > 0; RS::get_singleton()->environment_glow_set_use_bicubic_upscale(glow_bicubic); RS::EnvironmentSSRRoughnessQuality ssr_roughness_quality = RS::EnvironmentSSRRoughnessQuality(int(GLOBAL_GET("rendering/quality/screen_space_reflection/roughness_quality"))); @@ -374,6 +377,10 @@ void EditorNode::_notification(int p_what) { float sss_scale = GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_scale"); float sss_depth_scale = GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale"); RS::get_singleton()->sub_surface_scattering_set_scale(sss_scale, sss_depth_scale); + RS::ShadowQuality shadows_quality = RS::ShadowQuality(int(GLOBAL_GET("rendering/quality/shadows/soft_shadow_quality"))); + RS::get_singleton()->shadows_quality_set(shadows_quality); + RS::ShadowQuality directional_shadow_quality = RS::ShadowQuality(int(GLOBAL_GET("rendering/quality/directional_shadow/soft_shadow_quality"))); + RS::get_singleton()->directional_shadow_quality_set(directional_shadow_quality); } ResourceImporterTexture::get_singleton()->update_imports(); @@ -704,6 +711,11 @@ void EditorNode::_sources_changed(bool p_exist) { if (waiting_for_first_scan) { waiting_for_first_scan = false; + // Reload the global shader variables, but this time + // loading texures, as they are now properly imported. + print_line("done scanning, reload textures"); + RenderingServer::get_singleton()->global_variables_load_settings(true); + // Start preview thread now that it's safe. if (!singleton->cmdline_export_mode) { EditorResourcePreview::get_singleton()->start(); @@ -5706,6 +5718,10 @@ EditorNode::EditorNode() { import_obj.instance(); ResourceFormatImporter::get_singleton()->add_importer(import_obj); + Ref<ResourceImporterShaderFile> import_shader_file; + import_shader_file.instance(); + ResourceFormatImporter::get_singleton()->add_importer(import_shader_file); + Ref<ResourceImporterScene> import_scene; import_scene.instance(); ResourceFormatImporter::get_singleton()->add_importer(import_scene); @@ -6623,6 +6639,7 @@ EditorNode::EditorNode() { add_editor_plugin(VersionControlEditorPlugin::get_singleton()); add_editor_plugin(memnew(ShaderEditorPlugin(this))); + add_editor_plugin(memnew(ShaderFileEditorPlugin(this))); add_editor_plugin(memnew(VisualShaderEditorPlugin(this))); add_editor_plugin(memnew(Camera3DEditorPlugin(this))); diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index cf478f20e5..5213d7ec15 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -1150,12 +1150,15 @@ void EditorPropertyVector2::setup(double p_min, double p_max, double p_step, boo } } -EditorPropertyVector2::EditorPropertyVector2() { +EditorPropertyVector2::EditorPropertyVector2(bool p_force_wide) { bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector2_editing"); BoxContainer *bc; - if (horizontal) { + if (p_force_wide) { + bc = memnew(HBoxContainer); + add_child(bc); + } else if (horizontal) { bc = memnew(HBoxContainer); add_child(bc); set_bottom_editor(bc); @@ -1231,13 +1234,16 @@ void EditorPropertyRect2::setup(double p_min, double p_max, double p_step, bool } } -EditorPropertyRect2::EditorPropertyRect2() { +EditorPropertyRect2::EditorPropertyRect2(bool p_force_wide) { - bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing"); + bool horizontal = !p_force_wide && bool(EDITOR_GET("interface/inspector/horizontal_vector_types_editing")); BoxContainer *bc; - if (horizontal) { + if (p_force_wide) { + bc = memnew(HBoxContainer); + add_child(bc); + } else if (horizontal) { bc = memnew(HBoxContainer); add_child(bc); set_bottom_editor(bc); @@ -1311,12 +1317,15 @@ void EditorPropertyVector3::setup(double p_min, double p_max, double p_step, boo } } -EditorPropertyVector3::EditorPropertyVector3() { +EditorPropertyVector3::EditorPropertyVector3(bool p_force_wide) { bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing"); BoxContainer *bc; - if (horizontal) { + if (p_force_wide) { + bc = memnew(HBoxContainer); + add_child(bc); + } else if (horizontal) { bc = memnew(HBoxContainer); add_child(bc); set_bottom_editor(bc); @@ -1343,6 +1352,255 @@ EditorPropertyVector3::EditorPropertyVector3() { } setting = false; } + +///////////////////// VECTOR2i ///////////////////////// + +void EditorPropertyVector2i::_value_changed(double val, const String &p_name) { + if (setting) + return; + + Vector2i v2; + v2.x = spin[0]->get_value(); + v2.y = spin[1]->get_value(); + emit_changed(get_edited_property(), v2, p_name); +} + +void EditorPropertyVector2i::update_property() { + Vector2i val = get_edited_object()->get(get_edited_property()); + setting = true; + spin[0]->set_value(val.x); + spin[1]->set_value(val.y); + setting = false; +} + +void EditorPropertyVector2i::_notification(int p_what) { + if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { + Color base = get_theme_color("accent_color", "Editor"); + for (int i = 0; i < 2; i++) { + + Color c = base; + c.set_hsv(float(i) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v()); + spin[i]->set_custom_label_color(true, c); + } + } +} + +void EditorPropertyVector2i::_bind_methods() { +} + +void EditorPropertyVector2i::setup(int p_min, int p_max, bool p_no_slider) { + for (int i = 0; i < 2; i++) { + spin[i]->set_min(p_min); + spin[i]->set_max(p_max); + spin[i]->set_step(1); + spin[i]->set_hide_slider(p_no_slider); + spin[i]->set_allow_greater(true); + spin[i]->set_allow_lesser(true); + } +} + +EditorPropertyVector2i::EditorPropertyVector2i(bool p_force_wide) { + bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector2_editing"); + + BoxContainer *bc; + + if (p_force_wide) { + bc = memnew(HBoxContainer); + add_child(bc); + } else if (horizontal) { + bc = memnew(HBoxContainer); + add_child(bc); + set_bottom_editor(bc); + } else { + bc = memnew(VBoxContainer); + add_child(bc); + } + + static const char *desc[2] = { "x", "y" }; + for (int i = 0; i < 2; i++) { + spin[i] = memnew(EditorSpinSlider); + spin[i]->set_flat(true); + spin[i]->set_label(desc[i]); + bc->add_child(spin[i]); + add_focusable(spin[i]); + spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyVector2i::_value_changed), varray(desc[i])); + if (horizontal) { + spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); + } + } + + if (!horizontal) { + set_label_reference(spin[0]); //show text and buttons around this + } + setting = false; +} + +///////////////////// RECT2 ///////////////////////// + +void EditorPropertyRect2i::_value_changed(double val, const String &p_name) { + if (setting) + return; + + Rect2i r2; + r2.position.x = spin[0]->get_value(); + r2.position.y = spin[1]->get_value(); + r2.size.x = spin[2]->get_value(); + r2.size.y = spin[3]->get_value(); + emit_changed(get_edited_property(), r2, p_name); +} + +void EditorPropertyRect2i::update_property() { + Rect2i val = get_edited_object()->get(get_edited_property()); + setting = true; + spin[0]->set_value(val.position.x); + spin[1]->set_value(val.position.y); + spin[2]->set_value(val.size.x); + spin[3]->set_value(val.size.y); + setting = false; +} +void EditorPropertyRect2i::_notification(int p_what) { + if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { + Color base = get_theme_color("accent_color", "Editor"); + for (int i = 0; i < 4; i++) { + + Color c = base; + c.set_hsv(float(i % 2) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v()); + spin[i]->set_custom_label_color(true, c); + } + } +} +void EditorPropertyRect2i::_bind_methods() { +} + +void EditorPropertyRect2i::setup(int p_min, int p_max, bool p_no_slider) { + for (int i = 0; i < 4; i++) { + spin[i]->set_min(p_min); + spin[i]->set_max(p_max); + spin[i]->set_step(1); + spin[i]->set_hide_slider(p_no_slider); + spin[i]->set_allow_greater(true); + spin[i]->set_allow_lesser(true); + } +} + +EditorPropertyRect2i::EditorPropertyRect2i(bool p_force_wide) { + + bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing"); + + BoxContainer *bc; + + if (p_force_wide) { + bc = memnew(HBoxContainer); + add_child(bc); + } else if (horizontal) { + bc = memnew(HBoxContainer); + add_child(bc); + set_bottom_editor(bc); + } else { + bc = memnew(VBoxContainer); + add_child(bc); + } + + static const char *desc[4] = { "x", "y", "w", "h" }; + for (int i = 0; i < 4; i++) { + spin[i] = memnew(EditorSpinSlider); + spin[i]->set_label(desc[i]); + spin[i]->set_flat(true); + bc->add_child(spin[i]); + add_focusable(spin[i]); + spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyRect2i::_value_changed), varray(desc[i])); + if (horizontal) { + spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); + } + } + + if (!horizontal) { + set_label_reference(spin[0]); //show text and buttons around this + } + setting = false; +} + +///////////////////// VECTOR3 ///////////////////////// + +void EditorPropertyVector3i::_value_changed(double val, const String &p_name) { + if (setting) + return; + + Vector3i v3; + v3.x = spin[0]->get_value(); + v3.y = spin[1]->get_value(); + v3.z = spin[2]->get_value(); + emit_changed(get_edited_property(), v3, p_name); +} + +void EditorPropertyVector3i::update_property() { + Vector3i val = get_edited_object()->get(get_edited_property()); + setting = true; + spin[0]->set_value(val.x); + spin[1]->set_value(val.y); + spin[2]->set_value(val.z); + setting = false; +} +void EditorPropertyVector3i::_notification(int p_what) { + if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { + Color base = get_theme_color("accent_color", "Editor"); + for (int i = 0; i < 3; i++) { + + Color c = base; + c.set_hsv(float(i) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v()); + spin[i]->set_custom_label_color(true, c); + } + } +} +void EditorPropertyVector3i::_bind_methods() { +} + +void EditorPropertyVector3i::setup(int p_min, int p_max, bool p_no_slider) { + for (int i = 0; i < 3; i++) { + spin[i]->set_min(p_min); + spin[i]->set_max(p_max); + spin[i]->set_step(1); + spin[i]->set_hide_slider(p_no_slider); + spin[i]->set_allow_greater(true); + spin[i]->set_allow_lesser(true); + } +} + +EditorPropertyVector3i::EditorPropertyVector3i(bool p_force_wide) { + bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing"); + + BoxContainer *bc; + if (p_force_wide) { + bc = memnew(HBoxContainer); + add_child(bc); + } else if (horizontal) { + bc = memnew(HBoxContainer); + add_child(bc); + set_bottom_editor(bc); + } else { + bc = memnew(VBoxContainer); + add_child(bc); + } + + static const char *desc[3] = { "x", "y", "z" }; + for (int i = 0; i < 3; i++) { + spin[i] = memnew(EditorSpinSlider); + spin[i]->set_flat(true); + spin[i]->set_label(desc[i]); + bc->add_child(spin[i]); + add_focusable(spin[i]); + spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyVector3i::_value_changed), varray(desc[i])); + if (horizontal) { + spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); + } + } + + if (!horizontal) { + set_label_reference(spin[0]); //show text and buttons around this + } + setting = false; +} + ///////////////////// PLANE ///////////////////////// void EditorPropertyPlane::_value_changed(double val, const String &p_name) { @@ -1391,13 +1649,16 @@ void EditorPropertyPlane::setup(double p_min, double p_max, double p_step, bool } } -EditorPropertyPlane::EditorPropertyPlane() { +EditorPropertyPlane::EditorPropertyPlane(bool p_force_wide) { bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing"); BoxContainer *bc; - if (horizontal) { + if (p_force_wide) { + bc = memnew(HBoxContainer); + add_child(bc); + } else if (horizontal) { bc = memnew(HBoxContainer); add_child(bc); set_bottom_editor(bc); @@ -2877,7 +3138,7 @@ void EditorInspectorDefaultPlugin::parse_begin(Object *p_object) { //do none } -bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage) { +bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide) { float default_float_step = EDITOR_GET("interface/inspector/default_float_step"); @@ -3083,7 +3344,7 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ // math types case Variant::VECTOR2: { - EditorPropertyVector2 *editor = memnew(EditorPropertyVector2); + EditorPropertyVector2 *editor = memnew(EditorPropertyVector2(p_wide)); double min = -65535, max = 65535, step = default_float_step; bool hide_slider = true; @@ -3100,8 +3361,23 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ add_property_editor(p_path, editor); } break; + case Variant::VECTOR2I: { + EditorPropertyVector2i *editor = memnew(EditorPropertyVector2i(p_wide)); + int min = -65535, max = 65535; + bool hide_slider = true; + + if (p_hint == PROPERTY_HINT_RANGE && p_hint_text.get_slice_count(",") >= 2) { + min = p_hint_text.get_slice(",", 0).to_double(); + max = p_hint_text.get_slice(",", 1).to_double(); + hide_slider = false; + } + + editor->setup(min, max, hide_slider); + add_property_editor(p_path, editor); + + } break; case Variant::RECT2: { - EditorPropertyRect2 *editor = memnew(EditorPropertyRect2); + EditorPropertyRect2 *editor = memnew(EditorPropertyRect2(p_wide)); double min = -65535, max = 65535, step = default_float_step; bool hide_slider = true; @@ -3117,8 +3393,22 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ editor->setup(min, max, step, hide_slider); add_property_editor(p_path, editor); } break; + case Variant::RECT2I: { + EditorPropertyRect2i *editor = memnew(EditorPropertyRect2i(p_wide)); + int min = -65535, max = 65535; + bool hide_slider = true; + + if (p_hint == PROPERTY_HINT_RANGE && p_hint_text.get_slice_count(",") >= 2) { + min = p_hint_text.get_slice(",", 0).to_double(); + max = p_hint_text.get_slice(",", 1).to_double(); + hide_slider = false; + } + + editor->setup(min, max, hide_slider); + add_property_editor(p_path, editor); + } break; case Variant::VECTOR3: { - EditorPropertyVector3 *editor = memnew(EditorPropertyVector3); + EditorPropertyVector3 *editor = memnew(EditorPropertyVector3(p_wide)); double min = -65535, max = 65535, step = default_float_step; bool hide_slider = true; @@ -3135,6 +3425,22 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ add_property_editor(p_path, editor); } break; + case Variant::VECTOR3I: { + EditorPropertyVector3i *editor = memnew(EditorPropertyVector3i(p_wide)); + int min = -65535, max = 65535; + bool hide_slider = true; + + if (p_hint == PROPERTY_HINT_RANGE && p_hint_text.get_slice_count(",") >= 2) { + min = p_hint_text.get_slice(",", 0).to_double(); + max = p_hint_text.get_slice(",", 1).to_double(); + + hide_slider = false; + } + + editor->setup(min, max, hide_slider); + add_property_editor(p_path, editor); + + } break; case Variant::TRANSFORM2D: { EditorPropertyTransform2D *editor = memnew(EditorPropertyTransform2D); double min = -65535, max = 65535, step = default_float_step; @@ -3154,7 +3460,7 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ } break; case Variant::PLANE: { - EditorPropertyPlane *editor = memnew(EditorPropertyPlane); + EditorPropertyPlane *editor = memnew(EditorPropertyPlane(p_wide)); double min = -65535, max = 65535, step = default_float_step; bool hide_slider = true; diff --git a/editor/editor_properties.h b/editor/editor_properties.h index c5fc8aaf77..61c11f4534 100644 --- a/editor/editor_properties.h +++ b/editor/editor_properties.h @@ -361,7 +361,7 @@ protected: public: virtual void update_property(); void setup(double p_min, double p_max, double p_step, bool p_no_slider); - EditorPropertyVector2(); + EditorPropertyVector2(bool p_force_wide = false); }; class EditorPropertyRect2 : public EditorProperty { @@ -377,7 +377,7 @@ protected: public: virtual void update_property(); void setup(double p_min, double p_max, double p_step, bool p_no_slider); - EditorPropertyRect2(); + EditorPropertyRect2(bool p_force_wide = false); }; class EditorPropertyVector3 : public EditorProperty { @@ -393,7 +393,55 @@ protected: public: virtual void update_property(); void setup(double p_min, double p_max, double p_step, bool p_no_slider); - EditorPropertyVector3(); + EditorPropertyVector3(bool p_force_wide = false); +}; + +class EditorPropertyVector2i : public EditorProperty { + GDCLASS(EditorPropertyVector2i, EditorProperty); + EditorSpinSlider *spin[2]; + bool setting; + void _value_changed(double p_val, const String &p_name); + +protected: + void _notification(int p_what); + static void _bind_methods(); + +public: + virtual void update_property(); + void setup(int p_min, int p_max, bool p_no_slider); + EditorPropertyVector2i(bool p_force_wide = false); +}; + +class EditorPropertyRect2i : public EditorProperty { + GDCLASS(EditorPropertyRect2i, EditorProperty); + EditorSpinSlider *spin[4]; + bool setting; + void _value_changed(double p_val, const String &p_name); + +protected: + void _notification(int p_what); + static void _bind_methods(); + +public: + virtual void update_property(); + void setup(int p_min, int p_max, bool p_no_slider); + EditorPropertyRect2i(bool p_force_wide = false); +}; + +class EditorPropertyVector3i : public EditorProperty { + GDCLASS(EditorPropertyVector3i, EditorProperty); + EditorSpinSlider *spin[3]; + bool setting; + void _value_changed(double p_val, const String &p_name); + +protected: + void _notification(int p_what); + static void _bind_methods(); + +public: + virtual void update_property(); + void setup(int p_min, int p_max, bool p_no_slider); + EditorPropertyVector3i(bool p_force_wide = false); }; class EditorPropertyPlane : public EditorProperty { @@ -409,7 +457,7 @@ protected: public: virtual void update_property(); void setup(double p_min, double p_max, double p_step, bool p_no_slider); - EditorPropertyPlane(); + EditorPropertyPlane(bool p_force_wide = false); }; class EditorPropertyQuat : public EditorProperty { @@ -626,7 +674,7 @@ class EditorInspectorDefaultPlugin : public EditorInspectorPlugin { public: virtual bool can_handle(Object *p_object); virtual void parse_begin(Object *p_object); - virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage); + virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide = false); virtual void parse_end(); }; diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp index b4ce60171b..fdd5bd8db6 100644 --- a/editor/editor_properties_array_dict.cpp +++ b/editor/editor_properties_array_dict.cpp @@ -742,6 +742,13 @@ void EditorPropertyDictionary::update_property() { prop = editor; } break; + case Variant::VECTOR2I: { + + EditorPropertyVector2i *editor = memnew(EditorPropertyVector2i); + editor->setup(-100000, 100000, true); + prop = editor; + + } break; case Variant::RECT2: { EditorPropertyRect2 *editor = memnew(EditorPropertyRect2); @@ -749,6 +756,13 @@ void EditorPropertyDictionary::update_property() { prop = editor; } break; + case Variant::RECT2I: { + + EditorPropertyRect2i *editor = memnew(EditorPropertyRect2i); + editor->setup(-100000, 100000, true); + prop = editor; + + } break; case Variant::VECTOR3: { EditorPropertyVector3 *editor = memnew(EditorPropertyVector3); @@ -756,6 +770,13 @@ void EditorPropertyDictionary::update_property() { prop = editor; } break; + case Variant::VECTOR3I: { + + EditorPropertyVector3i *editor = memnew(EditorPropertyVector3i); + editor->setup(-100000, 100000, true); + prop = editor; + + } break; case Variant::TRANSFORM2D: { EditorPropertyTransform2D *editor = memnew(EditorPropertyTransform2D); diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 5d5bb1242d..9b58c18f51 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -559,6 +559,8 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { hints["editors/3d/navigation_feel/manipulation_translation_inertia"] = PropertyInfo(Variant::FLOAT, "editors/3d/navigation_feel/manipulation_translation_inertia", PROPERTY_HINT_RANGE, "0.0, 1, 0.01"); // 3D: Freelook + _initial_set("editors/3d/freelook/freelook_navigation_scheme", false); + hints["editors/3d/freelook/freelook_navigation_scheme"] = PropertyInfo(Variant::INT, "editors/3d/freelook/freelook_navigation_scheme", PROPERTY_HINT_ENUM, "Default,Partially Axis-Locked (id Tech),Fully Axis-Locked (Minecraft)"); _initial_set("editors/3d/freelook/freelook_inertia", 0.1); hints["editors/3d/freelook/freelook_inertia"] = PropertyInfo(Variant::FLOAT, "editors/3d/freelook/freelook_inertia", PROPERTY_HINT_RANGE, "0.0, 1, 0.01"); _initial_set("editors/3d/freelook/freelook_base_speed", 5.0); diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 37bca661dd..576ee436de 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -961,12 +961,14 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_icon("grabber", "HSlider", theme->get_icon("GuiSliderGrabber", "EditorIcons")); theme->set_stylebox("slider", "HSlider", make_flat_stylebox(dark_color_3, 0, default_margin_size / 2, 0, default_margin_size / 2)); theme->set_stylebox("grabber_area", "HSlider", make_flat_stylebox(contrast_color_1, 0, default_margin_size / 2, 0, default_margin_size / 2)); + theme->set_stylebox("grabber_area_highlight", "HSlider", make_flat_stylebox(contrast_color_1, 0, default_margin_size / 2, 0, default_margin_size / 2)); // VSlider theme->set_icon("grabber", "VSlider", theme->get_icon("GuiSliderGrabber", "EditorIcons")); theme->set_icon("grabber_highlight", "VSlider", theme->get_icon("GuiSliderGrabberHl", "EditorIcons")); theme->set_stylebox("slider", "VSlider", make_flat_stylebox(dark_color_3, default_margin_size / 2, 0, default_margin_size / 2, 0)); theme->set_stylebox("grabber_area", "VSlider", make_flat_stylebox(contrast_color_1, default_margin_size / 2, 0, default_margin_size / 2, 0)); + theme->set_stylebox("grabber_area_highlight", "VSlider", make_flat_stylebox(contrast_color_1, default_margin_size / 2, 0, default_margin_size / 2, 0)); //RichTextLabel theme->set_color("default_color", "RichTextLabel", font_color); diff --git a/editor/icons/AcceptDialog.svg b/editor/icons/AcceptDialog.svg index e0bf7b8336..07e54d722f 100644 --- a/editor/icons/AcceptDialog.svg +++ b/editor/icons/AcceptDialog.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .8954-2 2v1h14v-1c0-1.1046-.89543-2-2-2zm9 1h1v1h-1zm-11 3v8c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-8zm9.4746 1.6367 1.4141 1.4141-4.9492 4.9492-2.8281-2.8281 1.4141-1.4141 1.4141 1.4141z" fill="#a5efac"/></svg>
\ No newline at end of file +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .8954-2 2v1h14v-1c0-1.1046-.89543-2-2-2zm9 1h1v1h-1zm-11 3v8c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-8zm9.4746 1.6367 1.4141 1.4141-4.9492 4.9492-2.8281-2.8281 1.4141-1.4141 1.4141 1.4141z" fill="#e0e0e0"/></svg>
\ No newline at end of file diff --git a/editor/icons/ConfirmationDialog.svg b/editor/icons/ConfirmationDialog.svg index d1f13fbb3b..2d6e45b51f 100644 --- a/editor/icons/ConfirmationDialog.svg +++ b/editor/icons/ConfirmationDialog.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .8954-2 2v1h14v-1c0-1.1046-.89543-2-2-2zm9 1h1v1h-1zm-11 3v8c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-8zm6.9863 1.002c.34689-.0022844.6986.055762 1.0391.17969 1.3618.4956 2.1813 1.9126 1.9297 3.3398-.19105 1.0835-.96172 1.9461-1.9551 2.3008v.17773h-1-1v-.8418a1.0001 1.0001 0 0 1 1-1.1582c.49193 0 .89895-.34177.98438-.82617.085424-.4845-.18031-.94508-.64258-1.1133-.46227-.1683-.96106.013453-1.207.43945a1.0002 1.0002 0 0 1 -1.7324-1c.54346-.94148 1.5433-1.4912 2.584-1.498zm-.98633 6.998h2v1h-2z" fill="#a5efac"/></svg>
\ No newline at end of file +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .8954-2 2v1h14v-1c0-1.1046-.89543-2-2-2zm9 1h1v1h-1zm-11 3v8c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-8zm6.9863 1.002c.34689-.0022844.6986.055762 1.0391.17969 1.3618.4956 2.1813 1.9126 1.9297 3.3398-.19105 1.0835-.96172 1.9461-1.9551 2.3008v.17773h-1-1v-.8418a1.0001 1.0001 0 0 1 1-1.1582c.49193 0 .89895-.34177.98438-.82617.085424-.4845-.18031-.94508-.64258-1.1133-.46227-.1683-.96106.013453-1.207.43945a1.0002 1.0002 0 0 1 -1.7324-1c.54346-.94148 1.5433-1.4912 2.584-1.498zm-.98633 6.998h2v1h-2z" fill="#e0e0e0"/></svg>
\ No newline at end of file diff --git a/editor/icons/PopupDialog.svg b/editor/icons/EditorFileDialog.svg index d871e56a63..95906234ab 100644 --- a/editor/icons/PopupDialog.svg +++ b/editor/icons/EditorFileDialog.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .8954-2 2v1h14v-1c0-1.1046-.89543-2-2-2zm9 1h1v1h-1zm-11 3v8c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-8zm6 1h2v5h-2zm0 6h2v2h-2z" fill="#a5efac"/></svg>
\ No newline at end of file +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .8954-2 2v1h14v-1c0-1.1046-.89543-2-2-2zm9 1h1v1h-1zm-11 3v8c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-8zm3 2h3c1 0 1 2 2 2h3v4h-8z" fill="#e0e0e0"/></svg>
\ No newline at end of file diff --git a/editor/icons/FileDialog.svg b/editor/icons/FileDialog.svg index 7708659c21..95906234ab 100644 --- a/editor/icons/FileDialog.svg +++ b/editor/icons/FileDialog.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .8954-2 2v1h14v-1c0-1.1046-.89543-2-2-2zm9 1h1v1h-1zm-11 3v8c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-8zm3 2h3c1 0 1 2 2 2h3v4h-8z" fill="#a5efac"/></svg>
\ No newline at end of file +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .8954-2 2v1h14v-1c0-1.1046-.89543-2-2-2zm9 1h1v1h-1zm-11 3v8c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-8zm3 2h3c1 0 1 2 2 2h3v4h-8z" fill="#e0e0e0"/></svg>
\ No newline at end of file diff --git a/editor/icons/Popup.svg b/editor/icons/Popup.svg index 93f7e5000d..a497b7a7fc 100644 --- a/editor/icons/Popup.svg +++ b/editor/icons/Popup.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm4 2h2v6h-2zm0 8h2v2h-2z" fill="#a5efac"/></svg>
\ No newline at end of file +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm4 2h2v6h-2zm0 8h2v2h-2z" fill="#e0e0e0"/></svg>
\ No newline at end of file diff --git a/editor/icons/PopupMenu.svg b/editor/icons/PopupMenu.svg index dd7b2bb0fd..ebf62208e0 100644 --- a/editor/icons/PopupMenu.svg +++ b/editor/icons/PopupMenu.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v4h6v-4zm1 1h4l-2 2zm0 4a1 1 0 0 0 -1 1v7a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-7a1 1 0 0 0 -1-1zm1 2h10v2h-10zm0 3h10v2h-10z" fill="#a5efac"/></svg>
\ No newline at end of file +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v4h6v-4zm1 1h4l-2 2zm0 4a1 1 0 0 0 -1 1v7a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-7a1 1 0 0 0 -1-1zm1 2h10v2h-10zm0 3h10v2h-10z" fill="#e0e0e0"/></svg>
\ No newline at end of file diff --git a/editor/icons/PopupPanel.svg b/editor/icons/PopupPanel.svg index 47a5448f5b..b45a3c9c3c 100644 --- a/editor/icons/PopupPanel.svg +++ b/editor/icons/PopupPanel.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v4h6v-4zm1 1h4l-2 2zm0 4c-.55228 0-1 .44772-1 1v7c0 .55228.44772 1 1 1h12c.55228 0 1-.44772 1-1v-7c0-.55228-.44772-1-1-1z" fill="#a5efac"/></svg>
\ No newline at end of file +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v4h6v-4zm1 1h4l-2 2zm0 4c-.55228 0-1 .44772-1 1v7c0 .55228.44772 1 1 1h12c.55228 0 1-.44772 1-1v-7c0-.55228-.44772-1-1-1z" fill="#e0e0e0"/></svg>
\ No newline at end of file diff --git a/editor/icons/ScriptCreateDialog.svg b/editor/icons/ScriptCreateDialog.svg index 751b799ba9..78a69c5e59 100644 --- a/editor/icons/ScriptCreateDialog.svg +++ b/editor/icons/ScriptCreateDialog.svg @@ -1 +1 @@ -<svg height="17.067" viewBox="0 0 16 16" width="17.067" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m6 1v1c-.55228 0-1 .44772-1 1v10h-1v-2h-2v2c.0002826.35698.19084.68674.5.86523.15194.088045.32439.13452.5.13477v1h6v-5l3-2v-3h3v-2c0-1.1046-.89543-2-2-2z" fill="#a5efac" transform="translate(0 1036.4)"/><path d="m6 1c-1.1046 0-2 .89543-2 2v7h-3v3c0 1.1046.89543 2 2 2s2-.89543 2-2v-10c0-.55228.44772-1 1-1s1 .44772 1 1v3h5v-1h-4v-2c0-1.1046-.89543-2-2-2zm-4 10h2v2c0 .55228-.44772 1-1 1s-1-.44772-1-1z" fill="#87e29f" transform="translate(0 1036.4)"/><circle cx="3" cy="1048.4" fill="#e0e0e0" r="0"/><g fill="#87e29f"><ellipse cx="12" cy="1048.4" rx=".5" ry="3"/><ellipse cx="913.91" cy="513.79" rx=".5" ry="3" transform="matrix(.5 .8660254 -.8660254 .5 0 0)"/><ellipse cx="901.91" cy="-534.57" rx=".5" ry="3" transform="matrix(-.5 .8660254 -.8660254 -.5 0 0)"/></g></g></svg>
\ No newline at end of file +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="m3 1c-1.1046 0-2 .8954-2 2v1h14v-1c0-1.1046-.89543-2-2-2zm9 1h1v1h-1zm-11 3v8c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-8zm5.5722656 1h3.9980464a1.1426143 1.1426143 0 0 1 1.142579 1.1425781v1.1425781h-1.712891-2.2851562v-.5703124-.5722657c0-.6310659-.5115295-1.1425781-1.1425782-1.1425781zm0 .5722656c.3155215 0 .5703125.254791.5703125.5703125v.5722657.5703124.5722657h.5722657 2.2851562v3.9980471a1.1426143 1.1426143 0 0 1 -1.1425781 1.142578h-4c.6310487 0 1.1425781-.511529 1.1425781-1.142578v-5.7128909c0-.0785019.01823-.1545692.046875-.2226562v-.0019531c.02868-.0672829.0683226-.1266374.1191406-.1777344.00097-.00096.0029352-.0010048.0039063-.0019532.0513303-.0508898.1121075-.0944618.1796875-.1230468.0683505-.028909.1437752-.0429688.2226562-.0429688zm-2.2851562 5.1406254h1.1425781v1.142578c0 .315522-.2567441.572265-.5722656.572265-.0776611 0-.15125-.016852-.21875-.044922-.00206-.000799-.0038594-.003049-.0058594-.003906-.0656506-.028192-.1236101-.067817-.1738281-.117187a.57130715.57130715 0 0 1 -.0097656-.009766c-.0490902-.050487-.0893425-.107988-.1171876-.173828-.028908-.06835-.0449218-.143776-.0449218-.222656z"/><circle cx="-23.915255" cy="3.118624" r="0"/></g></svg>
\ No newline at end of file diff --git a/editor/icons/WindowDialog.svg b/editor/icons/Window.svg index 3c7be2a58d..a02a86d56a 100644 --- a/editor/icons/WindowDialog.svg +++ b/editor/icons/Window.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .8954-2 2v1h14v-1c0-1.1046-.89543-2-2-2zm9 1h1v1h-1zm-11 3v8c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-8z" fill="#a5efac"/></svg>
\ No newline at end of file +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .8954-2 2v1h14v-1c0-1.1046-.89543-2-2-2zm9 1h1v1h-1zm-11 3v8c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-8z" fill="#e0e0e0"/></svg>
\ No newline at end of file diff --git a/editor/icons/ARVRAnchor.svg b/editor/icons/XRAnchor3D.svg index f1571b3fcc..f1571b3fcc 100644 --- a/editor/icons/ARVRAnchor.svg +++ b/editor/icons/XRAnchor3D.svg diff --git a/editor/icons/ARVRCamera.svg b/editor/icons/XRCamera3D.svg index f59a8c8b4a..f59a8c8b4a 100644 --- a/editor/icons/ARVRCamera.svg +++ b/editor/icons/XRCamera3D.svg diff --git a/editor/icons/ARVRController.svg b/editor/icons/XRController3D.svg index 40e5b8dce1..40e5b8dce1 100644 --- a/editor/icons/ARVRController.svg +++ b/editor/icons/XRController3D.svg diff --git a/editor/icons/ARVROrigin.svg b/editor/icons/XROrigin3D.svg index dbb93ba7a5..dbb93ba7a5 100644 --- a/editor/icons/ARVROrigin.svg +++ b/editor/icons/XROrigin3D.svg diff --git a/editor/import/resource_importer_shader_file.cpp b/editor/import/resource_importer_shader_file.cpp new file mode 100644 index 0000000000..a2f178de12 --- /dev/null +++ b/editor/import/resource_importer_shader_file.cpp @@ -0,0 +1,90 @@ +#include "resource_importer_shader_file.h" + +#include "core/io/marshalls.h" +#include "core/io/resource_saver.h" +#include "core/os/file_access.h" +#include "editor/editor_node.h" +#include "editor/plugins/shader_file_editor_plugin.h" +#include "servers/rendering/rendering_device_binds.h" + +String ResourceImporterShaderFile::get_importer_name() const { + + return "glsl"; +} + +String ResourceImporterShaderFile::get_visible_name() const { + + return "GLSL Shader File"; +} +void ResourceImporterShaderFile::get_recognized_extensions(List<String> *p_extensions) const { + + p_extensions->push_back("glsl"); +} +String ResourceImporterShaderFile::get_save_extension() const { + return "res"; +} + +String ResourceImporterShaderFile::get_resource_type() const { + + return "RDShaderFile"; +} + +int ResourceImporterShaderFile::get_preset_count() const { + return 0; +} +String ResourceImporterShaderFile::get_preset_name(int p_idx) const { + + return String(); +} + +void ResourceImporterShaderFile::get_import_options(List<ImportOption> *r_options, int p_preset) const { +} + +bool ResourceImporterShaderFile::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const { + return true; +} +static String _include_function(const String &p_path, void *userpointer) { + Error err; + + String *base_path = (String *)userpointer; + + String include = p_path; + if (include.is_rel_path()) { + include = base_path->plus_file(include); + } + + FileAccessRef file_inc = FileAccess::open(include, FileAccess::READ, &err); + if (err != OK) { + return String(); + } + return file_inc->get_as_utf8_string(); +} + +Error ResourceImporterShaderFile::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { + + /* STEP 1, Read shader code */ + + Error err; + FileAccessRef file = FileAccess::open(p_source_file, FileAccess::READ, &err); + ERR_FAIL_COND_V(err != OK, ERR_CANT_OPEN); + ERR_FAIL_COND_V(!file.operator->(), ERR_CANT_OPEN); + + String file_txt = file->get_as_utf8_string(); + Ref<RDShaderFile> shader_file; + shader_file.instance(); + String base_path = p_source_file.get_base_dir(); + err = shader_file->parse_versions_from_text(file_txt, _include_function, &base_path); + + if (err != OK) { + if (!ShaderFileEditor::singleton->is_visible_in_tree()) { + EditorNode::get_singleton()->add_io_error(vformat(TTR("Error importing GLSL shader file: '%s'. Open the file in the filesystem dock in order to see the reason."), p_source_file)); + } + } + + ResourceSaver::save(p_save_path + ".res", shader_file); + + return OK; +} + +ResourceImporterShaderFile::ResourceImporterShaderFile() { +} diff --git a/editor/import/resource_importer_shader_file.h b/editor/import/resource_importer_shader_file.h new file mode 100644 index 0000000000..f6b50bee9e --- /dev/null +++ b/editor/import/resource_importer_shader_file.h @@ -0,0 +1,27 @@ +#ifndef RESOURCE_IMPORTER_SHADER_FILE_H +#define RESOURCE_IMPORTER_SHADER_FILE_H + +#include "core/io/resource_importer.h" + +class ResourceImporterShaderFile : public ResourceImporter { + GDCLASS(ResourceImporterShaderFile, ResourceImporter); + +public: + virtual String get_importer_name() const; + virtual String get_visible_name() const; + virtual void get_recognized_extensions(List<String> *p_extensions) const; + virtual String get_save_extension() const; + virtual String get_resource_type() const; + + virtual int get_preset_count() const; + virtual String get_preset_name(int p_idx) const; + + virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const; + virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const; + + virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr); + + ResourceImporterShaderFile(); +}; + +#endif // RESOURCE_IMPORTER_SHADER_FILE_H diff --git a/editor/node_3d_editor_gizmos.cpp b/editor/node_3d_editor_gizmos.cpp index c06e5f3741..31a8320209 100644 --- a/editor/node_3d_editor_gizmos.cpp +++ b/editor/node_3d_editor_gizmos.cpp @@ -37,6 +37,7 @@ #include "scene/3d/collision_polygon_3d.h" #include "scene/3d/collision_shape_3d.h" #include "scene/3d/cpu_particles_3d.h" +#include "scene/3d/decal.h" #include "scene/3d/gi_probe.h" #include "scene/3d/gpu_particles_3d.h" #include "scene/3d/light_3d.h" @@ -2718,7 +2719,143 @@ void ReflectionProbeGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { p_gizmo->add_unscaled_billboard(icon, 0.05); p_gizmo->add_handles(handles, get_material("handles")); } +/////////////////////////////// +//// + +DecalGizmoPlugin::DecalGizmoPlugin() { + Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/decal", Color(0.6, 0.5, 1.0)); + + create_material("decal_material", gizmo_color); + + create_handle_material("handles"); +} + +bool DecalGizmoPlugin::has_gizmo(Node3D *p_spatial) { + return Object::cast_to<Decal>(p_spatial) != nullptr; +} + +String DecalGizmoPlugin::get_name() const { + return "Decal"; +} + +int DecalGizmoPlugin::get_priority() const { + return -1; +} + +String DecalGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const { + + switch (p_idx) { + case 0: return "Extents X"; + case 1: return "Extents Y"; + case 2: return "Extents Z"; + } + + return ""; +} +Variant DecalGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const { + + Decal *decal = Object::cast_to<Decal>(p_gizmo->get_spatial_node()); + return decal->get_extents(); +} +void DecalGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) { + + Decal *decal = Object::cast_to<Decal>(p_gizmo->get_spatial_node()); + Transform gt = decal->get_global_transform(); + + Transform gi = gt.affine_inverse(); + + Vector3 extents = decal->get_extents(); + + Vector3 ray_from = p_camera->project_ray_origin(p_point); + Vector3 ray_dir = p_camera->project_ray_normal(p_point); + + Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) }; + + Vector3 axis; + axis[p_idx] = 1.0; + + Vector3 ra, rb; + Geometry::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb); + float d = ra[p_idx]; + if (Node3DEditor::get_singleton()->is_snap_enabled()) { + d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap()); + } + + if (d < 0.001) + d = 0.001; + + extents[p_idx] = d; + decal->set_extents(extents); +} + +void DecalGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) { + + Decal *decal = Object::cast_to<Decal>(p_gizmo->get_spatial_node()); + + Vector3 restore = p_restore; + + if (p_cancel) { + decal->set_extents(restore); + return; + } + + UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo(); + ur->create_action(TTR("Change Decal Extents")); + ur->add_do_method(decal, "set_extents", decal->get_extents()); + ur->add_undo_method(decal, "set_extents", restore); + ur->commit_action(); +} + +void DecalGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { + + Decal *decal = Object::cast_to<Decal>(p_gizmo->get_spatial_node()); + + p_gizmo->clear(); + + Vector<Vector3> lines; + Vector3 extents = decal->get_extents(); + + AABB aabb; + aabb.position = -extents; + aabb.size = extents * 2; + + for (int i = 0; i < 12; i++) { + Vector3 a, b; + aabb.get_edge(i, a, b); + if (a.y == b.y) { + lines.push_back(a); + lines.push_back(b); + } else { + Vector3 ah = a.linear_interpolate(b, 0.2); + lines.push_back(a); + lines.push_back(ah); + Vector3 bh = b.linear_interpolate(a, 0.2); + lines.push_back(b); + lines.push_back(bh); + } + } + + lines.push_back(Vector3(0, extents.y, 0)); + lines.push_back(Vector3(0, extents.y * 1.2, 0)); + + Vector<Vector3> handles; + + for (int i = 0; i < 3; i++) { + + Vector3 ax; + ax[i] = aabb.position[i] + aabb.size[i]; + handles.push_back(ax); + } + + Ref<Material> material = get_material("decal_material", p_gizmo); + + p_gizmo->add_lines(lines, material); + + p_gizmo->add_handles(handles, get_material("handles")); +} + +/////////////////////////////// GIProbeGizmoPlugin::GIProbeGizmoPlugin() { Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/gi_probe", Color(0.5, 1, 0.6)); @@ -4082,6 +4219,21 @@ Joint3DGizmoPlugin::Joint3DGizmoPlugin() { create_material("joint_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint", Color(0.5, 0.8, 1))); create_material("joint_body_a_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint_body_a", Color(0.6, 0.8, 1))); create_material("joint_body_b_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint_body_b", Color(0.6, 0.9, 1))); + + update_timer = memnew(Timer); + update_timer->set_name("JointGizmoUpdateTimer"); + update_timer->set_wait_time(1.0 / 120.0); + update_timer->connect("timeout", callable_mp(this, &Joint3DGizmoPlugin::incremental_update_gizmos)); + update_timer->set_autostart(true); + EditorNode::get_singleton()->call_deferred("add_child", update_timer); +} + +void Joint3DGizmoPlugin::incremental_update_gizmos() { + if (!current_gizmos.empty()) { + update_idx++; + update_idx = update_idx % current_gizmos.size(); + redraw(current_gizmos[update_idx]); + } } bool Joint3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { diff --git a/editor/node_3d_editor_gizmos.h b/editor/node_3d_editor_gizmos.h index 889b0e8315..6432feeecb 100644 --- a/editor/node_3d_editor_gizmos.h +++ b/editor/node_3d_editor_gizmos.h @@ -285,6 +285,24 @@ public: ReflectionProbeGizmoPlugin(); }; +class DecalGizmoPlugin : public EditorNode3DGizmoPlugin { + + GDCLASS(DecalGizmoPlugin, EditorNode3DGizmoPlugin); + +public: + bool has_gizmo(Node3D *p_spatial); + String get_name() const; + int get_priority() const; + void redraw(EditorNode3DGizmo *p_gizmo); + + String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const; + Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const; + void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point); + void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false); + + DecalGizmoPlugin(); +}; + class GIProbeGizmoPlugin : public EditorNode3DGizmoPlugin { GDCLASS(GIProbeGizmoPlugin, EditorNode3DGizmoPlugin); @@ -391,6 +409,11 @@ class Joint3DGizmoPlugin : public EditorNode3DGizmoPlugin { GDCLASS(Joint3DGizmoPlugin, EditorNode3DGizmoPlugin); + Timer *update_timer; + uint64_t update_idx = 0; + + void incremental_update_gizmos(); + public: bool has_gizmo(Node3D *p_spatial); String get_name() const; diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 2f7747d0ff..cd3df08276 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -1919,6 +1919,7 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) { Point2 offset = drag_to_local - drag_from_local; Size2 scale = canvas_item->call("get_scale"); + Size2 original_scale = scale; float ratio = scale.y / scale.x; if (drag_type == DRAG_SCALE_BOTH) { Size2 scale_factor = drag_to_local / drag_from_local; @@ -1931,6 +1932,7 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) { Size2 scale_factor = Vector2(offset.x, -offset.y) / SCALE_HANDLE_DISTANCE; Size2 parent_scale = parent_xform.get_scale(); scale_factor *= Vector2(1.0 / parent_scale.x, 1.0 / parent_scale.y); + if (drag_type == DRAG_SCALE_X) { scale.x += scale_factor.x; if (uniform) { @@ -1945,8 +1947,13 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) { } if (snap_scale && !is_ctrl) { - scale.x = roundf(scale.x / snap_scale_step) * snap_scale_step; - scale.y = roundf(scale.y / snap_scale_step) * snap_scale_step; + if (snap_relative) { + scale.x = original_scale.x * (roundf((scale.x / original_scale.x) / snap_scale_step) * snap_scale_step); + scale.y = original_scale.y * (roundf((scale.y / original_scale.y) / snap_scale_step) * snap_scale_step); + } else { + scale.x = roundf(scale.x / snap_scale_step) * snap_scale_step; + scale.y = roundf(scale.y / snap_scale_step) * snap_scale_step; + } } canvas_item->call("set_scale", scale); @@ -3193,13 +3200,15 @@ void CanvasItemEditor::_draw_selection() { RID ci = viewport->get_canvas_item(); - List<CanvasItem *> selection = _get_edited_canvas_items(false, false); + List<CanvasItem *> selection = _get_edited_canvas_items(true, false); bool single = selection.size() == 1; for (List<CanvasItem *>::Element *E = selection.front(); E; E = E->next()) { CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get()); CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); + bool item_locked = canvas_item->has_meta("_edit_lock_"); + // Draw the previous position if we are dragging the node if (show_helpers && (drag_type == DRAG_MOVE || drag_type == DRAG_ROTATE || @@ -3239,6 +3248,10 @@ void CanvasItemEditor::_draw_selection() { Color c = Color(1, 0.6, 0.4, 0.7); + if (item_locked) { + c = Color(0.7, 0.7, 0.7, 0.7); + } + for (int i = 0; i < 4; i++) { viewport->draw_line(endpoints[i], endpoints[(i + 1) % 4], c, Math::round(2 * EDSCALE)); } @@ -3251,7 +3264,7 @@ void CanvasItemEditor::_draw_selection() { viewport->draw_set_transform_matrix(viewport->get_transform()); } - if (single && (tool == TOOL_SELECT || tool == TOOL_MOVE || tool == TOOL_SCALE || tool == TOOL_ROTATE || tool == TOOL_EDIT_PIVOT)) { //kind of sucks + if (single && !item_locked && (tool == TOOL_SELECT || tool == TOOL_MOVE || tool == TOOL_SCALE || tool == TOOL_ROTATE || tool == TOOL_EDIT_PIVOT)) { //kind of sucks // Draw the pivot if (canvas_item->_edit_use_pivot()) { diff --git a/editor/plugins/cpu_particles_2d_editor_plugin.cpp b/editor/plugins/cpu_particles_2d_editor_plugin.cpp index b005519a5e..ef4d7d7646 100644 --- a/editor/plugins/cpu_particles_2d_editor_plugin.cpp +++ b/editor/plugins/cpu_particles_2d_editor_plugin.cpp @@ -262,9 +262,8 @@ CPUParticles2DEditorPlugin::CPUParticles2DEditorPlugin(EditorNode *p_node) { toolbar->add_child(memnew(VSeparator)); menu = memnew(MenuButton); - menu->get_popup()->add_item(TTR("Load Emission Mask"), MENU_LOAD_EMISSION_MASK); - menu->get_popup()->add_separator(); menu->get_popup()->add_item(TTR("Restart"), MENU_RESTART); + menu->get_popup()->add_item(TTR("Load Emission Mask"), MENU_LOAD_EMISSION_MASK); menu->set_text(TTR("CPUParticles2D")); menu->set_switch_on_hover(true); toolbar->add_child(menu); diff --git a/editor/plugins/cpu_particles_3d_editor_plugin.cpp b/editor/plugins/cpu_particles_3d_editor_plugin.cpp index 0c2fbaf62a..59a353a581 100644 --- a/editor/plugins/cpu_particles_3d_editor_plugin.cpp +++ b/editor/plugins/cpu_particles_3d_editor_plugin.cpp @@ -104,9 +104,8 @@ CPUParticles3DEditor::CPUParticles3DEditor() { particles_editor_hb->hide(); options->set_text(TTR("CPUParticles3D")); - options->get_popup()->add_item(TTR("Create Emission Points From Node"), MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE); - options->get_popup()->add_separator(); options->get_popup()->add_item(TTR("Restart"), MENU_OPTION_RESTART); + options->get_popup()->add_item(TTR("Create Emission Points From Node"), MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE); options->get_popup()->connect("id_pressed", callable_mp(this, &CPUParticles3DEditor::_menu_option)); } diff --git a/editor/plugins/gpu_particles_2d_editor_plugin.cpp b/editor/plugins/gpu_particles_2d_editor_plugin.cpp index 29c47a2b67..5c35285c22 100644 --- a/editor/plugins/gpu_particles_2d_editor_plugin.cpp +++ b/editor/plugins/gpu_particles_2d_editor_plugin.cpp @@ -371,14 +371,11 @@ GPUParticles2DEditorPlugin::GPUParticles2DEditorPlugin(EditorNode *p_node) { toolbar->add_child(memnew(VSeparator)); menu = memnew(MenuButton); + menu->get_popup()->add_item(TTR("Restart"), MENU_RESTART); menu->get_popup()->add_item(TTR("Generate Visibility Rect"), MENU_GENERATE_VISIBILITY_RECT); - menu->get_popup()->add_separator(); menu->get_popup()->add_item(TTR("Load Emission Mask"), MENU_LOAD_EMISSION_MASK); // menu->get_popup()->add_item(TTR("Clear Emission Mask"), MENU_CLEAR_EMISSION_MASK); - menu->get_popup()->add_separator(); menu->get_popup()->add_item(TTR("Convert to CPUParticles2D"), MENU_OPTION_CONVERT_TO_CPU_PARTICLES); - menu->get_popup()->add_separator(); - menu->get_popup()->add_item(TTR("Restart"), MENU_RESTART); menu->set_text(TTR("GPUParticles2D")); menu->set_switch_on_hover(true); toolbar->add_child(menu); diff --git a/editor/plugins/gpu_particles_3d_editor_plugin.cpp b/editor/plugins/gpu_particles_3d_editor_plugin.cpp index 534a228098..7f80acc176 100644 --- a/editor/plugins/gpu_particles_3d_editor_plugin.cpp +++ b/editor/plugins/gpu_particles_3d_editor_plugin.cpp @@ -433,13 +433,10 @@ GPUParticles3DEditor::GPUParticles3DEditor() { particles_editor_hb->hide(); options->set_text(TTR("GPUParticles3D")); + options->get_popup()->add_item(TTR("Restart"), MENU_OPTION_RESTART); options->get_popup()->add_item(TTR("Generate AABB"), MENU_OPTION_GENERATE_AABB); - options->get_popup()->add_separator(); options->get_popup()->add_item(TTR("Create Emission Points From Node"), MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE); - options->get_popup()->add_separator(); options->get_popup()->add_item(TTR("Convert to CPUParticles3D"), MENU_OPTION_CONVERT_TO_CPU_PARTICLES); - options->get_popup()->add_separator(); - options->get_popup()->add_item(TTR("Restart"), MENU_OPTION_RESTART); options->get_popup()->connect("id_pressed", callable_mp(this, &GPUParticles3DEditor::_menu_option)); diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp index 00e8a05e4e..eb14495b9c 100644 --- a/editor/plugins/material_editor_plugin.cpp +++ b/editor/plugins/material_editor_plugin.cpp @@ -95,6 +95,7 @@ void MaterialEditor::_button_pressed(Node *p_button) { sphere_instance->hide(); box_switch->set_pressed(true); sphere_switch->set_pressed(false); + EditorSettings::get_singleton()->set_project_metadata("inspector_options", "material_preview_on_sphere", false); } if (p_button == sphere_switch) { @@ -102,6 +103,7 @@ void MaterialEditor::_button_pressed(Node *p_button) { sphere_instance->show(); box_switch->set_pressed(false); sphere_switch->set_pressed(true); + EditorSettings::get_singleton()->set_project_metadata("inspector_options", "material_preview_on_sphere", true); } } @@ -155,7 +157,6 @@ MaterialEditor::MaterialEditor() { sphere_instance->set_mesh(sphere_mesh); box_mesh.instance(); box_instance->set_mesh(box_mesh); - box_instance->hide(); set_custom_minimum_size(Size2(1, 150) * EDSCALE); @@ -194,6 +195,15 @@ MaterialEditor::MaterialEditor() { light_2_switch->connect("pressed", callable_mp(this, &MaterialEditor::_button_pressed), varray(light_2_switch)); first_enter = true; + + if (EditorSettings::get_singleton()->get_project_metadata("inspector_options", "material_preview_on_sphere", true)) { + box_instance->hide(); + } else { + box_instance->show(); + sphere_instance->hide(); + box_switch->set_pressed(true); + sphere_switch->set_pressed(false); + } } /////////////////////// diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 1ebcd3abfd..f51b9b20e4 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -347,7 +347,7 @@ void Node3DEditorViewport::_update_camera(float p_interp_delta) { if (orthogonal) { float half_fov = Math::deg2rad(get_fov()) / 2.0; float height = 2.0 * cursor.distance * Math::tan(half_fov); - camera->set_orthogonal(height, 0.1, 8192); + camera->set_orthogonal(height, get_znear(), get_zfar()); } else { camera->set_perspective(get_fov(), get_znear(), get_zfar()); } @@ -364,7 +364,7 @@ Transform Node3DEditorViewport::to_camera_transform(const Cursor &p_cursor) cons camera_transform.basis.rotate(Vector3(0, 1, 0), -p_cursor.y_rot); if (orthogonal) - camera_transform.translate(0, 0, 4096); + camera_transform.translate(0, 0, (get_zfar() - get_znear()) / 2.0); else camera_transform.translate(0, 0, p_cursor.distance); @@ -2287,9 +2287,27 @@ void Node3DEditorViewport::_update_freelook(real_t delta) { return; } - const Vector3 forward = camera->get_transform().basis.xform(Vector3(0, 0, -1)); + const FreelookNavigationScheme navigation_scheme = (FreelookNavigationScheme)EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_navigation_scheme").operator int(); + + Vector3 forward; + if (navigation_scheme == FREELOOK_FULLY_AXIS_LOCKED) { + // Forward/backward keys will always go straight forward/backward, never moving on the Y axis. + forward = Vector3(0, 0, -1).rotated(Vector3(0, 1, 0), camera->get_rotation().y); + } else { + // Forward/backward keys will be relative to the camera pitch. + forward = camera->get_transform().basis.xform(Vector3(0, 0, -1)); + } + const Vector3 right = camera->get_transform().basis.xform(Vector3(1, 0, 0)); - const Vector3 up = camera->get_transform().basis.xform(Vector3(0, 1, 0)); + + Vector3 up; + if (navigation_scheme == FREELOOK_PARTIALLY_AXIS_LOCKED || navigation_scheme == FREELOOK_FULLY_AXIS_LOCKED) { + // Up/down keys will always go up/down regardless of camera pitch. + up = Vector3(0, 1, 0); + } else { + // Up/down keys will be relative to the camera pitch. + up = camera->get_transform().basis.xform(Vector3(0, 1, 0)); + } Vector3 direction; @@ -2478,11 +2496,15 @@ void Node3DEditorViewport::_notification(int p_what) { //update msaa if changed - int msaa_mode = ProjectSettings::get_singleton()->get("rendering/quality/filters/msaa"); + int msaa_mode = ProjectSettings::get_singleton()->get("rendering/quality/screen_filters/msaa"); viewport->set_msaa(Viewport::MSAA(msaa_mode)); + int ssaa_mode = GLOBAL_GET("rendering/quality/screen_filters/screen_space_aa"); + viewport->set_screen_space_aa(Viewport::ScreenSpaceAA(ssaa_mode)); bool show_info = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_INFORMATION)); - info_label->set_visible(show_info); + if (show_info != info_label->is_visible()) { + info_label->set_visible(show_info); + } Camera3D *current_camera; @@ -2509,17 +2531,46 @@ void Node3DEditorViewport::_notification(int p_what) { text += TTR("Surface Changes") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_SURFACE_CHANGES_IN_FRAME)) + "\n"; text += TTR("Draw Calls") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_DRAW_CALLS_IN_FRAME)) + "\n"; text += TTR("Vertices") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_VERTICES_IN_FRAME)); + info_label->set_text(text); } // FPS Counter. - bool show_fps = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_FPS)); - fps_label->set_visible(show_fps); - + bool show_fps = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_FRAME_TIME)); + + if (show_fps != fps_label->is_visible()) { + fps_label->set_visible(show_fps); + RS::get_singleton()->viewport_set_measure_render_time(viewport->get_viewport_rid(), show_fps); + for (int i = 0; i < FRAME_TIME_HISTORY; i++) { + cpu_time_history[i] = 0; + gpu_time_history[i] = 0; + } + cpu_time_history_index = 0; + cpu_time_history_index = 0; + } if (show_fps) { + + cpu_time_history[cpu_time_history_index] = RS::get_singleton()->viewport_get_measured_render_time_cpu(viewport->get_viewport_rid()); + cpu_time_history_index = (cpu_time_history_index + 1) % FRAME_TIME_HISTORY; + float cpu_time = 0.0; + for (int i = 0; i < FRAME_TIME_HISTORY; i++) { + cpu_time += cpu_time_history[i]; + } + cpu_time /= FRAME_TIME_HISTORY; + + gpu_time_history[gpu_time_history_index] = RS::get_singleton()->viewport_get_measured_render_time_gpu(viewport->get_viewport_rid()); + gpu_time_history_index = (gpu_time_history_index + 1) % FRAME_TIME_HISTORY; + float gpu_time = 0.0; + for (int i = 0; i < FRAME_TIME_HISTORY; i++) { + gpu_time += gpu_time_history[i]; + } + gpu_time /= FRAME_TIME_HISTORY; + String text; - const float temp_fps = Engine::get_singleton()->get_frames_per_second(); - text += TTR(vformat("FPS: %d (%s ms)", temp_fps, String::num(1000.0f / temp_fps, 2))); + text += TTR("CPU Time") + ": " + String::num(cpu_time, 1) + " ms\n"; + text += TTR("GPU Time") + ": " + String::num(gpu_time, 1) + " ms\n"; + text += TTR("FPS") + ": " + itos(1000.0 / gpu_time); + fps_label->set_text(text); } @@ -2980,9 +3031,9 @@ void Node3DEditorViewport::_menu_option(int p_option) { view_menu->get_popup()->set_item_checked(idx, !current); } break; - case VIEW_FPS: { + case VIEW_FRAME_TIME: { - int idx = view_menu->get_popup()->get_item_index(VIEW_FPS); + int idx = view_menu->get_popup()->get_item_index(VIEW_FRAME_TIME); bool current = view_menu->get_popup()->is_item_checked(idx); view_menu->get_popup()->set_item_checked(idx, !current); @@ -3000,6 +3051,8 @@ void Node3DEditorViewport::_menu_option(int p_option) { case VIEW_DISPLAY_DEBUG_GIPROBE_EMISSION: case VIEW_DISPLAY_DEBUG_SCENE_LUMINANCE: case VIEW_DISPLAY_DEBUG_SSAO: + case VIEW_DISPLAY_DEBUG_PSSM_SPLITS: + case VIEW_DISPLAY_DEBUG_DECAL_ATLAS: case VIEW_DISPLAY_DEBUG_ROUGHNESS_LIMITER: { static const int display_options[] = { @@ -3018,6 +3071,8 @@ void Node3DEditorViewport::_menu_option(int p_option) { VIEW_DISPLAY_DEBUG_SCENE_LUMINANCE, VIEW_DISPLAY_DEBUG_SSAO, VIEW_DISPLAY_DEBUG_ROUGHNESS_LIMITER, + VIEW_DISPLAY_DEBUG_PSSM_SPLITS, + VIEW_DISPLAY_DEBUG_DECAL_ATLAS, VIEW_MAX }; static const Viewport::DebugDraw debug_draw_modes[] = { @@ -3036,6 +3091,8 @@ void Node3DEditorViewport::_menu_option(int p_option) { Viewport::DEBUG_DRAW_SCENE_LUMINANCE, Viewport::DEBUG_DRAW_SSAO, Viewport::DEBUG_DRAW_ROUGHNESS_LIMITER, + Viewport::DEBUG_DRAW_PSSM_SPLITS, + Viewport::DEBUG_DRAW_DECAL_ATLAS, }; int idx = 0; @@ -3335,12 +3392,12 @@ void Node3DEditorViewport::set_state(const Dictionary &p_state) { if (view_menu->get_popup()->is_item_checked(idx) != information) _menu_option(VIEW_INFORMATION); } - if (p_state.has("fps")) { - bool fps = p_state["fps"]; + if (p_state.has("frame_time")) { + bool fps = p_state["frame_time"]; - int idx = view_menu->get_popup()->get_item_index(VIEW_FPS); + int idx = view_menu->get_popup()->get_item_index(VIEW_FRAME_TIME); if (view_menu->get_popup()->is_item_checked(idx) != fps) - _menu_option(VIEW_FPS); + _menu_option(VIEW_FRAME_TIME); } if (p_state.has("half_res")) { bool half_res = p_state["half_res"]; @@ -3397,7 +3454,7 @@ Dictionary Node3DEditorViewport::get_state() const { d["doppler"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_AUDIO_DOPPLER)); d["gizmos"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_GIZMOS)); d["information"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_INFORMATION)); - d["fps"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_FPS)); + d["frame_time"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_FRAME_TIME)); d["half_res"] = subviewport_container->get_stretch_shrink() > 1; d["cinematic_preview"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_CINEMATIC_PREVIEW)); if (previewing) @@ -3809,6 +3866,9 @@ void Node3DEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p_ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, EditorNode *p_editor, int p_index) { + cpu_time_history_index = 0; + gpu_time_history_index = 0; + _edit.mode = TRANSFORM_NONE; _edit.plane = TRANSFORM_VIEW; _edit.edited_gizmo = 0; @@ -3887,11 +3947,15 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito view_menu->get_popup()->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_lighting", TTR("Display Lighting")), VIEW_DISPLAY_LIGHTING); view_menu->get_popup()->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_unshaded", TTR("Display Unshaded")), VIEW_DISPLAY_SHADELESS); view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_NORMAL), true); + display_submenu->add_radio_check_item(TTR("Directional Shadow Splits"), VIEW_DISPLAY_DEBUG_PSSM_SPLITS); + display_submenu->add_separator(); display_submenu->add_radio_check_item(TTR("Normal Buffer"), VIEW_DISPLAY_NORMAL_BUFFER); display_submenu->add_separator(); display_submenu->add_radio_check_item(TTR("Shadow Atlas"), VIEW_DISPLAY_DEBUG_SHADOW_ATLAS); display_submenu->add_radio_check_item(TTR("Directional Shadow"), VIEW_DISPLAY_DEBUG_DIRECTIONAL_SHADOW_ATLAS); display_submenu->add_separator(); + display_submenu->add_radio_check_item(TTR("Decal Atlas"), VIEW_DISPLAY_DEBUG_DECAL_ATLAS); + display_submenu->add_separator(); display_submenu->add_radio_check_item(TTR("GIProbe Lighting"), VIEW_DISPLAY_DEBUG_GIPROBE_LIGHTING); display_submenu->add_radio_check_item(TTR("GIProbe Albedo"), VIEW_DISPLAY_DEBUG_GIPROBE_ALBEDO); display_submenu->add_radio_check_item(TTR("GIProbe Emission"), VIEW_DISPLAY_DEBUG_GIPROBE_EMISSION); @@ -3907,7 +3971,7 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_environment", TTR("View Environment")), VIEW_ENVIRONMENT); view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_gizmos", TTR("View Gizmos")), VIEW_GIZMOS); view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_information", TTR("View Information")), VIEW_INFORMATION); - view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_fps", TTR("View FPS")), VIEW_FPS); + view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_fps", TTR("View Frame Time")), VIEW_FRAME_TIME); view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_ENVIRONMENT), true); view_menu->get_popup()->add_separator(); view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_half_resolution", TTR("Half Resolution")), VIEW_HALF_RESOLUTION); @@ -3984,7 +4048,7 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito fps_label->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 10 * EDSCALE); fps_label->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, -10 * EDSCALE); fps_label->set_h_grow_direction(GROW_DIRECTION_BEGIN); - fps_label->set_tooltip(TTR("Note: The FPS value displayed is the editor's framerate.\nIt cannot be used as a reliable indication of in-game performance.")); + fps_label->set_tooltip(TTR("Note: The FPS is estimated on a 60hz refresh rate.")); fps_label->set_mouse_filter(MOUSE_FILTER_PASS); // Otherwise tooltip doesn't show. surface->add_child(fps_label); fps_label->hide(); @@ -5922,6 +5986,7 @@ void Node3DEditor::_register_all_gizmos() { add_gizmo_plugin(Ref<GPUParticles3DGizmoPlugin>(memnew(GPUParticles3DGizmoPlugin))); add_gizmo_plugin(Ref<CPUParticles3DGizmoPlugin>(memnew(CPUParticles3DGizmoPlugin))); add_gizmo_plugin(Ref<ReflectionProbeGizmoPlugin>(memnew(ReflectionProbeGizmoPlugin))); + add_gizmo_plugin(Ref<DecalGizmoPlugin>(memnew(DecalGizmoPlugin))); add_gizmo_plugin(Ref<GIProbeGizmoPlugin>(memnew(GIProbeGizmoPlugin))); // add_gizmo_plugin(Ref<BakedIndirectLightGizmoPlugin>(memnew(BakedIndirectLightGizmoPlugin))); add_gizmo_plugin(Ref<CollisionShape3DGizmoPlugin>(memnew(CollisionShape3DGizmoPlugin))); diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index 552afb99e0..71da14ae1a 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -202,7 +202,7 @@ class Node3DEditorViewport : public Control { VIEW_AUDIO_DOPPLER, VIEW_GIZMOS, VIEW_INFORMATION, - VIEW_FPS, + VIEW_FRAME_TIME, VIEW_DISPLAY_NORMAL, VIEW_DISPLAY_WIREFRAME, VIEW_DISPLAY_OVERDRAW, @@ -218,6 +218,8 @@ class Node3DEditorViewport : public Control { VIEW_DISPLAY_DEBUG_SCENE_LUMINANCE, VIEW_DISPLAY_DEBUG_SSAO, VIEW_DISPLAY_DEBUG_ROUGHNESS_LIMITER, + VIEW_DISPLAY_DEBUG_PSSM_SPLITS, + VIEW_DISPLAY_DEBUG_DECAL_ATLAS, VIEW_LOCK_ROTATION, VIEW_CINEMATIC_PREVIEW, VIEW_AUTO_ORTHOGONAL, @@ -228,7 +230,9 @@ public: enum { GIZMO_BASE_LAYER = 27, GIZMO_EDIT_LAYER = 26, - GIZMO_GRID_LAYER = 25 + GIZMO_GRID_LAYER = 25, + + FRAME_TIME_HISTORY = 20, }; enum NavigationScheme { @@ -237,7 +241,18 @@ public: NAVIGATION_MODO, }; + enum FreelookNavigationScheme { + FREELOOK_DEFAULT, + FREELOOK_PARTIALLY_AXIS_LOCKED, + FREELOOK_FULLY_AXIS_LOCKED, + }; + private: + float cpu_time_history[FRAME_TIME_HISTORY]; + int cpu_time_history_index; + float gpu_time_history[FRAME_TIME_HISTORY]; + int gpu_time_history_index; + int index; String name; void _menu_option(int p_option); @@ -841,12 +856,11 @@ public: static const int HIDDEN = 1; static const int ON_TOP = 2; -private: +protected: int current_state; List<EditorNode3DGizmo *> current_gizmos; HashMap<String, Vector<Ref<StandardMaterial3D>>> materials; -protected: static void _bind_methods(); virtual bool has_gizmo(Node3D *p_spatial); virtual Ref<EditorNode3DGizmo> create_gizmo(Node3D *p_spatial); diff --git a/editor/plugins/root_motion_editor_plugin.cpp b/editor/plugins/root_motion_editor_plugin.cpp index 67e836082d..a7120c5d68 100644 --- a/editor/plugins/root_motion_editor_plugin.cpp +++ b/editor/plugins/root_motion_editor_plugin.cpp @@ -288,7 +288,7 @@ void EditorInspectorRootMotionPlugin::parse_begin(Object *p_object) { //do none } -bool EditorInspectorRootMotionPlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage) { +bool EditorInspectorRootMotionPlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide) { if (p_path == "root_motion_track" && p_object->is_class("AnimationTree") && p_type == Variant::NODE_PATH) { EditorPropertyRootMotion *editor = memnew(EditorPropertyRootMotion); diff --git a/editor/plugins/root_motion_editor_plugin.h b/editor/plugins/root_motion_editor_plugin.h index 8a7691de5d..f72ad1ec05 100644 --- a/editor/plugins/root_motion_editor_plugin.h +++ b/editor/plugins/root_motion_editor_plugin.h @@ -65,7 +65,7 @@ class EditorInspectorRootMotionPlugin : public EditorInspectorPlugin { public: virtual bool can_handle(Object *p_object); virtual void parse_begin(Object *p_object); - virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage); + virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide = false); virtual void parse_end(); }; diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 0b97ade278..2c831979de 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -1778,9 +1778,11 @@ void ScriptEditor::_update_script_names() { if (built_in) { name = path.get_file(); - String resource_name = se->get_edited_resource()->get_name(); + const String &resource_name = se->get_edited_resource()->get_name(); if (resource_name != "") { - name = name.substr(0, name.find("::", 0) + 2) + resource_name; + // If the built-in script has a custom resource name defined, + // display the built-in script name as follows: `ResourceName (scene_file.tscn)` + name = vformat("%s (%s)", resource_name, name.substr(0, name.find("::", 0))); } } else { diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 4b8383e1e5..1a77eeb9de 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -172,7 +172,7 @@ void ScriptTextEditor::_update_member_keywords() { for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { String name = E->get().name; - if (E->get().usage & PROPERTY_USAGE_CATEGORY || E->get().usage & PROPERTY_USAGE_GROUP) + if (E->get().usage & PROPERTY_USAGE_CATEGORY || E->get().usage & PROPERTY_USAGE_GROUP || E->get().usage & PROPERTY_USAGE_SUBGROUP) continue; if (name.find("/") != -1) continue; diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index 2a36700105..9ef8148241 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -193,6 +193,12 @@ void ShaderTextEditor::_check_shader_mode() { } } +static ShaderLanguage::DataType _get_global_variable_type(const StringName &p_variable) { + + RS::GlobalVariableType gvt = RS::get_singleton()->global_variable_get_type(p_variable); + return RS::global_variable_type_get_shader_datatype(gvt); +} + void ShaderTextEditor::_code_complete_script(const String &p_code, List<ScriptCodeCompletionOption> *r_options) { _check_shader_mode(); @@ -200,7 +206,7 @@ void ShaderTextEditor::_code_complete_script(const String &p_code, List<ScriptCo ShaderLanguage sl; String calltip; - sl.complete(p_code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_types(), r_options, calltip); + sl.complete(p_code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_types(), _get_global_variable_type, r_options, calltip); get_text_edit()->set_code_hint(calltip); } @@ -215,7 +221,7 @@ void ShaderTextEditor::_validate_script() { ShaderLanguage sl; - Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_types()); + Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_types(), _get_global_variable_type); if (err != OK) { String error_text = "error(" + itos(sl.get_error_line()) + "): " + sl.get_error_text(); diff --git a/editor/plugins/shader_file_editor_plugin.cpp b/editor/plugins/shader_file_editor_plugin.cpp new file mode 100644 index 0000000000..296c7a01b6 --- /dev/null +++ b/editor/plugins/shader_file_editor_plugin.cpp @@ -0,0 +1,303 @@ +#include "shader_file_editor_plugin.h" + +#include "core/io/resource_loader.h" +#include "core/io/resource_saver.h" +#include "core/os/keyboard.h" +#include "core/os/os.h" +#include "editor/editor_node.h" +#include "editor/editor_scale.h" +#include "editor/editor_settings.h" +#include "editor/property_editor.h" +#include "servers/display_server.h" +#include "servers/rendering/shader_types.h" + +/*** SHADER SCRIPT EDITOR ****/ + +/*** SCRIPT EDITOR ******/ + +void ShaderFileEditor::_update_version(const StringName &p_version_txt, const RD::ShaderStage p_stage) { +} + +void ShaderFileEditor::_version_selected(int p_option) { + + int c = versions->get_current(); + StringName version_txt = versions->get_item_metadata(c); + + RD::ShaderStage stage = RD::SHADER_STAGE_MAX; + int first_found = -1; + + Ref<RDShaderBytecode> bytecode = shader_file->get_bytecode(version_txt); + ERR_FAIL_COND(bytecode.is_null()); + + for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { + if (bytecode->get_stage_bytecode(RD::ShaderStage(i)).empty() && bytecode->get_stage_compile_error(RD::ShaderStage(i)) == String()) { + stages[i]->set_icon(Ref<Texture2D>()); + continue; + } + + Ref<Texture2D> icon; + if (bytecode->get_stage_compile_error(RD::ShaderStage(i)) != String()) { + icon = get_theme_icon("ImportFail", "EditorIcons"); + } else { + icon = get_theme_icon("ImportCheck", "EditorIcons"); + } + stages[i]->set_icon(icon); + + if (first_found == -1) { + first_found = i; + } + + if (stages[i]->is_pressed()) { + stage = RD::ShaderStage(i); + break; + } + } + + error_text->clear(); + + if (stage == RD::SHADER_STAGE_MAX) { //need to change stage, does not have it + if (first_found == -1) { + error_text->add_text(TTR("No valid shader stages found.")); + return; //well you did not put any stage I guess? + } + stages[first_found]->set_pressed(true); + stage = RD::ShaderStage(first_found); + } + + String error = bytecode->get_stage_compile_error(stage); + + error_text->push_font(get_theme_font("source", "EditorFonts")); + + if (error == String()) { + error_text->add_text(TTR("Shader stage compiled without errors.")); + } else { + error_text->add_text(error); + } +} + +void ShaderFileEditor::_update_options() { + + ERR_FAIL_COND(shader_file.is_null()); + + if (shader_file->get_base_error() != String()) { + stage_hb->hide(); + versions->hide(); + error_text->clear(); + error_text->push_font(get_theme_font("source", "EditorFonts")); + error_text->add_text(vformat(TTR("File structure for '%s' contains unrecoverable errors:\n\n"), shader_file->get_path().get_file())); + error_text->add_text(shader_file->get_base_error()); + return; + } + + stage_hb->show(); + versions->show(); + + int c = versions->get_current(); + //remember current + versions->clear(); + Vector<StringName> version_list = shader_file->get_version_list(); + + if (c >= version_list.size()) { + c = version_list.size() - 1; + } + if (c < 0) { + c = 0; + } + + StringName current_version; + + for (int i = 0; i < version_list.size(); i++) { + String title = version_list[i]; + if (title == "") { + title = "default"; + } + + Ref<Texture2D> icon; + + Ref<RDShaderBytecode> bytecode = shader_file->get_bytecode(version_list[i]); + ERR_FAIL_COND(bytecode.is_null()); + + bool failed = false; + for (int j = 0; j < RD::SHADER_STAGE_MAX; j++) { + String error = bytecode->get_stage_compile_error(RD::ShaderStage(j)); + if (error != String()) { + failed = true; + } + } + + if (failed) { + icon = get_theme_icon("ImportFail", "EditorIcons"); + } else { + icon = get_theme_icon("ImportCheck", "EditorIcons"); + } + + versions->add_item(title, icon); + versions->set_item_metadata(i, version_list[i]); + + if (i == c) { + versions->select(i); + current_version = version_list[i]; + } + } + + if (version_list.size() == 0) { + for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { + stages[i]->set_disabled(true); + } + return; + } + + Ref<RDShaderBytecode> bytecode = shader_file->get_bytecode(current_version); + ERR_FAIL_COND(bytecode.is_null()); + int first_valid = -1; + int current = -1; + for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { + Vector<uint8_t> bc = bytecode->get_stage_bytecode(RD::ShaderStage(i)); + String error = bytecode->get_stage_compile_error(RD::ShaderStage(i)); + bool disable = error == String() && bc.empty(); + stages[i]->set_disabled(disable); + if (!disable) { + if (stages[i]->is_pressed()) { + current = i; + } + first_valid = i; + } + } + + if (current == -1 && first_valid != -1) { + stages[first_valid]->set_pressed(true); + } + + _version_selected(0); +} + +void ShaderFileEditor::_notification(int p_what) { + + if (p_what == NOTIFICATION_WM_FOCUS_IN) { + if (is_visible_in_tree() && shader_file.is_valid()) { + _update_options(); + } + } +} + +void ShaderFileEditor::_editor_settings_changed() { + + if (is_visible_in_tree() && shader_file.is_valid()) { + _update_options(); + } +} + +void ShaderFileEditor::_bind_methods() { +} + +void ShaderFileEditor::edit(const Ref<RDShaderFile> &p_shader) { + + if (p_shader.is_null()) { + if (shader_file.is_valid()) { + shader_file->disconnect("changed", callable_mp(this, &ShaderFileEditor::_shader_changed)); + } + return; + } + + if (shader_file == p_shader) + return; + + shader_file = p_shader; + + if (shader_file.is_valid()) { + shader_file->connect("changed", callable_mp(this, &ShaderFileEditor::_shader_changed)); + } + + _update_options(); +} + +void ShaderFileEditor::_shader_changed() { + + if (is_visible_in_tree()) { + _update_options(); + } +} + +ShaderFileEditor *ShaderFileEditor::singleton = nullptr; + +ShaderFileEditor::ShaderFileEditor(EditorNode *p_node) { + singleton = this; + HSplitContainer *main_hs = memnew(HSplitContainer); + + add_child(main_hs); + + versions = memnew(ItemList); + versions->connect("item_selected", callable_mp(this, &ShaderFileEditor::_version_selected)); + versions->set_custom_minimum_size(Size2i(200 * EDSCALE, 0)); + main_hs->add_child(versions); + + VBoxContainer *main_vb = memnew(VBoxContainer); + main_vb->set_h_size_flags(SIZE_EXPAND_FILL); + main_hs->add_child(main_vb); + + static const char *stage_str[RD::SHADER_STAGE_MAX] = { + "Vertex", + "Fragment", + "TessControl", + "TessEval", + "Compute" + }; + + stage_hb = memnew(HBoxContainer); + main_vb->add_child(stage_hb); + + Ref<ButtonGroup> bg; + bg.instance(); + for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { + Button *button = memnew(Button(stage_str[i])); + button->set_toggle_mode(true); + button->set_focus_mode(FOCUS_NONE); + stage_hb->add_child(button); + stages[i] = button; + button->set_button_group(bg); + button->connect("pressed", callable_mp(this, &ShaderFileEditor::_version_selected), varray(i)); + } + + error_text = memnew(RichTextLabel); + error_text->set_v_size_flags(SIZE_EXPAND_FILL); + main_vb->add_child(error_text); +} + +void ShaderFileEditorPlugin::edit(Object *p_object) { + + RDShaderFile *s = Object::cast_to<RDShaderFile>(p_object); + shader_editor->edit(s); +} + +bool ShaderFileEditorPlugin::handles(Object *p_object) const { + + RDShaderFile *shader = Object::cast_to<RDShaderFile>(p_object); + return shader != nullptr; +} + +void ShaderFileEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + button->show(); + editor->make_bottom_panel_item_visible(shader_editor); + + } else { + + button->hide(); + if (shader_editor->is_visible_in_tree()) + editor->hide_bottom_panel(); + } +} + +ShaderFileEditorPlugin::ShaderFileEditorPlugin(EditorNode *p_node) { + + editor = p_node; + shader_editor = memnew(ShaderFileEditor(p_node)); + + shader_editor->set_custom_minimum_size(Size2(0, 300) * EDSCALE); + button = editor->add_bottom_panel_item(TTR("ShaderFile"), shader_editor); + button->hide(); +} + +ShaderFileEditorPlugin::~ShaderFileEditorPlugin() { +} diff --git a/editor/plugins/shader_file_editor_plugin.h b/editor/plugins/shader_file_editor_plugin.h new file mode 100644 index 0000000000..44d32de2f1 --- /dev/null +++ b/editor/plugins/shader_file_editor_plugin.h @@ -0,0 +1,64 @@ +#ifndef SHADER_FILE_EDITOR_PLUGIN_H +#define SHADER_FILE_EDITOR_PLUGIN_H + +#include "editor/code_editor.h" +#include "editor/editor_plugin.h" +#include "scene/gui/menu_button.h" +#include "scene/gui/panel_container.h" +#include "scene/gui/rich_text_label.h" +#include "scene/gui/tab_container.h" +#include "scene/gui/text_edit.h" +#include "scene/main/timer.h" +#include "servers/rendering/rendering_device_binds.h" + +class ShaderFileEditor : public PanelContainer { + + GDCLASS(ShaderFileEditor, PanelContainer); + + Ref<RDShaderFile> shader_file; + + HBoxContainer *stage_hb; + ItemList *versions; + Button *stages[RD::SHADER_STAGE_MAX]; + RichTextLabel *error_text; + + void _update_version(const StringName &p_version_txt, const RenderingDevice::ShaderStage p_stage); + void _version_selected(int p_stage); + void _editor_settings_changed(); + + void _update_options(); + void _shader_changed(); + +protected: + void _notification(int p_what); + static void _bind_methods(); + +public: + static ShaderFileEditor *singleton; + void edit(const Ref<RDShaderFile> &p_shader); + + ShaderFileEditor(EditorNode *p_node); +}; + +class ShaderFileEditorPlugin : public EditorPlugin { + + GDCLASS(ShaderFileEditorPlugin, EditorPlugin); + + ShaderFileEditor *shader_editor; + EditorNode *editor; + Button *button; + +public: + virtual String get_name() const { return "ShaderFile"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_object); + virtual bool handles(Object *p_object) const; + virtual void make_visible(bool p_visible); + + ShaderFileEditor *get_shader_editor() const { return shader_editor; } + + ShaderFileEditorPlugin(EditorNode *p_node); + ~ShaderFileEditorPlugin(); +}; + +#endif // SHADER_FILE_EDITOR_PLUGIN_H diff --git a/editor/plugins/style_box_editor_plugin.cpp b/editor/plugins/style_box_editor_plugin.cpp index fbb6616dea..eb6e261305 100644 --- a/editor/plugins/style_box_editor_plugin.cpp +++ b/editor/plugins/style_box_editor_plugin.cpp @@ -45,7 +45,7 @@ void EditorInspectorPluginStyleBox::parse_begin(Object *p_object) { preview->edit(sb); add_custom_control(preview); } -bool EditorInspectorPluginStyleBox::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage) { +bool EditorInspectorPluginStyleBox::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide) { return false; //do not want } void EditorInspectorPluginStyleBox::parse_end() { diff --git a/editor/plugins/style_box_editor_plugin.h b/editor/plugins/style_box_editor_plugin.h index f4a72d9d1c..1eea9260b2 100644 --- a/editor/plugins/style_box_editor_plugin.h +++ b/editor/plugins/style_box_editor_plugin.h @@ -62,7 +62,7 @@ class EditorInspectorPluginStyleBox : public EditorInspectorPlugin { public: virtual bool can_handle(Object *p_object); virtual void parse_begin(Object *p_object); - virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage); + virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide = false); virtual void parse_end(); }; diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp index ce421ac0a5..9e88cd8889 100644 --- a/editor/plugins/tile_map_editor_plugin.cpp +++ b/editor/plugins/tile_map_editor_plugin.cpp @@ -57,17 +57,18 @@ void TileMapEditor::_notification(int p_what) { } break; + case NOTIFICATION_ENTER_TREE: { + + get_tree()->connect("node_removed", callable_mp(this, &TileMapEditor::_node_removed)); + [[fallthrough]]; + } + case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { if (is_visible_in_tree()) { _update_palette(); } - [[fallthrough]]; - } - case NOTIFICATION_ENTER_TREE: { - - get_tree()->connect("node_removed", callable_mp(this, &TileMapEditor::_node_removed)); paint_button->set_icon(get_theme_icon("Edit", "EditorIcons")); bucket_fill_button->set_icon(get_theme_icon("Bucket", "EditorIcons")); picker_button->set_icon(get_theme_icon("ColorPick", "EditorIcons")); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 294ce2c4cd..d5128db0d5 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -2261,6 +2261,12 @@ void VisualShaderEditor::_show_preview_text() { } } +static ShaderLanguage::DataType _get_global_variable_type(const StringName &p_variable) { + + RS::GlobalVariableType gvt = RS::get_singleton()->global_variable_get_type(p_variable); + return RS::global_variable_type_get_shader_datatype(gvt); +} + void VisualShaderEditor::_update_preview() { if (!preview_showed) { @@ -2274,7 +2280,7 @@ void VisualShaderEditor::_update_preview() { ShaderLanguage sl; - Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(visual_shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(visual_shader->get_mode())), ShaderTypes::get_singleton()->get_types()); + Error err = sl.compile(code, ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(visual_shader->get_mode())), ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(visual_shader->get_mode())), ShaderTypes::get_singleton()->get_types(), _get_global_variable_type); for (int i = 0; i < preview_text->get_line_count(); i++) { preview_text->set_line_as_marked(i, false); @@ -3291,7 +3297,7 @@ void EditorInspectorShaderModePlugin::parse_begin(Object *p_object) { //do none } -bool EditorInspectorShaderModePlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage) { +bool EditorInspectorShaderModePlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide) { if (p_path == "mode" && p_object->is_class("VisualShader") && p_type == Variant::INT) { diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index 473c1bb070..a495b09b5c 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -338,7 +338,7 @@ class EditorInspectorShaderModePlugin : public EditorInspectorPlugin { public: virtual bool can_handle(Object *p_object); virtual void parse_begin(Object *p_object); - virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage); + virtual bool parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide = false); virtual void parse_end(); }; diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index 42493191a8..49c02dc895 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -2135,6 +2135,11 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { tab_container->add_child(autoload_settings); autoload_settings->connect("autoload_changed", callable_mp(this, &ProjectSettingsEditor::_settings_changed)); + shaders_global_variables_editor = memnew(ShaderGlobalsEditor); + shaders_global_variables_editor->set_name(TTR("Shader Globals")); + tab_container->add_child(shaders_global_variables_editor); + shaders_global_variables_editor->connect("globals_changed", callable_mp(this, &ProjectSettingsEditor::_settings_changed)); + plugin_settings = memnew(EditorPluginSettings); plugin_settings->set_name(TTR("Plugins")); tab_container->add_child(plugin_settings); diff --git a/editor/project_settings_editor.h b/editor/project_settings_editor.h index 2cecb13198..5475bb5508 100644 --- a/editor/project_settings_editor.h +++ b/editor/project_settings_editor.h @@ -36,6 +36,7 @@ #include "editor/editor_data.h" #include "editor/editor_plugin_settings.h" #include "editor/editor_sectioned_inspector.h" +#include "editor/shader_globals_editor.h" #include "scene/gui/dialogs.h" #include "scene/gui/tab_container.h" @@ -85,6 +86,7 @@ class ProjectSettingsEditor : public AcceptDialog { OptionButton *device_index; Label *device_index_label; MenuButton *popup_copy_to_feature; + ShaderGlobalsEditor *shaders_global_variables_editor; LineEdit *action_name; Button *action_add; diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index a729f62123..4041256dd5 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -2867,6 +2867,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel edit_local->set_h_size_flags(SIZE_EXPAND_FILL); edit_local->set_text(TTR("Local")); edit_local->set_toggle_mode(true); + edit_local->set_pressed(true); edit_local->connect("pressed", callable_mp(this, &SceneTreeDock::_local_tree_selected)); remote_tree = nullptr; diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index 82199fc1f1..12b21d871b 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -689,6 +689,8 @@ void ScriptCreateDialog::_update_dialog() { // Is Script created or loaded from existing file? + builtin_warning_label->set_visible(is_built_in); + if (is_built_in) { get_ok()->set_text(TTR("Create")); parent_name->set_editable(true); @@ -756,6 +758,13 @@ ScriptCreateDialog::ScriptCreateDialog() { path_error_label = memnew(Label); vb->add_child(path_error_label); + builtin_warning_label = memnew(Label); + builtin_warning_label->set_text( + TTR("Note: Built-in scripts have some limitations and can't be edited using an external editor.")); + vb->add_child(builtin_warning_label); + builtin_warning_label->set_autowrap(true); + builtin_warning_label->hide(); + status_panel = memnew(PanelContainer); status_panel->set_h_size_flags(Control::SIZE_FILL); status_panel->add_child(vb); diff --git a/editor/script_create_dialog.h b/editor/script_create_dialog.h index f164cd2a15..63a30eba88 100644 --- a/editor/script_create_dialog.h +++ b/editor/script_create_dialog.h @@ -49,6 +49,7 @@ class ScriptCreateDialog : public ConfirmationDialog { LineEdit *class_name; Label *error_label; Label *path_error_label; + Label *builtin_warning_label; PanelContainer *status_panel; LineEdit *parent_name; Button *parent_browse_button; diff --git a/editor/shader_globals_editor.cpp b/editor/shader_globals_editor.cpp new file mode 100644 index 0000000000..566ac54612 --- /dev/null +++ b/editor/shader_globals_editor.cpp @@ -0,0 +1,452 @@ +#include "shader_globals_editor.h" +#include "editor_node.h" + +static const char *global_var_type_names[RS::GLOBAL_VAR_TYPE_MAX] = { + "bool", + "bvec2", + "bvec3", + "bvec4", + "int", + "ivec2", + "ivec3", + "ivec4", + "rect2i", + "uint", + "uvec2", + "uvec3", + "uvec4", + "float", + "vec2", + "vec3", + "vec4", + "color", + "rect2", + "mat2", + "mat3", + "mat4", + "transform_2d", + "transform", + "sampler2D", + "sampler2DArray", + "sampler3D", + "samplerCube", +}; + +class ShaderGlobalsEditorInterface : public Object { + GDCLASS(ShaderGlobalsEditorInterface, Object) + + void _var_changed() { + emit_signal("var_changed"); + } + +protected: + static void _bind_methods() { + ClassDB::bind_method("_var_changed", &ShaderGlobalsEditorInterface::_var_changed); + ADD_SIGNAL(MethodInfo("var_changed")); + } + + bool _set(const StringName &p_name, const Variant &p_value) { + Variant existing = RS::get_singleton()->global_variable_get(p_name); + + if (existing.get_type() == Variant::NIL) { + return false; + } + + UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo(); + + undo_redo->create_action("Set Shader Global Variable"); + undo_redo->add_do_method(RS::get_singleton(), "global_variable_set", p_name, p_value); + undo_redo->add_undo_method(RS::get_singleton(), "global_variable_set", p_name, existing); + RS::GlobalVariableType type = RS::get_singleton()->global_variable_get_type(p_name); + Dictionary gv; + gv["type"] = global_var_type_names[type]; + if (type >= RS::GLOBAL_VAR_TYPE_SAMPLER2D) { + RES res = p_value; + if (res.is_valid()) { + gv["value"] = res->get_path(); + } else { + gv["value"] = ""; + } + } else { + gv["value"] = p_value; + } + + String path = "shader_globals/" + String(p_name); + undo_redo->add_do_property(ProjectSettings::get_singleton(), path, gv); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), path, ProjectSettings::get_singleton()->get(path)); + undo_redo->add_do_method(this, "_var_changed"); + undo_redo->add_undo_method(this, "_var_changed"); + block_update = true; + undo_redo->commit_action(); + block_update = false; + + print_line("all good?"); + return true; + } + + bool _get(const StringName &p_name, Variant &r_ret) const { + r_ret = RS::get_singleton()->global_variable_get(p_name); + return r_ret.get_type() != Variant::NIL; + } + void _get_property_list(List<PropertyInfo> *p_list) const { + Vector<StringName> variables; + variables = RS::get_singleton()->global_variable_get_list(); + for (int i = 0; i < variables.size(); i++) { + PropertyInfo pinfo; + pinfo.name = variables[i]; + + switch (RS::get_singleton()->global_variable_get_type(variables[i])) { + case RS::GLOBAL_VAR_TYPE_BOOL: { + pinfo.type = Variant::BOOL; + } break; + case RS::GLOBAL_VAR_TYPE_BVEC2: { + pinfo.type = Variant::INT; + pinfo.hint = PROPERTY_HINT_FLAGS; + pinfo.hint_string = "x,y"; + } break; + case RS::GLOBAL_VAR_TYPE_BVEC3: { + pinfo.type = Variant::INT; + pinfo.hint = PROPERTY_HINT_FLAGS; + pinfo.hint_string = "x,y,z"; + } break; + case RS::GLOBAL_VAR_TYPE_BVEC4: { + pinfo.type = Variant::INT; + pinfo.hint = PROPERTY_HINT_FLAGS; + pinfo.hint_string = "x,y,z,w"; + } break; + case RS::GLOBAL_VAR_TYPE_INT: { + pinfo.type = Variant::INT; + } break; + case RS::GLOBAL_VAR_TYPE_IVEC2: { + pinfo.type = Variant::VECTOR2I; + } break; + case RS::GLOBAL_VAR_TYPE_IVEC3: { + pinfo.type = Variant::VECTOR3I; + } break; + case RS::GLOBAL_VAR_TYPE_IVEC4: { + pinfo.type = Variant::PACKED_INT32_ARRAY; + } break; + case RS::GLOBAL_VAR_TYPE_RECT2I: { + pinfo.type = Variant::RECT2I; + } break; + case RS::GLOBAL_VAR_TYPE_UINT: { + pinfo.type = Variant::INT; + } break; + case RS::GLOBAL_VAR_TYPE_UVEC2: { + pinfo.type = Variant::VECTOR2I; + } break; + case RS::GLOBAL_VAR_TYPE_UVEC3: { + pinfo.type = Variant::VECTOR3I; + } break; + case RS::GLOBAL_VAR_TYPE_UVEC4: { + pinfo.type = Variant::PACKED_INT32_ARRAY; + } break; + case RS::GLOBAL_VAR_TYPE_FLOAT: { + pinfo.type = Variant::FLOAT; + } break; + case RS::GLOBAL_VAR_TYPE_VEC2: { + pinfo.type = Variant::VECTOR2; + } break; + case RS::GLOBAL_VAR_TYPE_VEC3: { + pinfo.type = Variant::VECTOR3; + } break; + case RS::GLOBAL_VAR_TYPE_VEC4: { + pinfo.type = Variant::PLANE; + } break; + case RS::GLOBAL_VAR_TYPE_RECT2: { + pinfo.type = Variant::RECT2; + } break; + case RS::GLOBAL_VAR_TYPE_COLOR: { + pinfo.type = Variant::COLOR; + } break; + case RS::GLOBAL_VAR_TYPE_MAT2: { + pinfo.type = Variant::PACKED_INT32_ARRAY; + } break; + case RS::GLOBAL_VAR_TYPE_MAT3: { + pinfo.type = Variant::BASIS; + } break; + case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D: { + pinfo.type = Variant::TRANSFORM2D; + } break; + case RS::GLOBAL_VAR_TYPE_TRANSFORM: { + pinfo.type = Variant::TRANSFORM; + } break; + case RS::GLOBAL_VAR_TYPE_MAT4: { + pinfo.type = Variant::PACKED_INT32_ARRAY; + } break; + case RS::GLOBAL_VAR_TYPE_SAMPLER2D: { + pinfo.type = Variant::OBJECT; + pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE; + pinfo.hint_string = "Texture2D"; + } break; + case RS::GLOBAL_VAR_TYPE_SAMPLER2DARRAY: { + pinfo.type = Variant::OBJECT; + pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE; + pinfo.hint_string = "Texture2DArray"; + } break; + case RS::GLOBAL_VAR_TYPE_SAMPLER3D: { + pinfo.type = Variant::OBJECT; + pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE; + pinfo.hint_string = "Texture3D"; + } break; + case RS::GLOBAL_VAR_TYPE_SAMPLERCUBE: { + pinfo.type = Variant::OBJECT; + pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE; + pinfo.hint_string = "Cubemap"; + } break; + default: { + + } break; + } + + p_list->push_back(pinfo); + } + } + +public: + bool block_update = false; + + ShaderGlobalsEditorInterface() { + } +}; + +static Variant create_var(RS::GlobalVariableType p_type) { + switch (p_type) { + case RS::GLOBAL_VAR_TYPE_BOOL: { + return false; + } + case RS::GLOBAL_VAR_TYPE_BVEC2: { + return 0; //bits + } + case RS::GLOBAL_VAR_TYPE_BVEC3: { + return 0; //bits + } + case RS::GLOBAL_VAR_TYPE_BVEC4: { + return 0; //bits + } + case RS::GLOBAL_VAR_TYPE_INT: { + return 0; //bits + } + case RS::GLOBAL_VAR_TYPE_IVEC2: { + return Vector2i(); + } + case RS::GLOBAL_VAR_TYPE_IVEC3: { + return Vector3i(); + } + case RS::GLOBAL_VAR_TYPE_IVEC4: { + Vector<int> v4; + v4.resize(4); + v4.write[0] = 0; + v4.write[1] = 0; + v4.write[2] = 0; + v4.write[3] = 0; + return v4; + } + case RS::GLOBAL_VAR_TYPE_RECT2I: { + return Rect2i(); + } + case RS::GLOBAL_VAR_TYPE_UINT: { + return 0; + } + case RS::GLOBAL_VAR_TYPE_UVEC2: { + return Vector2i(); + } + case RS::GLOBAL_VAR_TYPE_UVEC3: { + return Vector3i(); + } + case RS::GLOBAL_VAR_TYPE_UVEC4: { + return Rect2i(); + } + case RS::GLOBAL_VAR_TYPE_FLOAT: { + return 0.0; + } + case RS::GLOBAL_VAR_TYPE_VEC2: { + return Vector2(); + } + case RS::GLOBAL_VAR_TYPE_VEC3: { + return Vector3(); + } + case RS::GLOBAL_VAR_TYPE_VEC4: { + return Plane(); + } + case RS::GLOBAL_VAR_TYPE_RECT2: { + return Rect2(); + } + case RS::GLOBAL_VAR_TYPE_COLOR: { + return Color(); + } + case RS::GLOBAL_VAR_TYPE_MAT2: { + Vector<real_t> xform; + xform.resize(4); + xform.write[0] = 1; + xform.write[1] = 0; + xform.write[2] = 0; + xform.write[3] = 1; + return xform; + } + case RS::GLOBAL_VAR_TYPE_MAT3: { + return Basis(); + } + case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D: { + return Transform2D(); + } + case RS::GLOBAL_VAR_TYPE_TRANSFORM: { + return Transform(); + } + case RS::GLOBAL_VAR_TYPE_MAT4: { + Vector<real_t> xform; + xform.resize(4); + xform.write[0] = 1; + xform.write[1] = 0; + xform.write[2] = 0; + xform.write[3] = 0; + + xform.write[4] = 0; + xform.write[5] = 1; + xform.write[6] = 0; + xform.write[7] = 0; + + xform.write[8] = 0; + xform.write[9] = 0; + xform.write[10] = 1; + xform.write[11] = 0; + + xform.write[12] = 0; + xform.write[13] = 0; + xform.write[14] = 0; + xform.write[15] = 1; + + return xform; + } + case RS::GLOBAL_VAR_TYPE_SAMPLER2D: { + return ""; + } + case RS::GLOBAL_VAR_TYPE_SAMPLER2DARRAY: { + return ""; + } + case RS::GLOBAL_VAR_TYPE_SAMPLER3D: { + return ""; + } + case RS::GLOBAL_VAR_TYPE_SAMPLERCUBE: { + return ""; + } + default: { + return Variant(); + } + } +} + +void ShaderGlobalsEditor::_variable_added() { + + String var = variable_name->get_text().strip_edges(); + if (var == "" || !var.is_valid_identifier()) { + EditorNode::get_singleton()->show_warning(TTR("Please specify a valid variable identifier name.")); + return; + } + + if (RenderingServer::get_singleton()->global_variable_get(var).get_type() != Variant::NIL) { + EditorNode::get_singleton()->show_warning(vformat(TTR("Global variable '%s' already exists'"), var)); + return; + } + + List<String> keywords; + ShaderLanguage::get_keyword_list(&keywords); + + if (keywords.find(var) != nullptr || var == "script") { + EditorNode::get_singleton()->show_warning(vformat(TTR("Name '%s' is a reserved shader language keyword."), var)); + return; + } + + UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo(); + + Variant value = create_var(RS::GlobalVariableType(variable_type->get_selected())); + + undo_redo->create_action("Add Shader Global Variable"); + undo_redo->add_do_method(RS::get_singleton(), "global_variable_add", var, RS::GlobalVariableType(variable_type->get_selected()), value); + undo_redo->add_undo_method(RS::get_singleton(), "global_variable_remove", var); + Dictionary gv; + gv["type"] = global_var_type_names[variable_type->get_selected()]; + gv["value"] = value; + + undo_redo->add_do_property(ProjectSettings::get_singleton(), "shader_globals/" + var, gv); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), "shader_globals/" + var, Variant()); + undo_redo->add_do_method(this, "_changed"); + undo_redo->add_undo_method(this, "_changed"); + undo_redo->commit_action(); +} + +void ShaderGlobalsEditor::_variable_deleted(const String &p_variable) { + + print_line("deleted " + p_variable); + UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo(); + + undo_redo->create_action("Add Shader Global Variable"); + undo_redo->add_do_method(RS::get_singleton(), "global_variable_remove", p_variable); + undo_redo->add_undo_method(RS::get_singleton(), "global_variable_add", p_variable, RS::get_singleton()->global_variable_get_type(p_variable), RS::get_singleton()->global_variable_get(p_variable)); + + undo_redo->add_do_property(ProjectSettings::get_singleton(), "shader_globals/" + p_variable, Variant()); + undo_redo->add_undo_property(ProjectSettings::get_singleton(), "shader_globals/" + p_variable, ProjectSettings::get_singleton()->get("shader_globals/" + p_variable)); + undo_redo->add_do_method(this, "_changed"); + undo_redo->add_undo_method(this, "_changed"); + undo_redo->commit_action(); +} + +void ShaderGlobalsEditor::_changed() { + emit_signal("globals_changed"); + if (!interface->block_update) { + interface->_change_notify(); + } +} + +void ShaderGlobalsEditor::_bind_methods() { + ClassDB::bind_method("_changed", &ShaderGlobalsEditor::_changed); + ADD_SIGNAL(MethodInfo("globals_changed")); +} + +void ShaderGlobalsEditor::_notification(int p_what) { + if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { + if (is_visible_in_tree()) { + print_line("OK load settings in globalseditor"); + inspector->edit(interface); + } + } +} + +ShaderGlobalsEditor::ShaderGlobalsEditor() { + + HBoxContainer *add_menu_hb = memnew(HBoxContainer); + add_child(add_menu_hb); + + add_menu_hb->add_child(memnew(Label(TTR("Name:")))); + variable_name = memnew(LineEdit); + variable_name->set_h_size_flags(SIZE_EXPAND_FILL); + add_menu_hb->add_child(variable_name); + + add_menu_hb->add_child(memnew(Label(TTR("Type:")))); + variable_type = memnew(OptionButton); + variable_type->set_h_size_flags(SIZE_EXPAND_FILL); + add_menu_hb->add_child(variable_type); + + for (int i = 0; i < RS::GLOBAL_VAR_TYPE_MAX; i++) { + variable_type->add_item(global_var_type_names[i]); + } + + variable_add = memnew(Button(TTR("Add"))); + add_menu_hb->add_child(variable_add); + variable_add->connect("pressed", callable_mp(this, &ShaderGlobalsEditor::_variable_added)); + + inspector = memnew(EditorInspector); + inspector->set_v_size_flags(SIZE_EXPAND_FILL); + add_child(inspector); + inspector->set_use_wide_editors(true); + inspector->set_enable_capitalize_paths(false); + inspector->set_use_deletable_properties(true); + inspector->connect("property_deleted", callable_mp(this, &ShaderGlobalsEditor::_variable_deleted), varray(), CONNECT_DEFERRED); + + interface = memnew(ShaderGlobalsEditorInterface); + interface->connect("var_changed", Callable(this, "_changed")); +} +ShaderGlobalsEditor::~ShaderGlobalsEditor() { + inspector->edit(NULL); + memdelete(interface); +} diff --git a/editor/shader_globals_editor.h b/editor/shader_globals_editor.h new file mode 100644 index 0000000000..59cdeddd8d --- /dev/null +++ b/editor/shader_globals_editor.h @@ -0,0 +1,38 @@ +#ifndef SHADER_GLOBALS_EDITOR_H +#define SHADER_GLOBALS_EDITOR_H + +#include "core/undo_redo.h" +#include "editor/editor_autoload_settings.h" +#include "editor/editor_data.h" +#include "editor/editor_plugin_settings.h" +#include "editor/editor_sectioned_inspector.h" +#include "scene/gui/dialogs.h" +#include "scene/gui/tab_container.h" + +class ShaderGlobalsEditorInterface; + +class ShaderGlobalsEditor : public VBoxContainer { + + GDCLASS(ShaderGlobalsEditor, VBoxContainer) + + ShaderGlobalsEditorInterface *interface; + EditorInspector *inspector; + + LineEdit *variable_name; + OptionButton *variable_type; + Button *variable_add; + + void _variable_added(); + void _variable_deleted(const String &p_variable); + void _changed(); + +protected: + static void _bind_methods(); + void _notification(int p_what); + +public: + ShaderGlobalsEditor(); + ~ShaderGlobalsEditor(); +}; + +#endif // SHADER_GLOBALS_EDITOR_H diff --git a/editor/translations/af.po b/editor/translations/af.po index 23afeb2e55..d9e1753c65 100644 --- a/editor/translations/af.po +++ b/editor/translations/af.po @@ -1505,7 +1505,7 @@ msgstr "Skuif AutoLaai" msgid "Remove Autoload" msgstr "Hernoem AutoLaai" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "Aktiveer" @@ -2974,7 +2974,11 @@ msgid "Q&A" msgstr "" #: editor/editor_node.cpp -msgid "Issue Tracker" +msgid "Report a Bug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp @@ -4040,7 +4044,7 @@ msgid "Reimport" msgstr "" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -6936,14 +6940,6 @@ msgid "Open Godot online documentation." msgstr "Opnoemings" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7393,6 +7389,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7482,13 +7482,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -10928,6 +10928,12 @@ msgid "Script file already exists." msgstr "AutoLaai '%s' bestaan reeds!" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp #, fuzzy msgid "Class Name:" msgstr "Klas:" @@ -12592,6 +12598,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/ar.po b/editor/translations/ar.po index 2cd523ec69..2ea1bd1dd5 100644 --- a/editor/translations/ar.po +++ b/editor/translations/ar.po @@ -33,12 +33,14 @@ # traveller010 <manar.bushnaq.001@gmail.com>, 2019. # Ahmed Shahwan <dev.ahmed.shahwan@gmail.com>, 2019. # hshw <shw@tutanota.com>, 2020. +# Youssef Harmal <the.coder.crab@gmail.com>, 2020. +# Nabeel20 <nabeelandnizam@gmail.com>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-01-16 22:23+0000\n" -"Last-Translator: hshw <shw@tutanota.com>\n" +"PO-Revision-Date: 2020-04-15 14:29+0000\n" +"Last-Translator: Nabeel20 <nabeelandnizam@gmail.com>\n" "Language-Team: Arabic <https://hosted.weblate.org/projects/godot-engine/" "godot/ar/>\n" "Language: ar\n" @@ -47,7 +49,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " "&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n" -"X-Generator: Weblate 3.10.2-dev\n" +"X-Generator: Weblate 4.0-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -710,7 +712,7 @@ msgstr "رقم الخط:" #: editor/code_editor.cpp #, fuzzy msgid "%d replaced." -msgstr "إستبدال" +msgstr "تم إستبدال %d" #: editor/code_editor.cpp editor/editor_help.cpp msgid "%d match." @@ -747,7 +749,7 @@ msgstr "معياري" #: editor/code_editor.cpp editor/plugins/script_editor_plugin.cpp msgid "Toggle Scripts Panel" -msgstr "" +msgstr "ØªØØ¯ÙŠØ¯ التبويب البرمجي" #: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/texture_region_editor_plugin.cpp @@ -915,7 +917,7 @@ msgstr "هل أنت(ÙŠ) متأكد(Ø©) أنك تود إزالة كل Ø§Ù„Ø¥ØªØµØ #: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp msgid "Signals" -msgstr "إشارات" +msgstr "الإشارات" #: editor/connections_dialog.cpp msgid "Are you sure you want to remove all connections from this signal?" @@ -1225,9 +1227,8 @@ msgid "The following files failed extraction from package:" msgstr "ÙØ´Ù„ استخراج Ø§Ù„Ù…Ù„ÙØ§Øª التالية من Ø§Ù„ØØ²Ù…Ø©:" #: editor/editor_asset_installer.cpp -#, fuzzy msgid "And %s more files." -msgstr "%d مزيد من Ø§Ù„Ù…Ù„ÙØ§Øª" +msgstr "%s مزيد من Ø§Ù„Ù…Ù„ÙØ§Øª" #: editor/editor_asset_installer.cpp editor/project_manager.cpp msgid "Package installed successfully!" @@ -1381,9 +1382,8 @@ msgid "Invalid file, not an audio bus layout." msgstr "مل٠خطأ، ليس مل٠نسق بيوس الصوت." #: editor/editor_audio_buses.cpp -#, fuzzy msgid "Error saving file: %s" -msgstr "خطأ ÙÙŠ ØÙظ مجموعة البلاط!" +msgstr "خطأ !خطأ ÙÙŠ تسجيل الملÙ: s%" #: editor/editor_audio_buses.cpp msgid "Add Bus" @@ -1469,7 +1469,7 @@ msgstr "نقل التØÙ…يل التلقائي" msgid "Remove Autoload" msgstr "ازالة التØÙ…يل التلقائي" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "تمكين" @@ -1609,9 +1609,8 @@ msgstr "" #: editor/editor_export.cpp platform/android/export/export.cpp #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp #: platform/osx/export/export.cpp platform/uwp/export/export.cpp -#, fuzzy msgid "Custom debug template not found." -msgstr "مل٠النموذج غير موجود:" +msgstr "نمودج تصØÙŠØ الأخطاء غير موجود." #: editor/editor_export.cpp platform/android/export/export.cpp #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp @@ -1628,9 +1627,8 @@ msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." msgstr "" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "3D Editor" -msgstr "Ø§Ù„Ù…ÙØ¹Ø¯Ù„" +msgstr "معدل تلاثي الأبعاد" #: editor/editor_feature_profile.cpp #, fuzzy @@ -1643,22 +1641,19 @@ msgstr "مكتبة الأصول" #: editor/editor_feature_profile.cpp msgid "Scene Tree Editing" -msgstr "" +msgstr "تعديل شجرة المشهد" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Dock" -msgstr "إستيراد" +msgstr "رصي٠الاستيراد" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Node Dock" -msgstr "وضع Ø§Ù„ØªØØ±ÙŠÙƒ" +msgstr "رصي٠العقد" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "FileSystem and Import Docks" -msgstr "نظام Ø§Ù„Ù…Ù„ÙØ§Øª" +msgstr "رصي٠نظام Ø§Ù„Ù…Ù„ÙØ§Øª Ùˆ الاستيراد" #: editor/editor_feature_profile.cpp #, fuzzy @@ -3010,8 +3005,13 @@ msgid "Q&A" msgstr "الأسئلة Ùˆ الأجوبة" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "متتبع الأخطاء" +#, fuzzy +msgid "Report a Bug" +msgstr "إعادة إستيراد" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4100,7 +4100,7 @@ msgid "Reimport" msgstr "إعادة إستيراد" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -7090,14 +7090,6 @@ msgid "Open Godot online documentation." msgstr "ÙÙØªØ مؤخراً" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7552,6 +7544,10 @@ msgid "This operation requires a single selected node." msgstr "هذه العملية تتطلب عقدة ÙˆØ§ØØ¯Ø© Ù…ØØ¯Ø¯Ø©." #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7642,13 +7638,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -9157,38 +9153,39 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "E constant (2.718282). Represents the base of the natural logarithm." msgstr "" +"ثابت E ويعادل القيمة (2.718282)ØŒ وهو يمثل الأساس ÙÙŠ اللوغاريتم الطبيعي." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Epsilon constant (0.00001). Smallest possible scalar number." -msgstr "" +msgstr "ثابت إيبسلون (0.00001)ØŒ أصغر الأعداد على الإطلاق." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Phi constant (1.618034). Golden ratio." -msgstr "" +msgstr "ثابت ÙØ§ÙŠ (1.618034)ØŒ ويمثل النسبة الذهبية ذاتها." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi/4 constant (0.785398) or 45 degrees." -msgstr "" +msgstr "ثابت باي/4 (0.785398) أو 45 درجة." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi/2 constant (1.570796) or 90 degrees." -msgstr "" +msgstr "ثابت باي/2 (1.570796) أو 90 درجة." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi constant (3.141593) or 180 degrees." -msgstr "" +msgstr "ثابت باي (3.141593) أو 180 درجة." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Tau constant (6.283185) or 360 degrees." -msgstr "" +msgstr "ثابت تاو Tau وقيمته (6.283185) أو 360 درجة." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Sqrt2 constant (1.414214). Square root of 2." -msgstr "" +msgstr "ثابت جذر-العدد2 (1.414214)ØŒ أي قيمة جذر العدد 2." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the absolute value of the parameter." -msgstr "" +msgstr "ÙŠØØ³Ø¨ القيمة المطلقة لقيمة المَعلم." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-cosine of the parameter." @@ -11166,6 +11163,12 @@ msgid "Script file already exists." msgstr "التØÙ…يل التلقائي '%s' موجود اصلا!" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp #, fuzzy msgid "Class Name:" msgstr "إسم صنÙ" @@ -12859,6 +12862,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "مصدر غير ØµØ§Ù„Ø Ù„Ù„Ù…Ø¹Ø§ÙŠÙ†Ø©." @@ -12887,6 +12894,9 @@ msgstr "يمكن تعيين المتغيرات Ùقط ÙÙŠ الذروة ." msgid "Constants cannot be modified." msgstr "لا يمكن تعديل الثوابت." +#~ msgid "Issue Tracker" +#~ msgstr "متتبع الأخطاء" + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "Ø¥Ø³ØªØ¨ÙØ¯Ù„ %d ØØ§Ø¯Ø«Ø©(ØÙˆØ§Ø¯Ø«)." diff --git a/editor/translations/bg.po b/editor/translations/bg.po index 651776b6ab..1dcaf7fa32 100644 --- a/editor/translations/bg.po +++ b/editor/translations/bg.po @@ -6,14 +6,15 @@ # Иван Пенев (Ðдмирал ÐнимЕ) <aeternus.arcis@gmail.com>, 2016-2017. # Любомир ВаÑилев <lyubomirv@abv.bg>, 2018, 2020. # MaresPW <marespw206@gmail.com>, 2018. -# PakoSt <kokotekilata@gmail.com>, 2018. +# PakoSt <kokotekilata@gmail.com>, 2018, 2020. # Damyan Dichev <mwshock2@gmail.com>, 2019. +# anonymous <noreply@weblate.org>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-02-28 13:33+0000\n" -"Last-Translator: Любомир ВаÑилев <lyubomirv@abv.bg>\n" +"PO-Revision-Date: 2020-03-27 15:42+0000\n" +"Last-Translator: PakoSt <kokotekilata@gmail.com>\n" "Language-Team: Bulgarian <https://hosted.weblate.org/projects/godot-engine/" "godot/bg/>\n" "Language: bg\n" @@ -42,11 +43,12 @@ msgstr "ÐедоÑтатъчно байтове за разкодиране ил #: core/math/expression.cpp msgid "Invalid input %i (not passed) in expression" -msgstr "" +msgstr "Ðеправилно въведени дани %i (не подаден) в израза" #: core/math/expression.cpp msgid "self can't be used because instance is null (not passed)" msgstr "" +"self не може да Ñе ползва, тъй като инÑтанциÑта е null (не е била подадена)" #: core/math/expression.cpp msgid "Invalid operands to operator %s, %s and %s." @@ -58,7 +60,7 @@ msgstr "Ðевалиден Ð¸Ð½Ð´ÐµÐºÑ Ð¾Ñ‚ тип %s за базов тип %s #: core/math/expression.cpp msgid "Invalid named index '%s' for base type %s" -msgstr "" +msgstr "Ðевалидно наименован Ð¸Ð½Ð´ÐµÐºÑ '%s' за базов тип %s" #: core/math/expression.cpp msgid "Invalid arguments to construct '%s'" @@ -66,7 +68,7 @@ msgstr "Ðеправилни аргументи за Ñъздаване на „ #: core/math/expression.cpp msgid "On call to '%s':" -msgstr "" +msgstr "При обаждане към '%s':" #: core/ustring.cpp msgid "B" @@ -118,15 +120,15 @@ msgstr "СтойноÑÑ‚:" #: editor/animation_bezier_editor.cpp msgid "Insert Key Here" -msgstr "" +msgstr "Вмъкване на ключ тук" #: editor/animation_bezier_editor.cpp msgid "Duplicate Selected Key(s)" -msgstr "" +msgstr "Копиране на избран(и) ключ(ове)" #: editor/animation_bezier_editor.cpp msgid "Delete Selected Key(s)" -msgstr "" +msgstr "Изтриване на избран(и) ключ(ове)" #: editor/animation_bezier_editor.cpp msgid "Add Bezier Point" @@ -138,31 +140,31 @@ msgstr "ПремеÑтване на точки на Безие" #: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp msgid "Anim Duplicate Keys" -msgstr "" +msgstr "Копиране на ключ(ове) (ÐнимациÑ)" #: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp msgid "Anim Delete Keys" -msgstr "" +msgstr "Изтриване на ключ(ове) (ÐнимациÑ)" #: editor/animation_track_editor.cpp msgid "Anim Change Keyframe Time" -msgstr "" +msgstr "ПромÑна на момент на ключов кадър (ÐнимациÑ)" #: editor/animation_track_editor.cpp msgid "Anim Change Transition" -msgstr "" +msgstr "ПромÑна на вид преход (ÐнимациÑ)" #: editor/animation_track_editor.cpp msgid "Anim Change Transform" -msgstr "" +msgstr "ПромÑна на транÑÑ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ (ÐнимациÑ)" #: editor/animation_track_editor.cpp msgid "Anim Change Keyframe Value" -msgstr "" +msgstr "ПромÑна на ÑтойноÑÑ‚ на ключов кадър (ÐнимациÑ)" #: editor/animation_track_editor.cpp msgid "Anim Change Call" -msgstr "" +msgstr "ПромÑна на повикана Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ (ÐнимациÑ)" #: editor/animation_track_editor.cpp msgid "Anim Multi Change Keyframe Time" @@ -1417,7 +1419,7 @@ msgstr "" msgid "Remove Autoload" msgstr "" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "" @@ -2821,7 +2823,12 @@ msgid "Q&A" msgstr "" #: editor/editor_node.cpp -msgid "Issue Tracker" +#, fuzzy +msgid "Report a Bug" +msgstr "Повторно внаÑÑне" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp @@ -3844,7 +3851,7 @@ msgid "Reimport" msgstr "Повторно внаÑÑне" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -6694,14 +6701,6 @@ msgid "Open Godot online documentation." msgstr "ОтварÑне на документациÑта на Godot в Интернет." #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7139,6 +7138,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7230,13 +7233,13 @@ msgid "Freelook Slow Modifier" msgstr "Свободен Изглед Отпред" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -10656,6 +10659,12 @@ msgid "Script file already exists." msgstr "Група Ñ Ñ‚Ð¾Ð²Ð° име вече ÑъщеÑтвува." #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp #, fuzzy msgid "Class Name:" msgstr "КлаÑ:" @@ -12375,6 +12384,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/bn.po b/editor/translations/bn.po index 77ff28a113..b37267652e 100644 --- a/editor/translations/bn.po +++ b/editor/translations/bn.po @@ -1537,7 +1537,7 @@ msgstr "Autoload সà§à¦¥à¦¾à¦¨à¦¾à¦¨à§à¦¤à¦° করà§à¦¨" msgid "Remove Autoload" msgstr "Autoload অপসারণ করà§à¦¨" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "সকà§à¦°à¦¿à¦¯à¦¼ করà§à¦¨" @@ -3130,8 +3130,13 @@ msgid "Q&A" msgstr "Q&A" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "ইসà§à¦¯à§ টà§à¦°à§à¦¯à¦¾à¦•ার" +#, fuzzy +msgid "Report a Bug" +msgstr "পà§à¦¨-ইমà§à¦ªà§‹à¦°à§à¦Ÿ" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4291,7 +4296,7 @@ msgid "Reimport" msgstr "পà§à¦¨-ইমà§à¦ªà§‹à¦°à§à¦Ÿ" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -7354,14 +7359,6 @@ msgid "Open Godot online documentation." msgstr "রেফারেনà§à¦¸à§‡à¦° ডকà§à¦®à§‡à¦¨à§à¦Ÿà§‡à¦¶à¦¨à§‡ খà§à¦à¦œà§à¦¨à¥¤" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "রেফারেনà§à¦¸à§‡à¦° ডকà§à¦®à§‡à¦¨à§à¦Ÿà§‡à¦¶à¦¨à§‡ খà§à¦à¦œà§à¦¨à¥¤" @@ -7836,6 +7833,11 @@ msgstr "à¦à¦‡ কাজটি করার জনà§à¦¯ à¦à¦•টি à¦à¦•ক #: editor/plugins/spatial_editor_plugin.cpp #, fuzzy +msgid "Auto Orthogonal Enabled" +msgstr "সমকোণীয় (Orthogonal)" + +#: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy msgid "Lock View Rotation" msgstr "তথà§à¦¯ দেখà§à¦¨" @@ -7935,17 +7937,17 @@ msgid "Freelook Slow Modifier" msgstr "ফà§à¦°à¦¿ লà§à¦• সà§à¦ªà¦¿à¦¡ মডিফায়ার" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "View Rotation Locked" +msgstr "তথà§à¦¯ দেখà§à¦¨" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy -msgid "View Rotation Locked" -msgstr "তথà§à¦¯ দেখà§à¦¨" - -#: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "XForm à¦à¦° সংলাপ" @@ -11620,6 +11622,12 @@ msgid "Script file already exists." msgstr "'%s' অà§à¦¯à¦¾à¦•শন ইতিমধà§à¦¯à§‡à¦‡ বিদà§à¦¯à¦®à¦¾à¦¨!" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp #, fuzzy msgid "Class Name:" msgstr "কà§à¦²à¦¾à¦¸ নাম:" @@ -13433,6 +13441,10 @@ msgstr "" "আকার ধারণ করতে পারে। অনà§à¦¯à¦¥à¦¾à§Ÿ, à¦à¦Ÿà¦¿à¦•ে à¦à¦•টি RenderTarget করà§à¦¨ à¦à¦¬à¦‚ à¦à¦° অà¦à§à¦¯à¦¨à§à¦¤à¦°à§€à¦£ " "দৃশà§à¦¯à¦¾à¦¬à¦²à¦¿à¦•ে (texture) দৃশà§à¦¯à¦®à¦¾à¦¨ করতে কোনো নোডে হসà§à¦¤à¦¾à¦¨à§à¦¤à¦° করà§à¦¨à¥¤" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." @@ -13464,6 +13476,9 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#~ msgid "Issue Tracker" +#~ msgstr "ইসà§à¦¯à§ টà§à¦°à§à¦¯à¦¾à¦•ার" + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "%d সংখà§à¦¯à¦• সংঘটন পà§à¦°à¦¤à¦¿à¦¸à§à¦¥à¦¾à¦ªà¦¿à¦¤ হয়েছে ।" diff --git a/editor/translations/ca.po b/editor/translations/ca.po index 304fa8905b..21886cea24 100644 --- a/editor/translations/ca.po +++ b/editor/translations/ca.po @@ -1452,7 +1452,7 @@ msgstr "Mou l'AutoCà rrega" msgid "Remove Autoload" msgstr "Treu Autocà rrega" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "Activa" @@ -2953,8 +2953,13 @@ msgid "Q&A" msgstr "Preguntes i Respostes" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "Seguiment d'Incidències" +#, fuzzy +msgid "Report a Bug" +msgstr "ReImportar" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4027,7 +4032,8 @@ msgid "Reimport" msgstr "ReImportar" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +#, fuzzy +msgid "Save Scenes, Re-Import, and Restart" msgstr "Guardar escenes, reimportar i reiniciar" #: editor/import_dock.cpp @@ -6956,15 +6962,6 @@ msgid "Open Godot online documentation." msgstr "Obrir la documentació en lÃnia de Godot." #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "Sol·licitar Documentació" - -#: editor/plugins/script_editor_plugin.cpp -#, fuzzy -msgid "Help improve the Godot documentation by giving feedback." -msgstr "Ajudeu a millorar la documentació de Godot donant comentaris" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "Cerca dins la documentació de referència." @@ -7416,6 +7413,11 @@ msgid "This operation requires a single selected node." msgstr "Aquesta operació requereix un únic node seleccionat." #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Auto Orthogonal Enabled" +msgstr "Ortogonal" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "Bloquejar Rotació de la Vista" @@ -7507,6 +7509,10 @@ msgid "Freelook Slow Modifier" msgstr "Modificador de la Velocitat de la Vista Lliure" #: editor/plugins/spatial_editor_plugin.cpp +msgid "View Rotation Locked" +msgstr "Rotació de la Vista Bloquejada" + +#: editor/plugins/spatial_editor_plugin.cpp #, fuzzy msgid "" "Note: The FPS value displayed is the editor's framerate.\n" @@ -7516,10 +7522,6 @@ msgstr "" "No es pot utilitzar com una indicació fiable del rendiment en el joc." #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" -msgstr "Rotació de la Vista Bloquejada" - -#: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "Dià leg XForm" @@ -11209,6 +11211,12 @@ msgid "Script file already exists." msgstr "L'Acció '%s' ja existeix!" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp #, fuzzy msgid "Class Name:" msgstr "Nom de Classe" @@ -13063,6 +13071,10 @@ msgstr "" "forma per tal d'obtenir-ne la mida. Altrament, establiu-la com a Destinació " "de Renderització i assigneu-ne la textura interna a algun node." +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." @@ -13093,6 +13105,16 @@ msgstr "" msgid "Constants cannot be modified." msgstr "Les constants no es poden modificar." +#~ msgid "Issue Tracker" +#~ msgstr "Seguiment d'Incidències" + +#~ msgid "Request Docs" +#~ msgstr "Sol·licitar Documentació" + +#, fuzzy +#~ msgid "Help improve the Godot documentation by giving feedback." +#~ msgstr "Ajudeu a millorar la documentació de Godot donant comentaris" + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "%d ocurrència/es reemplaçades." diff --git a/editor/translations/cs.po b/editor/translations/cs.po index 595db1837f..887bbeb8f4 100644 --- a/editor/translations/cs.po +++ b/editor/translations/cs.po @@ -1455,7 +1455,7 @@ msgstr "PÅ™emÃstit Autoload" msgid "Remove Autoload" msgstr "Odstranit Autoload" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "Povolit" @@ -2933,8 +2933,13 @@ msgid "Q&A" msgstr "Otázky a odpovÄ›di" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "Sledovánà chyb" +#, fuzzy +msgid "Report a Bug" +msgstr "Znovu importovat" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -3972,7 +3977,7 @@ msgid "Reimport" msgstr "Znovu importovat" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -6828,14 +6833,6 @@ msgid "Open Godot online documentation." msgstr "OtevÅ™Ãt online dokumentaci Godotu." #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "Požádat o dokumentaci" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "Hledat v referenÄnà dokumentaci." @@ -7282,6 +7279,11 @@ msgstr "Tato operace vyžaduje jeden vybraný uzel." #: editor/plugins/spatial_editor_plugin.cpp #, fuzzy +msgid "Auto Orthogonal Enabled" +msgstr "OrtogonálnÃ" + +#: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy msgid "Lock View Rotation" msgstr "Zobrazit informace" @@ -7372,17 +7374,17 @@ msgid "Freelook Slow Modifier" msgstr "Rychlost volného pohledu" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "View Rotation Locked" +msgstr "Zobrazit informace" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy -msgid "View Rotation Locked" -msgstr "Zobrazit informace" - -#: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "XForm Dialog" @@ -10904,6 +10906,12 @@ msgid "Script file already exists." msgstr "Soubor skriptu již existuje." #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "Jméno tÅ™Ãdy:" @@ -12648,6 +12656,10 @@ msgstr "" "mohl zÃskat velikost. Jinak ho nastavte jako render target a pÅ™iÅ™aÄte jeho " "vnitÅ™nà texturu nÄ›jakému uzlu k zobrazenÃ." +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." @@ -12678,6 +12690,12 @@ msgstr "" msgid "Constants cannot be modified." msgstr "Konstanty nenà možné upravovat." +#~ msgid "Issue Tracker" +#~ msgstr "Sledovánà chyb" + +#~ msgid "Request Docs" +#~ msgstr "Požádat o dokumentaci" + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "Nahrazeno %d výskytů." diff --git a/editor/translations/da.po b/editor/translations/da.po index 3d2c4cb48b..e582e4f3f9 100644 --- a/editor/translations/da.po +++ b/editor/translations/da.po @@ -1508,7 +1508,7 @@ msgstr "Flyt Autoload" msgid "Remove Autoload" msgstr "Fjern Autoload" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "Aktivér" @@ -3041,8 +3041,13 @@ msgid "Q&A" msgstr "SpørgsmÃ¥l og Svar" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "Problem Tracker" +#, fuzzy +msgid "Report a Bug" +msgstr "Genimporter" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4132,7 +4137,7 @@ msgid "Reimport" msgstr "Genimporter" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -7083,14 +7088,6 @@ msgid "Open Godot online documentation." msgstr "Ã…ben Seneste" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7546,6 +7543,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7636,13 +7637,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -11161,6 +11162,12 @@ msgid "Script file already exists." msgstr "Autoload '%s' eksisterer allerede!" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp #, fuzzy msgid "Class Name:" msgstr "Klasse:" @@ -12917,6 +12924,10 @@ msgstr "" "den kan opnÃ¥ en størrelse. Ellers gør den til en RenderTarget og tildel dens " "indre textur til en node sÃ¥ den kan vises." +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." @@ -12948,6 +12959,9 @@ msgstr "" msgid "Constants cannot be modified." msgstr "Konstanter kan ikke ændres." +#~ msgid "Issue Tracker" +#~ msgstr "Problem Tracker" + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "Erstattede %d forekomst(er)." diff --git a/editor/translations/de.po b/editor/translations/de.po index 1520c3aa2a..dc12e814b0 100644 --- a/editor/translations/de.po +++ b/editor/translations/de.po @@ -1494,7 +1494,7 @@ msgstr "Autoload verschieben" msgid "Remove Autoload" msgstr "Autoload entfernen" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "Aktivieren" @@ -2992,8 +2992,13 @@ msgid "Q&A" msgstr "Fragen & Antworten" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "Problem-Melder" +#, fuzzy +msgid "Report a Bug" +msgstr "Neuimport" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4051,7 +4056,8 @@ msgid "Reimport" msgstr "Neuimport" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +#, fuzzy +msgid "Save Scenes, Re-Import, and Restart" msgstr "Szenen speichern, reimportieren und neu starten" #: editor/import_dock.cpp @@ -6920,15 +6926,6 @@ msgid "Open Godot online documentation." msgstr "Godot-Onlinedokumentation öffnen." #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "Dokumentation anfragen" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" -"Mithelfen die Godot-Dokumentation durch Meinungsäußerungen zu verbessern." - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "Durchsuche die Referenzdokumentation." @@ -7368,6 +7365,11 @@ msgid "This operation requires a single selected node." msgstr "Diese Aktion benötigt einen einzelnen ausgewählten Node." #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Auto Orthogonal Enabled" +msgstr "Orthogonal" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "Sichtrotation sperren" @@ -7456,6 +7458,10 @@ msgid "Freelook Slow Modifier" msgstr "Freisicht Trägheitsregler" #: editor/plugins/spatial_editor_plugin.cpp +msgid "View Rotation Locked" +msgstr "Sichtrotation gesperrt" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." @@ -7464,10 +7470,6 @@ msgstr "" "Sie ist kein zuverlässiger Vergleichswert für die In-Spiel-Leistung." #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" -msgstr "Sichtrotation gesperrt" - -#: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "Transformationsdialog" @@ -10989,6 +10991,12 @@ msgid "Script file already exists." msgstr "Skriptdatei existiert bereits." #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "Klassenname:" @@ -12797,6 +12805,10 @@ msgstr "" "Eigenschaft ‚Render Target‘ des Viewports aktiviert und seine Textur " "irgendeinem Node zum Anzeigen zugewiesen werden." +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "Ungültige Quelle für Vorschau." @@ -12825,6 +12837,16 @@ msgstr "Varyings können nur in Vertex-Funktion zugewiesen werden." msgid "Constants cannot be modified." msgstr "Konstanten können nicht verändert werden." +#~ msgid "Issue Tracker" +#~ msgstr "Problem-Melder" + +#~ msgid "Request Docs" +#~ msgstr "Dokumentation anfragen" + +#~ msgid "Help improve the Godot documentation by giving feedback." +#~ msgstr "" +#~ "Mithelfen die Godot-Dokumentation durch Meinungsäußerungen zu verbessern." + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "Suchbegriff wurde %d mal ersetzt." diff --git a/editor/translations/de_CH.po b/editor/translations/de_CH.po index 84e1dd1599..e17231a0dd 100644 --- a/editor/translations/de_CH.po +++ b/editor/translations/de_CH.po @@ -1458,7 +1458,7 @@ msgstr "" msgid "Remove Autoload" msgstr "" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "" @@ -2918,7 +2918,11 @@ msgid "Q&A" msgstr "" #: editor/editor_node.cpp -msgid "Issue Tracker" +msgid "Report a Bug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp @@ -3992,7 +3996,7 @@ msgid "Reimport" msgstr "" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -6925,14 +6929,6 @@ msgid "Open Godot online documentation." msgstr "" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7378,6 +7374,10 @@ msgid "This operation requires a single selected node." msgstr "Bitte nur ein Node selektieren." #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7468,13 +7468,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -10962,6 +10962,12 @@ msgid "Script file already exists." msgstr "" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "" @@ -12667,6 +12673,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/editor.pot b/editor/translations/editor.pot index 232f6eb087..466aa8fa7f 100644 --- a/editor/translations/editor.pot +++ b/editor/translations/editor.pot @@ -1401,7 +1401,7 @@ msgstr "" msgid "Remove Autoload" msgstr "" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "" @@ -2804,7 +2804,11 @@ msgid "Q&A" msgstr "" #: editor/editor_node.cpp -msgid "Issue Tracker" +msgid "Report a Bug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp @@ -3825,7 +3829,7 @@ msgid "Reimport" msgstr "" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -6607,14 +6611,6 @@ msgid "Open Godot online documentation." msgstr "" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7044,6 +7040,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7132,13 +7132,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -10456,6 +10456,12 @@ msgid "Script file already exists." msgstr "" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "" @@ -12069,6 +12075,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/el.po b/editor/translations/el.po index fb9029a861..2c8335393b 100644 --- a/editor/translations/el.po +++ b/editor/translations/el.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-03-08 22:32+0000\n" +"PO-Revision-Date: 2020-03-23 03:47+0000\n" "Last-Translator: George Tsiamasiotis <gtsiam@windowslive.com>\n" "Language-Team: Greek <https://hosted.weblate.org/projects/godot-engine/godot/" "el/>\n" @@ -1451,7 +1451,7 @@ msgstr "Μετακίνηση AutoLoad" msgid "Remove Autoload" msgstr "ΑφαίÏεση AutoLoad" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "ΕνεÏγοποίηση" @@ -2951,8 +2951,13 @@ msgid "Q&A" msgstr "ΕÏωτήσεις & Απαντήσεις" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "ΔιαχείÏιση Ï€Ïοβλημάτων" +#, fuzzy +msgid "Report a Bug" +msgstr "Επανεισαγωγή" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4013,7 +4018,8 @@ msgid "Reimport" msgstr "Επανεισαγωγή" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +#, fuzzy +msgid "Save Scenes, Re-Import, and Restart" msgstr "Αποθήκευση σκηνών, επανεισαγωγή και επανεκκίνηση" #: editor/import_dock.cpp @@ -5992,9 +5998,8 @@ msgstr "" "Είναι η πιο ακÏιβής (αλλά αÏγότεÏη) επιλογή για εντοπισμό σÏγκÏουσης." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Single Convex Collision Sibling" -msgstr "ΔημιουÏγία Μοναδικών ΚυÏτών Αδελφών ΣÏγκÏουσης" +msgstr "ΔημιουÏγία ÎœÎ¿Î½Î±Î´Î¹ÎºÎ¿Ï ÎšÏ…ÏÏ„Î¿Ï Î‘Î´ÎµÎ»Ï†Î¿Ï Î£ÏγκÏουσης" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "" @@ -6889,14 +6894,6 @@ msgid "Open Godot online documentation." msgstr "Άνοιγμα ηλεκτÏονικής τεκμηÏίωσης της Godot." #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "Αίτηση ΤεκμηÏίωσης" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "Βοηθήστε στην βελτίωση της τεκμηÏίωσης σχολιάζοντας." - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "Αναζήτηση στην τεκμηÏίωση αναφοÏάς." @@ -7337,6 +7334,11 @@ msgid "This operation requires a single selected node." msgstr "Αυτή η λειτουÏγία απαιτεί Îναν μόνο επιλεγμÎνο κόμβο." #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Auto Orthogonal Enabled" +msgstr "ΑξονομετÏική" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "Κλείδωμα ΠεÏιστÏοφής Î Ïοβολής" @@ -7425,6 +7427,10 @@ msgid "Freelook Slow Modifier" msgstr "ΑÏγός ΤÏοποποιητής ΕλεÏθεÏου Κοιτάγματος" #: editor/plugins/spatial_editor_plugin.cpp +msgid "View Rotation Locked" +msgstr "Κλείδωμα ΠεÏιστÏοφής" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." @@ -7434,10 +7440,6 @@ msgstr "" "παιχνιδιοÏ." #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" -msgstr "Κλείδωμα ΠεÏιστÏοφής" - -#: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "Διάλογος XForm" @@ -10949,6 +10951,12 @@ msgid "Script file already exists." msgstr "ΥπαÏκτό αÏχείο δÎσμης ενεÏγειών." #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "Όνομα Κλάσης:" @@ -12446,6 +12454,8 @@ msgstr "" msgid "" "ConcavePolygonShape doesn't support RigidBody in another mode than static." msgstr "" +"Το ConcavePolygonShape δεν υποστηÏίζει το RigidBody εκτός της static " +"λειτουÏγίας." #: scene/3d/cpu_particles.cpp msgid "Nothing is visible because no mesh has been assigned." @@ -12749,6 +12759,10 @@ msgstr "" "μÎγεθος. Αλλιώς, κάντε το Îνα RenderTarget και οÏίστε το internal texture σε " "Îναν κόμβο για απεικόνιση." +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "ΆκυÏη πηγή για Ï€Ïοεπισκόπηση." @@ -12777,6 +12791,15 @@ msgstr "Τα «varying» μποÏοÏν να ανατεθοÏν μόνο στηΠmsgid "Constants cannot be modified." msgstr "Οι σταθεÏÎÏ‚ δεν μποÏοÏν να Ï„ÏοποποιηθοÏν." +#~ msgid "Issue Tracker" +#~ msgstr "ΔιαχείÏιση Ï€Ïοβλημάτων" + +#~ msgid "Request Docs" +#~ msgstr "Αίτηση ΤεκμηÏίωσης" + +#~ msgid "Help improve the Godot documentation by giving feedback." +#~ msgstr "Βοηθήστε στην βελτίωση της τεκμηÏίωσης σχολιάζοντας." + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "Αντικαταστάθηκαν %d εμφανίσεις." diff --git a/editor/translations/eo.po b/editor/translations/eo.po index cd84f54a40..7dc152659f 100644 --- a/editor/translations/eo.po +++ b/editor/translations/eo.po @@ -1439,7 +1439,7 @@ msgstr "" msgid "Remove Autoload" msgstr "" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "" @@ -2895,7 +2895,11 @@ msgid "Q&A" msgstr "" #: editor/editor_node.cpp -msgid "Issue Tracker" +msgid "Report a Bug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp @@ -3929,7 +3933,7 @@ msgid "Reimport" msgstr "" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -6727,15 +6731,6 @@ msgid "Open Godot online documentation." msgstr "" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -#, fuzzy -msgid "Help improve the Godot documentation by giving feedback." -msgstr "Helpi plibonigi la Godotan dokumentadon per doni reagon." - -#: editor/plugins/script_editor_plugin.cpp #, fuzzy msgid "Search the reference documentation." msgstr "Serĉi la referencan dokumentadon." @@ -7167,6 +7162,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7255,13 +7254,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -10606,6 +10605,12 @@ msgid "Script file already exists." msgstr "Grupa nomo jam ekzistas." #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp #, fuzzy msgid "Class Name:" msgstr "Nomo:" @@ -12237,6 +12242,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." @@ -12267,6 +12276,10 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#, fuzzy +#~ msgid "Help improve the Godot documentation by giving feedback." +#~ msgstr "Helpi plibonigi la Godotan dokumentadon per doni reagon." + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "AnstataÅigis %d apero(j)n." diff --git a/editor/translations/es.po b/editor/translations/es.po index 3bbe96bcb3..c9ca261498 100644 --- a/editor/translations/es.po +++ b/editor/translations/es.po @@ -43,12 +43,15 @@ # Dario <darlex259@gmail.com>, 2019. # Adolfo Jayme Barrientos <fitojb@ubuntu.com>, 2019. # Julián Luini <jluini@gmail.com>, 2020. +# anonymous <noreply@weblate.org>, 2020. +# Victor S. <victorstancioiu@gmail.com>, 2020. +# henry rujano herrera <rujhen@gmail.com>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-03-11 12:20+0000\n" -"Last-Translator: Javier Ocampos <xavier.ocampos@gmail.com>\n" +"PO-Revision-Date: 2020-04-16 11:03+0000\n" +"Last-Translator: anonymous <noreply@weblate.org>\n" "Language-Team: Spanish <https://hosted.weblate.org/projects/godot-engine/" "godot/es/>\n" "Language: es\n" @@ -56,12 +59,13 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.0-dev\n" +"X-Generator: Weblate 4.0.1-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp msgid "Invalid type argument to convert(), use TYPE_* constants." -msgstr "Argumento de tipo inválido para convert(), utiliza constantes TYPE_*." +msgstr "" +"Tipo de argumento inválido para 'convert()', utiliza constantes TYPE_*." #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp msgid "Expected a string of length 1 (a character)." @@ -76,7 +80,7 @@ msgstr "" #: core/math/expression.cpp msgid "Invalid input %i (not passed) in expression" -msgstr "Entrada inválida %i (no pasó) en la expresión" +msgstr "Entrada inválida %i (no se pasó) en la expresión" #: core/math/expression.cpp msgid "self can't be used because instance is null (not passed)" @@ -638,7 +642,7 @@ msgstr "Usar Curvas Bezier" #: editor/animation_track_editor.cpp msgid "Anim. Optimizer" -msgstr "Optimizar Animación" +msgstr "Optimizador de Animación" #: editor/animation_track_editor.cpp msgid "Max. Linear Error:" @@ -841,7 +845,7 @@ msgstr "Eliminar" #: editor/connections_dialog.cpp msgid "Add Extra Call Argument:" -msgstr "Añadir Argumento de Llamada Extra:" +msgstr "Añadir un Argumento de Llamada Extra:" #: editor/connections_dialog.cpp msgid "Extra Call Arguments:" @@ -1488,7 +1492,7 @@ msgstr "Mover Autoload" msgid "Remove Autoload" msgstr "Eliminar Autoload" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "Activar" @@ -2990,8 +2994,13 @@ msgid "Q&A" msgstr "Preguntas y respuestas" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "Registro de problemas" +#, fuzzy +msgid "Report a Bug" +msgstr "Reimportar" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -3003,7 +3012,7 @@ msgstr "Acerca de" #: editor/editor_node.cpp msgid "Play the project." -msgstr "Reproducir el proyecto." +msgstr "Ejecutar el proyecto." #: editor/editor_node.cpp msgid "Play" @@ -4051,7 +4060,8 @@ msgid "Reimport" msgstr "Reimportar" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +#, fuzzy +msgid "Save Scenes, Re-Import, and Restart" msgstr "Guardar escenas, reimportar y reiniciar" #: editor/import_dock.cpp @@ -5264,7 +5274,7 @@ msgid "" "When active, moving Control nodes changes their anchors instead of their " "margins." msgstr "" -"Cuando esté activo, los nodos de Control en movimiento cambian sus anclas en " +"Cuando esté activo, moviendo los nodos de Control cambiará sus anclas en " "lugar de sus márgenes." #: editor/plugins/canvas_item_editor_plugin.cpp @@ -6921,14 +6931,6 @@ msgid "Open Godot online documentation." msgstr "Abrir la documentación en lÃnea de Godot." #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "Solicitar Documentos" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "Ayuda a mejorar la documentación de Godot aportando retroalimentación." - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "Buscar en la documentación de referencia." @@ -7365,6 +7367,11 @@ msgid "This operation requires a single selected node." msgstr "Esta operación requiere un solo nodo seleccionado." #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Auto Orthogonal Enabled" +msgstr "Ortogonal" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "Bloquear Rotación de Vista" @@ -7453,6 +7460,10 @@ msgid "Freelook Slow Modifier" msgstr "Modificador de Velocidad de Vista Libre" #: editor/plugins/spatial_editor_plugin.cpp +msgid "View Rotation Locked" +msgstr "Bloquear Rotación de Vista" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." @@ -7461,10 +7472,6 @@ msgstr "" "No se puede utilizar como un indicador fiable del rendimiento en el juego." #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" -msgstr "Bloquear Rotación de Vista" - -#: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "Diálogo XForm" @@ -7823,7 +7830,7 @@ msgstr "Añadir Textura desde Archivo" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frames from a Sprite Sheet" -msgstr "Añadir Frames de un Sprite Sheet" +msgstr "Añadir Frames desde un Sprite Sheet" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Insert Empty (Before)" @@ -8457,11 +8464,11 @@ msgstr "Editar Ãndice Z de Tile" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Make Convex" -msgstr "Crear Convexo" +msgstr "Hacerlo Convexo" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Make Concave" -msgstr "Crear Cóncavo" +msgstr "Hacerlo Cóncavo" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Create Collision Polygon" @@ -9447,7 +9454,7 @@ msgstr "Editar Propiedad Visual" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Visual Shader Mode Changed" -msgstr "Cambiar Modo de Visual Shader" +msgstr "El Modo de Visual Shader ha cambiado" #: editor/project_export.cpp msgid "Runnable" @@ -9518,7 +9525,7 @@ msgid "" "Only one preset per platform may be marked as runnable." msgstr "" "Si se selecciona, la plantilla estará disponible para su uso en un " -"despliegue con “un clickâ€.\n" +"despliegue con un clic.\n" "Sólo se puede marcar como ejecutable una plantilla por plataforma." #: editor/project_export.cpp @@ -10977,6 +10984,12 @@ msgid "Script file already exists." msgstr "El archivo de script ya existe." #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "Nombre de Clase:" @@ -11430,7 +11443,7 @@ msgstr "Eliminar Rotación del Cursor" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Paste Selects" -msgstr "Pegar Seleccionados" +msgstr "Pegar Selecciona" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Clear Selection" @@ -12020,7 +12033,7 @@ msgid "" "Trying to build from a custom built template, but no version info for it " "exists. Please reinstall from the 'Project' menu." msgstr "" -"Intentando construir a partir de una plantilla personalizada, pero no existe " +"Se intentó construir a partir de una plantilla personalizada, pero no existe " "información de la versión para ello. Por favor, reinstala desde el menú " "'Proyecto'." @@ -12785,6 +12798,10 @@ msgstr "" "bien, conviértalo en un RenderTarget y asigne su textura interna a algún " "nodo para que se muestre." +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "Fuente inválida para la vista previa." @@ -12813,6 +12830,16 @@ msgstr "Solo se pueden asignar variaciones en funciones de vértice." msgid "Constants cannot be modified." msgstr "Las constantes no pueden modificarse." +#~ msgid "Issue Tracker" +#~ msgstr "Registro de problemas" + +#~ msgid "Request Docs" +#~ msgstr "Solicitar Documentos" + +#~ msgid "Help improve the Godot documentation by giving feedback." +#~ msgstr "" +#~ "Ayuda a mejorar la documentación de Godot aportando retroalimentación." + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "%d ocurrencia(s) reemplazada(s)." diff --git a/editor/translations/es_AR.po b/editor/translations/es_AR.po index 7781d59f34..7e7ed33aca 100644 --- a/editor/translations/es_AR.po +++ b/editor/translations/es_AR.po @@ -1457,7 +1457,7 @@ msgstr "Mover Autoload" msgid "Remove Autoload" msgstr "Quitar Autoload" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "Activar" @@ -2954,8 +2954,13 @@ msgid "Q&A" msgstr "Q&A" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "Registro de problemas" +#, fuzzy +msgid "Report a Bug" +msgstr "Reimportar" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4015,7 +4020,8 @@ msgid "Reimport" msgstr "Reimportar" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +#, fuzzy +msgid "Save Scenes, Re-Import, and Restart" msgstr "Guardar escenas, reimportar y reiniciar" #: editor/import_dock.cpp @@ -6881,14 +6887,6 @@ msgid "Open Godot online documentation." msgstr "Abrir la documentación en lÃnea de Godot." #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "Solicitar Docum." - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "Ayudá a mejorar la documentación de Godot dando feedback." - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "Buscar en la documentación de referencia." @@ -7325,6 +7323,11 @@ msgid "This operation requires a single selected node." msgstr "Esta operación requiere un solo nodo seleccionado." #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Auto Orthogonal Enabled" +msgstr "Ortogonal" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "Trabar Rotación de Vista" @@ -7413,6 +7416,10 @@ msgid "Freelook Slow Modifier" msgstr "Modificador de Velocidad de Vista Libre" #: editor/plugins/spatial_editor_plugin.cpp +msgid "View Rotation Locked" +msgstr "Rotación de Vista Trabada" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." @@ -7421,10 +7428,6 @@ msgstr "" "No se puede utilizar como un indicador fiable del rendimiento en el juego." #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" -msgstr "Rotación de Vista Trabada" - -#: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "Dialogo XForm" @@ -10937,6 +10940,12 @@ msgid "Script file already exists." msgstr "El archivo de script ya existe." #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "Nombre de Clase:" @@ -12736,6 +12745,10 @@ msgstr "" "pueda obtener un tamaño. Alternativamente, haz un RenderTarget y asigna su " "textura interna a algún otro nodo para mostrar." +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "Fuente inválida para la vista previa." @@ -12764,6 +12777,15 @@ msgstr "Solo se pueden asignar variaciones en funciones de vértice." msgid "Constants cannot be modified." msgstr "Las constantes no pueden modificarse." +#~ msgid "Issue Tracker" +#~ msgstr "Registro de problemas" + +#~ msgid "Request Docs" +#~ msgstr "Solicitar Docum." + +#~ msgid "Help improve the Godot documentation by giving feedback." +#~ msgstr "Ayudá a mejorar la documentación de Godot dando feedback." + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "%d ocurrencia(s) Reemplazadas." diff --git a/editor/translations/et.po b/editor/translations/et.po index 9b9d9b9137..6c052803e0 100644 --- a/editor/translations/et.po +++ b/editor/translations/et.po @@ -1409,7 +1409,7 @@ msgstr "" msgid "Remove Autoload" msgstr "" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "" @@ -2816,7 +2816,11 @@ msgid "Q&A" msgstr "" #: editor/editor_node.cpp -msgid "Issue Tracker" +msgid "Report a Bug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp @@ -3838,7 +3842,7 @@ msgid "Reimport" msgstr "" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -6626,14 +6630,6 @@ msgid "Open Godot online documentation." msgstr "" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7064,6 +7060,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7152,13 +7152,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -10481,6 +10481,12 @@ msgid "Script file already exists." msgstr "" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "" @@ -12100,6 +12106,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/eu.po b/editor/translations/eu.po index 1075a4a046..49fb37e599 100644 --- a/editor/translations/eu.po +++ b/editor/translations/eu.po @@ -1406,7 +1406,7 @@ msgstr "" msgid "Remove Autoload" msgstr "" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "" @@ -2809,7 +2809,11 @@ msgid "Q&A" msgstr "" #: editor/editor_node.cpp -msgid "Issue Tracker" +msgid "Report a Bug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp @@ -3830,7 +3834,7 @@ msgid "Reimport" msgstr "" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -6612,14 +6616,6 @@ msgid "Open Godot online documentation." msgstr "" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7049,6 +7045,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7137,13 +7137,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -10461,6 +10461,12 @@ msgid "Script file already exists." msgstr "" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "" @@ -12074,6 +12080,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/fa.po b/editor/translations/fa.po index caee80995e..f45393c505 100644 --- a/editor/translations/fa.po +++ b/editor/translations/fa.po @@ -10,7 +10,7 @@ # sayyed hamed nasib <cghamed752@chmail.ir>, 2017. # Behrooz Kashani <bkashani@gmail.com>, 2018. # Mahdi <sadisticwarlock@gmail.com>, 2018. -# hpn33 <hamed.hpn332@gmail.com>, 2019. +# hpn33 <hamed.hpn332@gmail.com>, 2019, 2020. # Focus <saeeddashticlash@gmail.com>, 2019. # anonymous <noreply@weblate.org>, 2020. # mohamad por <mohamad24xx@gmail.com>, 2020. @@ -18,8 +18,8 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-03-08 22:33+0000\n" -"Last-Translator: mohamad por <mohamad24xx@gmail.com>\n" +"PO-Revision-Date: 2020-04-09 07:52+0000\n" +"Last-Translator: hpn33 <hamed.hpn332@gmail.com>\n" "Language-Team: Persian <https://hosted.weblate.org/projects/godot-engine/" "godot/fa/>\n" "Language: fa\n" @@ -31,10 +31,9 @@ msgstr "" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp -#, fuzzy msgid "Invalid type argument to convert(), use TYPE_* constants." msgstr "" -"نوع آرگومان برای متد ()convert ‌ نامعتبر است ،‌ از ثابت های *_TYPE‌ Ø§Ø³ØªÙØ§Ø¯Ù‡ " +"نوع ورودی برای متد ()convert ‌ نامعتبر است ،‌ از ثابت های *_TYPE‌ Ø§Ø³ØªÙØ§Ø¯Ù‡ " "کنید ." #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp @@ -1497,7 +1496,7 @@ msgstr "" msgid "Remove Autoload" msgstr "" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "" @@ -2984,7 +2983,12 @@ msgid "Q&A" msgstr "" #: editor/editor_node.cpp -msgid "Issue Tracker" +#, fuzzy +msgid "Report a Bug" +msgstr "وارد کردن دوباره" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp @@ -4071,7 +4075,7 @@ msgid "Reimport" msgstr "وارد کردن دوباره" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -7017,14 +7021,6 @@ msgid "Open Godot online documentation." msgstr "شمارش ها" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7483,6 +7479,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp #, fuzzy msgid "Lock View Rotation" msgstr "بومی‌سازی" @@ -7578,17 +7578,17 @@ msgid "Freelook Slow Modifier" msgstr "غلطاندن به پایین." #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "View Rotation Locked" +msgstr "بومی‌سازی" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy -msgid "View Rotation Locked" -msgstr "بومی‌سازی" - -#: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "" @@ -11119,6 +11119,12 @@ msgid "Script file already exists." msgstr "پیش از این وجود داشته است" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp #, fuzzy msgid "Class Name:" msgstr "کلاس:" @@ -12899,6 +12905,10 @@ msgstr "" "تا بتواند یک اندازه بگیرد. در غیر اینصورت، آن را یک RenderTarget قرار دهید Ùˆ " "Ø¨Ø§ÙØª داخلی آن را برای نمایش به تعدادی گره تخصیص دهید." +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." diff --git a/editor/translations/fi.po b/editor/translations/fi.po index 2798d56d28..74bc461021 100644 --- a/editor/translations/fi.po +++ b/editor/translations/fi.po @@ -1444,7 +1444,7 @@ msgstr "Siirrä automaattisesti ladattavaa" msgid "Remove Autoload" msgstr "Poista automaattinen lataus" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "Ota käyttöön" @@ -2921,8 +2921,13 @@ msgid "Q&A" msgstr "Kysymykset ja vastaukset" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "Ilmoita viasta" +#, fuzzy +msgid "Report a Bug" +msgstr "Tuo uudelleen" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -3976,7 +3981,8 @@ msgid "Reimport" msgstr "Tuo uudelleen" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +#, fuzzy +msgid "Save Scenes, Re-Import, and Restart" msgstr "Tallenna skenet, tuo uudelleen ja käynnistä uudelleen" #: editor/import_dock.cpp @@ -6836,14 +6842,6 @@ msgid "Open Godot online documentation." msgstr "Avaa Godotin online-dokumentaatio." #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "Pyydä dokumentaatiota" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "Auta parantamaan Godotin dokumentaatiota antamalla palautetta." - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "Etsi dokumentaatiosta." @@ -7279,6 +7277,11 @@ msgid "This operation requires a single selected node." msgstr "Tämä toiminto vaatii yhden valitun solmun." #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Auto Orthogonal Enabled" +msgstr "Ortogonaalinen" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "Lukitse näkymän kierto" @@ -7367,6 +7370,10 @@ msgid "Freelook Slow Modifier" msgstr "Liikkumisen hitauskerroin" #: editor/plugins/spatial_editor_plugin.cpp +msgid "View Rotation Locked" +msgstr "Näkymän kierto lukittu" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." @@ -7375,10 +7382,6 @@ msgstr "" "Sitä ei voi käyttää luotettavana pelin sisäisenä tehokkuuden ilmaisimena." #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" -msgstr "Näkymän kierto lukittu" - -#: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "XForm-ikkuna" @@ -10882,6 +10885,12 @@ msgid "Script file already exists." msgstr "Skriptitiedosto on jo olemassa." #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "Luokan nimi:" @@ -12661,6 +12670,10 @@ msgstr "" "saada koon. Muutoin tee siitä RenderTarget ja aseta sen sisäinen tekstuuri " "johonkin solmuun näkyväksi." +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "Virheellinen lähde esikatselulle." @@ -12689,6 +12702,15 @@ msgstr "Varying tyypin voi sijoittaa vain vertex-funktiossa." msgid "Constants cannot be modified." msgstr "Vakioita ei voi muokata." +#~ msgid "Issue Tracker" +#~ msgstr "Ilmoita viasta" + +#~ msgid "Request Docs" +#~ msgstr "Pyydä dokumentaatiota" + +#~ msgid "Help improve the Godot documentation by giving feedback." +#~ msgstr "Auta parantamaan Godotin dokumentaatiota antamalla palautetta." + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "Korvattu %d osuvuutta." diff --git a/editor/translations/fil.po b/editor/translations/fil.po index 60445be723..5a1942fee5 100644 --- a/editor/translations/fil.po +++ b/editor/translations/fil.po @@ -1414,7 +1414,7 @@ msgstr "" msgid "Remove Autoload" msgstr "" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "" @@ -2818,7 +2818,11 @@ msgid "Q&A" msgstr "" #: editor/editor_node.cpp -msgid "Issue Tracker" +msgid "Report a Bug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp @@ -3841,7 +3845,7 @@ msgid "Reimport" msgstr "" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -6628,14 +6632,6 @@ msgid "Open Godot online documentation." msgstr "" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7065,6 +7061,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7153,13 +7153,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -10480,6 +10480,12 @@ msgid "Script file already exists." msgstr "" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "" @@ -12098,6 +12104,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/fr.po b/editor/translations/fr.po index 2c53fcb8e2..0844df8dc7 100644 --- a/editor/translations/fr.po +++ b/editor/translations/fr.po @@ -70,12 +70,14 @@ # Camille Mohr-Daurat <pouleyketchoup@gmail.com>, 2019. # Pierre Stempin <pierre.stempin@gmail.com>, 2019. # Pierre Caye <pierrecaye@laposte.net>, 2020. +# Kevin Bouancheau <kevin.bouancheau@gmail.com>, 2020. +# anonymous <noreply@weblate.org>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-02-27 07:01+0000\n" -"Last-Translator: Pierre Caye <pierrecaye@laposte.net>\n" +"PO-Revision-Date: 2020-04-03 09:09+0000\n" +"Last-Translator: anonymous <noreply@weblate.org>\n" "Language-Team: French <https://hosted.weblate.org/projects/godot-engine/" "godot/fr/>\n" "Language: fr\n" @@ -93,7 +95,7 @@ msgstr "" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp msgid "Expected a string of length 1 (a character)." -msgstr "Attendu chaîne de longueur 1 (un caractère)." +msgstr "Une chaîne de caractères de longueur 1 est attendue (un caractère)." #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/mono/glue/gd_glue.cpp @@ -1518,7 +1520,7 @@ msgstr "Déplacer l'AutoLoad" msgid "Remove Autoload" msgstr "Supprimer l'AutoLoad" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "Activer" @@ -3022,8 +3024,13 @@ msgid "Q&A" msgstr "Questions et réponses" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "Traqueur de problèmes" +#, fuzzy +msgid "Report a Bug" +msgstr "Réimporter" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4085,7 +4092,8 @@ msgid "Reimport" msgstr "Réimporter" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +#, fuzzy +msgid "Save Scenes, Re-Import, and Restart" msgstr "Sauvegarde des scènes, réimportation et redémarrage" #: editor/import_dock.cpp @@ -6966,14 +6974,6 @@ msgid "Open Godot online documentation." msgstr "Ouvrir la documentation de Godot en ligne." #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "Demande de documentation" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "Aider à améliorer la documentation de Godot en donnant vos réactions." - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "Rechercher dans la documentation de référence." @@ -7413,6 +7413,11 @@ msgstr "" "sélectionné." #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Auto Orthogonal Enabled" +msgstr "Orthogonale" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "Verrouiller la rotation de la vue" @@ -7501,6 +7506,10 @@ msgid "Freelook Slow Modifier" msgstr "Modificateur de vitesse de la vue libre" #: editor/plugins/spatial_editor_plugin.cpp +msgid "View Rotation Locked" +msgstr "Verrouiller la rotation de la vue" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." @@ -7510,10 +7519,6 @@ msgstr "" "jeu." #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" -msgstr "Verrouiller la rotation de la vue" - -#: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "Dialogue XForm" @@ -10496,7 +10501,7 @@ msgstr "Valeur par laquelle le compteur est incrémenté pour chaque nÅ“ud" #: editor/rename_dialog.cpp msgid "Padding" -msgstr "Remplissage" +msgstr "Remplissage(Padding)" #: editor/rename_dialog.cpp msgid "" @@ -11034,6 +11039,12 @@ msgid "Script file already exists." msgstr "Le fichier de script existe déjà ." #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "Nom de la classe :" @@ -12543,6 +12554,8 @@ msgstr "" msgid "" "ConcavePolygonShape doesn't support RigidBody in another mode than static." msgstr "" +"ConcavePolygonShape ne supporte pas RigidBody dans un autre mode que le mode " +"statique." #: scene/3d/cpu_particles.cpp msgid "Nothing is visible because no mesh has been assigned." @@ -12851,6 +12864,10 @@ msgstr "" "nÅ“ud de type Control afin qu'il en obtienne une taille. Sinon, faites-en une " "RenderTarget et assignez sa texture à un nÅ“ud pouvant l'afficher." +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "Source invalide pour la prévisualisation." @@ -12879,6 +12896,16 @@ msgstr "Les variations ne peuvent être affectées que dans la fonction vertex." msgid "Constants cannot be modified." msgstr "Les constantes ne peuvent être modifiées." +#~ msgid "Issue Tracker" +#~ msgstr "Traqueur de problèmes" + +#~ msgid "Request Docs" +#~ msgstr "Demande de documentation" + +#~ msgid "Help improve the Godot documentation by giving feedback." +#~ msgstr "" +#~ "Aider à améliorer la documentation de Godot en donnant vos réactions." + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "%d occurrence(s) remplacée(s)." diff --git a/editor/translations/ga.po b/editor/translations/ga.po index e4e77fffc1..d40b50cd90 100644 --- a/editor/translations/ga.po +++ b/editor/translations/ga.po @@ -1408,7 +1408,7 @@ msgstr "" msgid "Remove Autoload" msgstr "" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "" @@ -2812,7 +2812,11 @@ msgid "Q&A" msgstr "" #: editor/editor_node.cpp -msgid "Issue Tracker" +msgid "Report a Bug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp @@ -3836,7 +3840,7 @@ msgid "Reimport" msgstr "" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -6621,14 +6625,6 @@ msgid "Open Godot online documentation." msgstr "" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7058,6 +7054,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7146,13 +7146,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -10476,6 +10476,12 @@ msgid "Script file already exists." msgstr "" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "" @@ -12095,6 +12101,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/he.po b/editor/translations/he.po index 17e04827a0..1a82804b31 100644 --- a/editor/translations/he.po +++ b/editor/translations/he.po @@ -1489,7 +1489,7 @@ msgstr "הזזת ×˜×¢×™× ×” ×וטומטית" msgid "Remove Autoload" msgstr "הסרת ×˜×¢×™× ×” ×וטומטית" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "הפעלה" @@ -2984,8 +2984,13 @@ msgid "Q&A" msgstr "ש×לות ותשובות × ×¤×•×¦×•×ª" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "עוקב תקלות" +#, fuzzy +msgid "Report a Bug" +msgstr "×™×™×‘×•× ×ž×—×“×©" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4065,7 +4070,7 @@ msgid "Reimport" msgstr "×™×™×‘×•× ×ž×—×“×©" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -7009,14 +7014,6 @@ msgid "Open Godot online documentation." msgstr "פתיחת התיעוד המקוון של Godot" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7477,6 +7474,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp #, fuzzy msgid "Lock View Rotation" msgstr "הצגת מידע" @@ -7567,17 +7568,17 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "View Rotation Locked" +msgstr "הצגת מידע" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy -msgid "View Rotation Locked" -msgstr "הצגת מידע" - -#: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "" @@ -11086,6 +11087,12 @@ msgid "Script file already exists." msgstr "הפעולה ‚%s’ כבר קיימת!" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp #, fuzzy msgid "Class Name:" msgstr "מחלקה:" @@ -12757,6 +12764,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." @@ -12788,6 +12799,9 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#~ msgid "Issue Tracker" +#~ msgstr "עוקב תקלות" + #~ msgid "enum " #~ msgstr "×ž×•× ×” " diff --git a/editor/translations/hi.po b/editor/translations/hi.po index d043407257..75f29b8e0b 100644 --- a/editor/translations/hi.po +++ b/editor/translations/hi.po @@ -9,11 +9,14 @@ # Abhay Patel <abhay111patel@gmail.com>, 2019. # Lakshmi-Jayakumar <lakshmi.jayakumar.tkm@gmail.com>, 2019. # Devashishsingh98 <devashishsingh98@gmail.com>, 2019. +# Shirious <sad3119823@gmail.com>, 2020. +# anonymous <noreply@weblate.org>, 2020. +# Abhay Patel <Traumaticbean@protonmail.com>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-01-30 03:56+0000\n" +"PO-Revision-Date: 2020-04-03 09:50+0000\n" "Last-Translator: Suryansh5545 <suryanshpathak5545@gmail.com>\n" "Language-Team: Hindi <https://hosted.weblate.org/projects/godot-engine/godot/" "hi/>\n" @@ -22,7 +25,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 3.11-dev\n" +"X-Generator: Weblate 4.0-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -31,17 +34,17 @@ msgstr "कनà¥à¤µà¤°à¥à¤Ÿ करने के लिठअमानà¥à¤¯ à #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp msgid "Expected a string of length 1 (a character)." -msgstr "लंबाई 1 (à¤à¤• चरितà¥à¤°) की à¤à¤• सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग की उमà¥à¤®à¥€à¤¦ है।" +msgstr "सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग की लंबाई 1 (1 अकà¥à¤·à¤°) अपेकà¥à¤·à¤¿à¤¤ है." #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/mono/glue/gd_glue.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp msgid "Not enough bytes for decoding bytes, or invalid format." -msgstr "डिकोडिंग बाइट, या अमानà¥à¤¯ पà¥à¤°à¤¾à¤°à¥‚प के लिठपरà¥à¤¯à¤¾à¤ªà¥à¤¤ बाइट नहीं।" +msgstr "अमानà¥à¤¯ फ़ोरà¥à¤®à¥ˆà¤Ÿ, या बाइटà¥à¤¸ डिकोडिंग के लिठपरà¥à¤¯à¤¾à¤ªà¥à¤¤ बाइटà¥à¤¸ नहीं।" #: core/math/expression.cpp msgid "Invalid input %i (not passed) in expression" -msgstr "अà¤à¤¿à¤µà¥à¤¯à¤•à¥à¤¤à¤¿ में अमानà¥à¤¯ इनपà¥à¤Ÿ%i (पारित नहीं)" +msgstr "à¤à¤•à¥à¤¸à¤ªà¥à¤°à¥‡à¤¶à¤¨ मे अमानà¥à¤¯ इनपà¥à¤Ÿ %i (पास नहीं हो पाया)" #: core/math/expression.cpp msgid "self can't be used because instance is null (not passed)" @@ -105,7 +108,7 @@ msgstr "संतà¥à¤²à¤¿à¤¤" #: editor/animation_bezier_editor.cpp msgid "Mirror" -msgstr "दरà¥à¤ªà¤£" +msgstr "आइना" #: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp msgid "Time:" @@ -666,7 +669,7 @@ msgstr "ऑडियो टà¥à¤°à¥ˆà¤• कà¥à¤²à¤¿à¤ª à¤à¤‚ड ऑफसेठ#: editor/array_property_edit.cpp msgid "Resize Array" -msgstr "रीसाइज रीवà¥à¤¯à¥‚" +msgstr "Array को बड़ा या छोटा करना" #: editor/array_property_edit.cpp msgid "Change Array Value Type" @@ -682,24 +685,23 @@ msgstr "लाइन पर जाà¤à¤‚" #: editor/code_editor.cpp msgid "Line Number:" -msgstr "लाइन नंबर:" +msgstr "लाइन कà¥à¤°.:" #: editor/code_editor.cpp -#, fuzzy msgid "%d replaced." -msgstr "बदलने के" +msgstr "%d बदले." #: editor/code_editor.cpp editor/editor_help.cpp msgid "%d match." -msgstr "% d मैच।" +msgstr "% d मिल गया।" #: editor/code_editor.cpp editor/editor_help.cpp msgid "%d matches." -msgstr "% डी मैच।" +msgstr "%d मिल गया।" #: editor/code_editor.cpp editor/find_in_files.cpp msgid "Match Case" -msgstr "मैच मामला" +msgstr "पूंजीकरण मेल करे" #: editor/code_editor.cpp editor/find_in_files.cpp msgid "Whole Words" @@ -707,7 +709,7 @@ msgstr "पूरे शबà¥à¤¦" #: editor/code_editor.cpp editor/rename_dialog.cpp msgid "Replace" -msgstr "बदलने के" +msgstr "बदले" #: editor/code_editor.cpp msgid "Replace All" @@ -715,7 +717,7 @@ msgstr "सबको बदली करें" #: editor/code_editor.cpp msgid "Selection Only" -msgstr "केवल चयन" +msgstr "सिरà¥à¤« चयन किये हà¥à¤" #: editor/code_editor.cpp editor/plugins/script_text_editor.cpp #: editor/plugins/text_editor.cpp @@ -748,40 +750,39 @@ msgstr "चेतावनियाà¤" #: editor/code_editor.cpp msgid "Line and column numbers." -msgstr "लाइन और कॉलम नंबर।" +msgstr "पंकà¥à¤¤à¤¿ और क़तार कà¥à¤°.।" #: editor/connections_dialog.cpp msgid "Method in target node must be specified." -msgstr "लकà¥à¤·à¥à¤¯ नोड में विधि निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ की जानी चाहिà¤à¥¤" +msgstr "Method को target node में निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ कीजिà¤." #: editor/connections_dialog.cpp msgid "" "Target method not found. Specify a valid method or attach a script to the " "target node." -msgstr "" -"लकà¥à¤·à¥à¤¯ विधि नहीं मिली। à¤à¤• मानà¥à¤¯ विधि निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ करें या सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ को लकà¥à¤·à¥à¤¯ नोड में संलगà¥à¤¨ करें।" +msgstr "target node नहीं मिला। method उलà¥à¤²à¤¿à¤–ित करें या script जोड़िये।" #: editor/connections_dialog.cpp msgid "Connect to Node:" -msgstr "नोड से कनेकà¥à¤Ÿ करें:" +msgstr "Node से कनेकà¥à¤Ÿ करें:" #: editor/connections_dialog.cpp msgid "Connect to Script:" -msgstr "सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ से कनेकà¥à¤Ÿ:" +msgstr "Script से कनेकà¥à¤Ÿ:" #: editor/connections_dialog.cpp msgid "From Signal:" -msgstr "सिगà¥à¤¨à¤² से:" +msgstr "Signal से:" #: editor/connections_dialog.cpp msgid "Scene does not contain any script." -msgstr "सीन में कोई सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ नहीं होती।" +msgstr "Scene में कोई script नहीं पाई गयी।" #: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp #: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp #: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp msgid "Add" -msgstr "जोड़ें" +msgstr "जोड़िये" #: editor/connections_dialog.cpp editor/dependency_editor.cpp #: editor/editor_feature_profile.cpp editor/groups_editor.cpp @@ -792,23 +793,23 @@ msgstr "जोड़ें" #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" -msgstr "मिटाना" +msgstr "मिटाइये" #: editor/connections_dialog.cpp msgid "Add Extra Call Argument:" -msgstr "अतिरिकà¥à¤¤ कॉल तरà¥à¤• जोड़ें:" +msgstr "अतिरिकà¥à¤¤ Call Argument अपेकà¥à¤·à¤¿à¤¤ है:" #: editor/connections_dialog.cpp msgid "Extra Call Arguments:" -msgstr "अतिरिकà¥à¤¤ कॉल तरà¥à¤•:" +msgstr "अतिरिकà¥à¤¤ Call Arguments:" #: editor/connections_dialog.cpp msgid "Receiver Method:" -msgstr "रिसीवर विधि:" +msgstr "पानेवाली Method:" #: editor/connections_dialog.cpp msgid "Advanced" -msgstr "उनà¥à¤¨à¤¤" +msgstr "अगà¥à¤°à¤µà¤°à¥à¤¤à¥€" #: editor/connections_dialog.cpp msgid "Deferred" @@ -818,20 +819,20 @@ msgstr "सà¥à¤¥à¤—ित" msgid "" "Defers the signal, storing it in a queue and only firing it at idle time." msgstr "" -"संकेत को सà¥à¤¥à¤—ित कर देता है, इसे à¤à¤• कतार में संगà¥à¤°à¤¹à¤¿à¤¤ करता है और केवल निषà¥à¤•à¥à¤°à¤¿à¤¯ समय पर इसे " +"इशारा को सà¥à¤¥à¤—ित कर देता है, इसे à¤à¤• कतार में संगà¥à¤°à¤¹à¤¿à¤¤ करता है और केवल निषà¥à¤•à¥à¤°à¤¿à¤¯ समय पर इसे " "फायरिंग करता है।" #: editor/connections_dialog.cpp msgid "Oneshot" -msgstr "वनशॉट" +msgstr "à¤à¤• बार" #: editor/connections_dialog.cpp msgid "Disconnects the signal after its first emission." -msgstr "अपने पहले उतà¥à¤¸à¤°à¥à¤œà¤¨ के बाद संकेत डिसà¥à¤•नेकà¥à¤Ÿ करता है।" +msgstr "इसके पहले उतà¥à¤¸à¤°à¥à¤œà¤¨ के बाद सिगà¥à¤¨à¤² को डिसà¥à¤•नेकà¥à¤Ÿ करें" #: editor/connections_dialog.cpp msgid "Cannot connect signal" -msgstr "सिगà¥à¤¨à¤² कनेकà¥à¤Ÿ नहीं कर सकते" +msgstr "इशारा कनेकà¥à¤Ÿ नहीं कर सकते" #: editor/connections_dialog.cpp editor/dependency_editor.cpp #: editor/export_template_manager.cpp editor/groups_editor.cpp @@ -850,11 +851,11 @@ msgstr "बंद करे" #: editor/connections_dialog.cpp msgid "Connect" -msgstr "जोड़ना" +msgstr "जोड़िये" #: editor/connections_dialog.cpp msgid "Signal:" -msgstr "संकेत:" +msgstr "इशारा:" #: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" @@ -862,11 +863,11 @@ msgstr "'%' को '%' से कनेकà¥à¤Ÿ करें" #: editor/connections_dialog.cpp msgid "Disconnect '%s' from '%s'" -msgstr "'%' से डिसà¥à¤•नेकà¥à¤Ÿ करें '%'" +msgstr "'%' से '%' को डिसà¥à¤•नेकà¥à¤Ÿ करें" #: editor/connections_dialog.cpp msgid "Disconnect all from signal: '%s'" -msgstr "सà¤à¥€ को सिगà¥à¤¨à¤² से डिसà¥à¤•नेकà¥à¤Ÿ करें: '%s'" +msgstr "सà¤à¥€ इशारो से डिसà¥à¤•नेकà¥à¤Ÿ करें: '%s'" #: editor/connections_dialog.cpp msgid "Connect..." @@ -875,15 +876,15 @@ msgstr "जोड़ना..." #: editor/connections_dialog.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Disconnect" -msgstr "डिसà¥à¤•नेकà¥à¤Ÿ" +msgstr "विलगन" #: editor/connections_dialog.cpp msgid "Connect a Signal to a Method" -msgstr "à¤à¤• विधि के लिठà¤à¤• संकेत कनेकà¥à¤Ÿ" +msgstr "method इशारे से जोड़िà¤" #: editor/connections_dialog.cpp msgid "Edit Connection:" -msgstr "संपादित करें कनेकà¥à¤¶à¤¨:" +msgstr "कनेकà¥à¤¶à¤¨ संपादित करें:" #: editor/connections_dialog.cpp msgid "Are you sure you want to remove all connections from the \"%s\" signal?" @@ -903,19 +904,19 @@ msgstr "सà¤à¥€ को डिसà¥à¤•नेकà¥à¤Ÿ करें" #: editor/connections_dialog.cpp msgid "Edit..." -msgstr "संपादित..." +msgstr "संपादित करें..." #: editor/connections_dialog.cpp msgid "Go To Method" -msgstr "" +msgstr "मेथड पे जाये" #: editor/create_dialog.cpp msgid "Change %s Type" -msgstr "" +msgstr "%s का टाइप बदले" #: editor/create_dialog.cpp editor/project_settings_editor.cpp msgid "Change" -msgstr "परिवरà¥à¤¤à¤¨" +msgstr "बदली" #: editor/create_dialog.cpp msgid "Create New %s" @@ -1196,11 +1197,11 @@ msgstr "असंपीड़ित संपतà¥à¤¤à¤¿à¤¯à¤¾à¤‚" #: editor/editor_asset_installer.cpp editor/project_manager.cpp msgid "The following files failed extraction from package:" -msgstr "" +msgstr "निमà¥à¤¨ फ़ाइलों का निसà¥à¤¸à¤¾à¤°à¤£ नहीं हो पाया:" #: editor/editor_asset_installer.cpp msgid "And %s more files." -msgstr "" +msgstr "और %s फ़ाइलें." #: editor/editor_asset_installer.cpp editor/project_manager.cpp msgid "Package installed successfully!" @@ -1213,7 +1214,7 @@ msgstr "सफलता!" #: editor/editor_asset_installer.cpp msgid "Package Contents:" -msgstr "पैकेज सामगà¥à¤°à¥€:" +msgstr "पैकेज में है:" #: editor/editor_asset_installer.cpp editor/editor_node.cpp msgid "Install" @@ -1273,7 +1274,7 @@ msgstr "पà¥à¤¨à¤°à¥à¤µà¥à¤¯à¤µà¤¸à¥à¤¥à¤¿à¤¤ करने के लिठ#: editor/editor_audio_buses.cpp msgid "Solo" -msgstr "à¤à¤•ल" +msgstr "सोलो" #: editor/editor_audio_buses.cpp msgid "Mute" @@ -1298,7 +1299,7 @@ msgstr "वॉलà¥à¤¯à¥‚म रीसेट करें" #: editor/editor_audio_buses.cpp msgid "Delete Effect" -msgstr "डिलीट इफेकà¥à¤Ÿ" +msgstr "इफेकà¥à¤Ÿ मिटाइये" #: editor/editor_audio_buses.cpp msgid "Audio" @@ -1306,31 +1307,31 @@ msgstr "ऑडियो" #: editor/editor_audio_buses.cpp msgid "Add Audio Bus" -msgstr "" +msgstr "ऑडियो बस à¤à¤¡ कीजिà¤" #: editor/editor_audio_buses.cpp msgid "Master bus can't be deleted!" -msgstr "" +msgstr "मासà¥à¤Ÿà¤° बस नहीं मिटा सकते!" #: editor/editor_audio_buses.cpp msgid "Delete Audio Bus" -msgstr "" +msgstr "ऑडियो बस मिटाइये" #: editor/editor_audio_buses.cpp msgid "Duplicate Audio Bus" -msgstr "" +msgstr "ऑडियो बस दà¥à¤—à¥à¤¨à¤¾ करे" #: editor/editor_audio_buses.cpp msgid "Reset Bus Volume" -msgstr "" +msgstr "बस की धà¥à¤µà¤¨à¤¿ मातà¥à¤°à¤¾ पूरà¥à¤µà¤°à¥‚प करे" #: editor/editor_audio_buses.cpp msgid "Move Audio Bus" -msgstr "" +msgstr "ऑडियो बस हटाइये" #: editor/editor_audio_buses.cpp msgid "Save Audio Bus Layout As..." -msgstr "" +msgstr "ऑडियो बस लेआउट इस तरह बचा के रखिये..." #: editor/editor_audio_buses.cpp msgid "Location for New Layout..." @@ -1338,113 +1339,113 @@ msgstr "नठलेआउट के लिठसà¥à¤¥à¤¾à¤¨..." #: editor/editor_audio_buses.cpp msgid "Open Audio Bus Layout" -msgstr "" +msgstr "ऑडियो बस लेआउट खोलिये" #: editor/editor_audio_buses.cpp msgid "There is no '%s' file." -msgstr "" +msgstr "कोई '%s' फ़ाइल नहीं." #: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp msgid "Layout" -msgstr "" +msgstr "लेआउट" #: editor/editor_audio_buses.cpp msgid "Invalid file, not an audio bus layout." -msgstr "" +msgstr "अमानà¥à¤¯ फ़ाइल, ऑडियो बस लेआउट." #: editor/editor_audio_buses.cpp msgid "Error saving file: %s" -msgstr "तà¥à¤°à¥à¤Ÿà¤¿ बचत फ़ाइल: %s" +msgstr "फ़ाइल बचाने में चूक: %s" #: editor/editor_audio_buses.cpp msgid "Add Bus" -msgstr "" +msgstr "बस à¤à¤¡ कीजिà¤" #: editor/editor_audio_buses.cpp msgid "Add a new Audio Bus to this layout." -msgstr "" +msgstr "लेआउट में नई ऑडियो बस à¤à¤¡ कीजिà¤." #: editor/editor_audio_buses.cpp editor/editor_properties.cpp #: editor/plugins/animation_player_editor_plugin.cpp editor/property_editor.cpp #: editor/script_create_dialog.cpp msgid "Load" -msgstr "" +msgstr "लोड कीजिये" #: editor/editor_audio_buses.cpp msgid "Load an existing Bus Layout." -msgstr "" +msgstr "मौजूदा बस लेआउट लोड कीजिये." #: editor/editor_audio_buses.cpp msgid "Save As" -msgstr "" +msgstr "इस तरह बचा के रखिये" #: editor/editor_audio_buses.cpp msgid "Save this Bus Layout to a file." -msgstr "" +msgstr "बस लेआउट को फ़ाइल में बचा के रखिये." #: editor/editor_audio_buses.cpp editor/import_dock.cpp msgid "Load Default" -msgstr "" +msgstr "पà¥à¤°à¤¾à¤¯à¤¿à¤• लोड कीजिये" #: editor/editor_audio_buses.cpp msgid "Load the default Bus Layout." -msgstr "" +msgstr "पà¥à¤°à¤¾à¤¯à¤¿à¤• बस लेआउट लोड कीजिये." #: editor/editor_audio_buses.cpp msgid "Create a new Bus Layout." -msgstr "" +msgstr "नई बस लेआउट बनाइये." #: editor/editor_autoload_settings.cpp msgid "Invalid name." -msgstr "" +msgstr "अमानà¥à¤¯ नाम." #: editor/editor_autoload_settings.cpp msgid "Valid characters:" -msgstr "" +msgstr "मानà¥à¤¯ अकà¥à¤·à¤°:" #: editor/editor_autoload_settings.cpp msgid "Must not collide with an existing engine class name." -msgstr "" +msgstr "मौजूदा कà¥à¤²à¤¾à¤¸ इंजन नाम से मेल नहीं खाना चाहिà¤." #: editor/editor_autoload_settings.cpp msgid "Must not collide with an existing built-in type name." -msgstr "" +msgstr "मौजूदा बिलà¥à¤Ÿ-इन टाइप के नाम से मेल नहीं खाना चाहिà¤." #: editor/editor_autoload_settings.cpp msgid "Must not collide with an existing global constant name." -msgstr "" +msgstr "मौजूदा गà¥à¤²à¥‹à¤¬à¤² कोनà¥à¤¸à¥à¤Ÿà¤¨à¥à¤Ÿ के नाम से मेल नहीं खाना चाहिà¤." #: editor/editor_autoload_settings.cpp msgid "Keyword cannot be used as an autoload name." -msgstr "" +msgstr "कीवरà¥à¤¡ को औटोलोड नाम के तरह नहीं इसà¥à¤¤à¥‡à¤®à¤¾à¤² कर सकते." #: editor/editor_autoload_settings.cpp msgid "Autoload '%s' already exists!" -msgstr "" +msgstr "औटोलोड '%s' पहले से मौजूद!" #: editor/editor_autoload_settings.cpp msgid "Rename Autoload" -msgstr "" +msgstr "औटोलोड का नाम बदली कीजिये" #: editor/editor_autoload_settings.cpp msgid "Toggle AutoLoad Globals" -msgstr "" +msgstr "औटोलोड गà¥à¤²à¥‹à¤¬à¤² टॉगल कीजिये" #: editor/editor_autoload_settings.cpp msgid "Move Autoload" -msgstr "" +msgstr "औटोलोड हिलाइये" #: editor/editor_autoload_settings.cpp msgid "Remove Autoload" -msgstr "" +msgstr "औटोलोड हटा दीजिये" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" -msgstr "" +msgstr "सकà¥à¤°à¤¿à¤¯ करे" #: editor/editor_autoload_settings.cpp msgid "Rearrange Autoloads" -msgstr "" +msgstr "औटोलोड पà¥à¤¨à¤°à¥à¤µà¥à¤¯à¤µà¤¸à¥à¤¥à¤¿à¤¤ करें" #: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp msgid "Invalid path." @@ -1452,114 +1453,118 @@ msgstr "अमानà¥à¤¯ रासà¥à¤¤à¤¾à¥¤" #: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp msgid "File does not exist." -msgstr "" +msgstr "फ़ाइल नहीं मौजूद." #: editor/editor_autoload_settings.cpp msgid "Not in resource path." -msgstr "" +msgstr "रेसोरà¥à¤¸ पाथ में नहीं." #: editor/editor_autoload_settings.cpp msgid "Add AutoLoad" -msgstr "" +msgstr "औटोलोड à¤à¤¡ कीजिà¤" #: editor/editor_autoload_settings.cpp editor/editor_file_dialog.cpp #: editor/editor_plugin_settings.cpp #: editor/plugins/animation_tree_editor_plugin.cpp #: editor/script_create_dialog.cpp scene/gui/file_dialog.cpp msgid "Path:" -msgstr "" +msgstr "पाथ:" #: editor/editor_autoload_settings.cpp msgid "Node Name:" -msgstr "" +msgstr "नोड का नाम:" #: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp #: editor/editor_profiler.cpp editor/project_manager.cpp #: editor/settings_config_dialog.cpp msgid "Name" -msgstr "" +msgstr "नाम" #: editor/editor_autoload_settings.cpp msgid "Singleton" -msgstr "" +msgstr "सिनà¥à¤—लटन" #: editor/editor_data.cpp editor/inspector_dock.cpp msgid "Paste Params" -msgstr "" +msgstr "पैरैमिटरà¥à¤¸ पेसà¥à¤Ÿ कीजिये" #: editor/editor_data.cpp msgid "Updating Scene" -msgstr "" +msgstr "सीन अपडेट कर रहा है" #: editor/editor_data.cpp msgid "Storing local changes..." -msgstr "" +msgstr "लोकल बदलीया सà¥à¤Ÿà¥‹à¤° कर रहा है..." #: editor/editor_data.cpp msgid "Updating scene..." -msgstr "" +msgstr "सीन अपडेट कर रहा है..." #: editor/editor_data.cpp editor/editor_properties.cpp msgid "[empty]" -msgstr "" +msgstr "[खाली]" #: editor/editor_data.cpp msgid "[unsaved]" -msgstr "" +msgstr "[अनसेवà¥à¤¡]" #: editor/editor_dir_dialog.cpp msgid "Please select a base directory first." -msgstr "" +msgstr "कृपया पहले बेस डायरेकà¥à¤Ÿà¤°à¥€ सिलेकà¥à¤Ÿ कीजिये." #: editor/editor_dir_dialog.cpp msgid "Choose a Directory" -msgstr "" +msgstr "डायरेकà¥à¤Ÿà¤°à¥€ चà¥à¤¨à¥‡à¤‚" #: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp #: editor/filesystem_dock.cpp editor/project_manager.cpp #: scene/gui/file_dialog.cpp msgid "Create Folder" -msgstr "" +msgstr "फ़ोलà¥à¤¡à¤° बनाइये" #: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp #: editor/editor_plugin_settings.cpp editor/filesystem_dock.cpp #: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp #: modules/visual_script/visual_script_editor.cpp scene/gui/file_dialog.cpp msgid "Name:" -msgstr "" +msgstr "नाम:" #: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp #: editor/filesystem_dock.cpp scene/gui/file_dialog.cpp msgid "Could not create folder." -msgstr "" +msgstr "फ़ोलà¥à¤¡à¤° नही बना सकते." #: editor/editor_dir_dialog.cpp msgid "Choose" -msgstr "" +msgstr "चà¥à¤¨à¥‡à¤‚" #: editor/editor_export.cpp msgid "Storing File:" -msgstr "" +msgstr "फ़ाइल सà¥à¤Ÿà¥‹à¤° कर रहा है:" #: editor/editor_export.cpp msgid "No export template found at the expected path:" -msgstr "" +msgstr "निशà¥à¤šà¤¿à¤¤ पाथ पर â€à¤à¤•à¥à¤¸à¤ªà¥‹à¤°à¥à¤Ÿ टेमà¥à¤ªà¥à¤²à¥‡à¤Ÿ नहीं मिला:" #: editor/editor_export.cpp msgid "Packing" -msgstr "" +msgstr "पैक कर रहा है" #: editor/editor_export.cpp msgid "" "Target platform requires 'ETC' texture compression for GLES2. Enable 'Import " "Etc' in Project Settings." msgstr "" +"GLES2 के लिये टारà¥à¤—ेट पà¥à¤²à¥à¤Ÿà¥ˆà¥žà¥‹à¤°à¥à¤® को 'ETC' टेâ€à¤•à¥à¤¸à¤šà¤° कोमà¥à¤ªà¥à¤°à¥‡à¤¶à¤¨ की आवशà¥à¤¯à¤•ता है. 'Import Etc' " +"को पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ सेटिनà¥à¤—स मे सकà¥à¤°à¤¿à¤¯ करे." #: editor/editor_export.cpp msgid "" "Target platform requires 'ETC2' texture compression for GLES3. Enable " "'Import Etc 2' in Project Settings." msgstr "" +"GLES3 के लिये टारà¥à¤—ेट पà¥à¤²à¥à¤Ÿà¥ˆà¥žà¥‹à¤°à¥à¤® को 'ETC2' टेâ€à¤•à¥à¤¸à¤šà¤° कोमà¥à¤ªà¥à¤°à¥‡à¤¶à¤¨ की आवशà¥à¤¯à¤•ता है. 'Import Etc " +"2' को पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ सेटिनà¥à¤—स मे सकà¥à¤°à¤¿à¤¯ करे." #: editor/editor_export.cpp msgid "" @@ -1568,364 +1573,361 @@ msgid "" "Enable 'Import Etc' in Project Settings, or disable 'Driver Fallback " "Enabled'." msgstr "" +"GLES2 के लिये टारà¥à¤—ेट पà¥à¤²à¥à¤Ÿà¥ˆà¥žà¥‹à¤°à¥à¤® को 'ETC' टेâ€à¤•à¥à¤¸à¤šà¤° कोमà¥à¤ªà¥à¤°à¥‡à¤¶à¤¨ की आवशà¥à¤¯à¤•ता है. \n" +"'Import Etc' को पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ सेटिनà¥à¤—स मे सकà¥à¤°à¤¿à¤¯ करे, या 'Driver Fallback Enabled' को " +"निषà¥à¤•à¥à¤°à¤¿à¤¯ करे." #: editor/editor_export.cpp platform/android/export/export.cpp #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp #: platform/osx/export/export.cpp platform/uwp/export/export.cpp msgid "Custom debug template not found." -msgstr "" +msgstr "कसà¥à¤Ÿà¤® डिबग टेमà¥à¤ªà¥à¤²à¥‡à¤Ÿ नहीं मिला." #: editor/editor_export.cpp platform/android/export/export.cpp #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp #: platform/osx/export/export.cpp platform/uwp/export/export.cpp msgid "Custom release template not found." -msgstr "" +msgstr "कसà¥à¤Ÿà¤® रिलिज टेमà¥à¤ªà¥à¤²à¥‡à¤Ÿ नहीं मिला." #: editor/editor_export.cpp platform/javascript/export/export.cpp msgid "Template file not found:" -msgstr "" +msgstr "टेमà¥à¤ªà¥à¤²à¥‡à¤Ÿ फ़ाइल नहीं मिला:" #: editor/editor_export.cpp msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." -msgstr "" +msgstr "32-बिट â€à¤à¤•à¥à¤¸à¤ªà¥‹à¤°à¥à¤Ÿ पर à¤à¤®à¤¬à¥‡à¤¡à¥à¤¡à¥‡à¤¡ PCK 4 GiB से बड़ी नहीं इसà¥à¤¤à¥‡à¤®à¤¾à¤² कर सकते." #: editor/editor_feature_profile.cpp msgid "3D Editor" msgstr "3D संपादक" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Script Editor" -msgstr "निरà¥à¤à¤°à¤¤à¤¾ संपादक" +msgstr "सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ à¤à¤¡à¥€à¤Ÿà¤°" #: editor/editor_feature_profile.cpp msgid "Asset Library" -msgstr "" +msgstr "असà¥à¤¸à¥‡à¤Ÿ संगà¥à¤°à¤¹" #: editor/editor_feature_profile.cpp msgid "Scene Tree Editing" -msgstr "" +msgstr "सीन टà¥à¤°à¥€ à¤à¤¡à¤¿à¤Ÿà¤¿à¤‚ग" #: editor/editor_feature_profile.cpp msgid "Import Dock" -msgstr "" +msgstr "इंपोरà¥à¤Ÿ डॉक" #: editor/editor_feature_profile.cpp msgid "Node Dock" -msgstr "" +msgstr "नोड डॉक" #: editor/editor_feature_profile.cpp msgid "FileSystem and Import Docks" -msgstr "" +msgstr "फाइलसिसà¥à¤Ÿà¥‡à¤® और इंपोरà¥à¤Ÿ डोकà¥à¤¸" #: editor/editor_feature_profile.cpp msgid "Erase profile '%s'? (no undo)" -msgstr "" +msgstr "पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤² '%s' को मिटाà¤à¤‚? (इसे अंडू नहीं किया जा सकता है)" #: editor/editor_feature_profile.cpp msgid "Profile must be a valid filename and must not contain '.'" -msgstr "" +msgstr "पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤² का à¤à¤• वैध फ़ाइलनेम होना चाहिठऔर उसमे '.' नहीं होना चाहिà¤" #: editor/editor_feature_profile.cpp msgid "Profile with this name already exists." -msgstr "" +msgstr "इस नाम का पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤² पहले से मौजूद है।" #: editor/editor_feature_profile.cpp msgid "(Editor Disabled, Properties Disabled)" -msgstr "" +msgstr "(à¤à¤¡à¥€à¤Ÿà¤° निषà¥à¤•à¥à¤°à¤¿à¤¯,पà¥à¤°à¥‹à¤ªà¤°à¤Ÿà¤¿à¤œ निषà¥à¤•à¥à¤°à¤¿à¤¯)" #: editor/editor_feature_profile.cpp msgid "(Properties Disabled)" -msgstr "" +msgstr "(पà¥à¤°à¥‹à¤ªà¤°à¤Ÿà¤¿à¤œ निषà¥à¤•à¥à¤°à¤¿à¤¯)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Editor Disabled)" -msgstr "बंद कर दिया गया है" +msgstr "(à¤à¤¡à¥€à¤Ÿà¤° निषà¥à¤•à¥à¤°à¤¿à¤¯)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options:" -msgstr "विवरण:" +msgstr "कà¥à¤²à¤¾à¤¸ विकलà¥à¤ª:" #: editor/editor_feature_profile.cpp msgid "Enable Contextual Editor" -msgstr "" +msgstr "कोनà¥à¤Ÿà¥‡à¤•à¥à¤¸à¤šà¥à¤…ल à¤à¤¡à¥€à¤Ÿà¤° सकà¥à¤°à¤¿à¤¯ करे" #: editor/editor_feature_profile.cpp msgid "Enabled Properties:" -msgstr "" +msgstr "सकà¥à¤°à¤¿à¤¯ पà¥à¤°à¥‹à¤ªà¤°à¤Ÿà¤¿à¤œ:" #: editor/editor_feature_profile.cpp msgid "Enabled Features:" -msgstr "" +msgstr "सकà¥à¤°à¤¿à¤¯ फ़िचरà¥à¤¸:" #: editor/editor_feature_profile.cpp msgid "Enabled Classes:" -msgstr "" +msgstr "सकà¥à¤°à¤¿à¤¯ कà¥à¤²à¤¾à¤¸:" #: editor/editor_feature_profile.cpp msgid "File '%s' format is invalid, import aborted." -msgstr "" +msgstr "'%s' फ़ोरà¥à¤®à¥ˆà¤Ÿ की फ़ाइल अमानà¥à¤¯, इंपोरà¥à¤Ÿ रोका गया." #: editor/editor_feature_profile.cpp msgid "" "Profile '%s' already exists. Remove it first before importing, import " "aborted." -msgstr "" +msgstr "'%s' पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤² पहले से मौजूद. इंपोरà¥à¤Ÿ से पहले हटा दीजिये, इंपोरà¥à¤Ÿ रोका गया." #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Error saving profile to path: '%s'." -msgstr "लोड हो रहा है तà¥à¤°à¥à¤Ÿà¤¿à¤¯à¤¾à¤!" +msgstr "पाथ मे पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤² सेव करनेमे à¤à¤°à¤°: '%s'." #: editor/editor_feature_profile.cpp msgid "Unset" -msgstr "" +msgstr "अनà¥à¤¸à¥‡à¤Ÿ" #: editor/editor_feature_profile.cpp msgid "Current Profile:" -msgstr "" +msgstr "वरà¥à¤¤à¤®à¤¾à¤¨ पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤²:" #: editor/editor_feature_profile.cpp msgid "Make Current" -msgstr "" +msgstr "वरà¥à¤¤à¤®à¤¾à¤¨ बनाय" #: editor/editor_feature_profile.cpp #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/version_control_editor_plugin.cpp msgid "New" -msgstr "" +msgstr "नई" #: editor/editor_feature_profile.cpp editor/editor_node.cpp #: editor/project_manager.cpp msgid "Import" -msgstr "" +msgstr "इंपोरà¥à¤Ÿ" #: editor/editor_feature_profile.cpp editor/project_export.cpp msgid "Export" -msgstr "" +msgstr "â€à¤à¤•à¥à¤¸à¤ªà¥‹à¤°à¥à¤Ÿ" #: editor/editor_feature_profile.cpp msgid "Available Profiles:" -msgstr "" +msgstr "उपलबà¥à¤§ पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤²:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" -msgstr "विवरण:" +msgstr "कà¥à¤²à¤¾à¤¸ विकलà¥à¤ª" #: editor/editor_feature_profile.cpp msgid "New profile name:" -msgstr "" +msgstr "नया पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤² नाम:" #: editor/editor_feature_profile.cpp msgid "Erase Profile" -msgstr "" +msgstr "पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤² मिटाय" #: editor/editor_feature_profile.cpp msgid "Godot Feature Profile" -msgstr "" +msgstr "Godot फ़िचर पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤²" #: editor/editor_feature_profile.cpp msgid "Import Profile(s)" -msgstr "" +msgstr "इंपोरà¥à¤Ÿ पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤²" #: editor/editor_feature_profile.cpp msgid "Export Profile" -msgstr "" +msgstr "â€à¤à¤•à¥à¤¸à¤ªà¥‹à¤°à¥à¤Ÿ पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤²" #: editor/editor_feature_profile.cpp msgid "Manage Editor Feature Profiles" -msgstr "" +msgstr "à¤à¤¡à¥€à¤Ÿà¤° फ़िचर पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤² वà¥à¤¯à¤µà¤¸à¥à¤¥à¤¾ कीजिये" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Select Current Folder" -msgstr "" +msgstr "वरà¥à¤¤à¤®à¤¾à¤¨ फ़ोलà¥à¤¡à¤° सिलेकà¥à¤Ÿ कीजिये" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "File Exists, Overwrite?" -msgstr "" +msgstr "फ़ाइल पहले से मौजूद, मौजूदा के ऊपर लिखे?" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Select This Folder" -msgstr "" +msgstr "यह फ़ोलà¥à¤¡à¤° सिलेकà¥à¤Ÿ कीजिये" #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "Copy Path" -msgstr "" +msgstr "पाथ कौपी कीजिये" #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp -#, fuzzy msgid "Open in File Manager" -msgstr "खोलो इसे" +msgstr "फ़ाइल मैनेजर में खोलिये" #: editor/editor_file_dialog.cpp editor/editor_node.cpp #: editor/filesystem_dock.cpp editor/project_manager.cpp msgid "Show in File Manager" -msgstr "" +msgstr "फ़ाइल मैनेजर मे दिखाइà¤" #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "New Folder..." -msgstr "" +msgstr "नया फ़ोलà¥à¤¡à¤°..." #: editor/editor_file_dialog.cpp editor/find_in_files.cpp #: editor/plugins/version_control_editor_plugin.cpp msgid "Refresh" -msgstr "" +msgstr "रिफ़à¥à¤°à¥‡à¤¶" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "All Recognized" -msgstr "" +msgstr "सà¤à¥€ सà¥à¤µà¥€à¤•ृत" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "All Files (*)" -msgstr "" +msgstr "सà¤à¥€ फ़ाइल (*)" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Open a File" -msgstr "" +msgstr "फ़ाइल खोलिये" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Open File(s)" -msgstr "" +msgstr "फ़ाइल(s) खोलिये" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Open a Directory" -msgstr "" +msgstr "डायरेकà¥à¤Ÿà¤°à¥€ खोलिये" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Open a File or Directory" -msgstr "" +msgstr "फ़ाइल या डायरेकà¥à¤Ÿà¤°à¥€ खोलिये" #: editor/editor_file_dialog.cpp editor/editor_node.cpp #: editor/editor_properties.cpp editor/inspector_dock.cpp #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp scene/gui/file_dialog.cpp msgid "Save" -msgstr "" +msgstr "सेव कीजिये" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Save a File" -msgstr "" +msgstr "फ़ाइल सेव कीजिये" #: editor/editor_file_dialog.cpp msgid "Go Back" -msgstr "" +msgstr "पीछे जाय" #: editor/editor_file_dialog.cpp msgid "Go Forward" -msgstr "" +msgstr "आगे जाय" #: editor/editor_file_dialog.cpp msgid "Go Up" -msgstr "" +msgstr "ऊपर जाय" #: editor/editor_file_dialog.cpp msgid "Toggle Hidden Files" -msgstr "" +msgstr "छिपी फ़ाइले टॉगल कीजिये" #: editor/editor_file_dialog.cpp msgid "Toggle Favorite" -msgstr "" +msgstr "फ़ेवरेट टॉगल कीजिये" #: editor/editor_file_dialog.cpp msgid "Toggle Mode" -msgstr "" +msgstr "मोड टॉगल कीजिये" #: editor/editor_file_dialog.cpp msgid "Focus Path" -msgstr "" +msgstr "फ़ोकस पाथ" #: editor/editor_file_dialog.cpp msgid "Move Favorite Up" -msgstr "" +msgstr "फ़ेवरेट उपर लीजिये" #: editor/editor_file_dialog.cpp msgid "Move Favorite Down" -msgstr "" +msgstr "फ़ेवरेट नीचे लीजिये" #: editor/editor_file_dialog.cpp msgid "Go to previous folder." -msgstr "" +msgstr "पिछले फ़ोलà¥à¤¡à¤° पे जाय." #: editor/editor_file_dialog.cpp msgid "Go to next folder." -msgstr "" +msgstr "अगले फ़ोलà¥à¤¡à¤° पे जाय." #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Go to parent folder." -msgstr "" +msgstr "मूल फ़ोलà¥à¤¡à¤° पे जाय." #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -#, fuzzy msgid "Refresh files." -msgstr "खोज कर:" +msgstr "रिफ़à¥à¤°à¥‡à¤¶ फ़ाइल." #: editor/editor_file_dialog.cpp msgid "(Un)favorite current folder." -msgstr "" +msgstr "फ़ेवरेट मे से वरà¥à¤¤à¤®à¤¾à¤¨ फ़ोलà¥à¤¡à¤° निकाले." #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Toggle the visibility of hidden files." -msgstr "" +msgstr "छिपी फ़ाइलों की दृशà¥à¤¯ टॉगल कीजिये." #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "View items as a grid of thumbnails." -msgstr "" +msgstr "आइटम थमà¥à¤¬à¤¨à¥‡à¤²à¥à¤¸ के ढाà¤à¤šà¥‡ के तरह देखे." #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "View items as a list." -msgstr "" +msgstr "आइटम लिसà¥à¤Ÿ के तरह देखे." #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Directories & Files:" -msgstr "" +msgstr "डायरेकà¥à¤Ÿà¤°à¤¿à¤œ & फ़ाइले:" #: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp #: editor/plugins/style_box_editor_plugin.cpp #: editor/plugins/theme_editor_plugin.cpp msgid "Preview:" -msgstr "" +msgstr "पूरà¥à¤µ दरà¥à¤¶à¤¨:" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "File:" -msgstr "" +msgstr "फ़ाइल:" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Must use a valid extension." -msgstr "" +msgstr "मानà¥à¤¯ à¤à¤•à¥à¤¸à¤Ÿà¥‡à¤¨à¤¶à¤¨ इसà¥à¤¤à¥‡à¤®à¤¾à¤² कीजिये." #: editor/editor_file_system.cpp msgid "ScanSources" -msgstr "" +msgstr "सà¥à¤°à¥‹à¤¤à¤¸à¥à¤•ैन कीजिये" #: editor/editor_file_system.cpp msgid "" "There are multiple importers for different types pointing to file %s, import " "aborted" msgstr "" +"विà¤à¤¿à¤¨à¥à¤¨ पà¥à¤°à¤•ार के लिठकई आयातक हैं जो % फाइल करने की ओर इशारा करते हैं, आयात निरसà¥à¤¤" #: editor/editor_file_system.cpp msgid "(Re)Importing Assets" -msgstr "" +msgstr "असà¥à¤¸à¥‡à¤Ÿ (पà¥à¤¨:) इंपोरà¥à¤Ÿ" #: editor/editor_help.cpp editor/plugins/spatial_editor_plugin.cpp msgid "Top" -msgstr "" +msgstr "सरà¥à¤µà¥‹à¤šà¥à¤š" #: editor/editor_help.cpp msgid "Class:" -msgstr "" +msgstr "कà¥à¤²à¤¾à¤¸:" #: editor/editor_help.cpp editor/scene_tree_editor.cpp #: editor/script_create_dialog.cpp msgid "Inherits:" -msgstr "" +msgstr "निमà¥à¤¨ का उतà¥à¤¤à¤°à¤¾à¤§à¤¿à¤•ारी:" #: editor/editor_help.cpp msgid "Inherited by:" -msgstr "" +msgstr "निमà¥à¤¨ से उतà¥à¤¤à¤°à¤¾à¤§à¤¿à¤•ार पà¥à¤°à¤¾à¤ªà¥à¤¤:" #: editor/editor_help.cpp msgid "Description" @@ -1933,155 +1935,152 @@ msgstr "विवरण" #: editor/editor_help.cpp msgid "Online Tutorials" -msgstr "" +msgstr "ऑनलाइन टà¥à¤¯à¥‚टोरियल" #: editor/editor_help.cpp msgid "Properties" -msgstr "" +msgstr "पà¥à¤°à¥‹à¤ªà¤°à¤Ÿà¤¿à¤œ" #: editor/editor_help.cpp msgid "override:" -msgstr "" +msgstr "अधिà¤à¤¾à¤µà¥€ करता है:" #: editor/editor_help.cpp msgid "default:" -msgstr "" +msgstr "पà¥à¤°à¤¾à¤¯à¤¿à¤•:" #: editor/editor_help.cpp msgid "Methods" -msgstr "" +msgstr "मेथड" #: editor/editor_help.cpp msgid "Theme Properties" -msgstr "" +msgstr "थिम पà¥à¤°à¥‹à¤ªà¤°à¤Ÿà¤¿à¤œ" #: editor/editor_help.cpp msgid "Enumerations" -msgstr "" +msgstr "à¤à¤¨à¥à¤¯à¥à¤®à¤°à¥‡à¤¶à¤¨" #: editor/editor_help.cpp msgid "Constants" -msgstr "" +msgstr "कोनà¥à¤¸à¥à¤Ÿà¤¨à¥à¤Ÿ" #: editor/editor_help.cpp -#, fuzzy msgid "Property Descriptions" -msgstr "विवरण:" +msgstr "पà¥à¤°à¥‹à¤ªà¤°à¥à¤Ÿà¥€ का विवरण" #: editor/editor_help.cpp -#, fuzzy msgid "(value)" -msgstr "मूलà¥à¤¯ :" +msgstr "(मूलà¥à¤¯)" #: editor/editor_help.cpp msgid "" "There is currently no description for this property. Please help us by " "[color=$color][url=$url]contributing one[/url][/color]!" msgstr "" +"वरà¥à¤¤à¤®à¤¾à¤¨ में पà¥à¤°à¥‹à¤ªà¤°à¥à¤Ÿà¥€ का विवरण नहीं. आप हमें [color=$color][url=$url]योगदान करके[/url]" +"[/color] मदत कर सकते है!" #: editor/editor_help.cpp -#, fuzzy msgid "Method Descriptions" -msgstr "विवरण:" +msgstr "मेथड विवरण" #: editor/editor_help.cpp msgid "" "There is currently no description for this method. Please help us by [color=" "$color][url=$url]contributing one[/url][/color]!" msgstr "" +"वरà¥à¤¤à¤®à¤¾à¤¨ में मेथड का विवरण नहीं. आप हमें [color=$color][url=$url]योगदान करके[/url][/" +"color] मदत कर सकते है!" #: editor/editor_help_search.cpp editor/editor_node.cpp #: editor/plugins/script_editor_plugin.cpp msgid "Search Help" -msgstr "" +msgstr "मदत खोजे" #: editor/editor_help_search.cpp msgid "Case Sensitive" -msgstr "" +msgstr "अकà¥à¤·à¤° संवेदनशील" #: editor/editor_help_search.cpp msgid "Show Hierarchy" -msgstr "" +msgstr "उतà¥à¤•à¥à¤°à¤® दिखाइà¤" #: editor/editor_help_search.cpp msgid "Display All" -msgstr "" +msgstr "सब दिखाइà¤" #: editor/editor_help_search.cpp msgid "Classes Only" -msgstr "" +msgstr "सिरà¥à¤« कà¥à¤²à¤¾à¤¸" #: editor/editor_help_search.cpp msgid "Methods Only" -msgstr "" +msgstr "सिरà¥à¤« मेथड" #: editor/editor_help_search.cpp -#, fuzzy msgid "Signals Only" -msgstr "संकेत" +msgstr "सिरà¥à¤« सिगà¥à¤¨à¤²" #: editor/editor_help_search.cpp msgid "Constants Only" -msgstr "" +msgstr "सिरà¥à¤« कोनà¥à¤¸à¥à¤Ÿà¤¨à¥à¤Ÿ" #: editor/editor_help_search.cpp msgid "Properties Only" -msgstr "" +msgstr "सिरà¥à¤« पà¥à¤°à¥‹à¤ªà¤°à¤Ÿà¤¿à¤œ" #: editor/editor_help_search.cpp msgid "Theme Properties Only" -msgstr "" +msgstr "सिरà¥à¤« थिम पà¥à¤°à¥‹à¤ªà¤°à¤Ÿà¤¿à¤œ" #: editor/editor_help_search.cpp msgid "Member Type" -msgstr "" +msgstr "मेंबर टाइप" #: editor/editor_help_search.cpp msgid "Class" -msgstr "" +msgstr "कà¥à¤²à¤¾à¤¸" #: editor/editor_help_search.cpp msgid "Method" -msgstr "" +msgstr "मेथड" #: editor/editor_help_search.cpp editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Signal" -msgstr "संकेत" +msgstr "सिगà¥à¤¨à¤²" #: editor/editor_help_search.cpp editor/plugins/theme_editor_plugin.cpp msgid "Constant" -msgstr "" +msgstr "कोनà¥à¤¸à¥à¤Ÿà¤¨à¥à¤Ÿ" #: editor/editor_help_search.cpp -#, fuzzy msgid "Property" -msgstr "गà¥à¤£(Property) टà¥à¤°à¥ˆà¤•" +msgstr "पà¥à¤°à¥‹à¤ªà¤°à¥à¤Ÿà¥€" #: editor/editor_help_search.cpp msgid "Theme Property" -msgstr "" +msgstr "थिम पà¥à¤°à¥‹à¤ªà¤°à¥à¤Ÿà¥€" #: editor/editor_inspector.cpp editor/project_settings_editor.cpp msgid "Property:" -msgstr "" +msgstr "पà¥à¤°à¥‹à¤ªà¤°à¥à¤Ÿà¥€:" #: editor/editor_inspector.cpp msgid "Set" -msgstr "" +msgstr "सेट करे" #: editor/editor_inspector.cpp msgid "Set Multiple:" -msgstr "" +msgstr "अनेक सेट करे:" #: editor/editor_log.cpp msgid "Output:" -msgstr "" +msgstr "परिणाम:" #: editor/editor_log.cpp editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Copy Selection" -msgstr "सà¤à¥€ खंड" +msgstr "खंड कौपी कीजिये" #: editor/editor_log.cpp editor/editor_network_profiler.cpp #: editor/editor_profiler.cpp editor/editor_properties.cpp @@ -2091,176 +2090,178 @@ msgstr "सà¤à¥€ खंड" #: modules/gdnative/gdnative_library_editor_plugin.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Clear" -msgstr "" +msgstr "साफ़" #: editor/editor_log.cpp msgid "Clear Output" -msgstr "" +msgstr "परिणाम साफ़ करे" #: editor/editor_network_profiler.cpp editor/editor_node.cpp #: editor/editor_profiler.cpp msgid "Stop" -msgstr "" +msgstr "रोकिये" #: editor/editor_network_profiler.cpp editor/editor_profiler.cpp #: editor/plugins/animation_state_machine_editor.cpp editor/rename_dialog.cpp msgid "Start" -msgstr "" +msgstr "शà¥à¤°à¥‚ कीजिये" #: editor/editor_network_profiler.cpp msgid "%s/s" -msgstr "" +msgstr "%s/s" #: editor/editor_network_profiler.cpp msgid "Down" -msgstr "" +msgstr "नीचे" #: editor/editor_network_profiler.cpp msgid "Up" -msgstr "" +msgstr "ऊपर" #: editor/editor_network_profiler.cpp editor/editor_node.cpp msgid "Node" -msgstr "" +msgstr "नोड" #: editor/editor_network_profiler.cpp msgid "Incoming RPC" -msgstr "" +msgstr "आगामी RPC" #: editor/editor_network_profiler.cpp msgid "Incoming RSET" -msgstr "" +msgstr "आगामी RSET" #: editor/editor_network_profiler.cpp msgid "Outgoing RPC" -msgstr "" +msgstr "बाहर जाने वाला RPC" #: editor/editor_network_profiler.cpp msgid "Outgoing RSET" -msgstr "" +msgstr "बाहर जाने वाला RSET" #: editor/editor_node.cpp editor/project_manager.cpp msgid "New Window" -msgstr "" +msgstr "नया विंडो" #: editor/editor_node.cpp msgid "Imported resources can't be saved." -msgstr "" +msgstr "इंपोरà¥à¤Ÿà¥‡à¤¡ रेसोरà¥à¤¸à¥‡à¤¸ सेव नहीं कर सकते." #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: scene/gui/dialogs.cpp msgid "OK" -msgstr "" +msgstr "ठीक है" #: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp msgid "Error saving resource!" -msgstr "" +msgstr "रेसोरà¥à¤¸ सेव करनेमे à¤à¤°à¤°!" #: editor/editor_node.cpp msgid "" "This resource can't be saved because it does not belong to the edited scene. " "Make it unique first." -msgstr "" +msgstr "रेसोरà¥à¤¸ सेव नहीं कर सकते कà¥à¤¯à¥‹à¤‚कि यह संपादित सीन से संबंधित नहीं. इसे पहले यà¥à¤¨à¤¿à¤• बनाय." #: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp msgid "Save Resource As..." -msgstr "" +msgstr "रेसोरà¥à¤¸ इसपà¥à¤°à¤•ार सेव कीजिये..." #: editor/editor_node.cpp msgid "Can't open file for writing:" -msgstr "" +msgstr "फ़ाइल रायटिंग के लिठनहीं खोल सकते:" #: editor/editor_node.cpp msgid "Requested file format unknown:" -msgstr "" +msgstr "निवेदित फ़ाइल फ़ोरà¥à¤®à¥ˆà¤Ÿ अजà¥à¤žà¤¾à¤¤:" #: editor/editor_node.cpp msgid "Error while saving." -msgstr "" +msgstr "सेव करनेमे à¤à¤°à¤°." #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Can't open '%s'. The file could have been moved or deleted." -msgstr "" +msgstr "'%s' नहीं खोल सकते. फ़ाइल हिलाइ गयी या हटाई गयी." #: editor/editor_node.cpp msgid "Error while parsing '%s'." -msgstr "" +msgstr "'%s' पारà¥à¤¸ करनेमे à¤à¤°à¤°." #: editor/editor_node.cpp msgid "Unexpected end of file '%s'." -msgstr "" +msgstr "अनपेकà¥à¤·à¤¿à¤¤ फ़ाइल समापà¥à¤¤à¤¿ '%s'." #: editor/editor_node.cpp msgid "Missing '%s' or its dependencies." -msgstr "" +msgstr "'%s' या उसकी निरà¥à¤à¤°à¤¿à¤¤ फ़ाइलें नहीं मिली." #: editor/editor_node.cpp msgid "Error while loading '%s'." -msgstr "" +msgstr "लोड करनेमे à¤à¤°à¤° '%s'." #: editor/editor_node.cpp msgid "Saving Scene" -msgstr "" +msgstr "सीन सेव कर रहा है" #: editor/editor_node.cpp msgid "Analyzing" -msgstr "" +msgstr "विशà¥à¤²à¥‡à¤·à¤£" #: editor/editor_node.cpp msgid "Creating Thumbnail" -msgstr "" +msgstr "थंबनेल बनाना" #: editor/editor_node.cpp msgid "This operation can't be done without a tree root." -msgstr "" +msgstr "यह ऑपरेशन पेड़ की जड़ के बिना नहीं किया जा सकता है।" #: editor/editor_node.cpp msgid "" "This scene can't be saved because there is a cyclic instancing inclusion.\n" "Please resolve it and then attempt to save again." msgstr "" +"इस दृशà¥à¤¯ को बचाया नहीं जा सकता कà¥à¤¯à¥‹à¤‚कि à¤à¤• चकà¥à¤°à¥€à¤¯ instancing समावेश है ।\n" +"कृपया इसे हल करें और फिर फिर से बचाने का पà¥à¤°à¤¯à¤¾à¤¸ करें।" #: editor/editor_node.cpp msgid "" "Couldn't save scene. Likely dependencies (instances or inheritance) couldn't " "be satisfied." -msgstr "" +msgstr "दृशà¥à¤¯ नहीं बचा सका । संà¤à¤¾à¤µà¤¿à¤¤ निरà¥à¤à¤°à¤¤à¤¾ (उदाहरण या विरासत) संतà¥à¤·à¥à¤Ÿ नहीं हो सकीं।" #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "Can't overwrite scene that is still open!" -msgstr "" +msgstr "दृशà¥à¤¯ है कि अà¤à¥€ à¤à¥€ खà¥à¤²à¤¾ है ओवरराइट नहीं कर सकते!" #: editor/editor_node.cpp msgid "Can't load MeshLibrary for merging!" -msgstr "" +msgstr "विलय के लिठMeshLibrary लोड नहीं कर सकते!" #: editor/editor_node.cpp msgid "Error saving MeshLibrary!" -msgstr "" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿ बचत मेष लाइबà¥à¤°à¥‡à¤°à¥€!" #: editor/editor_node.cpp msgid "Can't load TileSet for merging!" -msgstr "" +msgstr "विलय के लिठTileSet लोड नहीं कर सकते!" #: editor/editor_node.cpp msgid "Error saving TileSet!" -msgstr "" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿ बचत टाइलसेट!" #: editor/editor_node.cpp msgid "Error trying to save layout!" -msgstr "" +msgstr "लेआउट को बचाने की कोशिश कर रहा तà¥à¤°à¥à¤Ÿà¤¿!" #: editor/editor_node.cpp msgid "Default editor layout overridden." -msgstr "" +msgstr "डिफ़ॉलà¥à¤Ÿ संपादक लेआउट अà¤à¤¿à¤à¥‚त।" #: editor/editor_node.cpp msgid "Layout name not found!" -msgstr "" +msgstr "लेआउट नाम नहीं मिला!" #: editor/editor_node.cpp msgid "Restored default layout to base settings." -msgstr "" +msgstr "आधार सेटिंगà¥à¤¸ के लिठडिफ़ॉलà¥à¤Ÿ लेआउट बहाल।" #: editor/editor_node.cpp msgid "" @@ -2268,18 +2269,26 @@ msgid "" "Please read the documentation relevant to importing scenes to better " "understand this workflow." msgstr "" +"यह संसाधन à¤à¤• दृशà¥à¤¯ है कि आयात किया गया था के अंतरà¥à¤—त आता है, तो यह संपादन योगà¥à¤¯ नहीं है " +"।\n" +"कृपया इस कारà¥à¤¯à¤ªà¥à¤°à¤µà¤¾à¤¹ को बेहतर ढंग से समà¤à¤¨à¥‡ के लिठदृशà¥à¤¯à¥‹à¤‚ का आयात करने के लिठपà¥à¤°à¤¾à¤¸à¤‚गिक " +"दसà¥à¤¤à¤¾à¤µà¥‡à¤œ पढ़ें।" #: editor/editor_node.cpp msgid "" "This resource belongs to a scene that was instanced or inherited.\n" "Changes to it won't be kept when saving the current scene." msgstr "" +"यह संसाधन à¤à¤• दृशà¥à¤¯ है कि उदाहरण या विरासत में मिला था के अंतरà¥à¤—त आता है ।\n" +"वरà¥à¤¤à¤®à¤¾à¤¨ दृशà¥à¤¯ को सहेजते समय इसमें परिवरà¥à¤¤à¤¨ नहीं रखे जाà¤à¤‚गे।" #: editor/editor_node.cpp msgid "" "This resource was imported, so it's not editable. Change its settings in the " "import panel and then re-import." msgstr "" +"इस संसाधन का आयात किया गया था, तो यह संपादन योगà¥à¤¯ नहीं है । आयात पैनल में अपनी सेटिंग " +"बदलें और फिर फिर से आयात करें।" #: editor/editor_node.cpp msgid "" @@ -2288,6 +2297,10 @@ msgid "" "Please read the documentation relevant to importing scenes to better " "understand this workflow." msgstr "" +"यह दृशà¥à¤¯ आयात किया गया था, इसलिठइसमें परिवरà¥à¤¤à¤¨ नहीं रखे जाà¤à¤‚गे।\n" +"यह instancing या विरासत में यह परिवरà¥à¤¤à¤¨ करने की अनà¥à¤®à¤¤à¤¿ होगी ।\n" +"कृपया इस कारà¥à¤¯à¤ªà¥à¤°à¤µà¤¾à¤¹ को बेहतर ढंग से समà¤à¤¨à¥‡ के लिठदृशà¥à¤¯à¥‹à¤‚ का आयात करने के लिठपà¥à¤°à¤¾à¤¸à¤‚गिक " +"दसà¥à¤¤à¤¾à¤µà¥‡à¤œ पढ़ें।" #: editor/editor_node.cpp msgid "" @@ -2295,26 +2308,28 @@ msgid "" "Please read the documentation relevant to debugging to better understand " "this workflow." msgstr "" +"यह à¤à¤• दूरसà¥à¤¥ वसà¥à¤¤à¥ है, इसलिठइसमें परिवरà¥à¤¤à¤¨ नहीं रखे जाà¤à¤‚गे।\n" +"कृपया इस कारà¥à¤¯à¤ªà¥à¤°à¤µà¤¾à¤¹ को बेहतर ढंग से समà¤à¤¨à¥‡ के लिठडिबगिंग के लिठपà¥à¤°à¤¾à¤¸à¤‚गिक दसà¥à¤¤à¤¾à¤µà¥‡à¤œ पढ़ें।" #: editor/editor_node.cpp msgid "There is no defined scene to run." -msgstr "" +msgstr "चलाने के लिठकोई परिà¤à¤¾à¤·à¤¿à¤¤ दृशà¥à¤¯ नहीं है ।" #: editor/editor_node.cpp msgid "Current scene was never saved, please save it prior to running." -msgstr "" +msgstr "वरà¥à¤¤à¤®à¤¾à¤¨ दृशà¥à¤¯ कà¤à¥€ नहीं बचाया गया था, कृपया इसे चलाने से पहले बचाने के लिठ।" #: editor/editor_node.cpp msgid "Could not start subprocess!" -msgstr "" +msgstr "उपपà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ शà¥à¤°à¥‚ नहीं कर सका!" #: editor/editor_node.cpp editor/filesystem_dock.cpp msgid "Open Scene" -msgstr "" +msgstr "खà¥à¤²à¤¾ दृशà¥à¤¯" #: editor/editor_node.cpp msgid "Open Base Scene" -msgstr "" +msgstr "ओपन बेस सीन" #: editor/editor_node.cpp #, fuzzy @@ -2323,121 +2338,123 @@ msgstr "खोलो इसे" #: editor/editor_node.cpp msgid "Quick Open Scene..." -msgstr "" +msgstr "कà¥à¤µà¤¿à¤• ओपन सीन..." #: editor/editor_node.cpp msgid "Quick Open Script..." -msgstr "" +msgstr "कà¥à¤µà¤¿à¤• ओपन सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ..." #: editor/editor_node.cpp msgid "Save & Close" -msgstr "" +msgstr "सहेजें और बंद" #: editor/editor_node.cpp msgid "Save changes to '%s' before closing?" -msgstr "" +msgstr "बंद करने से पहले '%' में परिवरà¥à¤¤à¤¨ सहेजें?" #: editor/editor_node.cpp msgid "Saved %s modified resource(s)." -msgstr "" +msgstr "सहेजा गया% संशोधित संसाधन (à¤à¤¸)" #: editor/editor_node.cpp msgid "A root node is required to save the scene." -msgstr "" +msgstr "दृशà¥à¤¯ को बचाने के लिठà¤à¤• रूट नोड की आवशà¥à¤¯à¤•ता होती है।" #: editor/editor_node.cpp msgid "Save Scene As..." -msgstr "" +msgstr "दृशà¥à¤¯ के रूप में सहेजें ..." #: editor/editor_node.cpp msgid "No" -msgstr "" +msgstr "नहीं" #: editor/editor_node.cpp msgid "Yes" -msgstr "" +msgstr "हाà¤" #: editor/editor_node.cpp msgid "This scene has never been saved. Save before running?" -msgstr "" +msgstr "इस सीन को कà¤à¥€ नहीं बचाया गया। दौड़ने से पहले सहेजें?" #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "This operation can't be done without a scene." -msgstr "" +msgstr "यह ऑपरेशन बिना किसी दृशà¥à¤¯ के नहीं किया जा सकता है।" #: editor/editor_node.cpp msgid "Export Mesh Library" -msgstr "" +msgstr "निरà¥à¤¯à¤¾à¤¤ मेष पà¥à¤¸à¥à¤¤à¤•ालय" #: editor/editor_node.cpp msgid "This operation can't be done without a root node." -msgstr "" +msgstr "यह ऑपरेशन रूट नोड के बिना नहीं किया जा सकता है।" #: editor/editor_node.cpp msgid "Export Tile Set" -msgstr "" +msgstr "निरà¥à¤¯à¤¾à¤¤ टाइल सेट" #: editor/editor_node.cpp msgid "This operation can't be done without a selected node." -msgstr "" +msgstr "यह ऑपरेशन चयनित नोड के बिना नहीं किया जा सकता है।" #: editor/editor_node.cpp msgid "Current scene not saved. Open anyway?" -msgstr "" +msgstr "वरà¥à¤¤à¤®à¤¾à¤¨ दृशà¥à¤¯ को बचाया नहीं गया । वैसे à¤à¥€ खà¥à¤²à¤¾?" #: editor/editor_node.cpp msgid "Can't reload a scene that was never saved." -msgstr "" +msgstr "à¤à¤• दृशà¥à¤¯ है कि कà¤à¥€ नहीं बचाया गया था फिर से लोड नहीं कर सकते ।" #: editor/editor_node.cpp msgid "Revert" -msgstr "" +msgstr "वापस लौटना" #: editor/editor_node.cpp msgid "This action cannot be undone. Revert anyway?" -msgstr "" +msgstr "इस कारà¥à¤°à¤µà¤¾à¤ˆ को पूरà¥à¤µà¤µà¤¤ नहीं किया जा सकता । वैसे à¤à¥€ वापस?" #: editor/editor_node.cpp msgid "Quick Run Scene..." -msgstr "" +msgstr "कà¥à¤µà¤¿à¤• रन सीन..." #: editor/editor_node.cpp msgid "Quit" -msgstr "" +msgstr "छोड़ना" #: editor/editor_node.cpp msgid "Exit the editor?" -msgstr "" +msgstr "संपादक से बाहर निकलें?" #: editor/editor_node.cpp msgid "Open Project Manager?" -msgstr "" +msgstr "ओपन पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ मैनेजर?" #: editor/editor_node.cpp msgid "Save & Quit" -msgstr "" +msgstr "सहेजें और छोड़ो" #: editor/editor_node.cpp msgid "Save changes to the following scene(s) before quitting?" -msgstr "" +msgstr "छोड़ने से पहले निमà¥à¤¨à¤²à¤¿à¤–ित दृशà¥à¤¯ (ओं) में परिवरà¥à¤¤à¤¨ सहेजें?" #: editor/editor_node.cpp msgid "Save changes the following scene(s) before opening Project Manager?" -msgstr "" +msgstr "परियोजना पà¥à¤°à¤¬à¤‚धक खोलने से पहले निमà¥à¤¨à¤²à¤¿à¤–ित दृशà¥à¤¯ (ओं) में परिवरà¥à¤¤à¤¨ सहेजें?" #: editor/editor_node.cpp msgid "" "This option is deprecated. Situations where refresh must be forced are now " "considered a bug. Please report." msgstr "" +"यह विकलà¥à¤ª बहिषà¥à¤•ृत है। सà¥à¤¥à¤¿à¤¤à¤¿à¤¯à¥‹à¤‚ जहां ताज़ा मजबूर किया जाना चाहिठअब à¤à¤• बग माना जाता " +"है । कृपया रिपोरà¥à¤Ÿ करें।" #: editor/editor_node.cpp msgid "Pick a Main Scene" -msgstr "" +msgstr "à¤à¤• मà¥à¤–à¥à¤¯ दृशà¥à¤¯ चà¥à¤¨à¥‡à¤‚" #: editor/editor_node.cpp msgid "Close Scene" -msgstr "" +msgstr "कà¥à¤²à¥‹à¤œ सीन" #: editor/editor_node.cpp #, fuzzy @@ -2446,50 +2463,56 @@ msgstr "खोलो इसे" #: editor/editor_node.cpp msgid "Unable to enable addon plugin at: '%s' parsing of config failed." -msgstr "" +msgstr "à¤à¤¡à¤‘न पà¥à¤²à¤—इन को सकà¥à¤·à¤® करने में असमरà¥à¤¥: '%' कॉनà¥à¤«à¤¿à¤— का पारà¥à¤¸à¤¿à¤‚ग विफल रहा।" #: editor/editor_node.cpp msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." -msgstr "" +msgstr "à¤à¤¡à¤‘न पà¥à¤²à¤—इन के लिठसà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ फ़ीलà¥à¤¡ खोजने में असमरà¥à¤¥: 'res://addons/% s'।" #: editor/editor_node.cpp msgid "Unable to load addon script from path: '%s'." -msgstr "" +msgstr "पथ से à¤à¤¡à¤‘न सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ लोड करने में असमरà¥à¤¥: '%' ।" #: editor/editor_node.cpp msgid "" "Unable to load addon script from path: '%s' There seems to be an error in " "the code, please check the syntax." msgstr "" +"रासà¥à¤¤à¥‡ से à¤à¤¡à¤‘न सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ लोड करने में असमरà¥à¤¥: '% à¤à¤¸' कोड में गड़बड़ी लगती है, कृपया सिंटेकà¥à¤¸ की " +"जांच करें।" #: editor/editor_node.cpp msgid "" "Unable to load addon script from path: '%s' Base type is not EditorPlugin." -msgstr "" +msgstr "पथ से à¤à¤¡à¤‘न सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ लोड करने में असमरà¥à¤¥: '%' आधार पà¥à¤°à¤•ार संपादकपà¥à¤²à¤—इन नहीं है।" #: editor/editor_node.cpp msgid "Unable to load addon script from path: '%s' Script is not in tool mode." -msgstr "" +msgstr "पथ से à¤à¤¡à¤‘न सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ लोड करने में असमरà¥à¤¥: '%' सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ टूल मोड में नहीं है।" #: editor/editor_node.cpp msgid "" "Scene '%s' was automatically imported, so it can't be modified.\n" "To make changes to it, a new inherited scene can be created." msgstr "" +"दृशà¥à¤¯ '%' सà¥à¤µà¤šà¤¾à¤²à¤¿à¤¤ रूप से आयात किया गया था, इसलिठइसे संशोधित नहीं किया जा सकता है।\n" +"इसमें बदलाव करने के लिठविरासत में मिला à¤à¤• नया सीन बनाया जा सकता है।" #: editor/editor_node.cpp msgid "" "Error loading scene, it must be inside the project path. Use 'Import' to " "open the scene, then save it inside the project path." msgstr "" +"तà¥à¤°à¥à¤Ÿà¤¿ लोडिंग दृशà¥à¤¯, यह परियोजना पथ के अंदर होना चाहिà¤à¥¤ दृशà¥à¤¯ खोलने के लिठ'आयात' का " +"उपयोग करें, फिर इसे परियोजना पथ के अंदर बचाà¤à¤‚।" #: editor/editor_node.cpp msgid "Scene '%s' has broken dependencies:" -msgstr "" +msgstr "दृशà¥à¤¯ '%' निरà¥à¤à¤°à¤¤à¤¾ टूट गया है:" #: editor/editor_node.cpp msgid "Clear Recent Scenes" -msgstr "" +msgstr "हाल के दृशà¥à¤¯à¥‹à¤‚ को साफ करें" #: editor/editor_node.cpp msgid "" @@ -2497,6 +2520,8 @@ msgid "" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" +"कोई मà¥à¤–à¥à¤¯ दृशà¥à¤¯ कà¤à¥€ परिà¤à¤¾à¤·à¤¿à¤¤ किया गया है, à¤à¤• का चयन करें?\n" +"आप इसे बाद में 'à¤à¤ªà¥à¤²à¤¿à¤•ेशन' शà¥à¤°à¥‡à¤£à¥€ के तहत \"पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ सेटिंगà¥à¤¸\" में बदल सकते हैं।" #: editor/editor_node.cpp msgid "" @@ -2504,6 +2529,8 @@ msgid "" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" +"चयनित दृशà¥à¤¯ '%' मौजूद नहीं है, à¤à¤• वैध का चयन करें?\n" +"आप इसे बाद में 'à¤à¤ªà¥à¤²à¤¿à¤•ेशन' शà¥à¤°à¥‡à¤£à¥€ के तहत \"पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ सेटिंगà¥à¤¸\" में बदल सकते हैं।" #: editor/editor_node.cpp msgid "" @@ -2511,28 +2538,30 @@ msgid "" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" +"चयनित दृशà¥à¤¯ '%' à¤à¤• दृशà¥à¤¯ फ़ाइल नहीं है, à¤à¤• वैध का चयन करें?\n" +"आप इसे बाद में 'à¤à¤ªà¥à¤²à¤¿à¤•ेशन' शà¥à¤°à¥‡à¤£à¥€ के तहत \"पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ सेटिंगà¥à¤¸\" में बदल सकते हैं।" #: editor/editor_node.cpp msgid "Save Layout" -msgstr "" +msgstr "लेआउट सहेजें" #: editor/editor_node.cpp msgid "Delete Layout" -msgstr "" +msgstr "लेआउट हटाà¤à¤‚" #: editor/editor_node.cpp editor/import_dock.cpp #: editor/script_create_dialog.cpp msgid "Default" -msgstr "" +msgstr "चूक" #: editor/editor_node.cpp editor/editor_properties.cpp #: editor/plugins/script_editor_plugin.cpp editor/property_editor.cpp msgid "Show in FileSystem" -msgstr "" +msgstr "शो में फाइल सिसà¥à¤Ÿà¤®" #: editor/editor_node.cpp msgid "Play This Scene" -msgstr "" +msgstr "इस दृशà¥à¤¯ को खेलो" #: editor/editor_node.cpp #, fuzzy @@ -2546,11 +2575,11 @@ msgstr "बंद करे" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Close Other Tabs" -msgstr "" +msgstr "बंद करें अनà¥à¤¯ टैब" #: editor/editor_node.cpp msgid "Close Tabs to the Right" -msgstr "" +msgstr "टैब को दाईं ओर बंद करें" #: editor/editor_node.cpp #, fuzzy @@ -2559,43 +2588,43 @@ msgstr "बंद करे" #: editor/editor_node.cpp msgid "Switch Scene Tab" -msgstr "" +msgstr "सà¥à¤µà¤¿à¤š सीन टैब" #: editor/editor_node.cpp msgid "%d more files or folders" -msgstr "" +msgstr "% डी अधिक फाइलें या फ़ोलà¥à¤¡à¤°" #: editor/editor_node.cpp msgid "%d more folders" -msgstr "" +msgstr "% डी अधिक फ़ोलà¥à¤¡à¤°à¥à¤¸" #: editor/editor_node.cpp msgid "%d more files" -msgstr "" +msgstr "% डी अधिक फाइलें" #: editor/editor_node.cpp msgid "Dock Position" -msgstr "" +msgstr "डॉक पोजीशन" #: editor/editor_node.cpp msgid "Distraction Free Mode" -msgstr "" +msgstr "वà¥à¤¯à¤¾à¤•à¥à¤²à¤¤à¤¾ मà¥à¤•à¥à¤¤ मोड" #: editor/editor_node.cpp msgid "Toggle distraction-free mode." -msgstr "" +msgstr "वà¥à¤¯à¤¾à¤•à¥à¤²à¤¤à¤¾ मà¥à¤•à¥à¤¤ मोड टॉगल।" #: editor/editor_node.cpp msgid "Add a new scene." -msgstr "" +msgstr "à¤à¤• नया दृशà¥à¤¯ जोड़ें।" #: editor/editor_node.cpp msgid "Scene" -msgstr "" +msgstr "दृशà¥à¤¯" #: editor/editor_node.cpp msgid "Go to previously opened scene." -msgstr "" +msgstr "पहले खोले गठदृशà¥à¤¯ में जाà¤à¤‚।" #: editor/editor_node.cpp #, fuzzy @@ -2604,102 +2633,102 @@ msgstr "सà¤à¥€ खंड" #: editor/editor_node.cpp msgid "Next tab" -msgstr "" +msgstr "अगला टैब" #: editor/editor_node.cpp msgid "Previous tab" -msgstr "" +msgstr "पिछला टैब" #: editor/editor_node.cpp msgid "Filter Files..." -msgstr "" +msgstr "फ़िलà¥à¤Ÿà¤° फ़ाइलें..." #: editor/editor_node.cpp msgid "Operations with scene files." -msgstr "" +msgstr "दृशà¥à¤¯ फ़ाइलों के साथ संचालन।" #: editor/editor_node.cpp msgid "New Scene" -msgstr "" +msgstr "नया दृशà¥à¤¯" #: editor/editor_node.cpp msgid "New Inherited Scene..." -msgstr "" +msgstr "नया विरासत में मिला दृशà¥à¤¯..." #: editor/editor_node.cpp msgid "Open Scene..." -msgstr "" +msgstr "खà¥à¤²à¤¾ दृशà¥à¤¯..." #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Open Recent" -msgstr "" +msgstr "खà¥à¤²à¤¾ हाल" #: editor/editor_node.cpp msgid "Save Scene" -msgstr "" +msgstr "दृशà¥à¤¯ बचाओ" #: editor/editor_node.cpp msgid "Save All Scenes" -msgstr "" +msgstr "सà¤à¥€ दृशà¥à¤¯à¥‹à¤‚ को सहेजें" #: editor/editor_node.cpp msgid "Convert To..." -msgstr "" +msgstr "बदलने के लिà¤..." #: editor/editor_node.cpp msgid "MeshLibrary..." -msgstr "" +msgstr "मेष लाइबà¥à¤°à¥‡à¤°à¥€..." #: editor/editor_node.cpp msgid "TileSet..." -msgstr "" +msgstr "Tileset ..." #: editor/editor_node.cpp editor/plugins/script_text_editor.cpp #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Undo" -msgstr "" +msgstr "पूरà¥à¤µà¤µà¤¤à¥" #: editor/editor_node.cpp editor/plugins/script_text_editor.cpp #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Redo" -msgstr "" +msgstr "दोहराà¤à¤" #: editor/editor_node.cpp msgid "Revert Scene" -msgstr "" +msgstr "वापस दृशà¥à¤¯" #: editor/editor_node.cpp msgid "Miscellaneous project or scene-wide tools." -msgstr "" +msgstr "विविध परियोजना या दृशà¥à¤¯-वà¥à¤¯à¤¾à¤ªà¥€ उपकरण।" #: editor/editor_node.cpp editor/project_manager.cpp #: editor/script_create_dialog.cpp msgid "Project" -msgstr "" +msgstr "परियोजना" #: editor/editor_node.cpp msgid "Project Settings..." -msgstr "" +msgstr "पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ सेटिंग ..." #: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp msgid "Version Control" -msgstr "" +msgstr "वरà¥à¤œà¤¨ कंटà¥à¤°à¥‹à¤²" #: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp msgid "Set Up Version Control" -msgstr "" +msgstr "वरà¥à¤œà¤¨ नियंतà¥à¤°à¤£ सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करें" #: editor/editor_node.cpp msgid "Shut Down Version Control" -msgstr "" +msgstr "वरà¥à¤œà¤¨ नियंतà¥à¤°à¤£ बंद करें" #: editor/editor_node.cpp msgid "Export..." -msgstr "" +msgstr "निरà¥à¤¯à¤¾à¤¤..." #: editor/editor_node.cpp msgid "Install Android Build Template..." -msgstr "" +msgstr "à¤à¤‚डà¥à¤°à¥‰à¤¯à¤¡ बिलà¥à¤¡ टेमà¥à¤ªà¤²à¥‡à¤Ÿ सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करें..." #: editor/editor_node.cpp #, fuzzy @@ -2708,7 +2737,7 @@ msgstr "परियोजना के संसà¥à¤¥à¤¾à¤ªà¤•" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" -msgstr "" +msgstr "उपकरण" #: editor/editor_node.cpp #, fuzzy @@ -2717,26 +2746,28 @@ msgstr "Orphan Resource Explorer" #: editor/editor_node.cpp msgid "Quit to Project List" -msgstr "" +msgstr "परियोजना सूची में छोड़ो" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/project_export.cpp msgid "Debug" -msgstr "" +msgstr "डीबग करें" #: editor/editor_node.cpp msgid "Deploy with Remote Debug" -msgstr "" +msgstr "रिमोट डिबग के साथ तैनात" #: editor/editor_node.cpp msgid "" "When exporting or deploying, the resulting executable will attempt to " "connect to the IP of this computer in order to be debugged." msgstr "" +"निरà¥à¤¯à¤¾à¤¤ या तैनाती करते समय, परिणामी निषà¥à¤ªà¤¾à¤¦à¤• इस कंपà¥à¤¯à¥‚टर के आईपी से जà¥à¤¡à¤¼à¤¨à¥‡ का पà¥à¤°à¤¯à¤¾à¤¸ करेगा " +"ताकि डिबग किया जा सके।" #: editor/editor_node.cpp msgid "Small Deploy with Network FS" -msgstr "" +msgstr "नेटवरà¥à¤• à¤à¤«à¤à¤¸ के साथ छोटे तैनात" #: editor/editor_node.cpp msgid "" @@ -2747,30 +2778,36 @@ msgid "" "On Android, deploy will use the USB cable for faster performance. This " "option speeds up testing for games with a large footprint." msgstr "" +"जब यह विकलà¥à¤ª सकà¥à¤·à¤® हो जाता है, तो निरà¥à¤¯à¤¾à¤¤ या तैनाती नà¥à¤¯à¥‚नतम निषà¥à¤ªà¤¾à¤¦à¤¿à¤¤ उतà¥à¤ªà¤¾à¤¦à¤¨ करेगी।\n" +"नेटवरà¥à¤• के ऊपर संपादक दà¥à¤µà¤¾à¤°à¤¾ परियोजना से फाइलसिसà¥à¤Ÿà¤® उपलबà¥à¤§ कराया जाà¤à¤—ा।\n" +"à¤à¤‚डà¥à¤°à¥‰à¤¯à¤¡ पर, तैनात तेजी से पà¥à¤°à¤¦à¤°à¥à¤¶à¤¨ के लिठयूà¤à¤¸à¤¬à¥€ केबल का उपयोग करेंगे । यह विकलà¥à¤ª à¤à¤• बड़े " +"पदचिहà¥à¤¨ के साथ खेल के लिठपरीकà¥à¤·à¤£ को गति देता है।" #: editor/editor_node.cpp msgid "Visible Collision Shapes" -msgstr "" +msgstr "दृशà¥à¤¯à¤®à¤¾à¤¨ टकराव आकार" #: editor/editor_node.cpp msgid "" "Collision shapes and raycast nodes (for 2D and 3D) will be visible on the " "running game if this option is turned on." msgstr "" +"यदि यह विकलà¥à¤ª चालू हो जाता है तो टकराव के आकार और रेकासà¥à¤Ÿ नोडà¥à¤¸ (2डी और 3 डी के लिà¤) " +"चल रहे खेल पर दिखाई देंगे।" #: editor/editor_node.cpp msgid "Visible Navigation" -msgstr "" +msgstr "दरà¥à¤¶à¤¨à¥€à¤¯ नेविगेशन" #: editor/editor_node.cpp msgid "" "Navigation meshes and polygons will be visible on the running game if this " "option is turned on." -msgstr "" +msgstr "यदि यह विकलà¥à¤ª चालू हो जाता है तो नेविगेशन मेशेस और बहà¥à¤à¥à¤œ चल रहे खेल पर दिखाई देंगे।" #: editor/editor_node.cpp msgid "Sync Scene Changes" -msgstr "" +msgstr "सिंक सीन बदलता है" #: editor/editor_node.cpp msgid "" @@ -2779,10 +2816,14 @@ msgid "" "When used remotely on a device, this is more efficient with network " "filesystem." msgstr "" +"जब इस विकलà¥à¤ª को चालू किया जाता है, तो संपादक में दृशà¥à¤¯ में किठगठकिसी à¤à¥€ परिवरà¥à¤¤à¤¨ को " +"चल रहे खेल में दोहराया जाà¤à¤—ा।\n" +"जब किसी डिवाइस पर दूर से उपयोग किया जाता है, तो यह नेटवरà¥à¤• फाइलसिसà¥à¤Ÿà¤® के साथ अधिक " +"कà¥à¤¶à¤² होता है।" #: editor/editor_node.cpp msgid "Sync Script Changes" -msgstr "" +msgstr "सिंक सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ परिवरà¥à¤¤à¤¨" #: editor/editor_node.cpp msgid "" @@ -2791,10 +2832,14 @@ msgid "" "When used remotely on a device, this is more efficient with network " "filesystem." msgstr "" +"जब यह विकलà¥à¤ª चालू हो जाà¤à¤—ा, तो सहेजी गई किसी à¤à¥€ सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ को चल रहे गेम पर फिर से लोड " +"किया जाà¤à¤—ा।\n" +"जब किसी डिवाइस पर दूर से उपयोग किया जाता है, तो यह नेटवरà¥à¤• फाइलसिसà¥à¤Ÿà¤® के साथ अधिक " +"कà¥à¤¶à¤² होता है।" #: editor/editor_node.cpp editor/script_create_dialog.cpp msgid "Editor" -msgstr "" +msgstr "संपादक" #: editor/editor_node.cpp #, fuzzy @@ -2803,47 +2848,47 @@ msgstr "अनà¥à¤µà¤¾à¤¦ में बदलाव करें:" #: editor/editor_node.cpp msgid "Editor Layout" -msgstr "" +msgstr "संपादक लेआउट" #: editor/editor_node.cpp msgid "Take Screenshot" -msgstr "" +msgstr "सà¥à¤•à¥à¤°à¥€à¤¨à¤¶à¥‰à¤Ÿ लें" #: editor/editor_node.cpp msgid "Screenshots are stored in the Editor Data/Settings Folder." -msgstr "" +msgstr "सà¥à¤•à¥à¤°à¥€à¤¨à¤¶à¥‰à¤Ÿ à¤à¤¡à¤¿à¤Ÿà¤° डेटा/सेटिंगà¥à¤¸ फोलà¥à¤¡à¤° में सà¥à¤Ÿà¥‹à¤° किठजाते हैं ।" #: editor/editor_node.cpp msgid "Toggle Fullscreen" -msgstr "" +msgstr "पूरà¥à¤£à¤¸à¥à¤•à¥à¤°à¥€à¤¨ चालू करें" #: editor/editor_node.cpp msgid "Toggle System Console" -msgstr "" +msgstr "टॉगल सिसà¥à¤Ÿà¤® कंसोल" #: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" -msgstr "" +msgstr "संपादक डेटा / सेटिंगà¥à¤¸ फ़ोलà¥à¤¡à¤° खोलें" #: editor/editor_node.cpp msgid "Open Editor Data Folder" -msgstr "" +msgstr "संपादक डेटा फ़ोलà¥à¤¡à¤° खोलें" #: editor/editor_node.cpp msgid "Open Editor Settings Folder" -msgstr "" +msgstr "ओपन à¤à¤¡à¤¿à¤Ÿà¤° सेटिंगफ़र" #: editor/editor_node.cpp msgid "Manage Editor Features..." -msgstr "" +msgstr "संपादक सà¥à¤µà¤¿à¤§à¤¾à¤à¤ पà¥à¤°à¤¬à¤‚धित करें ..." #: editor/editor_node.cpp msgid "Manage Export Templates..." -msgstr "" +msgstr "निरà¥à¤¯à¤¾à¤¤ टेमà¥à¤ªà¤²à¥‡à¤Ÿà¥à¤¸ का पà¥à¤°à¤¬à¤‚धन करें ..." #: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp msgid "Help" -msgstr "" +msgstr "मदद" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp @@ -2852,19 +2897,23 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp editor/rename_dialog.cpp msgid "Search" -msgstr "" +msgstr "ढूंढें" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Online Docs" -msgstr "" +msgstr "ऑनलाइन डॉकà¥à¤¸" #: editor/editor_node.cpp msgid "Q&A" +msgstr "Q&A" + +#: editor/editor_node.cpp +msgid "Report a Bug" msgstr "" #: editor/editor_node.cpp -msgid "Issue Tracker" +msgid "Send Docs Feedback" msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp @@ -2877,92 +2926,92 @@ msgstr "के बारे में" #: editor/editor_node.cpp msgid "Play the project." -msgstr "" +msgstr "पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ चलाà¤à¤‚।" #: editor/editor_node.cpp msgid "Play" -msgstr "" +msgstr "खेल" #: editor/editor_node.cpp msgid "Pause the scene execution for debugging." -msgstr "" +msgstr "डिबगिंग के लिठदृशà¥à¤¯ निषà¥à¤ªà¤¾à¤¦à¤¨ को रोकें।" #: editor/editor_node.cpp msgid "Pause Scene" -msgstr "" +msgstr "दृशà¥à¤¯ रोकें" #: editor/editor_node.cpp msgid "Stop the scene." -msgstr "" +msgstr "सीन बंद करो।" #: editor/editor_node.cpp msgid "Play the edited scene." -msgstr "" +msgstr "संपादित दृशà¥à¤¯ खेलते हैं।" #: editor/editor_node.cpp msgid "Play Scene" -msgstr "" +msgstr "पà¥à¤²à¥‡ सीन" #: editor/editor_node.cpp msgid "Play custom scene" -msgstr "" +msgstr "कसà¥à¤Ÿà¤® दृशà¥à¤¯ बजाना" #: editor/editor_node.cpp msgid "Play Custom Scene" -msgstr "" +msgstr "कसà¥à¤Ÿà¤® दृशà¥à¤¯ बजाना" #: editor/editor_node.cpp msgid "Changing the video driver requires restarting the editor." -msgstr "" +msgstr "वीडियो डà¥à¤°à¤¾à¤‡à¤µà¤° को बदलने के लिठसंपादक को फिर से शà¥à¤°à¥‚ करने की आवशà¥à¤¯à¤•ता होती है।" #: editor/editor_node.cpp editor/project_settings_editor.cpp #: editor/settings_config_dialog.cpp msgid "Save & Restart" -msgstr "" +msgstr "सहेजें और पà¥à¤¨à¤ƒ आरंठकरें" #: editor/editor_node.cpp msgid "Spins when the editor window redraws." -msgstr "" +msgstr "जब संपादक खिड़की फिर से खींचता है तो सà¥à¤ªà¤¿à¤¨ करता है।" #: editor/editor_node.cpp msgid "Update Continuously" -msgstr "" +msgstr "लगातार अपडेट करें" #: editor/editor_node.cpp msgid "Update When Changed" -msgstr "" +msgstr "जब बदला अदà¥à¤¯à¤¤à¤¨" #: editor/editor_node.cpp msgid "Hide Update Spinner" -msgstr "" +msgstr "अपडेट सà¥à¤ªà¤¿à¤¨à¤° को छिपाà¤à¤‚" #: editor/editor_node.cpp msgid "FileSystem" -msgstr "" +msgstr "फ़ाइल" #: editor/editor_node.cpp msgid "Inspector" -msgstr "" +msgstr "निरीकà¥à¤·à¤•" #: editor/editor_node.cpp msgid "Expand Bottom Panel" -msgstr "" +msgstr "बॉटम पैनल का विसà¥à¤¤à¤¾à¤° करें" #: editor/editor_node.cpp msgid "Output" -msgstr "" +msgstr "आउटपà¥à¤Ÿ" #: editor/editor_node.cpp msgid "Don't Save" -msgstr "" +msgstr "सहेजें मत करो" #: editor/editor_node.cpp msgid "Android build template is missing, please install relevant templates." -msgstr "" +msgstr "à¤à¤‚डà¥à¤°à¥‰à¤‡à¤¡ बिलà¥à¤¡ टेमà¥à¤ªà¤²à¥‡à¤Ÿ गायब है, कृपया पà¥à¤°à¤¾à¤¸à¤‚गिक टेमà¥à¤ªà¤²à¥‡à¤Ÿà¥à¤¸ सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करें।" #: editor/editor_node.cpp msgid "Manage Templates" -msgstr "" +msgstr "टेमà¥à¤ªà¤²à¥‡à¤Ÿà¥à¤¸ का पà¥à¤°à¤¬à¤‚धन करें" #: editor/editor_node.cpp msgid "" @@ -2974,6 +3023,12 @@ msgid "" "the \"Use Custom Build\" option should be enabled in the Android export " "preset." msgstr "" +"यह \"res://android/build\" के लिठसà¥à¤°à¥‹à¤¤ टेमà¥à¤ªà¤²à¥‡à¤Ÿ सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करके कसà¥à¤Ÿà¤® à¤à¤‚डà¥à¤°à¥‰à¤‡à¤¡ बिलà¥à¤¡ के " +"लिठआपकी परियोजना सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करेगा।\n" +"फिर आप संशोधनों को लागू कर सकते हैं और निरà¥à¤¯à¤¾à¤¤ पर अपना खà¥à¤¦ का कसà¥à¤Ÿà¤® à¤à¤ªà¥€à¤•े बना सकते हैं " +"(मॉडà¥à¤¯à¥‚ल जोड़ना, AndroidManifest.xml, आदि बदलना)।\n" +"धà¥à¤¯à¤¾à¤¨ दें कि पूरà¥à¤µ-निरà¥à¤®à¤¿à¤¤ à¤à¤ªà¥€à¤•े का उपयोग करने के बजाय कसà¥à¤Ÿà¤® बिलà¥à¤¡ बनाने के लिà¤, à¤à¤‚डà¥à¤°à¥‰à¤‡à¤¡ " +"निरà¥à¤¯à¤¾à¤¤ पूरà¥à¤µ निरà¥à¤§à¤¾à¤°à¤¿à¤¤ में \"उपयोग कसà¥à¤Ÿà¤® बिलà¥à¤¡\" विकलà¥à¤ª सकà¥à¤·à¤® किया जाना चाहिà¤à¥¤" #: editor/editor_node.cpp msgid "" @@ -2982,66 +3037,70 @@ msgid "" "Remove the \"res://android/build\" directory manually before attempting this " "operation again." msgstr "" +"à¤à¤‚डà¥à¤°à¥‰à¤¯à¤¡ बिलà¥à¤¡ टेमà¥à¤ªà¤²à¥‡à¤Ÿ पहले से ही इस परियोजना में सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ है और यह अधिक नहीं लिखा जाà¤à¤—ा " +"।\n" +"इस ऑपरेशन को फिर से पà¥à¤°à¤¯à¤¾à¤¸ करने से पहले मैनà¥à¤¯à¥à¤…ल रूप से \"res://android/build\" " +"निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा निकालें।" #: editor/editor_node.cpp msgid "Import Templates From ZIP File" -msgstr "" +msgstr "जिप फाइल से आयात टेमà¥à¤ªà¤²à¥‡à¤Ÿà¥à¤¸" #: editor/editor_node.cpp msgid "Template Package" -msgstr "" +msgstr "टेमà¥à¤ªà¤²à¥‡à¤Ÿ पैकेज" #: editor/editor_node.cpp msgid "Export Library" -msgstr "" +msgstr "à¤à¤•à¥à¤¸à¤ªà¥‹à¤°à¥à¤Ÿ लाइबà¥à¤°à¥‡à¤°à¥€" #: editor/editor_node.cpp msgid "Merge With Existing" -msgstr "" +msgstr "मौजूदा के साथ विलय" #: editor/editor_node.cpp msgid "Open & Run a Script" -msgstr "" +msgstr "ओपन à¤à¤‚ड रन à¤à¤• सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ" #: editor/editor_node.cpp msgid "New Inherited" -msgstr "" +msgstr "नई विरासत में मिली" #: editor/editor_node.cpp msgid "Load Errors" -msgstr "" +msgstr "लोड तà¥à¤°à¥à¤Ÿà¤¿à¤¯à¤¾à¤‚" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp msgid "Select" -msgstr "" +msgstr "चà¥à¤¨à¥‡à¤‚" #: editor/editor_node.cpp msgid "Open 2D Editor" -msgstr "" +msgstr "ओपन 2D संपादक" #: editor/editor_node.cpp msgid "Open 3D Editor" -msgstr "" +msgstr "ओपन 3डी à¤à¤¡à¤¿à¤Ÿà¤°" #: editor/editor_node.cpp msgid "Open Script Editor" -msgstr "" +msgstr "ओपन सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ à¤à¤¡à¤¿à¤Ÿà¤°" #: editor/editor_node.cpp editor/project_manager.cpp msgid "Open Asset Library" -msgstr "" +msgstr "ओपन à¤à¤¸à¥‡à¤Ÿ लाइबà¥à¤°à¥‡à¤°à¥€" #: editor/editor_node.cpp msgid "Open the next Editor" -msgstr "" +msgstr "अगले संपादक खोलें" #: editor/editor_node.cpp msgid "Open the previous Editor" -msgstr "" +msgstr "पिछले संपादक खोलें" #: editor/editor_node.h msgid "Warning!" -msgstr "" +msgstr "चेतावनी!" #: editor/editor_path.cpp #, fuzzy @@ -3050,11 +3109,11 @@ msgstr "संसाधन" #: editor/editor_plugin.cpp msgid "Creating Mesh Previews" -msgstr "" +msgstr "मेष पूरà¥à¤µà¤¾à¤µà¤²à¥‹à¤•न बनाना" #: editor/editor_plugin.cpp msgid "Thumbnail..." -msgstr "" +msgstr "थंबनेल..." #: editor/editor_plugin_settings.cpp #, fuzzy @@ -3063,72 +3122,72 @@ msgstr "निरà¥à¤à¤°à¤¤à¤¾ संपादक" #: editor/editor_plugin_settings.cpp msgid "Edit Plugin" -msgstr "" +msgstr "पà¥à¤²à¤—इन को संपादित करें" #: editor/editor_plugin_settings.cpp msgid "Installed Plugins:" -msgstr "" +msgstr "सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ पà¥à¤²à¤—इनà¥à¤¸:" #: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp msgid "Update" -msgstr "" +msgstr "अदà¥à¤¯à¤¤à¤¨" #: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Version:" -msgstr "" +msgstr "संसà¥à¤•रण:" #: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp msgid "Author:" -msgstr "" +msgstr "लेखक:" #: editor/editor_plugin_settings.cpp msgid "Status:" -msgstr "" +msgstr "सà¥à¤¥à¤¿à¤¤à¤¿:" #: editor/editor_plugin_settings.cpp msgid "Edit:" -msgstr "" +msgstr "संपादित:" #: editor/editor_profiler.cpp msgid "Measure:" -msgstr "" +msgstr "рдорд╛рдк:" #: editor/editor_profiler.cpp msgid "Frame Time (sec)" -msgstr "" +msgstr "फà¥à¤°à¥‡à¤® समय (सेकंड)" #: editor/editor_profiler.cpp msgid "Average Time (sec)" -msgstr "" +msgstr "औसत समय (सेकंड)" #: editor/editor_profiler.cpp msgid "Frame %" -msgstr "" +msgstr "फ़à¥à¤°à¥‡à¤®%" #: editor/editor_profiler.cpp msgid "Physics Frame %" -msgstr "" +msgstr "फिजिकà¥à¤¸ फà¥à¤°à¥‡à¤® %" #: editor/editor_profiler.cpp msgid "Inclusive" -msgstr "" +msgstr "समावेशी" #: editor/editor_profiler.cpp msgid "Self" -msgstr "" +msgstr "सà¥à¤µà¤¯à¤‚" #: editor/editor_profiler.cpp msgid "Frame #:" -msgstr "" +msgstr "फà¥à¤°à¥‡à¤® #:" #: editor/editor_profiler.cpp msgid "Time" -msgstr "" +msgstr "समय" #: editor/editor_profiler.cpp msgid "Calls" -msgstr "" +msgstr "कॉल" #: editor/editor_properties.cpp #, fuzzy @@ -3137,23 +3196,23 @@ msgstr "परिवरà¥à¤¤à¤¨ वकà¥à¤° चयन" #: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" -msgstr "" +msgstr "पर" #: editor/editor_properties.cpp msgid "Layer" -msgstr "" +msgstr "परत" #: editor/editor_properties.cpp msgid "Bit %d, value %d" -msgstr "" +msgstr "बिट%d, मूलà¥à¤¯ % डी" #: editor/editor_properties.cpp msgid "[Empty]" -msgstr "" +msgstr "[खाली]" #: editor/editor_properties.cpp editor/plugins/root_motion_editor_plugin.cpp msgid "Assign..." -msgstr "" +msgstr "सौंपना..." #: editor/editor_properties.cpp #, fuzzy @@ -3165,12 +3224,15 @@ msgid "" "The selected resource (%s) does not match any type expected for this " "property (%s)." msgstr "" +"चयनित संसाधन (%s) इस संपतà¥à¤¤à¤¿ (% à¤à¤¸) के लिठअपेकà¥à¤·à¤¿à¤¤ किसी à¤à¥€ पà¥à¤°à¤•ार से मेल नहीं खाता है।" #: editor/editor_properties.cpp msgid "" "Can't create a ViewportTexture on resources saved as a file.\n" "Resource needs to belong to a scene." msgstr "" +"फ़ाइल के रूप में सहेजे गठसंसाधनों पर वà¥à¤¯à¥‚पोरà¥à¤Ÿà¤Ÿà¥‡à¤•à¥à¤¸à¤šà¤° नहीं बना सकते.\n" +"संसाधन के लिठà¤à¤• दृशà¥à¤¯ से संबंधित की जरूरत है ।" #: editor/editor_properties.cpp msgid "" @@ -3179,26 +3241,28 @@ msgid "" "Please switch on the 'local to scene' property on it (and all resources " "containing it up to a node)." msgstr "" +"इस संसाधन पर वà¥à¤¯à¥‚पोरà¥à¤Ÿà¤Ÿà¥‡à¤•à¥à¤¸à¤šà¤° नहीं बना सकते कà¥à¤¯à¥‹à¤‚कि यह सà¥à¤¥à¤¾à¤¨à¥€à¤¯ से दृशà¥à¤¯ के रूप में सेट नहीं है।\n" +"कृपया उस पर 'सà¥à¤¥à¤¾à¤¨à¥€à¤¯ से दृशà¥à¤¯' संपतà¥à¤¤à¤¿ पर सà¥à¤µà¤¿à¤š करें (और इसे यà¥à¤•à¥à¤¤ सà¤à¥€ संसाधन à¤à¤• नोड तक)।" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "Pick a Viewport" -msgstr "" +msgstr "वà¥à¤¯à¥‚पोरà¥à¤Ÿ चà¥à¤¨à¥‡à¤‚" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "New Script" -msgstr "" +msgstr "नई सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ" #: editor/editor_properties.cpp editor/scene_tree_dock.cpp msgid "Extend Script" -msgstr "" +msgstr "सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ बढ़ाà¤à¤" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "New %s" -msgstr "" +msgstr "नया%s" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "Make Unique" -msgstr "" +msgstr "अदà¥à¤µà¤¿à¤¤à¥€à¤¯ बनाओ" #: editor/editor_properties.cpp #: editor/plugins/animation_blend_space_1d_editor.cpp @@ -3212,193 +3276,197 @@ msgstr "" #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" -msgstr "" +msgstr "चिपकाà¤à¤" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "Convert To %s" -msgstr "" +msgstr "% à¤à¤¸ में परिवरà¥à¤¤à¤¿à¤¤ करें" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "Selected node is not a Viewport!" -msgstr "" +msgstr "चयनित नोड वà¥à¤¯à¥‚पोरà¥à¤Ÿ नहीं है!" #: editor/editor_properties_array_dict.cpp msgid "Size: " -msgstr "" +msgstr "आकार: " #: editor/editor_properties_array_dict.cpp msgid "Page: " -msgstr "" +msgstr "पृषà¥à¤ : " #: editor/editor_properties_array_dict.cpp #: editor/plugins/theme_editor_plugin.cpp msgid "Remove Item" -msgstr "" +msgstr "आइटम निकालें" #: editor/editor_properties_array_dict.cpp msgid "New Key:" -msgstr "" +msgstr "नई कà¥à¤‚जी:" #: editor/editor_properties_array_dict.cpp msgid "New Value:" -msgstr "" +msgstr "नया मूलà¥à¤¯:" #: editor/editor_properties_array_dict.cpp msgid "Add Key/Value Pair" -msgstr "" +msgstr "कà¥à¤‚जी/मूलà¥à¤¯ जोड़ी जोड़ें" #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" "Please add a runnable preset in the export menu." msgstr "" +"इस मंच के लिठकोई रननयोगà¥à¤¯ निरà¥à¤¯à¤¾à¤¤ पूरà¥à¤µ निरà¥à¤§à¤¾à¤°à¤¿à¤¤ नहीं मिला।\n" +"कृपया निरà¥à¤¯à¤¾à¤¤ मेनू में à¤à¤• रननेबल पà¥à¤°à¥€à¤¸à¥‡à¤Ÿ जोड़ें।" #: editor/editor_run_script.cpp msgid "Write your logic in the _run() method." -msgstr "" +msgstr "अपने तरà¥à¤• को _run () विधि में लिखें।" #: editor/editor_run_script.cpp msgid "There is an edited scene already." -msgstr "" +msgstr "वहां à¤à¤• संपादित दृशà¥à¤¯ पहले से ही है ।" #: editor/editor_run_script.cpp msgid "Couldn't instance script:" -msgstr "" +msgstr "उदाहरण सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ नहीं कर सका:" #: editor/editor_run_script.cpp msgid "Did you forget the 'tool' keyword?" -msgstr "" +msgstr "कà¥à¤¯à¤¾ आप 'टूल' कीवरà¥à¤¡ à¤à¥‚ल गà¤?" #: editor/editor_run_script.cpp msgid "Couldn't run script:" -msgstr "" +msgstr "सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ नहीं चला सका:" #: editor/editor_run_script.cpp msgid "Did you forget the '_run' method?" -msgstr "" +msgstr "कà¥à¤¯à¤¾ आप '_run' विधि को à¤à¥‚ल गà¤?" #: editor/editor_sub_scene.cpp msgid "Select Node(s) to Import" -msgstr "" +msgstr "आयात करने के लिठनोड (à¤à¤¸) का चयन करें" #: editor/editor_sub_scene.cpp editor/project_manager.cpp msgid "Browse" -msgstr "" +msgstr "बà¥à¤°à¤¾à¤‰à¤œà¤¼" #: editor/editor_sub_scene.cpp msgid "Scene Path:" -msgstr "" +msgstr "दृशà¥à¤¯ पथ:" #: editor/editor_sub_scene.cpp msgid "Import From Node:" -msgstr "" +msgstr "नोड से आयात:" #: editor/export_template_manager.cpp msgid "Redownload" -msgstr "" +msgstr "रीडाउनलोड करें" #: editor/export_template_manager.cpp msgid "Uninstall" -msgstr "" +msgstr "अनइंसà¥à¤Ÿà¤¾à¤² करें" #: editor/export_template_manager.cpp msgid "(Installed)" -msgstr "" +msgstr "(सà¥à¤¥à¤¾à¤ªà¤¿à¤¤)" #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Download" -msgstr "" +msgstr "डाउनलोड" #: editor/export_template_manager.cpp msgid "Official export templates aren't available for development builds." -msgstr "" +msgstr "विकास के निरà¥à¤®à¤¾à¤£ के लिठआधिकारिक निरà¥à¤¯à¤¾à¤¤ टेमà¥à¤ªà¤²à¥‡à¤Ÿà¤‰à¤ªà¤²à¤¬à¥à¤§ नहीं हैं।" #: editor/export_template_manager.cpp msgid "(Missing)" -msgstr "" +msgstr "(लापता)" #: editor/export_template_manager.cpp msgid "(Current)" -msgstr "" +msgstr "(वरà¥à¤¤à¤®à¤¾à¤¨)" #: editor/export_template_manager.cpp msgid "Retrieving mirrors, please wait..." -msgstr "" +msgstr "दरà¥à¤ªà¤£ को पà¥à¤¨à¤ƒ पà¥à¤°à¤¾à¤ªà¥à¤¤ करना, कृपया पà¥à¤°à¤¤à¥€à¤•à¥à¤·à¤¾ करें ..." #: editor/export_template_manager.cpp msgid "Remove template version '%s'?" -msgstr "" +msgstr "टेमà¥à¤ªà¤²à¥‡à¤Ÿ संसà¥à¤•रण '%s'?" #: editor/export_template_manager.cpp msgid "Can't open export templates zip." -msgstr "" +msgstr "निरà¥à¤¯à¤¾à¤¤ टेमà¥à¤ªà¤²à¥‡à¤Ÿà¥à¤¸ ज़िप नहीं खोल सकते।" #: editor/export_template_manager.cpp msgid "Invalid version.txt format inside templates: %s." -msgstr "" +msgstr "टेमà¥à¤ªà¤²à¥‡à¤Ÿà¥à¤¸ के अंदर अमानà¥à¤¯ संसà¥à¤•रण.txt पà¥à¤°à¤¾à¤°à¥‚प: % à¤à¤¸à¥¤" #: editor/export_template_manager.cpp msgid "No version.txt found inside templates." -msgstr "" +msgstr "टेमà¥à¤ªà¤²à¥‡à¤Ÿà¥à¤¸ के अंदर कोई संसà¥à¤•रण.txt नहीं मिला।" #: editor/export_template_manager.cpp msgid "Error creating path for templates:" -msgstr "" +msgstr "टेमà¥à¤ªà¤²à¥‡à¤Ÿà¥à¤¸ के लिठपथ बनाने में तà¥à¤°à¥à¤Ÿà¤¿:" #: editor/export_template_manager.cpp msgid "Extracting Export Templates" -msgstr "" +msgstr "à¤à¤•à¥à¤¸à¤ªà¥‹à¤°à¥à¤Ÿ टेमà¥à¤ªà¤²à¥‡à¤Ÿà¥à¤¸ निकालना" #: editor/export_template_manager.cpp msgid "Importing:" -msgstr "" +msgstr "आयात:" #: editor/export_template_manager.cpp msgid "Error getting the list of mirrors." -msgstr "" +msgstr "तà¥à¤°à¥à¤Ÿà¤¿ दरà¥à¤ªà¤£ की सूची हो रही है।" #: editor/export_template_manager.cpp msgid "Error parsing JSON of mirror list. Please report this issue!" -msgstr "" +msgstr "मिरर लिसà¥à¤Ÿ की तà¥à¤°à¥à¤Ÿà¤¿ पारà¥à¤¸à¤¿à¤‚ग जेसन । कृपया इस मà¥à¤¦à¥à¤¦à¥‡ की रिपोरà¥à¤Ÿ करें!" #: editor/export_template_manager.cpp msgid "" "No download links found for this version. Direct download is only available " "for official releases." msgstr "" +"इस संसà¥à¤•रण के लिठकोई डाउनलोड लिंक नहीं मिला। पà¥à¤°à¤¤à¥à¤¯à¤•à¥à¤· डाउनलोड केवल आधिकारिक रिलीज के " +"लिठउपलबà¥à¤§ है।" #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Can't resolve." -msgstr "" +msgstr "हल नहीं कर सकते।" #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Can't connect." -msgstr "" +msgstr "कनेकà¥à¤Ÿ नहीं कर सकते।" #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "No response." -msgstr "" +msgstr "कोई जवाब नहीं।" #: editor/export_template_manager.cpp msgid "Request Failed." -msgstr "" +msgstr "अनà¥à¤°à¥‹à¤§ विफल रहा।" #: editor/export_template_manager.cpp msgid "Redirect Loop." -msgstr "" +msgstr "लूप को रीडायरेकà¥à¤Ÿ करते हैं।" #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Failed:" -msgstr "" +msgstr "विफल:" #: editor/export_template_manager.cpp msgid "Download Complete." -msgstr "" +msgstr "पूरा डाउनलोड करें।" #: editor/export_template_manager.cpp #, fuzzy @@ -3410,6 +3478,8 @@ msgid "" "Templates installation failed.\n" "The problematic templates archives can be found at '%s'." msgstr "" +"टेमà¥à¤ªà¤²à¥‡à¤Ÿà¥à¤¸ सà¥à¤¥à¤¾à¤ªà¤¨à¤¾ विफल रही।\n" +"समसà¥à¤¯à¤¾à¤—à¥à¤°à¤¸à¥à¤¤ टेमà¥à¤ªà¤²à¥‡à¤Ÿà¥à¤¸ अà¤à¤¿à¤²à¥‡à¤–ागार '%' पर पाया जा सकता है।" #: editor/export_template_manager.cpp msgid "Error requesting URL:" @@ -3417,24 +3487,24 @@ msgstr "लोड होने मे तà¥à¤°à¥à¤Ÿà¤¿:" #: editor/export_template_manager.cpp msgid "Connecting to Mirror..." -msgstr "" +msgstr "मिरर से कनेकà¥à¤Ÿ..." #: editor/export_template_manager.cpp msgid "Disconnected" -msgstr "" +msgstr "डिसà¥à¤•नेकà¥à¤Ÿ" #: editor/export_template_manager.cpp msgid "Resolving" -msgstr "" +msgstr "समाधान" #: editor/export_template_manager.cpp msgid "Can't Resolve" -msgstr "" +msgstr "हल नहीं कर सकते" #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Connecting..." -msgstr "" +msgstr "जोड़ने..." #: editor/export_template_manager.cpp msgid "Can't Connect" @@ -3442,24 +3512,24 @@ msgstr "कनेकà¥à¤Ÿ नहीं कर सकते" #: editor/export_template_manager.cpp msgid "Connected" -msgstr "" +msgstr "जà¥à¤¡à¤¼à¤¾" #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Requesting..." -msgstr "" +msgstr "अनà¥à¤°à¥‹à¤§..." #: editor/export_template_manager.cpp msgid "Downloading" -msgstr "" +msgstr "डाउनलोड" #: editor/export_template_manager.cpp msgid "Connection Error" -msgstr "" +msgstr "कनेकà¥à¤¶à¤¨ तà¥à¤°à¥à¤Ÿà¤¿" #: editor/export_template_manager.cpp msgid "SSL Handshake Error" -msgstr "" +msgstr "à¤à¤¸à¤à¤¸à¤à¤² हैंडशेक à¤à¤°à¤°" #: editor/export_template_manager.cpp msgid "Uncompressing Android Build Sources" @@ -3467,19 +3537,19 @@ msgstr "अनकॉमिंग à¤à¤‚डà¥à¤°à¥‰à¤‡à¤¡ बिलà¥à¤¡ सॠ#: editor/export_template_manager.cpp msgid "Current Version:" -msgstr "" +msgstr "वरà¥à¤¤à¤®à¤¾à¤¨ संसà¥à¤•रण:" #: editor/export_template_manager.cpp msgid "Installed Versions:" -msgstr "" +msgstr "सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ संसà¥à¤•रण:" #: editor/export_template_manager.cpp msgid "Install From File" -msgstr "" +msgstr "फ़ाइल से इंसà¥à¤Ÿà¥‰à¤² करें" #: editor/export_template_manager.cpp msgid "Remove Template" -msgstr "" +msgstr "टेमà¥à¤ªà¤²à¥‡à¤Ÿ निकालें" #: editor/export_template_manager.cpp msgid "Select Template File" @@ -3487,19 +3557,19 @@ msgstr "टेमà¥à¤ªà¤²à¥‡à¤Ÿ फ़ाइल का चयन करें" #: editor/export_template_manager.cpp msgid "Godot Export Templates" -msgstr "" +msgstr "गोडॉट à¤à¤•à¥à¤¸à¤ªà¥‹à¤°à¥à¤Ÿ टेमà¥à¤ªà¤²à¥‡à¤Ÿà¥à¤¸" #: editor/export_template_manager.cpp msgid "Export Template Manager" -msgstr "" +msgstr "à¤à¤•à¥à¤¸à¤ªà¥‹à¤°à¥à¤Ÿ टेमà¥à¤ªà¤²à¥‡à¤Ÿ मैनेजर" #: editor/export_template_manager.cpp msgid "Download Templates" -msgstr "" +msgstr "टेमà¥à¤ªà¤²à¥‡à¤Ÿà¥à¤¸ डाउनलोड करें" #: editor/export_template_manager.cpp msgid "Select mirror from list: (Shift+Click: Open in Browser)" -msgstr "" +msgstr "सूची से दरà¥à¤ªà¤£ चà¥à¤¨à¥‡à¤‚: (शिफà¥à¤Ÿ +कà¥à¤²à¤¿à¤•: बà¥à¤°à¤¾à¤‰à¤œà¤¼à¤° में खà¥à¤²à¤¾)" #: editor/filesystem_dock.cpp msgid "Favorites" @@ -3508,14 +3578,15 @@ msgstr "पसंद" #: editor/filesystem_dock.cpp msgid "Status: Import of file failed. Please fix file and reimport manually." msgstr "" +"सà¥à¤¥à¤¿à¤¤à¤¿: फाइल का आयात विफल रहा। कृपया फाइल को ठीक करें और मैनà¥à¤¯à¥à¤…ल रूप से पà¥à¤¨à¤°à¥à¤†à¤¯à¤¾à¤¤ करें।" #: editor/filesystem_dock.cpp msgid "Cannot move/rename resources root." -msgstr "" +msgstr "संसाधनों की जड़ को सà¥à¤¥à¤¾à¤¨à¤¾à¤‚तरित/नाम नहीं दे सकते ।" #: editor/filesystem_dock.cpp msgid "Cannot move a folder into itself." -msgstr "" +msgstr "फ़ोलà¥à¤¡à¤° को अपने आप में नहीं ले जा सकते।" #: editor/filesystem_dock.cpp msgid "Error moving:" @@ -3531,11 +3602,11 @@ msgstr "निरà¥à¤à¤°à¤¤à¤¾ को अपडेट करने में à #: editor/filesystem_dock.cpp editor/scene_tree_editor.cpp msgid "No name provided." -msgstr "" +msgstr "कोई नाम पà¥à¤°à¤¦à¤¾à¤¨ नहीं किया गया।" #: editor/filesystem_dock.cpp msgid "Provided name contains invalid characters." -msgstr "" +msgstr "बशरà¥à¤¤à¥‡ नाम में अमानà¥à¤¯ पातà¥à¤° होते हैं।" #: editor/filesystem_dock.cpp msgid "A file or folder with this name already exists." @@ -3890,7 +3961,7 @@ msgid "Reimport" msgstr "" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -6691,14 +6762,6 @@ msgid "Open Godot online documentation." msgstr "" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7136,6 +7199,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7224,13 +7291,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -10633,6 +10700,12 @@ msgid "Script file already exists." msgstr "" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "" @@ -12280,6 +12353,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." @@ -12311,6 +12388,9 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#~ msgid "Issue Tracker" +#~ msgstr "मà¥à¤¦à¥à¤¦à¤¾ पर नज़र रखने वाला" + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "बदल दिया % डी घटना (à¤à¤¸) ।" diff --git a/editor/translations/hr.po b/editor/translations/hr.po index ce8191c638..5087044b13 100644 --- a/editor/translations/hr.po +++ b/editor/translations/hr.po @@ -1423,7 +1423,7 @@ msgstr "" msgid "Remove Autoload" msgstr "" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "" @@ -2829,7 +2829,11 @@ msgid "Q&A" msgstr "" #: editor/editor_node.cpp -msgid "Issue Tracker" +msgid "Report a Bug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp @@ -3855,7 +3859,7 @@ msgid "Reimport" msgstr "" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -6654,14 +6658,6 @@ msgid "Open Godot online documentation." msgstr "" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7091,6 +7087,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7179,13 +7179,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -10526,6 +10526,12 @@ msgid "Script file already exists." msgstr "" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "" @@ -12154,6 +12160,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/hu.po b/editor/translations/hu.po index cbe475b022..54206db36f 100644 --- a/editor/translations/hu.po +++ b/editor/translations/hu.po @@ -1507,7 +1507,7 @@ msgstr "AutoLoad Ãthelyezése" msgid "Remove Autoload" msgstr "AutoLoad EltávolÃtása" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "Engedélyezés" @@ -3075,8 +3075,13 @@ msgid "Q&A" msgstr "Kérdések és Válaszok" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "ProblémakövetÅ‘" +#, fuzzy +msgid "Report a Bug" +msgstr "Újraimportálás" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4167,7 +4172,7 @@ msgid "Reimport" msgstr "Újraimportálás" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -7177,14 +7182,6 @@ msgid "Open Godot online documentation." msgstr "Godot online dokumentáció megnyitása" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "Keresés a referencia dokumentációban." @@ -7645,6 +7642,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7735,13 +7736,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -11270,6 +11271,12 @@ msgid "Script file already exists." msgstr "Már létezik '%s' AutoLoad!" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp #, fuzzy msgid "Class Name:" msgstr "Osztály:" @@ -12954,6 +12961,10 @@ msgstr "" "gyermekévé, hogy Ãgy kapjon méretet. EllenkezÅ‘ esetben tegye RenderTarget-" "té, és állÃtsa hozzá a belsÅ‘ textúráját valamilyen node-hoz kirajzolásra." +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." @@ -12985,6 +12996,9 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#~ msgid "Issue Tracker" +#~ msgstr "ProblémakövetÅ‘" + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "Lecserélve %d elÅ‘fordulás." diff --git a/editor/translations/id.po b/editor/translations/id.po index c4ead514c6..087a274249 100644 --- a/editor/translations/id.po +++ b/editor/translations/id.po @@ -25,12 +25,13 @@ # Akhmad Zulfikar <azuldegratz@gmail.com>, 2020. # Ade Fikri Malihuddin <ade.fm97@gmail.com>, 2020. # zephyroths <ridho.hikaru@gmail.com>, 2020. +# Richard Urban <redasuio1@gmail.com>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-03-08 22:33+0000\n" -"Last-Translator: Sofyan Sugianto <sofyanartem@gmail.com>\n" +"PO-Revision-Date: 2020-04-16 11:03+0000\n" +"Last-Translator: Richard Urban <redasuio1@gmail.com>\n" "Language-Team: Indonesian <https://hosted.weblate.org/projects/godot-engine/" "godot/id/>\n" "Language: id\n" @@ -38,7 +39,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.0-dev\n" +"X-Generator: Weblate 4.0.1-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -1462,7 +1463,7 @@ msgstr "Pindahkan Autoload" msgid "Remove Autoload" msgstr "Hapus Autoload" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "Aktifkan" @@ -2947,8 +2948,13 @@ msgid "Q&A" msgstr "Tanya Jawab" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "Pelacak Isu" +#, fuzzy +msgid "Report a Bug" +msgstr "Impor ulang" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4000,7 +4006,8 @@ msgid "Reimport" msgstr "Impor ulang" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +#, fuzzy +msgid "Save Scenes, Re-Import, and Restart" msgstr "Simpan skena, impor ulang, dan mulai ulang" #: editor/import_dock.cpp @@ -5874,7 +5881,6 @@ msgid "Couldn't create a single convex collision shape." msgstr "Tidak dapat membuat convex collision shape tunggal." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Single Convex Shape" msgstr "Buat Bentuk Cembung" @@ -5887,7 +5893,6 @@ msgid "Couldn't create any collision shapes." msgstr "Tidak dapat membuat bentuk collision." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Multiple Convex Shapes" msgstr "Buat Beberapa Bentuk Cembung" @@ -5964,7 +5969,6 @@ msgstr "" "collision." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Single Convex Collision Sibling" msgstr "Buat Saudara Tunggal Convex Collision" @@ -6855,14 +6859,6 @@ msgid "Open Godot online documentation." msgstr "Buka dokumentasi daring Godot." #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "Minta Dokumentasi" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "Bantu tingkatkan dokumentasi Godot dengan memberikan tanggapan." - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "Cari dokumentasi referensi." @@ -7301,6 +7297,11 @@ msgid "This operation requires a single selected node." msgstr "Operasi ini membutuhkan satu node yang dipilih." #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Auto Orthogonal Enabled" +msgstr "Ortogonal" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "Kunci Rotasi Tampilan" @@ -7389,6 +7390,10 @@ msgid "Freelook Slow Modifier" msgstr "Pengubah Lambat Tampilan Bebas" #: editor/plugins/spatial_editor_plugin.cpp +msgid "View Rotation Locked" +msgstr "Rotasi Tampilan Terkunci" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." @@ -7397,10 +7402,6 @@ msgstr "" "Tidak bisa digunakan sebagai indikasi kinerja gim yang dapat dihandalkan." #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" -msgstr "Rotasi Tampilan Terkunci" - -#: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "Dialog XForm" @@ -10914,6 +10915,12 @@ msgid "Script file already exists." msgstr "Berkas skrip sudah ada." #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "Nama Kelas:" @@ -11298,7 +11305,6 @@ msgid "GridMap Paste Selection" msgstr "Rekat(Paste) Seleksi GridMap" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "GridMap Paint" msgstr "Cat GridMap" @@ -11716,7 +11722,7 @@ msgstr "Tidak dapat membuat fungsi dengan node fungsi." #: modules/visual_script/visual_script_editor.cpp msgid "Can't create function of nodes from nodes of multiple functions." -msgstr "" +msgstr "Tidak dapat membuat fungsi node dari node beberapa fungsi." #: modules/visual_script/visual_script_editor.cpp msgid "Select at least one node with sequence port." @@ -11881,19 +11887,19 @@ msgstr "Nama paket tidak ada." #: platform/android/export/export.cpp msgid "Package segments must be of non-zero length." -msgstr "" +msgstr "Segmen paket panjangnya harus tidak boleh nol." #: platform/android/export/export.cpp msgid "The character '%s' is not allowed in Android application package names." -msgstr "" +msgstr "Karakter '%s' tidak diizinkan dalam penamaan paket aplikasi Android." #: platform/android/export/export.cpp msgid "A digit cannot be the first character in a package segment." -msgstr "" +msgstr "Digit tidak boleh diletakkan sebagai karakter awal di segmen paket." #: platform/android/export/export.cpp msgid "The character '%s' cannot be the first character in a package segment." -msgstr "" +msgstr "Karakter '%s' tidak bisa dijadikan karakter awal dalam segmen paket." #: platform/android/export/export.cpp msgid "The package must have at least one '.' separator." @@ -11939,7 +11945,7 @@ msgstr "" #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." -msgstr "" +msgstr "Kunci Publik untuk ekspansi APK tidak valid." #: platform/android/export/export.cpp msgid "Invalid package name:" @@ -11950,6 +11956,8 @@ msgid "" "Trying to build from a custom built template, but no version info for it " "exists. Please reinstall from the 'Project' menu." msgstr "" +"Mencoba untuk membangun dari templat build khusus, tapi tidak ada informasi " +"versinya. Silakan pasang ulang dari menu 'Proyek'." #: platform/android/export/export.cpp msgid "" @@ -11958,24 +11966,30 @@ msgid "" " Godot Version: %s\n" "Please reinstall Android build template from 'Project' menu." msgstr "" +"Versi build Android tidak cocok:\n" +" Templat terpasang: %s\n" +" Versi Godot: %s\n" +"Silakan pasang ulang templat build Android dari menu 'Project'." #: platform/android/export/export.cpp msgid "Building Android Project (gradle)" -msgstr "" +msgstr "Membangun Proyek Android (gradle)" #: platform/android/export/export.cpp msgid "" "Building of Android project failed, check output for the error.\n" "Alternatively visit docs.godotengine.org for Android build documentation." msgstr "" +"Pembangunan proyek Android gagal, periksa output untuk galatnya.\n" +"Atau kunjungi docs.godotengine.org untuk dokumentasi build Android." #: platform/android/export/export.cpp msgid "No build apk generated at: " -msgstr "" +msgstr "Tak ada build apk yang dihasilkan di: " #: platform/iphone/export/export.cpp msgid "Identifier is missing." -msgstr "" +msgstr "Kurang identifier." #: platform/iphone/export/export.cpp msgid "The character '%s' is not allowed in Identifier." @@ -11984,6 +11998,7 @@ msgstr "Karakter '%s' tidak diizinkan dalam Identifier." #: platform/iphone/export/export.cpp msgid "App Store Team ID not specified - cannot configure the project." msgstr "" +"App Store Team ID tidak ditetapkan - tidak dapat mengonfigurasi proyek." #: platform/iphone/export/export.cpp msgid "Invalid Identifier:" @@ -11991,19 +12006,19 @@ msgstr "Identifier tidak valid:" #: platform/iphone/export/export.cpp msgid "Required icon is not specified in the preset." -msgstr "" +msgstr "Ikon yang dibutuhkan tidak ditentukan dalam preset." #: platform/javascript/export/export.cpp msgid "Stop HTTP Server" -msgstr "" +msgstr "Hentikan Server HTTP" #: platform/javascript/export/export.cpp msgid "Run in Browser" -msgstr "" +msgstr "Jalankan di Peramban" #: platform/javascript/export/export.cpp msgid "Run exported HTML in the system's default browser." -msgstr "" +msgstr "Jalankan HTML yang diekspor dalam peramban baku sistem." #: platform/javascript/export/export.cpp msgid "Could not write file:" @@ -12055,31 +12070,31 @@ msgstr "Warna latar belakang tidak valid." #: platform/uwp/export/export.cpp msgid "Invalid Store Logo image dimensions (should be 50x50)." -msgstr "" +msgstr "Dimensi gambar Logo Store tidak valid (harus 50x50)." #: platform/uwp/export/export.cpp msgid "Invalid square 44x44 logo image dimensions (should be 44x44)." -msgstr "" +msgstr "Dimensi gambar logo persegi 44x44 tidak valid (harus 44x44)." #: platform/uwp/export/export.cpp msgid "Invalid square 71x71 logo image dimensions (should be 71x71)." -msgstr "" +msgstr "Dimensi gambar logo persegi 71x71 tidak valid (harus 71x71)." #: platform/uwp/export/export.cpp msgid "Invalid square 150x150 logo image dimensions (should be 150x150)." -msgstr "" +msgstr "Dimensi gambar logo persegi 150x150 tidak valid (harus 150x150)." #: platform/uwp/export/export.cpp msgid "Invalid square 310x310 logo image dimensions (should be 310x310)." -msgstr "" +msgstr "Dimensi gambar logo persegi 310x310 tidak valid (harus 310x310)." #: platform/uwp/export/export.cpp msgid "Invalid wide 310x150 logo image dimensions (should be 310x150)." -msgstr "" +msgstr "Dimensi gambar logo 310x150 lebarnya tidak valid (harus 310x150)." #: platform/uwp/export/export.cpp msgid "Invalid splash screen image dimensions (should be 620x300)." -msgstr "" +msgstr "Dimensi gambar splash screen tidak valid (harus 620x300)." #: scene/2d/animated_sprite.cpp msgid "" @@ -12104,6 +12119,10 @@ msgid "" "Consider adding a CollisionShape2D or CollisionPolygon2D as a child to " "define its shape." msgstr "" +"Node ini tidak punya shape, jadi dia tidak bisa bertabrakan atau " +"berinteraksi dengan objek lain.\n" +"Pertimbangkan untuk menambahkan CollisionShape2D atau CollisionPolygon2D " +"sebagai anak untuk mendefinisikan bentuknya." #: scene/2d/collision_polygon_2d.cpp msgid "" @@ -12145,6 +12164,8 @@ msgid "" "CPUParticles2D animation requires the usage of a CanvasItemMaterial with " "\"Particles Animation\" enabled." msgstr "" +"Animasi CPUParticles2D membutuhkan penggunaan CanvasItemMaterial dengan " +"\"Animasi Partikel\" diaktifkan." #: scene/2d/light_2d.cpp msgid "" @@ -12194,18 +12215,25 @@ msgid "" "Use the CPUParticles2D node instead. You can use the \"Convert to " "CPUParticles\" option for this purpose." msgstr "" +"Partikel berbasis GPU tidak didukung oleh video driver GLES2.\n" +"Gunakan node CPUParticles2D sebagai gantinya. Anda dapat menggunakan opsi " +"\"Konversikan jadi CPUParticles\" untuk tujuan ini." #: scene/2d/particles_2d.cpp scene/3d/particles.cpp msgid "" "A material to process the particles is not assigned, so no behavior is " "imprinted." msgstr "" +"Material untuk memproses partikel belum ditetapkan, jadi tidak ada perilaku " +"yang dimunculkan." #: scene/2d/particles_2d.cpp msgid "" "Particles2D animation requires the usage of a CanvasItemMaterial with " "\"Particles Animation\" enabled." msgstr "" +"Animasi Particles2D membutuhkan penggunaan CanvasItemMaterial dengan " +"\"Animasi Partikel\" diaktifkan." #: scene/2d/path_2d.cpp msgid "PathFollow2D only works when set as a child of a Path2D node." @@ -12219,6 +12247,9 @@ msgid "" "by the physics engine when running.\n" "Change the size in children collision shapes instead." msgstr "" +"Perubahan ukuran RigidBody2D (dalam mode karakter atau rigid/pejal) akan " +"ditimpa oleh mesin fisika saat menjalankan.\n" +"Sebagai gantinya, ubahlah ukuran di anakan collision shape-nya saja." #: scene/2d/remote_transform_2d.cpp msgid "Path property must point to a valid Node2D node to work." @@ -12227,16 +12258,19 @@ msgstr "" #: scene/2d/skeleton_2d.cpp msgid "This Bone2D chain should end at a Skeleton2D node." -msgstr "" +msgstr "Ikatan Bone2D ini harus diakhiri dengan node Skeleton2D." #: scene/2d/skeleton_2d.cpp msgid "A Bone2D only works with a Skeleton2D or another Bone2D as parent node." msgstr "" +"Bone2D hanya bekerja dengan Skeleton2D atau Bone2D lain sebagai node induk." #: scene/2d/skeleton_2d.cpp msgid "" "This bone lacks a proper REST pose. Go to the Skeleton2D node and set one." msgstr "" +"Tulang ini tidak memiliki pose REST yang sesuai. Pergi ke node Skeleton2D " +"dan tetapkan." #: scene/2d/tile_map.cpp msgid "" @@ -12258,47 +12292,51 @@ msgstr "" #: scene/3d/arvr_nodes.cpp msgid "ARVRCamera must have an ARVROrigin node as its parent." -msgstr "" +msgstr "ARVRCamera wajib memiliki node ARVROrigin sebagai induknya." #: scene/3d/arvr_nodes.cpp msgid "ARVRController must have an ARVROrigin node as its parent." -msgstr "" +msgstr "ARVRController wajib memiliki node ARVROrigin sebagai induknya." #: scene/3d/arvr_nodes.cpp msgid "" "The controller ID must not be 0 or this controller won't be bound to an " "actual controller." msgstr "" +"ID pengontrol tidak boleh 0 atau pengontrol ini tidak terikat ke pengontrol " +"yang sebenarnya." #: scene/3d/arvr_nodes.cpp msgid "ARVRAnchor must have an ARVROrigin node as its parent." -msgstr "" +msgstr "ARVRAnchor wajib memiliki node ARVROrigin sebagai induknya." #: scene/3d/arvr_nodes.cpp msgid "" "The anchor ID must not be 0 or this anchor won't be bound to an actual " "anchor." msgstr "" +"ID jangkar tidak boleh 0 atau jangkar ini tidak akan terikat ke jangkar " +"aslinya." #: scene/3d/arvr_nodes.cpp msgid "ARVROrigin requires an ARVRCamera child node." -msgstr "" +msgstr "ARVROrigin membutuhkan node anak ARVRCamera." #: scene/3d/baked_lightmap.cpp msgid "%d%%" -msgstr "" +msgstr "%d%%" #: scene/3d/baked_lightmap.cpp msgid "(Time Left: %d:%02d s)" -msgstr "" +msgstr "(Waktu tersisa: %d:%02d s)" #: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " -msgstr "" +msgstr "Plotting Meshes: " #: scene/3d/baked_lightmap.cpp msgid "Plotting Lights:" -msgstr "" +msgstr "Plotting Lights:" #: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp msgid "Finishing Plot" @@ -12642,6 +12680,10 @@ msgstr "" "tidak, jadikan sebagai RenderTarget dan tetapkan tekstur internal nya ke " "beberapa node untuk ditampilkan." +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "Sumber tidak sah untuk pratinjau." @@ -12670,6 +12712,15 @@ msgstr "Variasi hanya bisa ditetapkan dalam fungsi vertex." msgid "Constants cannot be modified." msgstr "Konstanta tidak dapat dimodifikasi." +#~ msgid "Issue Tracker" +#~ msgstr "Pelacak Isu" + +#~ msgid "Request Docs" +#~ msgstr "Minta Dokumentasi" + +#~ msgid "Help improve the Godot documentation by giving feedback." +#~ msgstr "Bantu tingkatkan dokumentasi Godot dengan memberikan tanggapan." + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "kejadian %d diganti." diff --git a/editor/translations/is.po b/editor/translations/is.po index 213e7d239b..bb865e255a 100644 --- a/editor/translations/is.po +++ b/editor/translations/is.po @@ -4,12 +4,13 @@ # This file is distributed under the same license as the Godot source code. # Jóhannes G. Þorsteinsson <johannesg@johannesg.com>, 2017, 2018. # Kaan Gül <qaantum@hotmail.com>, 2018. +# Einar Magnús Einarsson <einar.m.einarsson@gmail.com>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2018-12-13 14:40+0100\n" -"Last-Translator: Jóhannes G. Þorsteinsson <johannesg@johannesg.com>\n" +"PO-Revision-Date: 2020-04-16 11:03+0000\n" +"Last-Translator: Einar Magnús Einarsson <einar.m.einarsson@gmail.com>\n" "Language-Team: Icelandic <https://hosted.weblate.org/projects/godot-engine/" "godot/is/>\n" "Language: is\n" @@ -17,34 +18,35 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Poedit 2.2\n" +"X-Generator: Weblate 4.0.1-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp msgid "Invalid type argument to convert(), use TYPE_* constants." -msgstr "" +msgstr "Ógild breyta send til convert(), notaðu TYPE_ * fasti." #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp msgid "Expected a string of length 1 (a character)." -msgstr "" +msgstr "Búist var við streng með lengd 1 (a character)." #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/mono/glue/gd_glue.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp msgid "Not enough bytes for decoding bytes, or invalid format." -msgstr "" +msgstr "Ekki nægt minni til að umskrá bæti eða ógilt snið." #: core/math/expression.cpp msgid "Invalid input %i (not passed) in expression" -msgstr "" +msgstr "Ógild inntak % i (ekki sent áfram)" #: core/math/expression.cpp msgid "self can't be used because instance is null (not passed)" msgstr "" +"Ekki hægt að nota \"self\" vegna þess að tilvik er \"null\" (ekki samþykkt)" #: core/math/expression.cpp msgid "Invalid operands to operator %s, %s and %s." -msgstr "" +msgstr "Ógilt reiknitákn notað à útreikningi % s,% s og% s." #: core/math/expression.cpp msgid "Invalid index of type %s for base type %s" @@ -1441,7 +1443,7 @@ msgstr "" msgid "Remove Autoload" msgstr "" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "" @@ -2852,7 +2854,11 @@ msgid "Q&A" msgstr "" #: editor/editor_node.cpp -msgid "Issue Tracker" +msgid "Report a Bug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp @@ -3878,7 +3884,7 @@ msgid "Reimport" msgstr "" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -6689,14 +6695,6 @@ msgid "Open Godot online documentation." msgstr "" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7127,6 +7125,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7215,13 +7217,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -10588,6 +10590,12 @@ msgid "Script file already exists." msgstr "" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "" @@ -12215,6 +12223,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/it.po b/editor/translations/it.po index 738718a0fa..4ce247c712 100644 --- a/editor/translations/it.po +++ b/editor/translations/it.po @@ -44,12 +44,13 @@ # nickfla1 <lanterniniflavio@gmail.com>, 2019. # Fabio Iotti <fabiogiopla@gmail.com>, 2020. # Douglas Fiedler <dognew@gmail.com>, 2020. +# E440QF <ettore.beltra@gmail.com>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-02-27 07:01+0000\n" -"Last-Translator: Micila Micillotto <micillotto@gmail.com>\n" +"PO-Revision-Date: 2020-04-08 16:36+0000\n" +"Last-Translator: E440QF <ettore.beltra@gmail.com>\n" "Language-Team: Italian <https://hosted.weblate.org/projects/godot-engine/" "godot/it/>\n" "Language: it\n" @@ -1484,7 +1485,7 @@ msgstr "Sposta Autoload" msgid "Remove Autoload" msgstr "Rimuovi Autoload" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "Abilita" @@ -2983,8 +2984,13 @@ msgid "Q&A" msgstr "Domande e risposte" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "Tracciatore segnalazioni" +#, fuzzy +msgid "Report a Bug" +msgstr "Reimporta" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4043,7 +4049,8 @@ msgid "Reimport" msgstr "Reimporta" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +#, fuzzy +msgid "Save Scenes, Re-Import, and Restart" msgstr "Salva scene, importa nuovamente e riavvia" #: editor/import_dock.cpp @@ -6918,14 +6925,6 @@ msgid "Open Godot online documentation." msgstr "Apri la documentazione online di Godot." #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "Documentazione richiesta" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "Aiutate a migliorare la documentazione di Godot fornendo feedback." - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "Cerca Riferimenti nella documentazione." @@ -7361,6 +7360,11 @@ msgid "This operation requires a single selected node." msgstr "Questa operazione richiede un solo nodo selezionato." #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Auto Orthogonal Enabled" +msgstr "Ortogonale" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "Blocca Rotazione Vista" @@ -7449,6 +7453,10 @@ msgid "Freelook Slow Modifier" msgstr "Modificatore Vista Libera Velocità Lenta" #: editor/plugins/spatial_editor_plugin.cpp +msgid "View Rotation Locked" +msgstr "Rotazione Vista Bloccata" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." @@ -7458,10 +7466,6 @@ msgstr "" "gioco." #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" -msgstr "Rotazione Vista Bloccata" - -#: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "Finestra di XForm" @@ -10975,6 +10979,12 @@ msgid "Script file already exists." msgstr "Il file di script esiste già ." #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "Nome Classe:" @@ -12477,6 +12487,7 @@ msgstr "" msgid "" "ConcavePolygonShape doesn't support RigidBody in another mode than static." msgstr "" +"ConcavePolygonShape non supporta RigidBody in modalità diverse da static." #: scene/3d/cpu_particles.cpp msgid "Nothing is visible because no mesh has been assigned." @@ -12774,6 +12785,10 @@ msgstr "" "Control, in modo che possa ottenere una dimensione. Altrimenti, renderlo un " "RenderTarget e assegnare alla sua texture interna qualche nodo da mostrare." +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "Fonte non valida per l'anteprima." @@ -12802,6 +12817,15 @@ msgstr "Varyings può essere assegnato soltanto nella funzione del vertice." msgid "Constants cannot be modified." msgstr "Le constanti non possono essere modificate." +#~ msgid "Issue Tracker" +#~ msgstr "Tracciatore segnalazioni" + +#~ msgid "Request Docs" +#~ msgstr "Documentazione richiesta" + +#~ msgid "Help improve the Godot documentation by giving feedback." +#~ msgstr "Aiutate a migliorare la documentazione di Godot fornendo feedback." + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "Rimpiazzate %d occorrenze." diff --git a/editor/translations/ja.po b/editor/translations/ja.po index 0bb76f1261..ab503d8294 100644 --- a/editor/translations/ja.po +++ b/editor/translations/ja.po @@ -35,8 +35,8 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-03-16 09:43+0000\n" -"Last-Translator: Akihiro Ogoshi <technical@palsystem-game.com>\n" +"PO-Revision-Date: 2020-04-15 14:29+0000\n" +"Last-Translator: Wataru Onuki <bettawat@yahoo.co.jp>\n" "Language-Team: Japanese <https://hosted.weblate.org/projects/godot-engine/" "godot/ja/>\n" "Language: ja\n" @@ -53,7 +53,7 @@ msgstr "convert() ã®å¼•æ•°ã®åž‹ãŒç„¡åйã§ã™ã€‚TYPE_* 定数を使ã£ã¦ãã #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp msgid "Expected a string of length 1 (a character)." -msgstr "é•·ã•ãŒ1ã®æ–‡å—列(文å—)を予期ã—ã¾ã—ãŸã€‚" +msgstr "é•·ã•1ã®æ–‡å—列(æ–‡å—)ãŒå¿…è¦ã§ã™ã€‚" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/mono/glue/gd_glue.cpp @@ -63,19 +63,19 @@ msgstr "デコードã™ã‚‹ã«ã¯ãƒã‚¤ãƒˆãŒè¶³ã‚Šãªã„ã‹ã€ã¾ãŸã¯ç„¡åŠ¹ãª #: core/math/expression.cpp msgid "Invalid input %i (not passed) in expression" -msgstr "入力ã•れãŸå¼ %i ã¯ç„¡åйã§ã™" +msgstr "å¼ä¸ã®ç„¡åйãªå…¥åŠ› %i (渡ã•れã¦ã„ã¾ã›ã‚“)" #: core/math/expression.cpp msgid "self can't be used because instance is null (not passed)" -msgstr "インスタンス㌠null ã®ãŸã‚ã€self ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" +msgstr "インスタンスãŒnull(渡ã•れãªã„)ã§ã‚ã‚‹ãŸã‚ã€selfã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" #: core/math/expression.cpp msgid "Invalid operands to operator %s, %s and %s." -msgstr "演算å %s, %s, %s ã«å¯¾ã™ã‚‹å€¤ãŒç„¡åйã§ã™ã€‚" +msgstr "演算å %s ã«å¯¾ã™ã‚‹ç„¡åйãªã‚ªãƒšãƒ©ãƒ³ãƒ‰ã§ã™ã€%s åŠã³ %s。" #: core/math/expression.cpp msgid "Invalid index of type %s for base type %s" -msgstr "基本型 %s ã®åž‹ %s ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ãŒç„¡åйã§ã™" +msgstr "タイプ %s ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ãŒç„¡åйã€ã“れã¯åŸºåº•åž‹ %s 用ã§ã™" #: core/math/expression.cpp msgid "Invalid named index '%s' for base type %s" @@ -83,39 +83,39 @@ msgstr "インデックス '%s' (基底型 %s) ã¯ç„¡åйãªåå‰ã§ã™" #: core/math/expression.cpp msgid "Invalid arguments to construct '%s'" -msgstr "'%s' ã®å¼•æ•°ã¯ç„¡åйã§ã™" +msgstr "'%s' を構築ã™ã‚‹ãŸã‚ã®å¼•æ•°ãŒç„¡åйã§ã™" #: core/math/expression.cpp msgid "On call to '%s':" -msgstr "'%s' ã¸ã®å‘¼ã³å‡ºã—:" +msgstr "'%s' ã®å‘¼ã³å‡ºã—時:" #: core/ustring.cpp msgid "B" -msgstr "\\ B" +msgstr "B" #: core/ustring.cpp msgid "KiB" -msgstr "\\ KiB" +msgstr "KiB" #: core/ustring.cpp msgid "MiB" -msgstr "\\ MiB" +msgstr "MiB" #: core/ustring.cpp msgid "GiB" -msgstr "\\ GiB" +msgstr "GiB" #: core/ustring.cpp msgid "TiB" -msgstr "\\ TiB" +msgstr "TiB" #: core/ustring.cpp msgid "PiB" -msgstr "\\ PiB" +msgstr "PiB" #: core/ustring.cpp msgid "EiB" -msgstr "\\ EiB" +msgstr "EiB" #: editor/animation_bezier_editor.cpp msgid "Free" @@ -330,11 +330,11 @@ msgstr "ã‚ュービック" #: editor/animation_track_editor.cpp msgid "Clamp Loop Interp" -msgstr "ループインタプリタを抑ãˆè¾¼ã¿ï¼ˆclamp)" +msgstr "ループインタプリタを抑ãˆè¾¼ã¿(clamp)" #: editor/animation_track_editor.cpp msgid "Wrap Loop Interp" -msgstr "ループインタプリタをラップ(wrap)" +msgstr "ループインタプリタをラップ(wrap)" #: editor/animation_track_editor.cpp #: editor/plugins/canvas_item_editor_plugin.cpp @@ -721,11 +721,11 @@ msgstr "%d ã‚’ç½®æ›ã—ã¾ã—ãŸã€‚" #: editor/code_editor.cpp editor/editor_help.cpp msgid "%d match." -msgstr "ï¼…dä»¶ã®ä¸€è‡´ãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸã€‚" +msgstr "%dä»¶ã®ä¸€è‡´ãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸã€‚" #: editor/code_editor.cpp editor/editor_help.cpp msgid "%d matches." -msgstr "ï¼…dä»¶ã®ä¸€è‡´ãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸã€‚" +msgstr "%dä»¶ã®ä¸€è‡´ãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸã€‚" #: editor/code_editor.cpp editor/find_in_files.cpp msgid "Match Case" @@ -1049,7 +1049,7 @@ msgstr "次ã®ã‚ªãƒ¼ãƒŠãƒ¼:" #: editor/dependency_editor.cpp msgid "Remove selected files from the project? (Can't be restored)" -msgstr "é¸æŠžã—ãŸãƒ•ァイルをプãƒã‚¸ã‚§ã‚¯ãƒˆã‹ã‚‰å‰Šé™¤ã—ã¾ã™ã‹? (å…ƒã«æˆ»ã›ã¾ã›ã‚“)" +msgstr "é¸æŠžã—ãŸãƒ•ァイルをプãƒã‚¸ã‚§ã‚¯ãƒˆã‹ã‚‰å‰Šé™¤ã—ã¾ã™ã‹ï¼Ÿ(å…ƒã«æˆ»ã›ã¾ã›ã‚“)" #: editor/dependency_editor.cpp msgid "" @@ -1058,7 +1058,7 @@ msgid "" "Remove them anyway? (no undo)" msgstr "" "除去ã—よã†ã¨ã—ã¦ã„るファイルã¯ä»–ã®ãƒªã‚½ãƒ¼ã‚¹ã®å‹•作ã«å¿…è¦ã§ã™ã€‚\n" -"無視ã—ã¦é™¤åŽ»ã—ã¾ã™ã‹ï¼Ÿ (å…ƒã«æˆ»ã›ã¾ã›ã‚“)" +"無視ã—ã¦é™¤åŽ»ã—ã¾ã™ã‹ï¼Ÿ(å…ƒã«æˆ»ã›ã¾ã›ã‚“)" #: editor/dependency_editor.cpp msgid "Cannot remove:" @@ -1090,7 +1090,7 @@ msgstr "èªã¿è¾¼ã¿ã‚¨ãƒ©ãƒ¼ï¼" #: editor/dependency_editor.cpp msgid "Permanently delete %d item(s)? (No undo!)" -msgstr "%d 個ã®ã‚¢ã‚¤ãƒ†ãƒ を完全ã«å‰Šé™¤ã—ã¾ã™ã‹?ï¼ˆå…ƒã«æˆ»ã›ã¾ã›ã‚“!)" +msgstr "%d 個ã®ã‚¢ã‚¤ãƒ†ãƒ を完全ã«å‰Šé™¤ã—ã¾ã™ã‹ï¼Ÿ(å…ƒã«æˆ»ã›ã¾ã›ã‚“ï¼)" #: editor/dependency_editor.cpp msgid "Show Dependencies" @@ -1299,7 +1299,7 @@ msgstr "ãƒã‚¹ã‚¨ãƒ•ェクトを削除" #: editor/editor_audio_buses.cpp msgid "Drag & drop to rearrange." -msgstr "ドラッグ・アンド・ドãƒãƒƒãƒ—ã§ä¸¦ã³æ›¿ãˆã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚" +msgstr "ドラッグ&ドãƒãƒƒãƒ—ã§ä¸¦ã³æ›¿ãˆã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚" #: editor/editor_audio_buses.cpp msgid "Solo" @@ -1340,7 +1340,7 @@ msgstr "オーディオãƒã‚¹ã‚’è¿½åŠ " #: editor/editor_audio_buses.cpp msgid "Master bus can't be deleted!" -msgstr "マスター ãƒã‚¹ã¯å‰Šé™¤ã§ãã¾ã›ã‚“!" +msgstr "マスターãƒã‚¹ã¯å‰Šé™¤ã§ãã¾ã›ã‚“ï¼" #: editor/editor_audio_buses.cpp msgid "Delete Audio Bus" @@ -1372,7 +1372,7 @@ msgstr "オーディオãƒã‚¹ã®ãƒ¬ã‚¤ã‚¢ã‚¦ãƒˆã‚’é–‹ã" #: editor/editor_audio_buses.cpp msgid "There is no '%s' file." -msgstr "'ï¼…s' ファイルãŒã‚りã¾ã›ã‚“。" +msgstr "'%s' ファイルãŒã‚りã¾ã›ã‚“。" #: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp msgid "Layout" @@ -1468,7 +1468,7 @@ msgstr "自動èªè¾¼ã¿ã‚’移動" msgid "Remove Autoload" msgstr "自動èªè¾¼ã¿ã‚’除去" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "有効" @@ -1549,7 +1549,7 @@ msgstr "ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’é¸æŠž" #: editor/filesystem_dock.cpp editor/project_manager.cpp #: scene/gui/file_dialog.cpp msgid "Create Folder" -msgstr "フォルダーを作æˆ" +msgstr "フォルダを作æˆ" #: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp #: editor/editor_plugin_settings.cpp editor/filesystem_dock.cpp @@ -1777,7 +1777,7 @@ msgstr "エディタ機能ã®ãƒ—ãƒãƒ•ァイルã®ç®¡ç†" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Select Current Folder" -msgstr "ç¾åœ¨ã®ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ã‚’é¸æŠž" +msgstr "ç¾åœ¨ã®ãƒ•ã‚©ãƒ«ãƒ€ã‚’é¸æŠž" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "File Exists, Overwrite?" @@ -1785,7 +1785,7 @@ msgstr "ãƒ•ã‚¡ã‚¤ãƒ«ãŒæ—¢ã«å˜åœ¨ã—ã¾ã™ã€‚上書ãã—ã¾ã™ã‹ï¼Ÿ" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Select This Folder" -msgstr "ã“ã®ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ã‚’é¸æŠž" +msgstr "ã“ã®ãƒ•ã‚©ãƒ«ãƒ€ã‚’é¸æŠž" #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "Copy Path" @@ -2393,7 +2393,7 @@ msgstr "é–‰ã˜ã‚‹å‰ã«ã€'%s' ã¸ã®å¤‰æ›´ã‚’ä¿å˜ã—ã¾ã™ã‹ï¼Ÿ" #: editor/editor_node.cpp msgid "Saved %s modified resource(s)." -msgstr "ï¼…s個ã®å¤‰æ›´ã•れãŸãƒªã‚½ãƒ¼ã‚¹ã‚’ä¿å˜ã—ã¾ã—ãŸã€‚" +msgstr "%s個ã®å¤‰æ›´ã•れãŸãƒªã‚½ãƒ¼ã‚¹ã‚’ä¿å˜ã—ã¾ã—ãŸã€‚" #: editor/editor_node.cpp msgid "A root node is required to save the scene." @@ -2449,7 +2449,7 @@ msgstr "å…ƒã«æˆ»ã™" #: editor/editor_node.cpp msgid "This action cannot be undone. Revert anyway?" -msgstr "ã“ã®æ“作ã¯å…ƒã«æˆ»ã›ã¾ã›ã‚“。ãれã§ã‚‚å…ƒã«æˆ»ã—ã¾ã™ã‹?" +msgstr "ã“ã®æ“作ã¯å–り消ã›ã¾ã›ã‚“。ãれã§ã‚‚å…ƒã«æˆ»ã—ã¾ã™ã‹?" #: editor/editor_node.cpp msgid "Quick Run Scene..." @@ -2461,7 +2461,7 @@ msgstr "終了" #: editor/editor_node.cpp msgid "Exit the editor?" -msgstr "エディターを終了ã—ã¾ã™ã‹ï¼Ÿ" +msgstr "エディタを終了ã—ã¾ã™ã‹ï¼Ÿ" #: editor/editor_node.cpp msgid "Open Project Manager?" @@ -2696,7 +2696,7 @@ msgstr "æ–°è¦ã‚·ãƒ¼ãƒ³" #: editor/editor_node.cpp msgid "New Inherited Scene..." -msgstr "æ–°ã—ã„継承ã—ãŸã‚·ãƒ¼ãƒ³..." +msgstr "æ–°ã—ã„継承シーン..." #: editor/editor_node.cpp msgid "Open Scene..." @@ -2804,7 +2804,7 @@ msgid "" "connect to the IP of this computer in order to be debugged." msgstr "" "エクスãƒãƒ¼ãƒˆã¾ãŸã¯ãƒ‡ãƒ—ãƒã‚¤ã‚’行ã†å ´åˆã€ç”Ÿæˆã•れãŸå®Ÿè¡Œãƒ•ァイルã¯ãƒ‡ãƒãƒƒã‚°ã®ãŸã‚" -"ã«ã€ã“ã®ã‚³ãƒ³ãƒ”ューターã®ï¼©ï¼°ã«æŽ¥ç¶šã‚’試ã¿ã¾ã™ã€‚" +"ã«ã€ã“ã®ã‚³ãƒ³ãƒ”ューターã®IPã«æŽ¥ç¶šã‚’è©¦ã¿ã¾ã™ã€‚" #: editor/editor_node.cpp msgid "Small Deploy with Network FS" @@ -2951,8 +2951,13 @@ msgid "Q&A" msgstr "Q&A" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "課題管ç†ã‚·ã‚¹ãƒ†ãƒ " +#, fuzzy +msgid "Report a Bug" +msgstr "å†ã‚¤ãƒ³ãƒãƒ¼ãƒˆ" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -3079,7 +3084,7 @@ msgid "" "operation again." msgstr "" "Androidビルドテンプレートã¯ã™ã§ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ãŠã‚Šã€ä¸Šæ›¸ãã•れã¾ã›ã‚“。\n" -"ã“ã®æ“作をå†è©¦è¡Œã™ã‚‹å‰ã«ã€ \"res://android/build\" ディレクトリを手動ã§å‰Šé™¤ã—" +"ã“ã®æ“作をå†è©¦è¡Œã™ã‚‹å‰ã«ã€\"res://android/build\" ディレクトリを手動ã§å‰Šé™¤ã—" "ã¦ãã ã•ã„。" #: editor/editor_node.cpp @@ -3096,7 +3101,7 @@ msgstr "ライブラリã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ" #: editor/editor_node.cpp msgid "Merge With Existing" -msgstr "æ—¢å˜ã®ï¼ˆãƒ©ã‚¤ãƒ–ラリを)マージ" +msgstr "æ—¢å˜ã®(ライブラリを)マージ" #: editor/editor_node.cpp msgid "Open & Run a Script" @@ -3193,11 +3198,11 @@ msgstr "測定:" #: editor/editor_profiler.cpp msgid "Frame Time (sec)" -msgstr "フレーム時間(秒)" +msgstr "フレーム時間(ç§’)" #: editor/editor_profiler.cpp msgid "Average Time (sec)" -msgstr "平凿™‚間(秒)" +msgstr "平凿™‚é–“(ç§’)" #: editor/editor_profiler.cpp msgid "Frame %" @@ -3348,7 +3353,7 @@ msgstr "æ–°è¦ã®å€¤:" #: editor/editor_properties_array_dict.cpp msgid "Add Key/Value Pair" -msgstr "ã‚ー・値ã®ãƒšã‚¢ã‚’è¿½åŠ " +msgstr "ã‚ー/値ã®ãƒšã‚¢ã‚’è¿½åŠ " #: editor/editor_run_native.cpp msgid "" @@ -3421,7 +3426,7 @@ msgstr "å…¬å¼ã®æ›¸ã出ã—テンプレートã¯é–‹ç™ºç”¨ãƒ“ルドã®å ´åˆã¯ #: editor/export_template_manager.cpp msgid "(Missing)" -msgstr "(見ã¤ã‹ã‚Šã¾ã›ã‚“)" +msgstr "(見ã¤ã‹ã‚Šã¾ã›ã‚“)" #: editor/export_template_manager.cpp msgid "(Current)" @@ -3607,7 +3612,7 @@ msgstr "テンプレートをダウンãƒãƒ¼ãƒ‰" #: editor/export_template_manager.cpp msgid "Select mirror from list: (Shift+Click: Open in Browser)" -msgstr "リストã‹ã‚‰ãƒŸãƒ©ãƒ¼ã‚’é¸æŠž: (Shift+クリック: ブラウザã§é–‹ã)" +msgstr "リストã‹ã‚‰ãƒŸãƒ©ãƒ¼ã‚’é¸æŠž: (Shift+クリック: ブラウザã§é–‹ã)" #: editor/filesystem_dock.cpp msgid "Favorites" @@ -3621,7 +3626,7 @@ msgstr "" #: editor/filesystem_dock.cpp msgid "Cannot move/rename resources root." -msgstr "ルートã®ãƒªã‚½ãƒ¼ã‚¹ã¯ç§»å‹•・リãƒãƒ¼ãƒ ã§ãã¾ã›ã‚“。" +msgstr "ルートã®ãƒªã‚½ãƒ¼ã‚¹ã¯ç§»å‹•/リãƒãƒ¼ãƒ ã§ãã¾ã›ã‚“。" #: editor/filesystem_dock.cpp msgid "Cannot move a folder into itself." @@ -3673,7 +3678,7 @@ msgstr "フォルダを複製:" #: editor/filesystem_dock.cpp msgid "New Inherited Scene" -msgstr "æ–°ã—ã„継承ã—ãŸã‚·ãƒ¼ãƒ³" +msgstr "æ–°ã—ã„継承シーン" #: editor/filesystem_dock.cpp msgid "Set As Main Scene" @@ -3806,7 +3811,7 @@ msgstr "フォルダ:" #: editor/find_in_files.cpp msgid "Filters:" -msgstr "フィルター:" +msgstr "フィルタ:" #: editor/find_in_files.cpp msgid "" @@ -3968,7 +3973,7 @@ msgstr "インãƒãƒ¼ãƒˆæ¸ˆã®ã‚¹ã‚¯ãƒªãƒ—トをèªè¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸï¼š" #: editor/import/resource_importer_scene.cpp msgid "Invalid/broken script for post-import (check console):" -msgstr "無効・壊れãŸã‚¤ãƒ³ãƒãƒ¼ãƒˆæ¸ˆã‚¹ã‚¯ãƒªãƒ—ト(コンソールを確èªã—ã¦ãã ã•ã„):" +msgstr "無効ã¾ãŸã¯å£Šã‚ŒãŸã‚¤ãƒ³ãƒãƒ¼ãƒˆæ¸ˆã‚¹ã‚¯ãƒªãƒ—ト(コンソールを確èªã—ã¦ãã ã•ã„):" #: editor/import/resource_importer_scene.cpp msgid "Error running post-import script:" @@ -4003,7 +4008,8 @@ msgid "Reimport" msgstr "å†ã‚¤ãƒ³ãƒãƒ¼ãƒˆ" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +#, fuzzy +msgid "Save Scenes, Re-Import, and Restart" msgstr "シーンをä¿å˜ã—ã¦ã€å†ã‚¤ãƒ³ãƒãƒ¼ãƒˆã—ã¦å†èµ·å‹•ã—ã¦ãã ã•ã„" #: editor/import_dock.cpp @@ -4052,7 +4058,7 @@ msgstr "ビルトインを作æˆ" #: editor/inspector_dock.cpp msgid "Make Sub-Resources Unique" -msgstr "ユニークãªã‚µãƒ–リソースを生æˆ" +msgstr "サブリソースをユニーク化ã™ã‚‹" #: editor/inspector_dock.cpp msgid "Open in Help" @@ -4166,7 +4172,7 @@ msgstr "ãƒã‚¤ãƒ³ãƒˆæŒ¿å…¥" #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "Edit Polygon (Remove Point)" -msgstr "ãƒãƒªã‚´ãƒ³ã‚’編集(点を除去)" +msgstr "ãƒãƒªã‚´ãƒ³ã‚’編集(点を除去)" #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "Remove Polygon And Point" @@ -4374,11 +4380,11 @@ msgstr "ノードを削除" #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Toggle Filter On/Off" -msgstr "フィルター㮠オン/オフ を切り替ãˆ" +msgstr "フィルタ㮠オン/オフ を切り替ãˆ" #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Change Filter" -msgstr "フィルターを変更" +msgstr "フィルタを変更" #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "No animation player set, so unable to retrieve track names." @@ -4506,27 +4512,27 @@ msgstr "編集ã™ã‚‹ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ãŒã‚りã¾ã›ã‚“ï¼" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation backwards from current pos. (A)" -msgstr "é¸æŠžã—ãŸã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’ç¾åœ¨ã®ä½ç½®ã‹ã‚‰é€†å†ç”Ÿã™ã‚‹ã€‚(A)" +msgstr "é¸æŠžã—ãŸã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’ç¾åœ¨ã®ä½ç½®ã‹ã‚‰é€†å†ç”Ÿã™ã‚‹ã€‚(A)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation backwards from end. (Shift+A)" -msgstr "é¸æŠžã—ãŸã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’最後ã‹ã‚‰é€†å†ç”Ÿã™ã‚‹ã€‚(Shift+A)" +msgstr "é¸æŠžã—ãŸã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’最後ã‹ã‚‰é€†å†ç”Ÿã™ã‚‹ã€‚(Shift+A)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Stop animation playback. (S)" -msgstr "アニメーションã®å†ç”Ÿã‚’åœæ¢ã™ã‚‹ã€‚(S)" +msgstr "アニメーションã®å†ç”Ÿã‚’åœæ¢ã™ã‚‹ã€‚(S)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation from start. (Shift+D)" -msgstr "é¸æŠžã—ãŸã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’最åˆã‹ã‚‰å†ç”Ÿã™ã‚‹ã€‚(Shift+D)" +msgstr "é¸æŠžã—ãŸã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’最åˆã‹ã‚‰å†ç”Ÿã™ã‚‹ã€‚(Shift+D)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation from current pos. (D)" -msgstr "é¸æŠžã—ãŸã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’ç¾åœ¨ã®ä½ç½®ã‹ã‚‰å†ç”Ÿã™ã‚‹ã€‚(D)" +msgstr "é¸æŠžã—ãŸã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’ç¾åœ¨ã®ä½ç½®ã‹ã‚‰å†ç”Ÿã™ã‚‹ã€‚(D)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation position (in seconds)." -msgstr "アニメーションã®ä½ç½®ï¼ˆç§’)。" +msgstr "アニメーションã®ä½ç½® (ç§’)。" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Scale animation playback globally for the node." @@ -4629,7 +4635,7 @@ msgstr "ブレンド時間:" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Next (Auto Queue):" -msgstr "次(自動ã‚ュー):" +msgstr "次 (自動ã‚ュー):" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Cross-Animation Blend Times" @@ -4678,7 +4684,7 @@ msgstr "サブトランジションã«ã¯ã€é–‹å§‹ãƒŽãƒ¼ãƒ‰ã¨çµ‚了ノード㌠#: editor/plugins/animation_state_machine_editor.cpp msgid "No playback resource set at path: %s." -msgstr "パス( %s )ã«å†ç”Ÿãƒªã‚½ãƒ¼ã‚¹ãŒè¨å®šã•れã¦ã„ã¾ã›ã‚“。" +msgstr "パス: %s ã«å†ç”Ÿãƒªã‚½ãƒ¼ã‚¹ãŒè¨å®šã•れã¦ã„ã¾ã›ã‚“。" #: editor/plugins/animation_state_machine_editor.cpp msgid "Node Removed" @@ -4793,7 +4799,7 @@ msgstr "ブレンド 1:" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "X-Fade Time (s):" -msgstr "クãƒã‚¹ãƒ•ェード時間(秒):" +msgstr "クãƒã‚¹ãƒ•ェード時間 (ç§’):" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Current:" @@ -5386,7 +5392,7 @@ msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Alt+RMB: Depth list selection" -msgstr "Alt+å³ã‚¯ãƒªãƒƒã‚¯: 奥行ã(被写界深度)リストã®é¸æŠž" +msgstr "Alt+å³ã‚¯ãƒªãƒƒã‚¯: 奥行ã(被写界深度)リストã®é¸æŠž" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -5597,8 +5603,8 @@ msgid "" "Keys are only added to existing tracks, no new tracks will be created.\n" "Keys must be inserted manually for the first time." msgstr "" -"ã‚ーã®è‡ªå‹•挿入ã¯ï¼ˆãƒžã‚¹ã‚¯ã«åŸºã¥ã„ã¦ï¼‰ã‚ªãƒ–ジェクトãŒç§»å‹•ã€å›žè»¢ã€ã¾ãŸã¯æ‹¡å¤§ç¸®å°" -"ã•れãŸéš›ã«è¡Œã‚れã¾ã™ã€‚\n" +"ã‚ーã®è‡ªå‹•挿入ã¯(マスクã«åŸºã¥ã„ã¦)オブジェクトãŒç§»å‹•ã€å›žè»¢ã€ã¾ãŸã¯æ‹¡å¤§ç¸®å°ã•" +"れãŸéš›ã«è¡Œã‚れã¾ã™ã€‚\n" "ã‚ãƒ¼ã¯æ—¢å˜ã®ãƒˆãƒ©ãƒƒã‚¯ã«ã®ã¿è¿½åŠ ã•ã‚Œã€æ–°ã—ã„トラックã¯ä½œæˆã•れã¾ã›ã‚“。\n" "åˆå›žã®ã‚ãƒ¼æŒ¿å…¥ã¯æ‰‹å‹•ã§è¡Œã†å¿…è¦ãŒã‚りã¾ã™ã€‚" @@ -5678,7 +5684,7 @@ msgstr "ãƒãƒªã‚´ãƒ³ã‚’編集" #: editor/plugins/collision_polygon_editor_plugin.cpp msgid "Edit Poly (Remove Point)" -msgstr "ãƒãƒªã‚´ãƒ³ã‚’編集(点を除去)" +msgstr "ãƒãƒªã‚´ãƒ³ã‚’編集(点を除去)" #: editor/plugins/collision_shape_2d_editor_plugin.cpp msgid "Set Handle" @@ -6064,14 +6070,13 @@ msgstr "シーンã‹ã‚‰ã‚¢ãƒƒãƒ—デート" #: editor/plugins/multimesh_editor_plugin.cpp msgid "No mesh source specified (and no MultiMesh set in node)." msgstr "" -"メッシュã®ã‚½ãƒ¼ã‚¹ãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“(ノードã«MultiMeshãŒè¨å®šã•れã¦ã„ã¾ã›" -"ん)。" +"メッシュã®ã‚½ãƒ¼ã‚¹ãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“(ノードã«MultiMeshãŒè¨å®šã•れã¦ã„ã¾ã›ã‚“)。" #: editor/plugins/multimesh_editor_plugin.cpp msgid "No mesh source specified (and MultiMesh contains no Mesh)." msgstr "" -"メッシュã®ã‚½ãƒ¼ã‚¹ãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“(ãã—ã¦MultiMeshã«ã¯ãƒ¡ãƒƒã‚·ãƒ¥ãŒå«ã¾ã‚Œã¦ã„" -"ã¾ã›ã‚“)。" +"メッシュã®ã‚½ãƒ¼ã‚¹ãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“(ãã—ã¦MultiMeshã«ã¯ãƒ¡ãƒƒã‚·ãƒ¥ãŒå«ã¾ã‚Œã¦ã„" +"ã¾ã›ã‚“)。" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh source is invalid (invalid path)." @@ -6854,15 +6859,6 @@ msgid "Open Godot online documentation." msgstr "Godotã®ã‚ªãƒ³ãƒ©ã‚¤ãƒ³ãƒ‰ã‚ュメントを開ã。" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "ドã‚ãƒ¥ãƒ¡ãƒ³ãƒˆã‚’è¦æ±‚" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" -"フィードãƒãƒƒã‚¯ã‚’æä¾›ã—ã¦ã€Godotã®ãƒ‰ã‚ãƒ¥ãƒ¡ãƒ³ãƒˆã®æ”¹å–„ã«å½¹ç«‹ã¦ã¦ãã ã•ã„。" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "リファレンス文書を探ã™." @@ -6924,8 +6920,8 @@ msgstr "ターゲット" msgid "" "Missing connected method '%s' for signal '%s' from node '%s' to node '%s'." msgstr "" -"ノード'ï¼…s'ã‹ã‚‰ãƒŽãƒ¼ãƒ‰'ï¼…s'ã¸é€ã‚‹ã‚·ã‚°ãƒŠãƒ«'ï¼…s'ã®ãƒ¡ã‚½ãƒƒãƒ‰'ï¼…s'ã¸ã®æŽ¥ç¶šãŒè¦‹ã¤ã‹" -"りã¾ã›ã‚“。" +"メソッド'%s' (シグナル'ï¼…s'用) ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã€ã“れã¯ãƒŽãƒ¼ãƒ‰'%s'ã‹ã‚‰ãƒŽãƒ¼" +"ド'%s'ã¸ã®ã‚·ã‚°ãƒŠãƒ«ç”¨ã§ã™ã€‚" #: editor/plugins/script_text_editor.cpp msgid "Line" @@ -6947,8 +6943,8 @@ msgstr "ファイルシステムã®ãƒªã‚½ãƒ¼ã‚¹ã®ã¿ãƒ‰ãƒãƒƒãƒ—ã§ãã¾ã™." #: modules/visual_script/visual_script_editor.cpp msgid "Can't drop nodes because script '%s' is not used in this scene." msgstr "" -"スクリプト '%s' ã¯ã“ã®ã‚·ãƒ¼ãƒ³ã§ä½¿ã‚れã¦ã„ãªã„ãŸã‚ã€ãƒŽãƒ¼ãƒ‰ã‚’(ドラッグ&)ドãƒãƒƒ" -"プã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。" +"スクリプト '%s' ã¯ã“ã®ã‚·ãƒ¼ãƒ³ã§ä½¿ã‚れã¦ã„ãªã„ãŸã‚ã€ãƒŽãƒ¼ãƒ‰ã‚’(ドラッグ&)ドãƒãƒƒãƒ—" +"ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。" #: editor/plugins/script_text_editor.cpp msgid "Lookup Symbol" @@ -7112,7 +7108,7 @@ msgid "" "This shader has been modified on on disk.\n" "What action should be taken?" msgstr "" -"ã“ã®ã‚·ã‚§ãƒ¼ãƒ€ã¯ãƒ‡ã‚£ã‚¹ã‚¯ä¸Šã§ä¿®æ£ã•れã¦ã„ã¾ã™ã€‚\n" +"ã“ã®ã‚·ã‚§ãƒ¼ãƒ€ãƒ¼ã¯ãƒ‡ã‚£ã‚¹ã‚¯ä¸Šã§ä¿®æ£ã•れã¦ã„ã¾ã™ã€‚\n" "ã©ã†ã—ã¾ã™ã‹?" #: editor/plugins/shader_editor_plugin.cpp @@ -7201,7 +7197,7 @@ msgstr "%s 度回転." #: editor/plugins/spatial_editor_plugin.cpp msgid "Keying is disabled (no key inserted)." -msgstr "ã‚ーã¯ç„¡åŠ¹åŒ–ã•れã¦ã„ã¾ã™ï¼ˆã‚ãƒ¼ã¯æŒ¿å…¥ã•れã¦ã„ã¾ã›ã‚“)." +msgstr "ã‚ーã¯ç„¡åŠ¹åŒ–ã•れã¦ã„ã¾ã™(ã‚ãƒ¼ã¯æŒ¿å…¥ã•れã¦ã„ã¾ã›ã‚“)。" #: editor/plugins/spatial_editor_plugin.cpp msgid "Animation Key Inserted." @@ -7241,11 +7237,11 @@ msgstr "é ‚ç‚¹" #: editor/plugins/spatial_editor_plugin.cpp msgid "Top View." -msgstr "上é¢å›³." +msgstr "上é¢å›³ã€‚" #: editor/plugins/spatial_editor_plugin.cpp msgid "Bottom View." -msgstr "下é¢å›³." +msgstr "下é¢å›³ã€‚" #: editor/plugins/spatial_editor_plugin.cpp msgid "Bottom" @@ -7269,7 +7265,7 @@ msgstr "å³å´é¢" #: editor/plugins/spatial_editor_plugin.cpp msgid "Front View." -msgstr "å‰é¢å›³." +msgstr "å‰é¢å›³ã€‚" #: editor/plugins/spatial_editor_plugin.cpp msgid "Front" @@ -7300,6 +7296,11 @@ msgid "This operation requires a single selected node." msgstr "å˜ä¸€ã®é¸æŠžã•れãŸãƒŽãƒ¼ãƒ‰ãŒãªã„ã¨ã€ã“ã®æ“作ã¯è¡Œãˆã¾ã›ã‚“。" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Auto Orthogonal Enabled" +msgstr "平行投影" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "ビューã®å›žè»¢ã‚’固定" @@ -7388,18 +7389,18 @@ msgid "Freelook Slow Modifier" msgstr "ãƒ•ãƒªãƒ¼ãƒ«ãƒƒã‚¯ã®æ¸›é€Ÿã‚’調整" #: editor/plugins/spatial_editor_plugin.cpp +msgid "View Rotation Locked" +msgstr "ビューã®å›žè»¢ã‚’固定ä¸" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." msgstr "" -"注æ„:表示ã•れるFPS値ã¯ã€ã‚¨ãƒ‡ã‚£ã‚¿ã®ãƒ•レームレートã§ã™ã€‚\n" +"注æ„: 表示ã•れるFPS値ã¯ã€ã‚¨ãƒ‡ã‚£ã‚¿ã®ãƒ•レームレートã§ã™ã€‚\n" "ゲーム内ã®ãƒ‘フォーマンスを確実ã«ç¤ºã™ã‚‚ã®ã¨ã—ã¦ä½¿ç”¨ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" -msgstr "ビューã®å›žè»¢ã‚’固定ä¸" - -#: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "Xformダイアãƒã‚°" @@ -7537,7 +7538,7 @@ msgstr "スナップを移動:" #: editor/plugins/spatial_editor_plugin.cpp msgid "Rotate Snap (deg.):" -msgstr "スナップã®å›žè»¢ï¼ˆåº¦ï¼‰:" +msgstr "スナップã®å›žè»¢(度):" #: editor/plugins/spatial_editor_plugin.cpp msgid "Scale Snap (%):" @@ -7569,7 +7570,7 @@ msgstr "移動:" #: editor/plugins/spatial_editor_plugin.cpp msgid "Rotate (deg.):" -msgstr "回転(度):" +msgstr "回転(度):" #: editor/plugins/spatial_editor_plugin.cpp msgid "Scale (ratio):" @@ -7593,7 +7594,7 @@ msgstr "ç„¡åã®ã‚®ã‚ºãƒ¢" #: editor/plugins/sprite_editor_plugin.cpp msgid "Create Mesh2D" -msgstr "Mesh2Dを作æˆã™ã‚‹" +msgstr "Mesh2Dを作æˆ" #: editor/plugins/sprite_editor_plugin.cpp msgid "Mesh2D Preview" @@ -7645,11 +7646,11 @@ msgstr "ジオメトリãŒç„¡åйã§ã™ã€‚ãƒãƒªã‚´ãƒ³ã‚’作æˆã§ãã¾ã›ã‚“。 #: editor/plugins/sprite_editor_plugin.cpp msgid "Convert to Polygon2D" -msgstr "Polygon2Dã«å¤‰æ›" +msgstr "Polygon2Dã«å¤‰æ›ã™ã‚‹" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't create collision polygon." -msgstr "ジオメトリãŒç„¡åйã§ã™ã€‚è¡çªãƒãƒªã‚´ãƒ³ã‚’作æˆã§ãã¾ã›ã‚“。" +msgstr "ジオメトリãŒç„¡åйã§ã™ã€‚コリジョンãƒãƒªã‚´ãƒ³ã‚’作æˆã§ãã¾ã›ã‚“。" #: editor/plugins/sprite_editor_plugin.cpp msgid "Create CollisionPolygon2D Sibling" @@ -7725,7 +7726,7 @@ msgstr "アニメーションã®FPSを変更" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "(empty)" -msgstr "(空)" +msgstr "(空)" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Move Frame" @@ -7866,7 +7867,7 @@ msgstr "テーマを編集" #: editor/plugins/theme_editor_plugin.cpp msgid "Theme editing menu." -msgstr "テーマ編集メニュー." +msgstr "テーマ編集メニュー。" #: editor/plugins/theme_editor_plugin.cpp msgid "Add Class Items" @@ -8036,7 +8037,7 @@ msgstr "タイルを検索ã™ã‚‹" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Transpose" -msgstr "行列(縦横)入れ替ãˆ" +msgstr "行列(縦横)入れ替ãˆ" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Disable Autotile" @@ -9282,9 +9283,9 @@ msgid "" "output ports. This is a direct injection of code into the vertex/fragment/" "light function, do not use it to write the function declarations inside." msgstr "" -"カスタムã®Godotシェーダ言語å¼ã€‚カスタムã®é‡ã®å…¥å‡ºåŠ›ãƒãƒ¼ãƒˆã‚’æŒã¡ã¾ã™ã€‚ ã“れã¯" -"vertex / fragment / light関数ã¸ã®ã‚³ãƒ¼ãƒ‰ã®ç›´æŽ¥æ³¨å…¥ã§ã™ã€‚内部ã§é–¢æ•°å®£è¨€ã‚’書ããŸ" -"ã‚ã«ãれを使用ã—ãªã„ã§ãã ã•ã„。" +"カスタムã®Godotシェーダー言語å¼ã€‚カスタムã®é‡ã®å…¥å‡ºåŠ›ãƒãƒ¼ãƒˆã‚’æŒã¡ã¾ã™ã€‚ ã“れ" +"ã¯vertex / fragment / light関数ã¸ã®ã‚³ãƒ¼ãƒ‰ã®ç›´æŽ¥æ³¨å…¥ã§ã™ã€‚内部ã§é–¢æ•°å®£è¨€ã‚’書ã" +"ãŸã‚ã«ãれを使用ã—ãªã„ã§ãã ã•ã„。" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -9458,11 +9459,11 @@ msgstr "プãƒã‚¸ã‚§ã‚¯ãƒˆå†…ã®ãƒªã‚½ãƒ¼ã‚¹ã‚’ã™ã¹ã¦ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ" #: editor/project_export.cpp msgid "Export selected scenes (and dependencies)" -msgstr "é¸æŠžã—ãŸã‚·ãƒ¼ãƒ³ï¼ˆã¨ä¾å˜é–¢ä¿‚ã«ã‚ã‚‹ã‚‚ã®ï¼‰ã‚’エクスãƒãƒ¼ãƒˆ" +msgstr "é¸æŠžã—ãŸã‚·ãƒ¼ãƒ³(ã¨ä¾å˜é–¢ä¿‚ã«ã‚ã‚‹ã‚‚ã®)をエクスãƒãƒ¼ãƒˆ" #: editor/project_export.cpp msgid "Export selected resources (and dependencies)" -msgstr "é¸æŠžã—ãŸãƒªã‚½ãƒ¼ã‚¹ï¼ˆã¨ä¾å˜é–¢ä¿‚ã«ã‚ã‚‹ã‚‚ã®ï¼‰ã‚’エクスãƒãƒ¼ãƒˆ" +msgstr "é¸æŠžã—ãŸãƒªã‚½ãƒ¼ã‚¹(ã¨ä¾å˜é–¢ä¿‚ã«ã‚ã‚‹ã‚‚ã®)をエクスãƒãƒ¼ãƒˆ" #: editor/project_export.cpp msgid "Export Mode:" @@ -9594,7 +9595,7 @@ msgstr "" #: editor/project_manager.cpp msgid "Please choose an empty folder." -msgstr "空ã®ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ã‚’é¸æŠžã—ã¦ãã ã•ã„。" +msgstr "空ã®ãƒ•ã‚©ãƒ«ãƒ€ã‚’é¸æŠžã—ã¦ãã ã•ã„。" #: editor/project_manager.cpp msgid "Please choose a \"project.godot\" or \".zip\" file." @@ -9622,7 +9623,7 @@ msgstr "フォルダを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸã€‚" #: editor/project_manager.cpp msgid "There is already a folder in this path with the specified name." -msgstr "ã“ã®ãƒ‘スã«ã¯ã€æŒ‡å®šã•れãŸåå‰ã®ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ãŒæ—¢ã«å˜åœ¨ã—ã¾ã™ã€‚" +msgstr "ã“ã®ãƒ‘スã«ã¯ã€æŒ‡å®šã•れãŸåå‰ã®ãƒ•ã‚©ãƒ«ãƒ€ãŒæ—¢ã«å˜åœ¨ã—ã¾ã™ã€‚" #: editor/project_manager.cpp msgid "It would be a good idea to name your project." @@ -9877,7 +9878,7 @@ msgstr "スã‚ャン" #: editor/project_manager.cpp msgid "Select a Folder to Scan" -msgstr "スã‚ャンã™ã‚‹ãƒ•ã‚©ãƒ«ãƒ€ãƒ¼ã‚’é¸æŠž" +msgstr "スã‚ャンã™ã‚‹ãƒ•ã‚©ãƒ«ãƒ€ã‚’é¸æŠž" #: editor/project_manager.cpp msgid "New Project" @@ -9928,8 +9929,8 @@ msgid "" "Invalid action name. it cannot be empty nor contain '/', ':', '=', '\\' or " "'\"'" msgstr "" -"アクションåãŒç„¡åйã§ã™ã€‚空ã«ã—ãŸã‚Šã€ã€Œ/ ã€ã€ã€Œ: ã€ã€ã€Œ= ã€ã€ã€Œ\\ ã€ã‚’å«ã‚ã‚‹ã“" -"ã¨ã¯ã§ãã¾ã›ã‚“" +"アクションåãŒç„¡åйã§ã™ã€‚空ã«ã—ãŸã‚Šã€'/'ã€':'ã€'='ã€'\\'ç‰ã‚’å«ã‚ã‚‹ã“ã¨ã¯ã§ãã¾" +"ã›ã‚“" #: editor/project_settings_editor.cpp msgid "An action with the name '%s' already exists." @@ -10041,11 +10042,11 @@ msgstr "ä¸ã‚¯ãƒªãƒƒã‚¯" #: editor/project_settings_editor.cpp msgid "Wheel Up." -msgstr "マウスホイールを上." +msgstr "マウスホイールを上ã«ã€‚" #: editor/project_settings_editor.cpp msgid "Wheel Down." -msgstr "マウスホイールを下." +msgstr "マウスホイールを下ã«ã€‚" #: editor/project_settings_editor.cpp msgid "Add Global Property" @@ -10072,8 +10073,8 @@ msgid "" "Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or " "'\"'." msgstr "" -"無効ãªã‚¢ã‚¯ã‚·ãƒ§ãƒ³åã§ã™ã€‚空もã—ãã¯'/', ':', '=', '\\' ã‚„ '\"'ã‚’å«ã‚ã‚‹ã“ã¨ã¯ã§" -"ãã¾ã›ã‚“。" +"無効ãªã‚¢ã‚¯ã‚·ãƒ§ãƒ³åã§ã™ã€‚空もã—ãã¯'/'ã€':'ã€'='ã€'\\' ã€'\"'ç‰ã‚’å«ã‚ã‚‹ã“ã¨ã¯" +"ã§ãã¾ã›ã‚“。" #: editor/project_settings_editor.cpp msgid "Add Input Action" @@ -10081,11 +10082,11 @@ msgstr "入力アクションã®è¿½åŠ " #: editor/project_settings_editor.cpp msgid "Error saving settings." -msgstr "è¨å®šã‚’ä¿å˜ã§ãã¾ã›ã‚“ã§ã—ãŸ." +msgstr "è¨å®šã‚’ä¿å˜ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚" #: editor/project_settings_editor.cpp msgid "Settings saved OK." -msgstr "è¨å®šã®ä¿å˜ã«æˆåŠŸã—ã¾ã—ãŸ." +msgstr "è¨å®šã®ä¿å˜ã«æˆåŠŸã—ã¾ã—ãŸã€‚" #: editor/project_settings_editor.cpp msgid "Moved Input Action Event" @@ -10201,7 +10202,7 @@ msgstr "ãƒã‚±ãƒ¼ãƒ«" #: editor/project_settings_editor.cpp msgid "Locales Filter" -msgstr "ãƒã‚±ãƒ¼ãƒ«ãƒ•ィルター" +msgstr "ãƒã‚±ãƒ¼ãƒ«ãƒ•ィルタ" #: editor/project_settings_editor.cpp msgid "Show All Locales" @@ -10213,7 +10214,7 @@ msgstr "é¸æŠžã—ãŸãƒã‚±ãƒ¼ãƒ«ã®ã¿è¡¨ç¤º" #: editor/project_settings_editor.cpp msgid "Filter mode:" -msgstr "フィルターモード:" +msgstr "フィルタモード:" #: editor/project_settings_editor.cpp msgid "Locales:" @@ -10790,7 +10791,7 @@ msgstr "ノードã®åå‰ã‚’変更" #: editor/scene_tree_editor.cpp msgid "Scene Tree (Nodes):" -msgstr "シーンツリー(ノード):" +msgstr "シーンツリー(ノード):" #: editor/scene_tree_editor.cpp msgid "Node Configuration Warning!" @@ -10874,7 +10875,7 @@ msgstr "スクリプトã®ãƒ‘ス/åå‰ã¯æœ‰åйã§ã™ã€‚" #: editor/script_create_dialog.cpp msgid "Allowed: a-z, A-Z, 0-9, _ and ." -msgstr "使用å¯èƒ½: a-z, A-Z, 0-9 㨠." +msgstr "使用å¯èƒ½: a-zã€A-Zã€0-9åŠã³_。" #: editor/script_create_dialog.cpp msgid "Built-in script (into scene file)." @@ -10893,6 +10894,12 @@ msgid "Script file already exists." msgstr "ã‚¹ã‚¯ãƒªãƒ—ãƒˆãƒ•ã‚¡ã‚¤ãƒ«ãŒæ—¢ã«ã‚りã¾ã™ã€‚" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "クラスå:" @@ -11202,7 +11209,7 @@ msgstr "ライブラリ: " #: modules/gdnative/register_types.cpp msgid "GDNative" -msgstr "\\ GDNative" +msgstr "GDNative" #: modules/gdscript/gdscript_functions.cpp msgid "Step argument is zero!" @@ -11384,7 +11391,7 @@ msgstr "NavMeshを焼ã込む" #: modules/recast/navigation_mesh_editor_plugin.cpp msgid "Clear the navigation mesh." -msgstr "ãƒŠãƒ“ãƒ¡ãƒƒã‚·ãƒ¥ï¼ˆãƒŠãƒ“ã‚²ãƒ¼ã‚·ãƒ§ãƒ³ãƒ¡ãƒƒã‚·ãƒ¥ï¼‰ã®æ¶ˆåŽ»." +msgstr "ナビメッシュ(ナビゲーションメッシュ)ã®æ¶ˆåŽ»ã€‚" #: modules/recast/navigation_mesh_generator.cpp msgid "Setting up Configuration..." @@ -11428,7 +11435,7 @@ msgstr "ãƒã‚¤ãƒ†ã‚£ãƒ–ナビゲーションメッシュã«å¤‰æ›ã—ã¦ã„ã¾ã™ #: modules/recast/navigation_mesh_generator.cpp msgid "Navigation Mesh Generator Setup:" -msgstr "ナビメッシュ(ナビゲーションメッシュ)生æˆè¨å®š:" +msgstr "ナビメッシュ(ナビゲーションメッシュ)生æˆè¨å®š:" #: modules/recast/navigation_mesh_generator.cpp msgid "Parsing Geometry..." @@ -11586,34 +11593,33 @@ msgstr "VisualScriptノードを複製" #: modules/visual_script/visual_script_editor.cpp msgid "Hold %s to drop a Getter. Hold Shift to drop a generic signature." msgstr "" -"%sを押ã—ãŸã¾ã¾Getterを(ドラッグ&)ドãƒãƒƒãƒ—ã™ã‚‹ã€‚Shiftを押ã—ãŸã¾ã¾æ±Žç”¨ç½²åã‚’" -"(ドラッグ&)ドãƒãƒƒãƒ—ã™ã‚‹ã€‚" +"%sを押ã—ãŸã¾ã¾Getterã‚’(ドラッグ&)ドãƒãƒƒãƒ—ã™ã‚‹ã€‚Shiftを押ã—ãŸã¾ã¾æ±Žç”¨ç½²åã‚’" +"(ドラッグ&)ドãƒãƒƒãƒ—ã™ã‚‹ã€‚" #: modules/visual_script/visual_script_editor.cpp msgid "Hold Ctrl to drop a Getter. Hold Shift to drop a generic signature." msgstr "" -"Ctrlを押ã—ãŸã¾ã¾Getterを(ドラッグ&)ドãƒãƒƒãƒ—ã™ã‚‹ã€‚Shiftを押ã—ãŸã¾ã¾æ±Žç”¨ã‚·ã‚°" -"ãƒãƒãƒ£ã‚’(ドラッグ&)ドãƒãƒƒãƒ—ã™ã‚‹." +"Ctrlを押ã—ãŸã¾ã¾Getterã‚’(ドラッグ&)ドãƒãƒƒãƒ—ã™ã‚‹ã€‚Shiftを押ã—ãŸã¾ã¾æ±Žç”¨ã‚·ã‚°ãƒ" +"ãƒãƒ£ã‚’(ドラッグ&)ドãƒãƒƒãƒ—ã™ã‚‹." #: modules/visual_script/visual_script_editor.cpp msgid "Hold %s to drop a simple reference to the node." msgstr "" -"%sを押ã—ãŸã¾ã¾ãƒŽãƒ¼ãƒ‰ã¸å˜ç´”å‚照(simple reference)を(ドラッグ&)ドãƒãƒƒãƒ—ã™" -"る。" +"%sを押ã—ãŸã¾ã¾ãƒŽãƒ¼ãƒ‰ã¸å˜ç´”å‚ç…§(simple reference)ã‚’(ドラッグ&)ドãƒãƒƒãƒ—ã™ã‚‹ã€‚" #: modules/visual_script/visual_script_editor.cpp msgid "Hold Ctrl to drop a simple reference to the node." msgstr "" -"Ctrlを押ã—ãŸã¾ã¾ãƒŽãƒ¼ãƒ‰ã¸å˜ç´”å‚照(simple reference)を(ドラッグ&)ドãƒãƒƒãƒ—ã™" +"Ctrlを押ã—ãŸã¾ã¾ãƒŽãƒ¼ãƒ‰ã¸å˜ç´”å‚ç…§(simple reference)ã‚’(ドラッグ&)ドãƒãƒƒãƒ—ã™" "る。" #: modules/visual_script/visual_script_editor.cpp msgid "Hold %s to drop a Variable Setter." -msgstr "%sを押ã—ãŸã¾ã¾å¤‰æ•°ã®Setterを(ドラッグ&)ドãƒãƒƒãƒ—ã™ã‚‹ã€‚" +msgstr "%sを押ã—ãŸã¾ã¾å¤‰æ•°ã®Setterã‚’(ドラッグ&)ドãƒãƒƒãƒ—ã™ã‚‹ã€‚" #: modules/visual_script/visual_script_editor.cpp msgid "Hold Ctrl to drop a Variable Setter." -msgstr "Ctrlを押ã—ãŸã¾ã¾å¤‰æ•°ã®Setterを(ドラッグ&)ドãƒãƒƒãƒ—ã™ã‚‹ã€‚" +msgstr "Ctrlを押ã—ãŸã¾ã¾å¤‰æ•°ã®Setterã‚’(ドラッグ&)ドãƒãƒƒãƒ—ã™ã‚‹ã€‚" #: modules/visual_script/visual_script_editor.cpp msgid "Add Preload Node" @@ -11890,7 +11896,7 @@ msgstr "ADB実行å¯èƒ½ãƒ•ァイルãŒã‚¨ãƒ‡ã‚£ã‚¿è¨å®šã§è¨å®šã•れã¦ã„ã¾ #: platform/android/export/export.cpp msgid "OpenJDK jarsigner not configured in the Editor Settings." -msgstr "OpenJDK jarsignerãŒã‚¨ãƒ‡ã‚£ã‚¿ãƒ¼è¨å®šã§è¨å®šã•れã¦ã„ã¾ã›ã‚“。" +msgstr "OpenJDK jarsignerãŒã‚¨ãƒ‡ã‚£ã‚¿è¨å®šã§è¨å®šã•れã¦ã„ã¾ã›ã‚“。" #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." @@ -12127,8 +12133,8 @@ msgid "" "A shape must be provided for CollisionShape2D to function. Please create a " "shape resource for it!" msgstr "" -"関数ã«å¯¾ã—㦠CollisionShape2D ã®å½¢çŠ¶ï¼ˆã‚·ã‚§ã‚¤ãƒ—ï¼‰ã‚’æŒ‡å®šã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚ã" -"ã®ãŸã‚ã®ã‚·ã‚§ã‚¤ãƒ—リソースを作æˆã—ã¦ãã ã•ã„!" +"関数ã«å¯¾ã—㦠CollisionShape2D ã®å½¢çж(シェイプ)を指定ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚ãã®" +"ãŸã‚ã®ã‚·ã‚§ã‚¤ãƒ—リソースを作æˆã—ã¦ãã ã•ã„!" #: scene/2d/cpu_particles_2d.cpp msgid "" @@ -12540,7 +12546,7 @@ msgstr "無効ãªã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³: '%s'。" #: scene/animation/animation_tree.cpp msgid "Nothing connected to input '%s' of node '%s'." -msgstr "ノード 'ï¼…s'ã®å…¥åŠ› 'ï¼…s'ã«æŽ¥ç¶šã•れã¦ã„ã‚‹ã‚‚ã®ãŒã‚りã¾ã›ã‚“。" +msgstr "入力 'ï¼…s'(ノード 'ï¼…s')ã«æŽ¥ç¶šã•れã¦ã„ã‚‹ã‚‚ã®ã¯ã‚りã¾ã›ã‚“。" #: scene/animation/animation_tree.cpp msgid "No root AnimationNode for the graph is set." @@ -12584,7 +12590,7 @@ msgstr "HSV" #: scene/gui/color_picker.cpp msgid "Raw" -msgstr "ãƒãƒ¼" +msgstr "Raw" #: scene/gui/color_picker.cpp msgid "Switch between hexadecimal and code values." @@ -12670,6 +12676,10 @@ msgstr "" "れ以外ã®å ´åˆã¯ã€RenderTarget ã«ã—ã¦ã€ãã®å†…部テクスãƒãƒ£ã‚’表示ã™ã‚‹ãƒŽãƒ¼ãƒ‰ã«å‰²ã‚Š" "当ã¦ã¾ã™ã€‚" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "プレビューã®ã‚½ãƒ¼ã‚¹ãŒç„¡åйã§ã™ã€‚" @@ -12698,6 +12708,16 @@ msgstr "Varying変数ã¯é ‚点関数ã«ã®ã¿å‰²ã‚Šå½“ã¦ã‚‹ã“ã¨ãŒã§ãã¾ã msgid "Constants cannot be modified." msgstr "定数ã¯å¤‰æ›´ã§ãã¾ã›ã‚“。" +#~ msgid "Issue Tracker" +#~ msgstr "課題管ç†ã‚·ã‚¹ãƒ†ãƒ " + +#~ msgid "Request Docs" +#~ msgstr "ドã‚ãƒ¥ãƒ¡ãƒ³ãƒˆã‚’è¦æ±‚" + +#~ msgid "Help improve the Godot documentation by giving feedback." +#~ msgstr "" +#~ "フィードãƒãƒƒã‚¯ã‚’æä¾›ã—ã¦ã€Godotã®ãƒ‰ã‚ãƒ¥ãƒ¡ãƒ³ãƒˆã®æ”¹å–„ã«å½¹ç«‹ã¦ã¦ãã ã•ã„。" + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "%d 箇所を置æ›ã—ã¾ã—ãŸã€‚" diff --git a/editor/translations/ka.po b/editor/translations/ka.po index 1aaa12d6a0..ad4d5072f6 100644 --- a/editor/translations/ka.po +++ b/editor/translations/ka.po @@ -1495,7 +1495,7 @@ msgstr "" msgid "Remove Autoload" msgstr "" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "" @@ -2933,7 +2933,11 @@ msgid "Q&A" msgstr "" #: editor/editor_node.cpp -msgid "Issue Tracker" +msgid "Report a Bug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp @@ -3979,7 +3983,7 @@ msgid "Reimport" msgstr "" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -6837,14 +6841,6 @@ msgid "Open Godot online documentation." msgstr "" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7288,6 +7284,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7377,13 +7377,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -10800,6 +10800,12 @@ msgid "Script file already exists." msgstr "" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "" @@ -12452,6 +12458,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." diff --git a/editor/translations/ko.po b/editor/translations/ko.po index ec33599440..dd2d617eb8 100644 --- a/editor/translations/ko.po +++ b/editor/translations/ko.po @@ -15,12 +15,13 @@ # moolow <copyhyeon@gmail.com>, 2019. # Jiyoon Kim <kimjiy@dickinson.edu>, 2019. # Ervin <zetsmart@gmail.com>, 2019. +# Tilto_ <tilto0822@develable.xyz>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-03-14 00:33+0000\n" -"Last-Translator: Ch. <ccwpc@hanmail.net>\n" +"PO-Revision-Date: 2020-03-27 07:42+0000\n" +"Last-Translator: Tilto_ <tilto0822@develable.xyz>\n" "Language-Team: Korean <https://hosted.weblate.org/projects/godot-engine/" "godot/ko/>\n" "Language: ko\n" @@ -1449,7 +1450,7 @@ msgstr "ì˜¤í† ë¡œë“œ ì´ë™" msgid "Remove Autoload" msgstr "ì˜¤í† ë¡œë“œ ì‚ì œ" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "켜기" @@ -2923,8 +2924,13 @@ msgid "Q&A" msgstr "Q&A" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "ì´ìŠˆ 트래커" +#, fuzzy +msgid "Report a Bug" +msgstr "다시 ê°€ì ¸ì˜¤ê¸°" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -3970,7 +3976,8 @@ msgid "Reimport" msgstr "다시 ê°€ì ¸ì˜¤ê¸°" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +#, fuzzy +msgid "Save Scenes, Re-Import, and Restart" msgstr "씬 ì €ìž¥, 다시 ê°€ì ¸ì˜¤ê¸° ë° ë‹¤ì‹œ 시작" #: editor/import_dock.cpp @@ -5836,9 +5843,8 @@ msgid "Couldn't create a single convex collision shape." msgstr "ë‹¨ì¼ convex ì¶©ëŒ ëª¨ì–‘ì„ ë§Œë“¤ 수 없습니다." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Single Convex Shape" -msgstr "Convex 모양 만들기" +msgstr "개별 Convex 모양 만들기" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Can't create multiple convex collision shapes for the scene root." @@ -5923,9 +5929,8 @@ msgstr "" "ì´ ë°©ë²•ì€ ê°€ìž¥ ì •í™•í•œ (하지만 가장 ëŠë¦°) ì¶©ëŒ íƒì§€ 방법입니다." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Single Convex Collision Sibling" -msgstr "Convex ì¶©ëŒ í˜•ì œ 만들기" +msgstr "개별 Convex ì¶©ëŒ í˜•ì œ 만들기" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "" @@ -5936,7 +5941,6 @@ msgstr "" "ì´ ë°©ë²•ì€ ê°€ìž¥ ë¹ ë¥¸ (하지만 ëœ ì •í™•í•œ) ì¶©ëŒ íƒì§€ 방법입니다." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Multiple Convex Collision Siblings" msgstr "다중 Convex ì¶©ëŒ í˜•ì œ 만들기" @@ -6810,14 +6814,6 @@ msgid "Open Godot online documentation." msgstr "Godot 온ë¼ì¸ 문서를 ì—´." #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "문서 ìš”ì²" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "피드백으로 Godot 문서를 ê°œì„ í•˜ëŠ”ë° ë„와주세요." - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "참조 문서 검색." @@ -7254,6 +7250,11 @@ msgid "This operation requires a single selected node." msgstr "ì´ ìž‘ì—…ì€ í•˜ë‚˜ì˜ ë…¸ë“œë¥¼ ì„ íƒí•´ì•¼ 합니다." #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Auto Orthogonal Enabled" +msgstr "ì§êµë³´ê¸°" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "ë·° íšŒì „ ìž ê¸ˆ" @@ -7342,6 +7343,10 @@ msgid "Freelook Slow Modifier" msgstr "ìžìœ 시ì ëŠë¦° ìˆ˜ì •ìž" #: editor/plugins/spatial_editor_plugin.cpp +msgid "View Rotation Locked" +msgstr "ë·° íšŒì „ ìž ê¹€" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." @@ -7350,10 +7355,6 @@ msgstr "" "ì´ê²ƒì´ 게임 ë‚´ ì„±ëŠ¥ì„ ë³´ìž¥í• ìˆ˜ 없습니다." #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" -msgstr "ë·° íšŒì „ ìž ê¹€" - -#: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "XForm 대화 ìƒìž" @@ -9530,9 +9531,8 @@ msgid "Please choose a \"project.godot\" or \".zip\" file." msgstr "\"project.godot\" íŒŒì¼ ë˜ëŠ” \".zip\" 파ì¼ì„ ì„ íƒí•´ì£¼ì„¸ìš”." #: editor/project_manager.cpp -#, fuzzy msgid "This directory already contains a Godot project." -msgstr "ë””ë ‰í† ë¦¬ì— Godot 프로ì 트가 ì´ë¯¸ 있습니다." +msgstr "ë””ë ‰í† ë¦¬ì— Godot 프로ì 트가 ì´ë¯¸ 존재합니다." #: editor/project_manager.cpp msgid "New Game Project" @@ -10263,7 +10263,6 @@ msgstr "" "ì¹´ìš´í„° ì„¤ì •ê³¼ 비êµí•©ë‹ˆë‹¤." #: editor/rename_dialog.cpp -#, fuzzy msgid "Per-level Counter" msgstr "단계별 ì¹´ìš´í„°" @@ -10817,6 +10816,12 @@ msgid "Script file already exists." msgstr "스í¬ë¦½íЏ 파ì¼ì´ ì´ë¯¸ 있습니다." #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "í´ëž˜ìФ ì´ë¦„:" @@ -12565,6 +12570,10 @@ msgstr "" "ìš°, í™”ë©´ì— í‘œì‹œí•˜ê¸° 위해서는 ë·°í¬íŠ¸ë¥¼ RenderTarget으로 ë§Œë“¤ê³ ë‚´ë¶€ì ì¸ í…스처" "를 다른 ë…¸ë“œì— ì§€ì •í•´ì•¼ 합니다." +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "미리 ë³´ê¸°ì— ìž˜ëª»ëœ ì†ŒìŠ¤." @@ -12593,6 +12602,15 @@ msgstr "Varyingì€ ê¼ì§“ì 함수ì—ë§Œ ì§€ì •í• ìˆ˜ 있습니다." msgid "Constants cannot be modified." msgstr "ìƒìˆ˜ëŠ” ìˆ˜ì •í• ìˆ˜ 없습니다." +#~ msgid "Issue Tracker" +#~ msgstr "ì´ìŠˆ 트래커" + +#~ msgid "Request Docs" +#~ msgstr "문서 ìš”ì²" + +#~ msgid "Help improve the Godot documentation by giving feedback." +#~ msgstr "피드백으로 Godot 문서를 ê°œì„ í•˜ëŠ”ë° ë„와주세요." + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "%d개를 바꿨습니다." diff --git a/editor/translations/lt.po b/editor/translations/lt.po index 1f58c4a658..25cec6842f 100644 --- a/editor/translations/lt.po +++ b/editor/translations/lt.po @@ -1457,7 +1457,7 @@ msgstr "" msgid "Remove Autoload" msgstr "" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "" @@ -2898,7 +2898,11 @@ msgid "Q&A" msgstr "" #: editor/editor_node.cpp -msgid "Issue Tracker" +msgid "Report a Bug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp @@ -3953,7 +3957,7 @@ msgid "Reimport" msgstr "" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -6821,14 +6825,6 @@ msgid "Open Godot online documentation." msgstr "" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7264,6 +7260,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7353,13 +7353,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -10785,6 +10785,12 @@ msgid "Script file already exists." msgstr "" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp #, fuzzy msgid "Class Name:" msgstr "Priedai" @@ -12439,6 +12445,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." diff --git a/editor/translations/lv.po b/editor/translations/lv.po index 14dfdff801..973e732e2d 100644 --- a/editor/translations/lv.po +++ b/editor/translations/lv.po @@ -1464,7 +1464,7 @@ msgstr "" msgid "Remove Autoload" msgstr "" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "IespÄ“jot" @@ -2896,7 +2896,11 @@ msgid "Q&A" msgstr "" #: editor/editor_node.cpp -msgid "Issue Tracker" +msgid "Report a Bug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp @@ -3944,7 +3948,7 @@ msgid "Reimport" msgstr "" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -6795,14 +6799,6 @@ msgid "Open Godot online documentation." msgstr "" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7245,6 +7241,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7334,13 +7334,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -10751,6 +10751,12 @@ msgid "Script file already exists." msgstr "" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "" @@ -12405,6 +12411,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." diff --git a/editor/translations/mi.po b/editor/translations/mi.po index 5ec6cc28e0..f0b661e381 100644 --- a/editor/translations/mi.po +++ b/editor/translations/mi.po @@ -1399,7 +1399,7 @@ msgstr "" msgid "Remove Autoload" msgstr "" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "" @@ -2802,7 +2802,11 @@ msgid "Q&A" msgstr "" #: editor/editor_node.cpp -msgid "Issue Tracker" +msgid "Report a Bug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp @@ -3823,7 +3827,7 @@ msgid "Reimport" msgstr "" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -6605,14 +6609,6 @@ msgid "Open Godot online documentation." msgstr "" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7042,6 +7038,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7130,13 +7130,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -10454,6 +10454,12 @@ msgid "Script file already exists." msgstr "" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "" @@ -12067,6 +12073,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/ml.po b/editor/translations/ml.po index 7e7149e05e..92ffb6f097 100644 --- a/editor/translations/ml.po +++ b/editor/translations/ml.po @@ -1409,7 +1409,7 @@ msgstr "" msgid "Remove Autoload" msgstr "" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "" @@ -2814,7 +2814,11 @@ msgid "Q&A" msgstr "" #: editor/editor_node.cpp -msgid "Issue Tracker" +msgid "Report a Bug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp @@ -3835,7 +3839,7 @@ msgid "Reimport" msgstr "" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -6621,14 +6625,6 @@ msgid "Open Godot online documentation." msgstr "" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7058,6 +7054,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7146,13 +7146,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -10470,6 +10470,12 @@ msgid "Script file already exists." msgstr "" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "" @@ -12084,6 +12090,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/mr.po b/editor/translations/mr.po index 4ae3df9f99..f368062a85 100644 --- a/editor/translations/mr.po +++ b/editor/translations/mr.po @@ -1405,7 +1405,7 @@ msgstr "" msgid "Remove Autoload" msgstr "" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "" @@ -2809,7 +2809,11 @@ msgid "Q&A" msgstr "" #: editor/editor_node.cpp -msgid "Issue Tracker" +msgid "Report a Bug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp @@ -3830,7 +3834,7 @@ msgid "Reimport" msgstr "" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -6612,14 +6616,6 @@ msgid "Open Godot online documentation." msgstr "" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7049,6 +7045,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7137,13 +7137,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -10461,6 +10461,12 @@ msgid "Script file already exists." msgstr "" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "" @@ -12074,6 +12080,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/ms.po b/editor/translations/ms.po index bdb52e4845..dc18540ce3 100644 --- a/editor/translations/ms.po +++ b/editor/translations/ms.po @@ -1429,7 +1429,7 @@ msgstr "" msgid "Remove Autoload" msgstr "" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "" @@ -2836,7 +2836,11 @@ msgid "Q&A" msgstr "" #: editor/editor_node.cpp -msgid "Issue Tracker" +msgid "Report a Bug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp @@ -3858,7 +3862,7 @@ msgid "Reimport" msgstr "" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -6659,14 +6663,6 @@ msgid "Open Godot online documentation." msgstr "" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7097,6 +7093,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7185,13 +7185,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -10531,6 +10531,12 @@ msgid "Script file already exists." msgstr "" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "" @@ -12154,6 +12160,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/nb.po b/editor/translations/nb.po index 90df4e7b4f..6ec911db7d 100644 --- a/editor/translations/nb.po +++ b/editor/translations/nb.po @@ -2,7 +2,7 @@ # Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. # Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). # This file is distributed under the same license as the Godot source code. -# Allan Nordhøy <epost@anotheragency.no>, 2017-2018, 2019. +# Allan Nordhøy <epost@anotheragency.no>, 2017-2018, 2019, 2020. # Anonymous <GentleSaucepan@protonmail.com>, 2017. # Elias <eliasnykrem@gmail.com>, 2018. # flesk <eivindkn@gmail.com>, 2017, 2019. @@ -14,13 +14,13 @@ # Byzantin <kasper-hoel@hotmail.com>, 2018. # Hans-Marius ØverÃ¥s <hansmariusoveras@gmail.com>, 2019. # Revolution <revosw@gmail.com>, 2019. -# Petter Reinholdtsen <pere-weblate@hungry.com>, 2019. +# Petter Reinholdtsen <pere-weblate@hungry.com>, 2019, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2019-10-29 12:49+0000\n" -"Last-Translator: Allan Nordhøy <epost@anotheragency.no>\n" +"PO-Revision-Date: 2020-04-16 11:03+0000\n" +"Last-Translator: Petter Reinholdtsen <pere-weblate@hungry.com>\n" "Language-Team: Norwegian BokmÃ¥l <https://hosted.weblate.org/projects/godot-" "engine/godot/nb_NO/>\n" "Language: nb\n" @@ -28,7 +28,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 3.9.1\n" +"X-Generator: Weblate 4.0.1-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -37,7 +37,7 @@ msgstr "Ugyldig argumenttype til convert(), bruk TYPE_*-konstantene." #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp msgid "Expected a string of length 1 (a character)." -msgstr "" +msgstr "Forventet en streng med lenge 1 (et tegn)." #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/mono/glue/gd_glue.cpp @@ -243,7 +243,7 @@ msgstr "Legg til Spor" #: editor/animation_track_editor.cpp #, fuzzy msgid "Animation Looping" -msgstr "Animasjons-zoom." +msgstr "Animasjonsløkke" #: editor/animation_track_editor.cpp #: modules/visual_script/visual_script_editor.cpp @@ -283,14 +283,12 @@ msgid "Loop Wrap Mode (Interpolate end with beginning on loop)" msgstr "" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Remove this track." -msgstr "Fjern valgt spor." +msgstr "Fjern dette sporet." #: editor/animation_track_editor.cpp -#, fuzzy msgid "Time (s): " -msgstr "X-Fade Tid (s):" +msgstr "Tid (s): " #: editor/animation_track_editor.cpp msgid "Toggle Track Enabled" @@ -309,9 +307,8 @@ msgid "Trigger" msgstr "Avtrekker" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Capture" -msgstr "Framtid" +msgstr "Fang" #: editor/animation_track_editor.cpp msgid "Nearest" @@ -340,14 +337,12 @@ msgid "Insert Key" msgstr "Sett inn Nøkkel" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Duplicate Key(s)" -msgstr "Anim Dupliser Nøkler" +msgstr "Dupliser Nøkler" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Delete Key(s)" -msgstr "Anim Fjern Nøkler" +msgstr "Fjern Nøkler" #: editor/animation_track_editor.cpp #, fuzzy @@ -1181,7 +1176,7 @@ msgstr "Utviklingsleder" #: editor/editor_about.cpp msgid "Project Manager " -msgstr "Prosjektleder " +msgstr "Prosjektstyring " #: editor/editor_about.cpp msgid "Developers" @@ -1284,7 +1279,7 @@ msgstr "Vellykket Installering av Pakke!" #: editor/editor_asset_installer.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Success!" -msgstr "Suksess!" +msgstr "Vellykket!" #: editor/editor_asset_installer.cpp #, fuzzy @@ -1524,7 +1519,7 @@ msgstr "Flytt Autoload" msgid "Remove Autoload" msgstr "Fjern Autoload" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "Aktiver" @@ -1588,7 +1583,7 @@ msgstr "Oppdaterer scene..." #: editor/editor_data.cpp editor/editor_properties.cpp msgid "[empty]" -msgstr "[tom]" +msgstr "[blank]" #: editor/editor_data.cpp msgid "[unsaved]" @@ -1669,16 +1664,14 @@ msgstr "" #: editor/editor_export.cpp platform/android/export/export.cpp #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp #: platform/osx/export/export.cpp platform/uwp/export/export.cpp -#, fuzzy msgid "Custom debug template not found." -msgstr "Malfil ble ikke funnet:" +msgstr "Tilpasset feilsøkingsmal ble ikke funnet." #: editor/editor_export.cpp platform/android/export/export.cpp #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp #: platform/osx/export/export.cpp platform/uwp/export/export.cpp -#, fuzzy msgid "Custom release template not found." -msgstr "Tilpasset utgivelsesmal ikke funnet." +msgstr "Fant ikke tilpasset utgivelsesmal." #: editor/editor_export.cpp platform/javascript/export/export.cpp msgid "Template file not found:" @@ -1699,9 +1692,8 @@ msgid "Script Editor" msgstr "Ã…pne SkriptEditor" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Asset Library" -msgstr "Ã…pne Assets-Bibliotek" +msgstr "Ressursbibliotek" #: editor/editor_feature_profile.cpp msgid "Scene Tree Editing" @@ -2024,7 +2016,7 @@ msgstr "MÃ¥ ha en gyldig filutvidelse." #: editor/editor_file_system.cpp msgid "ScanSources" -msgstr "SkannKilder" +msgstr "Gjennomsøk kilder" #: editor/editor_file_system.cpp msgid "" @@ -2054,9 +2046,8 @@ msgid "Inherited by:" msgstr "Arvet av:" #: editor/editor_help.cpp -#, fuzzy msgid "Description" -msgstr "Beskrivelse:" +msgstr "Beskrivelse" #: editor/editor_help.cpp #, fuzzy @@ -2180,9 +2171,8 @@ msgid "Member Type" msgstr "Medlemmer" #: editor/editor_help_search.cpp -#, fuzzy msgid "Class" -msgstr "Klasse:" +msgstr "Klasse" #: editor/editor_help_search.cpp #, fuzzy @@ -2927,7 +2917,7 @@ msgstr "Avslutt til Prosjektliste" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/project_export.cpp msgid "Debug" -msgstr "Debug" +msgstr "Feilsøk" #: editor/editor_node.cpp msgid "Deploy with Remote Debug" @@ -2943,9 +2933,8 @@ msgstr "" "koble til IP'en til denne datamaskinen for Ã¥ bli debugget." #: editor/editor_node.cpp -#, fuzzy msgid "Small Deploy with Network FS" -msgstr "Liten Deploy med Network FS" +msgstr "Liten utrulling med Network FS" #: editor/editor_node.cpp msgid "" @@ -2963,9 +2952,8 @@ msgstr "" "alternativet gjør testing for spill med et stort fotavtrykk raskere." #: editor/editor_node.cpp -#, fuzzy msgid "Visible Collision Shapes" -msgstr "Synlige Kollisjons-Former" +msgstr "Synlige kollisjons-former" #: editor/editor_node.cpp msgid "" @@ -2977,7 +2965,7 @@ msgstr "" #: editor/editor_node.cpp msgid "Visible Navigation" -msgstr "Synlig Navigasjon" +msgstr "Synlig navigasjon" #: editor/editor_node.cpp msgid "" @@ -2989,7 +2977,7 @@ msgstr "" #: editor/editor_node.cpp msgid "Sync Scene Changes" -msgstr "Synkroniser Sceneforandringer" +msgstr "Synkroniser Sceneendringer" #: editor/editor_node.cpp msgid "" @@ -3005,7 +2993,7 @@ msgstr "" #: editor/editor_node.cpp msgid "Sync Script Changes" -msgstr "Synkroniser Skriptforandringer" +msgstr "Synkroniser Skriptendringer" #: editor/editor_node.cpp #, fuzzy @@ -3021,7 +3009,6 @@ msgstr "" "nettverksfilsystem." #: editor/editor_node.cpp editor/script_create_dialog.cpp -#, fuzzy msgid "Editor" msgstr "Redigeringsverktøy" @@ -3100,8 +3087,13 @@ msgid "Q&A" msgstr "SpørsmÃ¥l og Svar" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "Problemtracker" +#, fuzzy +msgid "Report a Bug" +msgstr "Reimporter" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -3365,7 +3357,6 @@ msgid "Inclusive" msgstr "Inklusiv" #: editor/editor_profiler.cpp -#, fuzzy msgid "Self" msgstr "Selv" @@ -3547,8 +3538,9 @@ msgid "Select Node(s) to Import" msgstr "Velg Node(r) for Importering" #: editor/editor_sub_scene.cpp editor/project_manager.cpp +#, fuzzy msgid "Browse" -msgstr "Utforsk" +msgstr "Bla gjennom" #: editor/editor_sub_scene.cpp msgid "Scene Path:" @@ -3953,7 +3945,7 @@ msgstr "Lag mappe" #: editor/filesystem_dock.cpp msgid "Re-Scan Filesystem" -msgstr "Re-Skann Filsystem" +msgstr "Gjennomsøk filsystem pÃ¥ ny" #: editor/filesystem_dock.cpp #, fuzzy @@ -3970,8 +3962,8 @@ msgid "" "Scanning Files,\n" "Please Wait..." msgstr "" -"Skanner Filer,\n" -"Vennligst Vent..." +"GjennomgÃ¥r filer,\n" +"Vent…" #: editor/filesystem_dock.cpp msgid "Move" @@ -4225,7 +4217,8 @@ msgid "Reimport" msgstr "Reimporter" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +#, fuzzy +msgid "Save Scenes, Re-Import, and Restart" msgstr "Lagre scener, om-importer og start om" #: editor/import_dock.cpp @@ -4670,9 +4663,8 @@ msgid "Audio Clips" msgstr "Lydklipp:" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Functions" -msgstr "Funksjoner:" +msgstr "Funksjoner" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/animation_state_machine_editor.cpp @@ -5021,9 +5013,8 @@ msgstr "Panorerings-Modus" #: editor/plugins/animation_tree_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp -#, fuzzy msgid "AnimationTree" -msgstr "Animasjon" +msgstr "Animasjontre" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "New name:" @@ -7256,14 +7247,6 @@ msgid "Open Godot online documentation." msgstr "Ã…pne Godots nettbaserte dokumentasjon" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "Søk i referanse-dokumentasjonen." @@ -7297,7 +7280,7 @@ msgstr "Lagre pÃ¥ nytt" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" -msgstr "Feilretter" +msgstr "Feilsøking" #: editor/plugins/script_editor_plugin.cpp #, fuzzy @@ -7565,9 +7548,8 @@ msgid "Create physical bones" msgstr "" #: editor/plugins/skeleton_editor_plugin.cpp -#, fuzzy msgid "Skeleton" -msgstr "Singleton" +msgstr "Skelett" #: editor/plugins/skeleton_editor_plugin.cpp #, fuzzy @@ -7585,7 +7567,7 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Perspective" -msgstr "" +msgstr "Perspektiv" #: editor/plugins/spatial_editor_plugin.cpp msgid "Transform Aborted." @@ -7724,6 +7706,10 @@ msgid "This operation requires a single selected node." msgstr "Denne operasjonen krever én valgt node." #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp #, fuzzy msgid "Lock View Rotation" msgstr "Vis Informasjon" @@ -7780,7 +7766,7 @@ msgstr "Lager ForhÃ¥ndsvisning av Mesh" #: editor/plugins/spatial_editor_plugin.cpp msgid "Not available when using the GLES2 renderer." -msgstr "" +msgstr "Ikke tilgjengelig ved bruk av GLES2-opptegner." #: editor/plugins/spatial_editor_plugin.cpp msgid "Freelook Left" @@ -7815,17 +7801,17 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "View Rotation Locked" +msgstr "Vis Informasjon" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy -msgid "View Rotation Locked" -msgstr "Vis Informasjon" - -#: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "" @@ -7879,7 +7865,7 @@ msgstr "Høyrevisning" #: editor/plugins/spatial_editor_plugin.cpp msgid "Switch Perspective/Orthogonal View" -msgstr "" +msgstr "Bytt perspektiv/ortogonal fremvisning" #: editor/plugins/spatial_editor_plugin.cpp msgid "Insert Animation Key" @@ -7975,7 +7961,7 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Perspective FOV (deg.):" -msgstr "" +msgstr "Perspektiv-synsv. (deg.):" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Z-Near:" @@ -9032,9 +9018,8 @@ msgid "Scalar" msgstr "Skala:" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector" -msgstr "Inspektør" +msgstr "Vektor" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Boolean" @@ -10071,7 +10056,7 @@ msgstr "" #: editor/project_manager.cpp msgid "Please choose an empty folder." -msgstr "" +msgstr "Velg en tom mappe." #: editor/project_manager.cpp msgid "Please choose a \"project.godot\" or \".zip\" file." @@ -10144,9 +10129,8 @@ msgid "Create New Project" msgstr "Opprett Nytt Prosjekt" #: editor/project_manager.cpp -#, fuzzy msgid "Create & Edit" -msgstr "Opprett skript" +msgstr "Opprett og rediger" #: editor/project_manager.cpp msgid "Install Project:" @@ -10171,7 +10155,7 @@ msgstr "Prosjektsti:" #: editor/project_manager.cpp msgid "Renderer:" -msgstr "" +msgstr "Opptegner:" #: editor/project_manager.cpp msgid "OpenGL ES 3.0" @@ -10184,6 +10168,10 @@ msgid "" "Incompatible with older hardware\n" "Not recommended for web games" msgstr "" +"Høyere visuell kvalitet\n" +"All funksjonalitet tilgjengelig\n" +"Fungerer ikke med eldre maskinvare\n" +"Ikke anbefalt for nettsidebaserte spill" #: editor/project_manager.cpp msgid "OpenGL ES 2.0" @@ -10196,10 +10184,14 @@ msgid "" "Works on most hardware\n" "Recommended for web games" msgstr "" +"Lavere visuell kvalitet\n" +"Noe funksjonalitet er ikke tilgjengelig\n" +"Virker pÃ¥ det meste av maskinvare\n" +"Anbefalt for nettsidebaserte spill" #: editor/project_manager.cpp msgid "Renderer can be changed later, but scenes may need to be adjusted." -msgstr "" +msgstr "Rendrer kan endres senere, men scener mÃ¥ kanskje justeres." #: editor/project_manager.cpp msgid "Unnamed Project" @@ -10304,22 +10296,21 @@ msgid "" msgstr "" #: editor/project_manager.cpp -#, fuzzy msgid "" "Are you sure to scan %s folders for existing Godot projects?\n" "This could take a while." msgstr "" -"Du er i ferd med Ã¥ skanne %s mapper for eksisterende Godotprosjekter. " -"Bekrefter du?" +"Er du sikker pÃ¥ at du vil søke gjennom %s mapper etter eksisterende " +"Godotprosjekter.\n" +"Det kan ta en stund." #: editor/project_manager.cpp msgid "Project Manager" -msgstr "Prosjektleder" +msgstr "Prosjektstyring" #: editor/project_manager.cpp -#, fuzzy msgid "Projects" -msgstr "Prosjekt" +msgstr "Prosjekter" #: editor/project_manager.cpp msgid "Last Modified" @@ -10327,11 +10318,11 @@ msgstr "" #: editor/project_manager.cpp msgid "Scan" -msgstr "Skann" +msgstr "Gjennomsøk" #: editor/project_manager.cpp msgid "Select a Folder to Scan" -msgstr "Velg en Mappe Ã¥ Skanne" +msgstr "Velg en mappe Ã¥ søke gjennom" #: editor/project_manager.cpp msgid "New Project" @@ -10344,7 +10335,7 @@ msgstr "Fjern punkt" #: editor/project_manager.cpp msgid "Templates" -msgstr "" +msgstr "Maler" #: editor/project_manager.cpp msgid "Restart Now" @@ -10402,15 +10393,15 @@ msgstr "" #: editor/project_settings_editor.cpp msgid "All Devices" -msgstr "" +msgstr "Alle enheter" #: editor/project_settings_editor.cpp msgid "Device" -msgstr "" +msgstr "Enhet" #: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp msgid "Press a Key..." -msgstr "" +msgstr "Trykk en tast..." #: editor/project_settings_editor.cpp msgid "Mouse Button Index:" @@ -10418,15 +10409,15 @@ msgstr "" #: editor/project_settings_editor.cpp msgid "Left Button" -msgstr "" +msgstr "Venstre knapp" #: editor/project_settings_editor.cpp msgid "Right Button" -msgstr "" +msgstr "Høyre knapp" #: editor/project_settings_editor.cpp msgid "Middle Button" -msgstr "" +msgstr "Midtknapp" #: editor/project_settings_editor.cpp msgid "Wheel Up Button" @@ -10460,7 +10451,7 @@ msgstr "" #: editor/project_settings_editor.cpp msgid "Axis" -msgstr "" +msgstr "Akse" #: editor/project_settings_editor.cpp msgid "Joypad Button Index:" @@ -10477,23 +10468,23 @@ msgstr "" #: editor/project_settings_editor.cpp msgid "Add Event" -msgstr "" +msgstr "Legg til hendelse" #: editor/project_settings_editor.cpp msgid "Button" -msgstr "" +msgstr "Knapp" #: editor/project_settings_editor.cpp msgid "Left Button." -msgstr "" +msgstr "Venstre knapp." #: editor/project_settings_editor.cpp msgid "Right Button." -msgstr "" +msgstr "Høyre knapp." #: editor/project_settings_editor.cpp msgid "Middle Button." -msgstr "" +msgstr "Midtknapp." #: editor/project_settings_editor.cpp msgid "Wheel Up." @@ -10513,7 +10504,7 @@ msgstr "" #: editor/project_settings_editor.cpp msgid "No property '%s' exists." -msgstr "" +msgstr "Egenskapen «%s» eksisterer ikke." #: editor/project_settings_editor.cpp msgid "Setting '%s' is internal, and it can't be deleted." @@ -10553,11 +10544,11 @@ msgstr "" #: editor/project_settings_editor.cpp msgid "Add Translation" -msgstr "" +msgstr "Legg til oversettelse" #: editor/project_settings_editor.cpp msgid "Remove Translation" -msgstr "" +msgstr "Fjern oversettelse" #: editor/project_settings_editor.cpp msgid "Add Remapped Path" @@ -10597,7 +10588,7 @@ msgstr "Generelt" #: editor/project_settings_editor.cpp msgid "Override For..." -msgstr "" +msgstr "Overstyr for..." #: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp msgid "The editor must be restarted for changes to take effect." @@ -10612,17 +10603,16 @@ msgid "Action:" msgstr "" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Action" -msgstr "Flytt Handling" +msgstr "Handling" #: editor/project_settings_editor.cpp msgid "Deadzone" -msgstr "" +msgstr "Dødsone" #: editor/project_settings_editor.cpp msgid "Device:" -msgstr "" +msgstr "Enhet:" #: editor/project_settings_editor.cpp msgid "Index:" @@ -10634,11 +10624,11 @@ msgstr "" #: editor/project_settings_editor.cpp msgid "Translations" -msgstr "" +msgstr "Oversettelser" #: editor/project_settings_editor.cpp msgid "Translations:" -msgstr "" +msgstr "Oversettelser:" #: editor/project_settings_editor.cpp msgid "Remaps" @@ -10684,9 +10674,8 @@ msgid "AutoLoad" msgstr "" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Plugins" -msgstr "Plugins" +msgstr "Innstikkmoduler" #: editor/property_editor.cpp #, fuzzy @@ -10707,7 +10696,7 @@ msgstr "" #: editor/property_editor.cpp msgid "File..." -msgstr "" +msgstr "Fil..." #: editor/property_editor.cpp msgid "Dir..." @@ -10715,12 +10704,11 @@ msgstr "" #: editor/property_editor.cpp msgid "Assign" -msgstr "" +msgstr "Tildel" #: editor/property_editor.cpp -#, fuzzy msgid "Select Node" -msgstr "Kutt Noder" +msgstr "Velg node" #: editor/property_editor.cpp msgid "Error loading file: Not a resource!" @@ -11031,9 +11019,8 @@ msgid "New Scene Root" msgstr "Lagre Scene" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Create Root Node:" -msgstr "Lag Node" +msgstr "Opprett rot-node:" #: editor/scene_tree_dock.cpp #, fuzzy @@ -11047,12 +11034,11 @@ msgstr "Scene" #: editor/scene_tree_dock.cpp msgid "User Interface" -msgstr "" +msgstr "Brukergrensesnitt" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Other Node" -msgstr "Kutt Noder" +msgstr "Andre noder" #: editor/scene_tree_dock.cpp msgid "Can't operate on nodes from a foreign scene!" @@ -11161,6 +11147,8 @@ msgid "" "Instance a scene file as a Node. Creates an inherited scene if no root node " "exists." msgstr "" +"Opprett en scenefil som en node. Oppretter en arvet scene hvis det ikke " +"finnes en rot-node." #: editor/scene_tree_dock.cpp msgid "Attach a new or existing script for the selected node." @@ -11381,6 +11369,12 @@ msgid "Script file already exists." msgstr "Eksisterer allerede" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp #, fuzzy msgid "Class Name:" msgstr "Klasse:" @@ -11487,9 +11481,8 @@ msgid "Profiler" msgstr "" #: editor/script_editor_debugger.cpp -#, fuzzy msgid "Network Profiler" -msgstr "Eksporter Prosjekt" +msgstr "" #: editor/script_editor_debugger.cpp msgid "Monitor" @@ -12209,11 +12202,11 @@ msgstr "Endre CanvasItem" #: modules/visual_script/visual_script_editor.cpp msgid "Can't copy the function node." -msgstr "" +msgstr "Kan ikke kopiere funksjonsnoden." #: modules/visual_script/visual_script_editor.cpp msgid "Clipboard is empty!" -msgstr "" +msgstr "Utklippsbordet er tomt!" #: modules/visual_script/visual_script_editor.cpp #, fuzzy @@ -13084,6 +13077,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." @@ -13114,6 +13111,9 @@ msgstr "" msgid "Constants cannot be modified." msgstr "Konstanter kan ikke endres." +#~ msgid "Issue Tracker" +#~ msgstr "Problemtracker" + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "Erstattet %d forekomst(er)." diff --git a/editor/translations/nl.po b/editor/translations/nl.po index a729ea6119..d270e51f6f 100644 --- a/editor/translations/nl.po +++ b/editor/translations/nl.po @@ -40,11 +40,12 @@ # Tirrin <lensenjoe@gmail.com>, 2019. # Filip Van Raemdonck <arrawn@gmail.com>, 2019. # Julian <jdhoogvorst@gmail.com>, 2019, 2020. +# anonymous <noreply@weblate.org>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-03-16 09:43+0000\n" +"PO-Revision-Date: 2020-04-15 14:29+0000\n" "Last-Translator: Stijn Hinlopen <f.a.hinlopen@gmail.com>\n" "Language-Team: Dutch <https://hosted.weblate.org/projects/godot-engine/godot/" "nl/>\n" @@ -1466,7 +1467,7 @@ msgstr "Autoload '%s' bestaat al!" #: editor/editor_autoload_settings.cpp msgid "Rename Autoload" -msgstr "Autoload Hernoemen" +msgstr "Naam Autoload-script wijzigen" #: editor/editor_autoload_settings.cpp msgid "Toggle AutoLoad Globals" @@ -1480,7 +1481,7 @@ msgstr "Autoload verplaatsen" msgid "Remove Autoload" msgstr "Autoload verwijderen" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "Inschakelen" @@ -1748,7 +1749,7 @@ msgstr "Nieuw" #: editor/editor_feature_profile.cpp editor/editor_node.cpp #: editor/project_manager.cpp msgid "Import" -msgstr "Import" +msgstr "Importeren" #: editor/editor_feature_profile.cpp editor/project_export.cpp msgid "Export" @@ -2966,8 +2967,13 @@ msgid "Q&A" msgstr "Vragen en antwoorden" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "Issue Tracker" +#, fuzzy +msgid "Report a Bug" +msgstr "Opnieuw importeren" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -3641,7 +3647,7 @@ msgstr "" #: editor/filesystem_dock.cpp msgid "Cannot move/rename resources root." -msgstr "Kan de hoofdmap voor bronnen niet verplaatsen of hernoemen." +msgstr "Kan de hoofdmap voor bronnen niet verplaatsen of van naam veranderen." #: editor/filesystem_dock.cpp msgid "Cannot move a folder into itself." @@ -3681,7 +3687,7 @@ msgstr "Bestandsnaam wijzigen:" #: editor/filesystem_dock.cpp msgid "Renaming folder:" -msgstr "Hernoemen folder:" +msgstr "Mapnaam wijzigen:" #: editor/filesystem_dock.cpp msgid "Duplicating file:" @@ -3762,7 +3768,7 @@ msgstr "Alles inklappen" #: editor/project_manager.cpp editor/rename_dialog.cpp #: editor/scene_tree_dock.cpp msgid "Rename" -msgstr "Hernoemen" +msgstr "Naam wijzigen" #: editor/filesystem_dock.cpp msgid "Previous Folder/File" @@ -4024,7 +4030,8 @@ msgid "Reimport" msgstr "Opnieuw importeren" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +#, fuzzy +msgid "Save Scenes, Re-Import, and Restart" msgstr "Opnieuw importeren en herstarten (alle scènes worden opgeslagen)" #: editor/import_dock.cpp @@ -5997,9 +6004,8 @@ msgstr "" "Dit is de meest preciese (maar langzaamste) optie voor botsingsberekeningen." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Single Convex Collision Sibling" -msgstr "Een enkele convexe botsingsonderelement aanmaken" +msgstr "Maak een enkel convex botsingselement als subelement" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "" @@ -6888,14 +6894,6 @@ msgid "Open Godot online documentation." msgstr "Open Godot online documentatie." #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "Verzoek documentatie" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "Help de Godot-documentatie te verbeteren door feedback te geven." - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "Zoek in de referentie documentatie." @@ -7330,6 +7328,11 @@ msgid "This operation requires a single selected node." msgstr "Deze bewerking vereist één geselecteerde knoop." #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Auto Orthogonal Enabled" +msgstr "Orthogonaal" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "Beeldrotatie vergrendelen" @@ -7418,6 +7421,10 @@ msgid "Freelook Slow Modifier" msgstr "Vrijekijk Snelheid Modificator" #: editor/plugins/spatial_editor_plugin.cpp +msgid "View Rotation Locked" +msgstr "Beeldrotatie vergrendeld" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." @@ -7427,10 +7434,6 @@ msgstr "" "Het is geen betrouwbare indicatie voor werkelijke spelprestaties." #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" -msgstr "Beeldrotatie vergrendeld" - -#: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "XForm Dialoog" @@ -8169,7 +8172,7 @@ msgstr "Selecteer de vorige shape, subtegel of Tegel." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Region" -msgstr "Bereik" +msgstr "Gebied" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Collision" @@ -8197,7 +8200,7 @@ msgstr "Z Index" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Region Mode" -msgstr "Bereikmodus" +msgstr "Gebiedmodus" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Collision Mode" @@ -8249,7 +8252,7 @@ msgstr "Nieuwe veelhoek aanmaken." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Keep polygon inside region Rect." -msgstr "Hou de veelhoek binnen een rechthoekig bereik." +msgstr "Houd de veelhoek binnen het rechthoekige gebied." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Enable snap and show grid (configurable via the Inspector)." @@ -9877,7 +9880,7 @@ msgid "" "The project folders' contents won't be modified." msgstr "" "%d projecten uit de lijst verwijderen?\n" -"De inhoud van de projectmappen wordt niet geraakt." +"De inhoud van de projectmappen wordt niet gewijzigd." #: editor/project_manager.cpp msgid "" @@ -9885,7 +9888,7 @@ msgid "" "The project folder's contents won't be modified." msgstr "" "Project uit de lijst verwijderen?\n" -"De inhoud van de projectmap wordt niet geraakt." +"De inhoud van de projectmap wordt niet gewijzigd." #: editor/project_manager.cpp msgid "" @@ -10338,7 +10341,7 @@ msgstr "Selecteer Method" #: editor/rename_dialog.cpp editor/scene_tree_dock.cpp msgid "Batch Rename" -msgstr "Hernoemen meerdere" +msgstr "Bulk hernoemen" #: editor/rename_dialog.cpp msgid "Prefix" @@ -10647,7 +10650,7 @@ msgstr "Kan niet werken aan knopen waar de huidige scène van erft!" #: editor/scene_tree_dock.cpp msgid "Attach Script" -msgstr "Verbind Script" +msgstr "Script toevoegen" #: editor/scene_tree_dock.cpp msgid "Remove Node(s)" @@ -10950,6 +10953,12 @@ msgid "Script file already exists." msgstr "Scriptbestand bestaat al." #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "Klasse Naam:" @@ -12733,6 +12742,10 @@ msgstr "" "maken, zodat het een grootte kan ontvangen. Anders, maak er een RenderTarget " "van en wijs zijn interne textuur toe aan een knoop om te tonen." +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "Ongeldige bron voor voorvertoning." @@ -12761,6 +12774,15 @@ msgstr "Varyings kunnen alleen worden toegewezenin vertex functies." msgid "Constants cannot be modified." msgstr "Constanten kunnen niet worden aangepast." +#~ msgid "Issue Tracker" +#~ msgstr "Issue Tracker" + +#~ msgid "Request Docs" +#~ msgstr "Verzoek documentatie" + +#~ msgid "Help improve the Godot documentation by giving feedback." +#~ msgstr "Help de Godot-documentatie te verbeteren door feedback te geven." + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "%d voorgekomen waarde(s) vervangen." diff --git a/editor/translations/or.po b/editor/translations/or.po index 6819e53f38..1858bad087 100644 --- a/editor/translations/or.po +++ b/editor/translations/or.po @@ -1405,7 +1405,7 @@ msgstr "" msgid "Remove Autoload" msgstr "" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "" @@ -2808,7 +2808,11 @@ msgid "Q&A" msgstr "" #: editor/editor_node.cpp -msgid "Issue Tracker" +msgid "Report a Bug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp @@ -3829,7 +3833,7 @@ msgid "Reimport" msgstr "" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -6611,14 +6615,6 @@ msgid "Open Godot online documentation." msgstr "" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7048,6 +7044,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7136,13 +7136,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -10460,6 +10460,12 @@ msgid "Script file already exists." msgstr "" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "" @@ -12073,6 +12079,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/pl.po b/editor/translations/pl.po index de1d6d5375..eb40e7ecaa 100644 --- a/editor/translations/pl.po +++ b/editor/translations/pl.po @@ -42,7 +42,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-03-16 09:43+0000\n" +"PO-Revision-Date: 2020-03-26 05:19+0000\n" "Last-Translator: Tomek <kobewi4e@gmail.com>\n" "Language-Team: Polish <https://hosted.weblate.org/projects/godot-engine/" "godot/pl/>\n" @@ -1474,7 +1474,7 @@ msgstr "Przemieść Autoload" msgid "Remove Autoload" msgstr "UsuÅ„ Autoload" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "Włącz" @@ -2952,8 +2952,13 @@ msgid "Q&A" msgstr "Pytania i odpowiedzi" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "Lista problemów" +#, fuzzy +msgid "Report a Bug" +msgstr "Importuj ponownie" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4008,7 +4013,8 @@ msgid "Reimport" msgstr "Importuj ponownie" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +#, fuzzy +msgid "Save Scenes, Re-Import, and Restart" msgstr "Zapisz sceny, re-importuj i zrestartuj" #: editor/import_dock.cpp @@ -6867,14 +6873,6 @@ msgid "Open Godot online documentation." msgstr "Otwórz dokumentacjÄ™ Godota online." #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "PoproÅ› o dokumentacjÄ™" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "Pomóż polepszyć dokumentacjÄ™ Godota przesyÅ‚ajÄ…c opiniÄ™." - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "Poszukaj w dokumentacji referencyjnej." @@ -7311,6 +7309,11 @@ msgid "This operation requires a single selected node." msgstr "Ta operacja wymaga pojedynczego wybranego wÄ™zÅ‚a." #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Auto Orthogonal Enabled" +msgstr "Ortogonalna" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "Zablokuj obrót widoku" @@ -7399,6 +7402,10 @@ msgid "Freelook Slow Modifier" msgstr "Wolny modyfikator swobodnego widoku" #: editor/plugins/spatial_editor_plugin.cpp +msgid "View Rotation Locked" +msgstr "Obroty widoku zablokowane" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." @@ -7407,10 +7414,6 @@ msgstr "" "Nie może być używana jako miarodajny wskaźnik wydajnoÅ›ci w grze." #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" -msgstr "Obroty widoku zablokowane" - -#: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "Okno dialogowe XForm" @@ -8040,7 +8043,7 @@ msgstr "WypeÅ‚nienie" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Erase TileMap" -msgstr "Wyczyść TileMap" +msgstr "UsuÅ„ TileMap" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Find Tile" @@ -10914,6 +10917,12 @@ msgid "Script file already exists." msgstr "Plik skryptu już istnieje." #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "Nazwa klasy:" @@ -12697,6 +12706,10 @@ msgstr "" "otrzymaÅ‚ jakiÅ› rozmiar. W przeciwnym wypadku ustawi opcjÄ™ RenderTarget i " "przyporzÄ…dkuj jego teksturÄ™ dla któregoÅ› wÄ™zÅ‚a." +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "NieprawidÅ‚owe źródÅ‚o do podglÄ…du." @@ -12725,6 +12738,15 @@ msgstr "Varying może być przypisane tylko w funkcji wierzchoÅ‚ków." msgid "Constants cannot be modified." msgstr "StaÅ‚e nie mogÄ… być modyfikowane." +#~ msgid "Issue Tracker" +#~ msgstr "Lista problemów" + +#~ msgid "Request Docs" +#~ msgstr "PoproÅ› o dokumentacjÄ™" + +#~ msgid "Help improve the Godot documentation by giving feedback." +#~ msgstr "Pomóż polepszyć dokumentacjÄ™ Godota przesyÅ‚ajÄ…c opiniÄ™." + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "ZastÄ…piono %d wystÄ…pieÅ„." diff --git a/editor/translations/pr.po b/editor/translations/pr.po index 873a2d506b..70a061783c 100644 --- a/editor/translations/pr.po +++ b/editor/translations/pr.po @@ -1453,7 +1453,7 @@ msgstr "" msgid "Remove Autoload" msgstr "" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "" @@ -2897,7 +2897,11 @@ msgid "Q&A" msgstr "" #: editor/editor_node.cpp -msgid "Issue Tracker" +msgid "Report a Bug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp @@ -3956,7 +3960,7 @@ msgid "Reimport" msgstr "" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -6823,14 +6827,6 @@ msgid "Open Godot online documentation." msgstr "Yer functions:" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7277,6 +7273,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7366,13 +7366,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -10812,6 +10812,12 @@ msgid "Script file already exists." msgstr "" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "" @@ -12501,6 +12507,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." diff --git a/editor/translations/pt_BR.po b/editor/translations/pt_BR.po index a96186e434..82bd304311 100644 --- a/editor/translations/pt_BR.po +++ b/editor/translations/pt_BR.po @@ -84,12 +84,13 @@ # Leonardo Dimano <leodimano@live.com>, 2020. # anonymous <noreply@weblate.org>, 2020. # Guilherme Souza Reis de Melo Lopes <gsrmlopes@gmail.com>, 2020. +# Richard Urban <redasuio1@gmail.com>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: 2016-05-30\n" -"PO-Revision-Date: 2020-03-08 22:32+0000\n" -"Last-Translator: Guilherme Souza Reis de Melo Lopes <gsrmlopes@gmail.com>\n" +"PO-Revision-Date: 2020-04-16 11:03+0000\n" +"Last-Translator: Richard Urban <redasuio1@gmail.com>\n" "Language-Team: Portuguese (Brazil) <https://hosted.weblate.org/projects/" "godot-engine/godot/pt_BR/>\n" "Language: pt_BR\n" @@ -97,7 +98,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.0-dev\n" +"X-Generator: Weblate 4.0.1-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -1519,7 +1520,7 @@ msgstr "Mover Autoload" msgid "Remove Autoload" msgstr "Remover Autoload" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "Habilitar" @@ -3005,8 +3006,13 @@ msgid "Q&A" msgstr "Perguntas & Respostas" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "Rastreador de Problemas" +#, fuzzy +msgid "Report a Bug" +msgstr "Reimportar" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4065,7 +4071,8 @@ msgid "Reimport" msgstr "Reimportar" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +#, fuzzy +msgid "Save Scenes, Re-Import, and Restart" msgstr "Salvar cenas, reimportar e reiniciar" #: editor/import_dock.cpp @@ -6038,7 +6045,6 @@ msgstr "" "Este é a opção mais precisa (mas lenta) para detecção de colisão." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Single Convex Collision Sibling" msgstr "Criar Simples Colisão Convexa Irmã(s)" @@ -6930,14 +6936,6 @@ msgid "Open Godot online documentation." msgstr "Abrir a documentação online da Godot." #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "Solicitar documentos" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "Ajude a melhorar a documentação do Godot dando seu feedback." - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "Pesquise a documentação de referência." @@ -7372,6 +7370,11 @@ msgid "This operation requires a single selected node." msgstr "Essa operação requer um único nó selecionado." #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Auto Orthogonal Enabled" +msgstr "Ortogonal" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "Bloquear Rotação da Visão" @@ -7460,6 +7463,10 @@ msgid "Freelook Slow Modifier" msgstr "Modificador de velocidade lenta da Visão Livre" #: editor/plugins/spatial_editor_plugin.cpp +msgid "View Rotation Locked" +msgstr "Ver Rotação Bloqueada" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." @@ -7468,10 +7475,6 @@ msgstr "" "Ele não deve ser usado como indicação confiável de desempenho do jogo." #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" -msgstr "Ver Rotação Bloqueada" - -#: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "Diálogo XForm" @@ -10972,6 +10975,12 @@ msgid "Script file already exists." msgstr "O arquivo de script já existe." #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "Nome da Classe:" @@ -12453,7 +12462,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "ConcavePolygonShape doesn't support RigidBody in another mode than static." -msgstr "" +msgstr "Lol." #: scene/3d/cpu_particles.cpp msgid "Nothing is visible because no mesh has been assigned." @@ -12753,6 +12762,10 @@ msgstr "" "para que ele possa ter um tamanho. Caso contrário, defina-o como destino de " "render e atribua sua textura interna a algum nó para exibir." +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "Fonte inválida para a prévia." @@ -12781,6 +12794,15 @@ msgstr "Variáveis só podem ser atribuÃdas na função de vértice." msgid "Constants cannot be modified." msgstr "Constantes não podem serem modificadas." +#~ msgid "Issue Tracker" +#~ msgstr "Rastreador de Problemas" + +#~ msgid "Request Docs" +#~ msgstr "Solicitar documentos" + +#~ msgid "Help improve the Godot documentation by giving feedback." +#~ msgstr "Ajude a melhorar a documentação do Godot dando seu feedback." + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "%d ocorrência(s) substituÃda(s)." diff --git a/editor/translations/pt_PT.po b/editor/translations/pt_PT.po index d7532e38d4..f3b1014123 100644 --- a/editor/translations/pt_PT.po +++ b/editor/translations/pt_PT.po @@ -15,12 +15,13 @@ # Vinicius Gonçalves <viniciusgoncalves21@gmail.com>, 2017. # ssantos <ssantos@web.de>, 2018, 2019. # Gonçalo Dinis Guerreiro João <goncalojoao205@gmail.com>, 2019. +# Manuela Silva <mmsrs@sky.com>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-03-16 09:43+0000\n" -"Last-Translator: João Lopes <linux-man@hotmail.com>\n" +"PO-Revision-Date: 2020-04-07 13:38+0000\n" +"Last-Translator: Manuela Silva <mmsrs@sky.com>\n" "Language-Team: Portuguese (Portugal) <https://hosted.weblate.org/projects/" "godot-engine/godot/pt_PT/>\n" "Language: pt_PT\n" @@ -33,18 +34,18 @@ msgstr "" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp msgid "Invalid type argument to convert(), use TYPE_* constants." -msgstr "Tipo de argumento inválido para convert(), use constantes TYPE_*." +msgstr "Tipo de argumento inválido para convert(), utilize constantes TYPE_*." #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp msgid "Expected a string of length 1 (a character)." -msgstr "Esperado um string de comprimento 1 (um carácter)." +msgstr "Esperado uma \"string\" de comprimento 1 (um caráter)." #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/mono/glue/gd_glue.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp msgid "Not enough bytes for decoding bytes, or invalid format." msgstr "" -"Número de bytes insuficientes para descodificar, ou o formato é inválido." +"Número de \"bytes\" insuficientes para descodificar, ou o formato é inválido." #: core/math/expression.cpp msgid "Invalid input %i (not passed) in expression" @@ -1454,7 +1455,7 @@ msgstr "Mover Carregamento Automático" msgid "Remove Autoload" msgstr "Remover Carregamento Automático" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "Ativar" @@ -2939,8 +2940,13 @@ msgid "Q&A" msgstr "Perguntas & Respostas" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "Rastreador de Problemas" +#, fuzzy +msgid "Report a Bug" +msgstr "Reimportar" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -3994,7 +4000,8 @@ msgid "Reimport" msgstr "Reimportar" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +#, fuzzy +msgid "Save Scenes, Re-Import, and Restart" msgstr "Guardar cenas, reimportar e reiniciar" #: editor/import_dock.cpp @@ -6844,14 +6851,6 @@ msgid "Open Godot online documentation." msgstr "Abrir documentação online do Godot." #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "Requisitar Docs" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "Dê a sua opinião para ajudar a melhorar a documentação Godot." - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "Procurar na documentação de referência." @@ -7285,6 +7284,11 @@ msgid "This operation requires a single selected node." msgstr "Esta operação requer um único nó selecionado." #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Auto Orthogonal Enabled" +msgstr "Ortogonal" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "Bloquear Rotação da Vista" @@ -7373,6 +7377,10 @@ msgid "Freelook Slow Modifier" msgstr "Modificador de Velocidade Freelook" #: editor/plugins/spatial_editor_plugin.cpp +msgid "View Rotation Locked" +msgstr "Rotação da Vista Bloqueada" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." @@ -7381,10 +7389,6 @@ msgstr "" "Não é uma indicação fiável do desempenho do jogo." #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" -msgstr "Rotação da Vista Bloqueada" - -#: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "Diálogo XForm" @@ -10881,6 +10885,12 @@ msgid "Script file already exists." msgstr "Ficheiro Script já existe." #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "Nome de Classe:" @@ -12659,6 +12669,10 @@ msgstr "" "Control de modo a que obtenha um tamanho. Caso contrário, torne-a um " "RenderTarget e atribua a sua textura interna a outro nó para visualizar." +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "Fonte inválida para pré-visualização." @@ -12687,6 +12701,15 @@ msgstr "Variações só podem ser atribuÃdas na função vértice." msgid "Constants cannot be modified." msgstr "Constantes não podem ser modificadas." +#~ msgid "Issue Tracker" +#~ msgstr "Rastreador de Problemas" + +#~ msgid "Request Docs" +#~ msgstr "Requisitar Docs" + +#~ msgid "Help improve the Godot documentation by giving feedback." +#~ msgstr "Dê a sua opinião para ajudar a melhorar a documentação Godot." + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "SubstituÃdo %d ocorrência(s)." diff --git a/editor/translations/ro.po b/editor/translations/ro.po index d52127fd95..28d33d4609 100644 --- a/editor/translations/ro.po +++ b/editor/translations/ro.po @@ -1437,7 +1437,7 @@ msgstr "MutaÈ›i Autoload" msgid "Remove Autoload" msgstr "EliminaÈ›i Autoload" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "ActivaÈ›i" @@ -2935,8 +2935,13 @@ msgid "Q&A" msgstr "ÃŽntrebări È™i Răspunsuri" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "Agent de Monitorizare al Problemelor" +#, fuzzy +msgid "Report a Bug" +msgstr "Reimportă" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4026,7 +4031,7 @@ msgid "Reimport" msgstr "Reimportă" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -7030,14 +7035,6 @@ msgid "Open Godot online documentation." msgstr "Deschide Recente" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7489,6 +7486,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp #, fuzzy msgid "Lock View Rotation" msgstr "Curăță RotaÈ›ia Cursorului" @@ -7580,17 +7581,17 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "View Rotation Locked" +msgstr "Curăță RotaÈ›ia Cursorului" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy -msgid "View Rotation Locked" -msgstr "Curăță RotaÈ›ia Cursorului" - -#: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "" @@ -11107,6 +11108,12 @@ msgid "Script file already exists." msgstr "AutoLoad '%s' există deja!" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp #, fuzzy msgid "Class Name:" msgstr "Clasă:" @@ -12779,6 +12786,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" @@ -12807,6 +12818,9 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#~ msgid "Issue Tracker" +#~ msgstr "Agent de Monitorizare al Problemelor" + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "ÃŽnlocuit %d potriviri." diff --git a/editor/translations/ru.po b/editor/translations/ru.po index d3402fd63e..a0e80d0ce8 100644 --- a/editor/translations/ru.po +++ b/editor/translations/ru.po @@ -67,12 +67,15 @@ # Smadjavul <o1985af@gmail.com>, 2020. # anonymous <noreply@weblate.org>, 2020. # Vinsent Insaider_red <vinsent.in7aider@gmail.com>, 2020. +# TMF <themysticalfox@mail.ru>, 2020. +# Ivan Kuzmenko <kuzmenko.ivan2002@yandex.com>, 2020. +# Super Pracion <superpracion2@gmail.com>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-03-11 12:20+0000\n" -"Last-Translator: Vinsent Insaider_red <vinsent.in7aider@gmail.com>\n" +"PO-Revision-Date: 2020-04-10 09:09+0000\n" +"Last-Translator: Danil Alexeev <danil@alexeev.xyz>\n" "Language-Team: Russian <https://hosted.weblate.org/projects/godot-engine/" "godot/ru/>\n" "Language: ru\n" @@ -96,7 +99,7 @@ msgstr "ОжидалаÑÑŒ Ñтрока длиной 1 (Ñимвол)." #: modules/mono/glue/gd_glue.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp msgid "Not enough bytes for decoding bytes, or invalid format." -msgstr "ÐедоÑтаточно байтов Ð´Ð»Ñ Ð´ÐµÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð±Ð°Ð¹Ñ‚Ð¾Ð² или неверный формат." +msgstr "ÐедоÑтаточно байтов Ð´Ð»Ñ Ð´ÐµÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð»Ð¸ неверный формат." #: core/math/expression.cpp msgid "Invalid input %i (not passed) in expression" @@ -232,9 +235,8 @@ msgid "Anim Multi Change Transition" msgstr "Многократное изменение перехода" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Multi Change Transform" -msgstr "Ðнимационное многоÑменное преобразование" +msgstr "Ðнимационное многократное изменение положениÑ" #: editor/animation_track_editor.cpp msgid "Anim Multi Change Keyframe Value" @@ -1505,7 +1507,7 @@ msgstr "ПеремеÑтить автозагрузку" msgid "Remove Autoload" msgstr "Удалить автозагрузку" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "Включить" @@ -2988,8 +2990,13 @@ msgid "Q&A" msgstr "ВопроÑÑ‹ и ответы" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "СиÑтема отÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð¾ÑˆÐ¸Ð±Ð¾Ðº" +#, fuzzy +msgid "Report a Bug" +msgstr "Переимпортировать" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4043,7 +4050,8 @@ msgid "Reimport" msgstr "Переимпортировать" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +#, fuzzy +msgid "Save Scenes, Re-Import, and Restart" msgstr "Сохранить Ñцены, переимпортировать и перезапуÑтить" #: editor/import_dock.cpp @@ -5241,8 +5249,9 @@ msgid "" msgstr "Ð¯ÐºÐ¾Ñ€Ñ Ð¸ отÑтупы дочерних контейнеров переопределÑÑŽÑ‚ÑÑ Ð¸Ñ… родителÑми." #: editor/plugins/canvas_item_editor_plugin.cpp +#, fuzzy msgid "Presets for the anchors and margins values of a Control node." -msgstr "ПредуÑтановки Ð´Ð»Ñ Ñкорей и Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¾Ñ‚Ñтупов контрольного узла." +msgstr "ПреÑеты значений Ð´Ð»Ñ Ñкорей и отÑтупов узла Control." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "" @@ -5653,7 +5662,7 @@ msgstr "ÐвтовÑтавка ключа" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy msgid "Animation Key and Pose Options" -msgstr "Ключ анимации вÑтавлен." +msgstr "Опции анимационных Ключей и Позы" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Insert Key (Existing Tracks)" @@ -5764,9 +5773,8 @@ msgstr "МаÑка излучениÑ" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp -#, fuzzy msgid "Solid Pixels" -msgstr "Твёрдые пикÑели" +msgstr "Сплошные пикÑели" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp @@ -5775,9 +5783,8 @@ msgstr "Граничные пикÑели" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp -#, fuzzy msgid "Directed Border Pixels" -msgstr "Ðаправленные граничные пикÑели" +msgstr "Ðаправленные пограничные пикÑели" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp @@ -5912,22 +5919,21 @@ msgid "This doesn't work on scene root!" msgstr "Ðто не работает на корне Ñцены!" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Trimesh Static Shape" -msgstr "Создать вогнутую форму" +msgstr "Создать треугольную Ñетку ÑтатичеÑкой формы" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Can't create a single convex collision shape for the scene root." msgstr "" +"Ðе удаетÑÑ Ñоздать единÑтвенную выпуклую форму ÑÑ‚Ð¾Ð»ÐºÐ½Ð¾Ð²ÐµÐ½Ð¸Ñ Ð´Ð»Ñ ÐºÐ¾Ñ€Ð½Ñ Ñцены." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Couldn't create a single convex collision shape." -msgstr "" +msgstr "Ðе удалоÑÑŒ Ñоздать одну выпуклую форму Ñтолкновений." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Single Convex Shape" -msgstr "Создать выпуклую форму(Ñ‹)" +msgstr "Создать одну выпуклую форму" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Can't create multiple convex collision shapes for the scene root." @@ -5935,14 +5941,12 @@ msgstr "" "Ðевозможно Ñоздать неÑколько выпуклых форм ÑÑ‚Ð¾Ð»ÐºÐ½Ð¾Ð²ÐµÐ½Ð¸Ñ Ð´Ð»Ñ ÐºÐ¾Ñ€Ð½Ñ Ñцены." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Couldn't create any collision shapes." -msgstr "Ðе удалоÑÑŒ Ñоздать папку." +msgstr "Ðе удалоÑÑŒ Ñоздать ни одной форму ÑтолкновениÑ." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Multiple Convex Shapes" -msgstr "Создать выпуклую форму(Ñ‹)" +msgstr "Создать неÑколько выпуклых форм" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Navigation Mesh" @@ -5986,7 +5990,7 @@ msgstr "Создать контур" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh" -msgstr "МаÑÑив" +msgstr "Меш" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Trimesh Static Body" @@ -6015,9 +6019,8 @@ msgstr "" "Ðто Ñамый точный (но Ñамый медленный) ÑпоÑоб Ð¾Ð±Ð½Ð°Ñ€ÑƒÐ¶ÐµÐ½Ð¸Ñ Ñтолкновений." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Single Convex Collision Sibling" -msgstr "Создать выпуклую облаÑть ÑтолкновениÑ" +msgstr "Создать одну выпуклую облаÑть ÑтолкновениÑ" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "" @@ -6028,9 +6031,8 @@ msgstr "" "Ðто Ñамый быÑтрый (но наименее точный) ÑпоÑоб Ð¾Ð±Ð½Ð°Ñ€ÑƒÐ¶ÐµÐ½Ð¸Ñ Ñтолкновений." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Multiple Convex Collision Siblings" -msgstr "Создать выпуклую облаÑть ÑтолкновениÑ" +msgstr "Создать неÑколько ÑоÑедних выпуклых форм ÑтолкновениÑ" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "" @@ -6045,12 +6047,17 @@ msgid "Create Outline Mesh..." msgstr "Создать полиÑетку обводки..." #: editor/plugins/mesh_instance_editor_plugin.cpp +#, fuzzy msgid "" "Creates a static outline mesh. The outline mesh will have its normals " "flipped automatically.\n" "This can be used instead of the SpatialMaterial Grow property when using " "that property isn't possible." msgstr "" +"Создаёт Ñтатичную контурную полиÑетку. Её нормали будут перевёрнуты " +"автоматичеÑки.\n" +"Она может быть заменой ÑвойÑтву Grow реÑурÑа SpatialMaterial, когда Ñто " +"ÑвойÑтво невозможно иÑпользовать." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "View UV1" @@ -6900,14 +6907,6 @@ msgid "Open Godot online documentation." msgstr "Открыть онлайн-документацию Godot." #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "Проблема" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "Помогите улучшить документацию Godot, оÑтавьте Ñообщение об ошибке." - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "ПоиÑк Ñправочной документации." @@ -7344,6 +7343,11 @@ msgid "This operation requires a single selected node." msgstr "Ðта Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñ Ñ‚Ñ€ÐµÐ±ÑƒÐµÑ‚ одного выбранного узла." #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Auto Orthogonal Enabled" +msgstr "Ортогональный" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "Блокировать вращение камеры" @@ -7432,6 +7436,10 @@ msgid "Freelook Slow Modifier" msgstr "Медленный модификатор Ñвободного проÑмотра" #: editor/plugins/spatial_editor_plugin.cpp +msgid "View Rotation Locked" +msgstr "Блокировать вращение камеры" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." @@ -7441,10 +7449,6 @@ msgstr "" "игры." #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" -msgstr "Блокировать вращение камеры" - -#: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "XForm диалоговое окно" @@ -7662,7 +7666,7 @@ msgstr "ПредпроÑмотр CollisionPolygon2D" #: editor/plugins/sprite_editor_plugin.cpp msgid "Create LightOccluder2D" -msgstr "Создан LightOccluder2D" +msgstr "Создать LightOccluder2D" #: editor/plugins/sprite_editor_plugin.cpp msgid "LightOccluder2D Preview" @@ -8436,14 +8440,12 @@ msgid "Edit Tile Z Index" msgstr "Редактирование Z индекÑа плитки" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Make Convex" -msgstr "Сделать Convex" +msgstr "Сделать выпуклым" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Make Concave" -msgstr "Сделать Concave" +msgstr "Сделать вогнутым" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Create Collision Polygon" @@ -8708,9 +8710,8 @@ msgid "Dodge operator." msgstr "Оператор выцветаниÑ." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "HardLight operator." -msgstr "Оператор жёÑткого Ñвета." +msgstr "Оператор HardLight." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Lighten operator." @@ -9114,12 +9115,12 @@ msgstr "Изменить текÑтурную единицу" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy msgid "2D texture uniform lookup." -msgstr "Изменить текÑтурную единицу" +msgstr "Равномерный поиÑк 2D-текÑтур." #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy msgid "2D texture uniform lookup with triplanar." -msgstr "Изменить текÑтурную единицу" +msgstr "Форменный поиÑк 2d текÑтуры Ñ Ñ‚Ñ€Ð¸Ð¿Ð»Ð°Ð½Ð°Ñ€Ð¾Ð¼." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Transform function." @@ -9229,9 +9230,8 @@ msgid "Linear interpolation between two vectors." msgstr "Ð›Ð¸Ð½ÐµÐ¹Ð½Ð°Ñ Ð¸Ð½Ñ‚ÐµÑ€Ð¿Ð¾Ð»ÑÑ†Ð¸Ñ Ð¼ÐµÐ¶Ð´Ñƒ Ð´Ð²ÑƒÐ¼Ñ Ð²ÐµÐºÑ‚Ð¾Ñ€Ð°Ð¼Ð¸." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Linear interpolation between two vectors using scalar." -msgstr "Ð›Ð¸Ð½ÐµÐ¹Ð½Ð°Ñ Ð¸Ð½Ñ‚ÐµÑ€Ð¿Ð¾Ð»ÑÑ†Ð¸Ñ Ð¼ÐµÐ¶Ð´Ñƒ Ð´Ð²ÑƒÐ¼Ñ Ð²ÐµÐºÑ‚Ð¾Ñ€Ð°Ð¼Ð¸." +msgstr "Ð›Ð¸Ð½ÐµÐ¹Ð½Ð°Ñ Ð¸Ð½Ñ‚ÐµÑ€Ð¿Ð¾Ð»ÑÑ†Ð¸Ñ Ð¼ÐµÐ¶Ð´Ñƒ Ð´Ð²ÑƒÐ¼Ñ Ð²ÐµÐºÑ‚Ð¾Ñ€Ð°Ð¼Ð¸ Ñ Ð¸Ñпользованием ÑкалÑра." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the normalize product of vector." @@ -9352,17 +9352,16 @@ msgstr "" "Ð½Ð°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ð±Ð·Ð¾Ñ€Ð° камеры (пропуÑтите ÑоответÑтвующие входы к ней)." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "" "Custom Godot Shader Language expression, which is placed on top of the " "resulted shader. You can place various function definitions inside and call " "it later in the Expressions. You can also declare varyings, uniforms and " "constants." msgstr "" -"ПользовательÑкое выражение Ñзыка шейдеров Godot, которое помещаетÑÑ Ð¿Ð¾Ð²ÐµÑ€Ñ… " -"шейдера. Ð’Ñ‹ можете размеÑтить внутри различные объÑÐ²Ð»ÐµÐ½Ð¸Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¹ и вызвать " -"их позже в ВыражениÑÑ…. Ð’Ñ‹ также можете объÑвить varyings, uniforms и " -"конÑтанты." +"ПользовательÑкое выражение на Ñзыке шейдеров Godot, которое помещаетÑÑ " +"поверх шейдера. Ð’Ñ‹ можете размеÑтить внутри различные объÑÐ²Ð»ÐµÐ½Ð¸Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¹ и " +"вызвать их позже в ВыражениÑÑ…. Ð’Ñ‹ также можете объÑвить переменные типа " +"varying, uniform и конÑтанты." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(Fragment/Light mode only) Scalar derivative function." @@ -9637,35 +9636,30 @@ msgid "Export With Debug" msgstr "ÐкÑпорт в режиме отладки" #: editor/project_manager.cpp -#, fuzzy msgid "The path specified doesn't exist." -msgstr "Путь не ÑущеÑтвует." +msgstr "Указанный путь не ÑущеÑтвует." #: editor/project_manager.cpp -#, fuzzy msgid "Error opening package file (it's not in ZIP format)." -msgstr "Ошибка при открытии файла пакета, не в формате zip." +msgstr "Ошибка при открытии файла пакета (Ðе ÑвлÑетÑÑ ZIP форматом)." #: editor/project_manager.cpp -#, fuzzy msgid "" "Invalid \".zip\" project file; it doesn't contain a \"project.godot\" file." msgstr "" -"ÐедейÑтвительный '.zip' файл проекта, не Ñодержит файл 'project.godot'." +"ÐедейÑтвительный \".zip\" файл проекта; не Ñодержит файл \"project.godot\"." #: editor/project_manager.cpp msgid "Please choose an empty folder." msgstr "ПожалуйÑта, выберите пуÑтую папку." #: editor/project_manager.cpp -#, fuzzy msgid "Please choose a \"project.godot\" or \".zip\" file." -msgstr "ПожалуйÑта, выберите файл 'project.godot' или '.zip'." +msgstr "ПожалуйÑта, выберите файл \"project.godot\" или \".zip\"." #: editor/project_manager.cpp -#, fuzzy msgid "This directory already contains a Godot project." -msgstr "Каталог уже Ñодержит проект Godot." +msgstr "Ðтот каталог уже Ñодержит проект Godot." #: editor/project_manager.cpp msgid "New Game Project" @@ -10362,9 +10356,8 @@ msgid "Suffix" msgstr "СуффикÑ" #: editor/rename_dialog.cpp -#, fuzzy msgid "Use Regular Expressions" -msgstr "РегулÑрное выражение" +msgstr "ИÑпользовать регулÑрные выражениÑ" #: editor/rename_dialog.cpp msgid "Advanced Options" @@ -10446,14 +10439,12 @@ msgid "Keep" msgstr "ОÑтавить оригинал" #: editor/rename_dialog.cpp -#, fuzzy msgid "PascalCase to snake_case" -msgstr "CamelCase в under_scored" +msgstr "ВерблюжийРегиÑтр в змеиный_региÑтр" #: editor/rename_dialog.cpp -#, fuzzy msgid "snake_case to PascalCase" -msgstr "under_scored к CamelCase" +msgstr "змеиный_региÑтр в ВерблюжийРегиÑтр" #: editor/rename_dialog.cpp msgid "Case" @@ -10472,9 +10463,8 @@ msgid "Reset" msgstr "СброÑить" #: editor/rename_dialog.cpp -#, fuzzy msgid "Regular Expression Error" -msgstr "РегулÑрное выражение" +msgstr "Ошибка в регулÑрном выражении" #: editor/rename_dialog.cpp #, fuzzy @@ -10947,7 +10937,7 @@ msgstr "Ðеверное Ð¸Ð¼Ñ Ð¸Ð»Ð¸ путь наÑледуемого преР#: editor/script_create_dialog.cpp #, fuzzy msgid "Script path/name is valid." -msgstr "Скрипт корректен." +msgstr "Путь/Ð¸Ð¼Ñ Ñкрипта дейÑтвителен." #: editor/script_create_dialog.cpp msgid "Allowed: a-z, A-Z, 0-9, _ and ." @@ -10970,6 +10960,12 @@ msgid "Script file already exists." msgstr "Файл Ñкрипта уже ÑущеÑтвует." #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "Ð˜Ð¼Ñ ÐºÐ»Ð°ÑÑа:" @@ -12452,7 +12448,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "ConcavePolygonShape doesn't support RigidBody in another mode than static." -msgstr "" +msgstr "ConcavePolygonShape поддерживает RigidBody только в Ñтатичном режиме." #: scene/3d/cpu_particles.cpp msgid "Nothing is visible because no mesh has been assigned." @@ -12752,6 +12748,10 @@ msgstr "" "Ñделайте её целью рендеринга и назначьте её внутреннюю текÑтуру какому-либо " "узлу Ð´Ð»Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ." +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "Ðеверный иÑточник Ð´Ð»Ñ Ð¿Ñ€ÐµÐ´Ð¿Ñ€Ð¾Ñмотра." @@ -12780,6 +12780,15 @@ msgstr "Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð³ÑƒÑ‚ быть назначены только Ð msgid "Constants cannot be modified." msgstr "КонÑтанты не могут быть изменены." +#~ msgid "Issue Tracker" +#~ msgstr "СиÑтема отÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð¾ÑˆÐ¸Ð±Ð¾Ðº" + +#~ msgid "Request Docs" +#~ msgstr "Проблема" + +#~ msgid "Help improve the Godot documentation by giving feedback." +#~ msgstr "Помогите улучшить документацию Godot, оÑтавьте Ñообщение об ошибке." + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "Заменено %d Ñовпадений." diff --git a/editor/translations/si.po b/editor/translations/si.po index 119818e11f..f46a3ca292 100644 --- a/editor/translations/si.po +++ b/editor/translations/si.po @@ -1428,7 +1428,7 @@ msgstr "" msgid "Remove Autoload" msgstr "" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "" @@ -2832,7 +2832,11 @@ msgid "Q&A" msgstr "" #: editor/editor_node.cpp -msgid "Issue Tracker" +msgid "Report a Bug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp @@ -3856,7 +3860,7 @@ msgid "Reimport" msgstr "" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -6662,14 +6666,6 @@ msgid "Open Godot online documentation." msgstr "" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7100,6 +7096,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7188,13 +7188,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -10539,6 +10539,12 @@ msgid "Script file already exists." msgstr "" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "" @@ -12165,6 +12171,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/sk.po b/editor/translations/sk.po index 50cf59efdc..d0fe10184e 100644 --- a/editor/translations/sk.po +++ b/editor/translations/sk.po @@ -5,15 +5,17 @@ # J08nY <johnenter@gmail.com>, 2016. # MineGame 159 <minegame459@gmail.com>, 2018. # Zuzana Palenikova <sousana.is@gmail.com>, 2019. -# MineGame159 <petulko08@gmail.com>, 2019. +# MineGame159 <petulko08@gmail.com>, 2019, 2020. # Michal <alladinsiffon@gmail.com>, 2019. # Richard <rgarlik@gmail.com>, 2019. +# Richard Urban <redasuio1@gmail.com>, 2020. +# anonymous <noreply@weblate.org>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2019-07-02 10:51+0000\n" -"Last-Translator: Richard <rgarlik@gmail.com>\n" +"PO-Revision-Date: 2020-04-16 11:03+0000\n" +"Last-Translator: Richard Urban <redasuio1@gmail.com>\n" "Language-Team: Slovak <https://hosted.weblate.org/projects/godot-engine/" "godot/sk/>\n" "Language: sk\n" @@ -21,7 +23,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -"X-Generator: Weblate 3.8-dev\n" +"X-Generator: Weblate 4.0.1-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -30,7 +32,7 @@ msgstr "Chybný argument convert(), použite TYPE_* konÅ¡tanty." #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp msgid "Expected a string of length 1 (a character)." -msgstr "" +msgstr "OÄakávaná dĺžka stringu 1 (pÃsmeno)." #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/mono/glue/gd_glue.cpp @@ -40,12 +42,11 @@ msgstr "Nedostatok bajtov na dekódovanie, možný chybný formát." #: core/math/expression.cpp msgid "Invalid input %i (not passed) in expression" -msgstr "" +msgstr "Nesprávny vstup %i (chýba) vo výraze" #: core/math/expression.cpp -#, fuzzy msgid "self can't be used because instance is null (not passed)" -msgstr "self nemožno použiÅ¥ lebo inÅ¡tancia je rovná null (not passed)" +msgstr "self sa nedá použiÅ¥ lebo inÅ¡tancia je null (nepreÅ¡iel)" #: core/math/expression.cpp msgid "Invalid operands to operator %s, %s and %s." @@ -69,31 +70,31 @@ msgstr "Pri volanà '%s':" #: core/ustring.cpp msgid "B" -msgstr "" +msgstr "B" #: core/ustring.cpp msgid "KiB" -msgstr "" +msgstr "KiB" #: core/ustring.cpp msgid "MiB" -msgstr "" +msgstr "MiB" #: core/ustring.cpp msgid "GiB" -msgstr "" +msgstr "GiB" #: core/ustring.cpp msgid "TiB" -msgstr "" +msgstr "TiB" #: core/ustring.cpp msgid "PiB" -msgstr "" +msgstr "PiB" #: core/ustring.cpp msgid "EiB" -msgstr "" +msgstr "EiB" #: editor/animation_bezier_editor.cpp msgid "Free" @@ -153,41 +154,35 @@ msgstr "Animácia zmeniÅ¥ prechod" #: editor/animation_track_editor.cpp msgid "Anim Change Transform" -msgstr "" +msgstr "ZmeniÅ¥ VeľkosÅ¥ Animácie" #: editor/animation_track_editor.cpp msgid "Anim Change Keyframe Value" msgstr "Animácia ZmeniÅ¥ Keyframe Hodnotu" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Change Call" -msgstr "Animácia ZmeniÅ¥ Hovor" +msgstr "Animácia zmenila Hovor" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Multi Change Keyframe Time" -msgstr "Animácia ZmeniÅ¥ Keyframe ÄŒas" +msgstr "Animácia ZmeniÅ¥ Äas Keyframe-u" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Multi Change Transition" -msgstr "Animácia zmeniÅ¥ prechod" +msgstr "ZmeniÅ¥ Transition Animácie" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Multi Change Transform" -msgstr "Animácia zmeniÅ¥ prechod" +msgstr "Animácia zmeniÅ¥ Transform" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Multi Change Keyframe Value" -msgstr "Animácia ZmeniÅ¥ Keyframe Hodnotu" +msgstr "Animácia ZmeniÅ¥ hodnotu Keyframe-u" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Multi Change Call" -msgstr "Animácia ZmeniÅ¥ Hovor" +msgstr "Animácia Zmenila Hovor" #: editor/animation_track_editor.cpp msgid "Change Animation Length" @@ -200,45 +195,43 @@ msgstr "ZmeniÅ¥ Dĺžku Animácie" #: editor/animation_track_editor.cpp msgid "Property Track" -msgstr "" +msgstr "Property Track" #: editor/animation_track_editor.cpp msgid "3D Transform Track" -msgstr "" +msgstr "3D Transform Track" #: editor/animation_track_editor.cpp msgid "Call Method Track" -msgstr "" +msgstr "Call Method Track" #: editor/animation_track_editor.cpp msgid "Bezier Curve Track" -msgstr "" +msgstr "Krivka Bezier Track" #: editor/animation_track_editor.cpp msgid "Audio Playback Track" -msgstr "" +msgstr "Audio Playback Track" #: editor/animation_track_editor.cpp msgid "Animation Playback Track" -msgstr "" +msgstr "Playback Track Animácie" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Animation length (frames)" msgstr "Dĺžka ÄŒasu Animácie (v sekundách)" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Animation length (seconds)" msgstr "Dĺžka ÄŒasu Animácie (v sekundách)" #: editor/animation_track_editor.cpp msgid "Add Track" -msgstr "" +msgstr "PridaÅ¥ Track" #: editor/animation_track_editor.cpp msgid "Animation Looping" -msgstr "" +msgstr "Opakovanie Animácie" #: editor/animation_track_editor.cpp #: modules/visual_script/visual_script_editor.cpp @@ -255,15 +248,15 @@ msgstr "Klipy Animácie:" #: editor/animation_track_editor.cpp msgid "Change Track Path" -msgstr "" +msgstr "ZmeniÅ¥ cestu Tracku" #: editor/animation_track_editor.cpp msgid "Toggle this track on/off." -msgstr "" +msgstr "Zapnúť/Vypnúť tento track." #: editor/animation_track_editor.cpp msgid "Update Mode (How this property is set)" -msgstr "" +msgstr "Update Mode (ako je nastavená táto možnosÅ¥)" #: editor/animation_track_editor.cpp msgid "Interpolation Mode" @@ -271,12 +264,11 @@ msgstr "Režim Interpolácie" #: editor/animation_track_editor.cpp msgid "Loop Wrap Mode (Interpolate end with beginning on loop)" -msgstr "" +msgstr "Loop Wrap Mode (interpoluje koniec zo zaÄiatkom opakovania)" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Remove this track." -msgstr "VÅ¡etky vybrané" +msgstr "VymazaÅ¥ tento track." #: editor/animation_track_editor.cpp msgid "Time (s): " @@ -284,7 +276,7 @@ msgstr "ÄŒas (s): " #: editor/animation_track_editor.cpp msgid "Toggle Track Enabled" -msgstr "" +msgstr "Zmena Tracku Povolená" #: editor/animation_track_editor.cpp msgid "Continuous" @@ -317,11 +309,11 @@ msgstr "Kubický" #: editor/animation_track_editor.cpp msgid "Clamp Loop Interp" -msgstr "" +msgstr "Clamp Loop Interp" #: editor/animation_track_editor.cpp msgid "Wrap Loop Interp" -msgstr "" +msgstr "Wrap Loop Interp" #: editor/animation_track_editor.cpp #: editor/plugins/canvas_item_editor_plugin.cpp @@ -329,38 +321,36 @@ msgid "Insert Key" msgstr "VložiÅ¥ KľúÄ" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Duplicate Key(s)" -msgstr "DuplikovaÅ¥ výber" +msgstr "Duplikovanie KľúÄov" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Delete Key(s)" -msgstr "VÅ¡etky vybrané" +msgstr "Vymazanie kľúÄa(ov)" #: editor/animation_track_editor.cpp msgid "Change Animation Update Mode" -msgstr "" +msgstr "ZmeniÅ¥ Update Mode Animácie" #: editor/animation_track_editor.cpp msgid "Change Animation Interpolation Mode" -msgstr "" +msgstr "ZmeniÅ¥ Interpolacný Mód Animácie" #: editor/animation_track_editor.cpp msgid "Change Animation Loop Mode" -msgstr "" +msgstr "ZmeniÅ¥ Loop Mode Animacie" #: editor/animation_track_editor.cpp msgid "Remove Anim Track" -msgstr "" +msgstr "VymazaÅ¥ Track Animácie" #: editor/animation_track_editor.cpp msgid "Create NEW track for %s and insert key?" -msgstr "" +msgstr "VytvoriÅ¥ NOVà track za %s a vložiÅ¥ kľúÄ?" #: editor/animation_track_editor.cpp msgid "Create %d NEW tracks and insert keys?" -msgstr "" +msgstr "VytvoriÅ¥ %d NOVÉ track-y a vložiÅ¥ kľúÄe?" #: editor/animation_track_editor.cpp editor/create_dialog.cpp #: editor/editor_audio_buses.cpp editor/editor_feature_profile.cpp @@ -388,25 +378,23 @@ msgstr "Animácia VytvoriÅ¥ & VložiÅ¥" #: editor/animation_track_editor.cpp msgid "Anim Insert Track & Key" -msgstr "" +msgstr "Anim VložiÅ¥ Track & kľúÄ" #: editor/animation_track_editor.cpp msgid "Anim Insert Key" msgstr "Animácia VložiÅ¥ KľúÄ" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Change Animation Step" -msgstr "Animácia zmeniÅ¥ prechod" +msgstr "ZmeniÅ¥ krok Animácie" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Rearrange Tracks" -msgstr "VložiÅ¥" +msgstr "PreskupiÅ¥ Track-y" #: editor/animation_track_editor.cpp msgid "Transform tracks only apply to Spatial-based nodes." -msgstr "" +msgstr "TransformovaÅ¥ track-y a aplikovaÅ¥ do Spatial-based node-ov." #: editor/animation_track_editor.cpp msgid "" @@ -422,73 +410,72 @@ msgstr "" #: editor/animation_track_editor.cpp msgid "Animation tracks can only point to AnimationPlayer nodes." -msgstr "" +msgstr "Track-y Animácià môžu ukazovaÅ¥ iba na node-y AnimationPlayer." #: editor/animation_track_editor.cpp msgid "An animation player can't animate itself, only other players." -msgstr "" +msgstr "Animation player sa nemôže naanimovaÅ¥ sám, iba ostatné player-y." #: editor/animation_track_editor.cpp msgid "Not possible to add a new track without a root" -msgstr "" +msgstr "Nenà možné pridaÅ¥ nový track bez root-u" #: editor/animation_track_editor.cpp msgid "Invalid track for Bezier (no suitable sub-properties)" -msgstr "" +msgstr "Neplatný track pre Bezier (niesu vhodné sub-properties)" #: editor/animation_track_editor.cpp msgid "Add Bezier Track" -msgstr "" +msgstr "PridaÅ¥ Bezier Track" #: editor/animation_track_editor.cpp msgid "Track path is invalid, so can't add a key." -msgstr "" +msgstr "Cesta Track-u je neplatná, takže sa nedá pridaÅ¥ kľúÄ." #: editor/animation_track_editor.cpp msgid "Track is not of type Spatial, can't insert key" -msgstr "" +msgstr "Track nenà typ Spatial, nedá sa vložiÅ¥ kľúÄ" #: editor/animation_track_editor.cpp msgid "Add Transform Track Key" -msgstr "" +msgstr "PridaÅ¥ Transform Track Key" #: editor/animation_track_editor.cpp msgid "Add Track Key" -msgstr "" +msgstr "PridaÅ¥ Track Key" #: editor/animation_track_editor.cpp msgid "Track path is invalid, so can't add a method key." -msgstr "" +msgstr "Cesta track-u je neplatná, takže sa nedá pridaÅ¥ do method key." #: editor/animation_track_editor.cpp msgid "Add Method Track Key" -msgstr "" +msgstr "PridaÅ¥ Method Track Key" #: editor/animation_track_editor.cpp msgid "Method not found in object: " -msgstr "" +msgstr "Metóda nebola nájdená v objekte: " #: editor/animation_track_editor.cpp msgid "Anim Move Keys" -msgstr "" +msgstr "Pohybové kľúÄe Animácie" #: editor/animation_track_editor.cpp msgid "Clipboard is empty" -msgstr "" +msgstr "Schránka je prázdna" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Paste Tracks" -msgstr "VložiÅ¥" +msgstr "VložiÅ¥ Track-y" #: editor/animation_track_editor.cpp msgid "Anim Scale Keys" -msgstr "" +msgstr "Scale keys Animácie" #: editor/animation_track_editor.cpp msgid "" "This option does not work for Bezier editing, as it's only a single track." -msgstr "" +msgstr "Táto možnosÅ¥ nefunguje pre Bezier editovanie, lebo je to jeden track." #: editor/animation_track_editor.cpp msgid "" @@ -502,38 +489,47 @@ msgid "" "Alternatively, use an import preset that imports animations to separate " "files." msgstr "" +"Táto Animácia patrà importovanej scéne, takže zmeny pre importované track-y " +"nebudú uložené.\n" +" \n" +"Na povolenie abilite pridaÅ¥ vlastné track-y, prejdite na nastavenia importu " +"scén a nastavte\n" +"\" Animation > Storage\" na \"Files\", povolte \"Animation > Keep Custom " +"Tracks\", a potom re-import.\n" +"AlternatÃvne, použite import preset ktorý importuje animácie pre oddelenie " +"file-ov." #: editor/animation_track_editor.cpp msgid "Warning: Editing imported animation" -msgstr "" +msgstr "Upozornenie: Editovanie importovaných animáciÃ" #: editor/animation_track_editor.cpp msgid "Select an AnimationPlayer node to create and edit animations." -msgstr "" +msgstr "OznaÄte AnimationPlayer node aby ste vytvorili a upravili animácie." #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." -msgstr "" +msgstr "Iba show track-y z node-ov oznaÄené v strome." #: editor/animation_track_editor.cpp msgid "Group tracks by node or display them as plain list." -msgstr "" +msgstr "Zoskupte track-y pomocou node-u alebo ich zobrazte ako plain list." #: editor/animation_track_editor.cpp msgid "Snap:" -msgstr "" +msgstr "Snap:" #: editor/animation_track_editor.cpp msgid "Animation step value." -msgstr "" +msgstr "Hodnota kroku Animácie." #: editor/animation_track_editor.cpp msgid "Seconds" -msgstr "" +msgstr "Sekundy" #: editor/animation_track_editor.cpp msgid "FPS" -msgstr "" +msgstr "FPS" #: editor/animation_track_editor.cpp editor/editor_properties.cpp #: editor/plugins/polygon_2d_editor_plugin.cpp @@ -543,15 +539,15 @@ msgstr "" #: editor/project_settings_editor.cpp editor/property_editor.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Edit" -msgstr "" +msgstr "Edit" #: editor/animation_track_editor.cpp msgid "Animation properties." -msgstr "" +msgstr "Vlastnosti Animácie." #: editor/animation_track_editor.cpp msgid "Copy Tracks" -msgstr "" +msgstr "KopÃrovaÅ¥ track-y" #: editor/animation_track_editor.cpp msgid "Scale Selection" @@ -567,87 +563,83 @@ msgstr "DuplikovaÅ¥ výber" #: editor/animation_track_editor.cpp msgid "Duplicate Transposed" -msgstr "" +msgstr "Duplikovanie transponovaných" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Delete Selection" -msgstr "VÅ¡etky vybrané" +msgstr "VymazaÅ¥ výber" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Go to Next Step" msgstr "PrejsÅ¥ na Äalšà krok" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Go to Previous Step" msgstr "PrejsÅ¥ na predchádzajúci krok" #: editor/animation_track_editor.cpp msgid "Optimize Animation" -msgstr "" +msgstr "Optimalizácia Animacie" #: editor/animation_track_editor.cpp msgid "Clean-Up Animation" -msgstr "" +msgstr "VyÄistenie Animácie" #: editor/animation_track_editor.cpp msgid "Pick the node that will be animated:" -msgstr "" +msgstr "Vyberte node ktorý bude animovaný:" #: editor/animation_track_editor.cpp msgid "Use Bezier Curves" -msgstr "" +msgstr "PoužiÅ¥ Bezier Curves" #: editor/animation_track_editor.cpp msgid "Anim. Optimizer" -msgstr "" +msgstr "Optimalizér AnimáciÃ" #: editor/animation_track_editor.cpp msgid "Max. Linear Error:" -msgstr "" +msgstr "Max. Linear Error:" #: editor/animation_track_editor.cpp msgid "Max. Angular Error:" -msgstr "" +msgstr "Max. Angular Error:" #: editor/animation_track_editor.cpp msgid "Max Optimizable Angle:" -msgstr "" +msgstr "Maximálny Optimalizovatelný Uhol:" #: editor/animation_track_editor.cpp msgid "Optimize" -msgstr "" +msgstr "Optimalizácia" #: editor/animation_track_editor.cpp msgid "Remove invalid keys" -msgstr "" +msgstr "VymazaÅ¥ neplatné kľúÄe" #: editor/animation_track_editor.cpp msgid "Remove unresolved and empty tracks" -msgstr "" +msgstr "VymazaÅ¥ nevyrieÅ¡ené a prázdne track-y" #: editor/animation_track_editor.cpp msgid "Clean-up all animations" -msgstr "" +msgstr "VyÄistiÅ¥ vÅ¡etky animácie" #: editor/animation_track_editor.cpp msgid "Clean-Up Animation(s) (NO UNDO!)" -msgstr "" +msgstr "VyÄistenie Animácià (NIEJE KROK SPÄŤ!)" #: editor/animation_track_editor.cpp msgid "Clean-Up" -msgstr "" +msgstr "VyÄistenie" #: editor/animation_track_editor.cpp msgid "Scale Ratio:" -msgstr "" +msgstr "Pomer mierky:" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Select Tracks to Copy" -msgstr "NastaviÅ¥ prechody na:" +msgstr "VybraÅ¥ Track-y na skopÃrovanie" #: editor/animation_track_editor.cpp editor/editor_log.cpp #: editor/editor_properties.cpp @@ -659,136 +651,133 @@ msgid "Copy" msgstr "KopÃrovaÅ¥" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Select All/None" -msgstr "VÅ¡etky vybrané" +msgstr "VybraÅ¥ vÅ¡etko/niÄ" #: editor/animation_track_editor_plugins.cpp msgid "Add Audio Track Clip" -msgstr "" +msgstr "PridaÅ¥ Audio Track Clip" #: editor/animation_track_editor_plugins.cpp msgid "Change Audio Track Clip Start Offset" -msgstr "" +msgstr "ZmeniÅ¥ Audio Track Clip spustiÅ¥ Offset" #: editor/animation_track_editor_plugins.cpp msgid "Change Audio Track Clip End Offset" -msgstr "" +msgstr "ZmeniÅ¥ Audio Track Clip koniec Offset-u" #: editor/array_property_edit.cpp msgid "Resize Array" -msgstr "" +msgstr "ZmeniÅ¥ veľkosÅ¥ Array-u" #: editor/array_property_edit.cpp msgid "Change Array Value Type" -msgstr "" +msgstr "ZmeniÅ¥ hodnotu Array-u" #: editor/array_property_edit.cpp msgid "Change Array Value" -msgstr "" +msgstr "ZmeniÅ¥ hodnotu Array-u" #: editor/code_editor.cpp msgid "Go to Line" -msgstr "" +msgstr "ChoÄte na LÃniu" #: editor/code_editor.cpp msgid "Line Number:" -msgstr "" +msgstr "ÄŒÃslo lÃnie:" #: editor/code_editor.cpp msgid "%d replaced." -msgstr "" +msgstr "%d náhradené." #: editor/code_editor.cpp editor/editor_help.cpp msgid "%d match." -msgstr "" +msgstr "%d sa zhoduje." #: editor/code_editor.cpp editor/editor_help.cpp -#, fuzzy msgid "%d matches." -msgstr "Zhody:" +msgstr "%d zhody." #: editor/code_editor.cpp editor/find_in_files.cpp msgid "Match Case" -msgstr "" +msgstr "Match Case" #: editor/code_editor.cpp editor/find_in_files.cpp msgid "Whole Words" -msgstr "" +msgstr "Celé slová" #: editor/code_editor.cpp editor/rename_dialog.cpp msgid "Replace" -msgstr "" +msgstr "NahradiÅ¥" #: editor/code_editor.cpp msgid "Replace All" -msgstr "" +msgstr "NahradiÅ¥ VÅ¡etko" #: editor/code_editor.cpp msgid "Selection Only" -msgstr "" +msgstr "Iba Výber" #: editor/code_editor.cpp editor/plugins/script_text_editor.cpp #: editor/plugins/text_editor.cpp msgid "Standard" -msgstr "" +msgstr "Å tandard" #: editor/code_editor.cpp editor/plugins/script_editor_plugin.cpp msgid "Toggle Scripts Panel" -msgstr "" +msgstr "Vypnúť Panel Script-ov" #: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/texture_region_editor_plugin.cpp #: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp msgid "Zoom In" -msgstr "" +msgstr "PriblÞiÅ¥" #: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/texture_region_editor_plugin.cpp #: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp msgid "Zoom Out" -msgstr "" +msgstr "OddialiÅ¥" #: editor/code_editor.cpp msgid "Reset Zoom" -msgstr "" +msgstr "ResetovaÅ¥ priblÞenie" #: editor/code_editor.cpp msgid "Warnings" -msgstr "" +msgstr "Varovania" #: editor/code_editor.cpp msgid "Line and column numbers." -msgstr "" +msgstr "ÄŒÃsla riadkov a stĺpcov." #: editor/connections_dialog.cpp msgid "Method in target node must be specified." -msgstr "" +msgstr "Metóda v target node-e musà byÅ¥ Å¡pecifikovaná." #: editor/connections_dialog.cpp msgid "" "Target method not found. Specify a valid method or attach a script to the " "target node." msgstr "" +"Metóda Target sa nenaÅ¡la. Å pecifikujte platnú metódu alebo pripojte script k " +"target node-u." #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Node:" -msgstr "PripojiÅ¥ k Node:" +msgstr "PripojiÅ¥ k Node-u:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Script:" -msgstr "PripojiÅ¥ k Node:" +msgstr "PripojiÅ¥ k Scriptu:" #: editor/connections_dialog.cpp -#, fuzzy msgid "From Signal:" -msgstr "Signály:" +msgstr "Zo Signálu:" #: editor/connections_dialog.cpp msgid "Scene does not contain any script." -msgstr "" +msgstr "Scéna neobsahuje žiadny script." #: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp #: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp @@ -809,43 +798,40 @@ msgstr "OdstrániÅ¥" #: editor/connections_dialog.cpp msgid "Add Extra Call Argument:" -msgstr "" +msgstr "Pridajte Extra Call Argument:" #: editor/connections_dialog.cpp msgid "Extra Call Arguments:" -msgstr "" +msgstr "Extra Call Argumenty:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Receiver Method:" -msgstr "Filter:" +msgstr "Metóda PrijÃmaÄa:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Advanced" -msgstr "Vyvážený" +msgstr "PokroÄilé" #: editor/connections_dialog.cpp msgid "Deferred" -msgstr "" +msgstr "Odložené" #: editor/connections_dialog.cpp msgid "" "Defers the signal, storing it in a queue and only firing it at idle time." -msgstr "" +msgstr "Odložà signál, uložà ho do queue a vystrelà ho iba cez idle time." #: editor/connections_dialog.cpp msgid "Oneshot" -msgstr "" +msgstr "Oneshot" #: editor/connections_dialog.cpp msgid "Disconnects the signal after its first emission." -msgstr "" +msgstr "Odpojà signál po jeho prvej emisii." #: editor/connections_dialog.cpp -#, fuzzy msgid "Cannot connect signal" -msgstr "PripojiÅ¥ Signál: " +msgstr "Nedá sa pripojiÅ¥ signál" #: editor/connections_dialog.cpp editor/dependency_editor.cpp #: editor/export_template_manager.cpp editor/groups_editor.cpp @@ -867,9 +853,8 @@ msgid "Connect" msgstr "PripojiÅ¥" #: editor/connections_dialog.cpp -#, fuzzy msgid "Signal:" -msgstr "Signály:" +msgstr "Signál:" #: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" @@ -893,14 +878,12 @@ msgid "Disconnect" msgstr "OdpojiÅ¥" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect a Signal to a Method" -msgstr "PripojiÅ¥ Signál: " +msgstr "PripojiÅ¥ Signál k Metóde" #: editor/connections_dialog.cpp -#, fuzzy msgid "Edit Connection:" -msgstr "UpraviÅ¥ Pripojenie: " +msgstr "UpraviÅ¥ Pripojenie:" #: editor/connections_dialog.cpp msgid "Are you sure you want to remove all connections from the \"%s\" signal?" @@ -976,22 +959,20 @@ msgid "Dependencies For:" msgstr "Závislosti pre:" #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Scene '%s' is currently being edited.\n" "Changes will only take effect when reloaded." msgstr "" "Scéna '%s' sa práve upravuje.\n" -"Zmeny sa neprejavia, pokiaľ znovu naÄÃtané." +"Zmeny sa prejavia iba keÄ sa znovu naÄÃtajú." #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Resource '%s' is in use.\n" "Changes will only take effect when reloaded." msgstr "" "Scéna '%s' sa práve upravuje.\n" -"Zmeny sa neprejavia, pokiaľ znovu naÄÃtané." +"Zmeny sa prejavia iba keÄ sa znovu naÄÃtajú." #: editor/dependency_editor.cpp #: modules/gdnative/gdnative_library_editor_plugin.cpp @@ -1038,7 +1019,6 @@ msgid "Owners Of:" msgstr "Majitelia:" #: editor/dependency_editor.cpp -#, fuzzy msgid "Remove selected files from the project? (Can't be restored)" msgstr "OdstrániÅ¥ vybraté súbory z projektu? (nedá sa vrátiÅ¥ späť)" @@ -1084,13 +1064,12 @@ msgid "Permanently delete %d item(s)? (No undo!)" msgstr "Natrvalo odstrániÅ¥ %d položky? (Nedá sa vrátiÅ¥ späť!)" #: editor/dependency_editor.cpp -#, fuzzy msgid "Show Dependencies" -msgstr "ZávislostÃ" +msgstr "ZobraziÅ¥ ZávislosÅ¥i" #: editor/dependency_editor.cpp msgid "Orphan Resource Explorer" -msgstr "" +msgstr "Orphan Resource Explorer" #: editor/dependency_editor.cpp editor/editor_audio_buses.cpp #: editor/editor_file_dialog.cpp editor/editor_node.cpp @@ -1177,7 +1156,6 @@ msgid "License" msgstr "Licencia" #: editor/editor_about.cpp -#, fuzzy msgid "Third-party Licenses" msgstr "Thirdparty Licencie" @@ -1188,13 +1166,16 @@ msgid "" "is an exhaustive list of all such third-party components with their " "respective copyright statements and license terms." msgstr "" +"Godot Engine sa spolieha na množstvo bezplatných a otvorených knižnÃc " +"tretÃch strán, ktoré sú kompatibilné s podmienkami licencie MIT. Nasleduje " +"vyÄerpávajúci zoznam vÅ¡etkých takýchto komponentov tretÃch strán s ich " +"prÃsluÅ¡nými prehláseniami o autorských právach a licenÄnými podmienkami." #: editor/editor_about.cpp msgid "All Components" msgstr "VÅ¡etky Komponenty" #: editor/editor_about.cpp -#, fuzzy msgid "Components" msgstr "Komponenty" @@ -1203,26 +1184,24 @@ msgid "Licenses" msgstr "Licencie" #: editor/editor_asset_installer.cpp editor/project_manager.cpp -#, fuzzy msgid "Error opening package file, not in ZIP format." msgstr "Chyba pri otváranà súboru balÃka, nie je vo formáte zip." #: editor/editor_asset_installer.cpp msgid "%s (Already Exists)" -msgstr "" +msgstr "%s (Už Existuje)" #: editor/editor_asset_installer.cpp msgid "Uncompressing Assets" -msgstr "" +msgstr "Dekompresia Prostriedkov" #: editor/editor_asset_installer.cpp editor/project_manager.cpp msgid "The following files failed extraction from package:" -msgstr "" +msgstr "Nasledovné súbory sa nepodarilo extrahovaÅ¥ z balÃka:" #: editor/editor_asset_installer.cpp -#, fuzzy msgid "And %s more files." -msgstr "VytvoriÅ¥ adresár" +msgstr "A %s viac súborov." #: editor/editor_asset_installer.cpp editor/project_manager.cpp msgid "Package installed successfully!" @@ -1234,9 +1213,8 @@ msgid "Success!" msgstr "Úspech!" #: editor/editor_asset_installer.cpp -#, fuzzy msgid "Package Contents:" -msgstr "KonÅ¡tanty:" +msgstr "BalÃÄek Obsahu:" #: editor/editor_asset_installer.cpp editor/editor_node.cpp msgid "Install" @@ -1255,46 +1233,44 @@ msgid "Add Effect" msgstr "PridaÅ¥ Efekt" #: editor/editor_audio_buses.cpp -#, fuzzy msgid "Rename Audio Bus" -msgstr "VÅ¡etky vybrané" +msgstr "PremenovaÅ¥ Audio Bus" #: editor/editor_audio_buses.cpp -#, fuzzy msgid "Change Audio Bus Volume" -msgstr "VÅ¡etky vybrané" +msgstr "ZmeniÅ¥ hlasitosÅ¥ Audio Bus-u" #: editor/editor_audio_buses.cpp msgid "Toggle Audio Bus Solo" -msgstr "" +msgstr "Prepnúť Audio Bus Solo" #: editor/editor_audio_buses.cpp msgid "Toggle Audio Bus Mute" -msgstr "" +msgstr "Prepnúť Audio Bus Mute" #: editor/editor_audio_buses.cpp msgid "Toggle Audio Bus Bypass Effects" -msgstr "" +msgstr "Prepnúť Audio Bus Bypass Effects" #: editor/editor_audio_buses.cpp msgid "Select Audio Bus Send" -msgstr "" +msgstr "VybraÅ¥ Audio Bus Send" #: editor/editor_audio_buses.cpp msgid "Add Audio Bus Effect" -msgstr "" +msgstr "PridaÅ¥ Audio Bus Effect" #: editor/editor_audio_buses.cpp msgid "Move Bus Effect" -msgstr "" +msgstr "Posunúť Bus Effect" #: editor/editor_audio_buses.cpp msgid "Delete Bus Effect" -msgstr "" +msgstr "VymazaÅ¥ Bus Effect" #: editor/editor_audio_buses.cpp msgid "Drag & drop to rearrange." -msgstr "" +msgstr "Zoberte a položte(drag & drop) pre rearandžovanie." #: editor/editor_audio_buses.cpp msgid "Solo" @@ -1310,7 +1286,7 @@ msgstr "ObÃsÅ¥" #: editor/editor_audio_buses.cpp msgid "Bus options" -msgstr "" +msgstr "Možnosti pre Bus" #: editor/editor_audio_buses.cpp editor/filesystem_dock.cpp #: editor/plugins/animation_player_editor_plugin.cpp editor/scene_tree_dock.cpp @@ -1331,64 +1307,63 @@ msgstr "Audio" #: editor/editor_audio_buses.cpp msgid "Add Audio Bus" -msgstr "" +msgstr "PridaÅ¥ Audio Bus" #: editor/editor_audio_buses.cpp msgid "Master bus can't be deleted!" -msgstr "" +msgstr "Master bus nemôžete vymazaÅ¥!" #: editor/editor_audio_buses.cpp msgid "Delete Audio Bus" -msgstr "" +msgstr "VymazaÅ¥ Audio Bus" #: editor/editor_audio_buses.cpp msgid "Duplicate Audio Bus" -msgstr "" +msgstr "DuplikovaÅ¥ Audio Bus" #: editor/editor_audio_buses.cpp msgid "Reset Bus Volume" -msgstr "" +msgstr "ResetovaÅ¥ hlasitosÅ¥ Bus-u" #: editor/editor_audio_buses.cpp msgid "Move Audio Bus" -msgstr "" +msgstr "Presunúť Audio Bus" #: editor/editor_audio_buses.cpp msgid "Save Audio Bus Layout As..." -msgstr "" +msgstr "UložiÅ¥ Audio Bus Layaut Ako..." #: editor/editor_audio_buses.cpp msgid "Location for New Layout..." -msgstr "" +msgstr "Lokácia pre Nový Layout..." #: editor/editor_audio_buses.cpp msgid "Open Audio Bus Layout" -msgstr "" +msgstr "OtvoriÅ¥ Audio Bus Layout" #: editor/editor_audio_buses.cpp msgid "There is no '%s' file." -msgstr "" +msgstr "Nenà tu žiadny '%s' súbor." #: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp msgid "Layout" -msgstr "" +msgstr "Layout" #: editor/editor_audio_buses.cpp msgid "Invalid file, not an audio bus layout." -msgstr "" +msgstr "Neplatný súbor, nenà audio bus layout." #: editor/editor_audio_buses.cpp -#, fuzzy msgid "Error saving file: %s" -msgstr "Chyba pri naÄÃtanÃ:" +msgstr "Chyba uloženia súbora: %s" #: editor/editor_audio_buses.cpp msgid "Add Bus" -msgstr "" +msgstr "PridaÅ¥ Bus" #: editor/editor_audio_buses.cpp msgid "Add a new Audio Bus to this layout." -msgstr "" +msgstr "PridaÅ¥ nový Audio Bus do tohoto layout-u." #: editor/editor_audio_buses.cpp editor/editor_properties.cpp #: editor/plugins/animation_player_editor_plugin.cpp editor/property_editor.cpp @@ -1397,9 +1372,8 @@ msgid "Load" msgstr "NaÄÃtaÅ¥" #: editor/editor_audio_buses.cpp -#, fuzzy msgid "Load an existing Bus Layout." -msgstr "Popis:" +msgstr "NaÄÃtaÅ¥ existujúci Bus Layout." #: editor/editor_audio_buses.cpp msgid "Save As" @@ -1407,7 +1381,7 @@ msgstr "UložiÅ¥ Ako" #: editor/editor_audio_buses.cpp msgid "Save this Bus Layout to a file." -msgstr "" +msgstr "UložiÅ¥ tento Bus Layout do súboru." #: editor/editor_audio_buses.cpp editor/import_dock.cpp msgid "Load Default" @@ -1415,11 +1389,11 @@ msgstr "NaÄÃtaÅ¥ predvolené" #: editor/editor_audio_buses.cpp msgid "Load the default Bus Layout." -msgstr "" +msgstr "NaÄÃtaÅ¥ základný Bus Layout." #: editor/editor_audio_buses.cpp msgid "Create a new Bus Layout." -msgstr "" +msgstr "VytvoriÅ¥ nový Bus Layout." #: editor/editor_autoload_settings.cpp msgid "Invalid name." @@ -1427,68 +1401,67 @@ msgstr "Neplatný Názov." #: editor/editor_autoload_settings.cpp msgid "Valid characters:" -msgstr "" +msgstr "Platné pÃsmená:" #: editor/editor_autoload_settings.cpp msgid "Must not collide with an existing engine class name." -msgstr "" +msgstr "Nesmie kolidovaÅ¥(collide) s existujúcim názvom engine class-u." #: editor/editor_autoload_settings.cpp msgid "Must not collide with an existing built-in type name." -msgstr "" +msgstr "Nesmie kolidovaÅ¥(collide) s existujúcim menom pre built-in-type." #: editor/editor_autoload_settings.cpp msgid "Must not collide with an existing global constant name." -msgstr "" +msgstr "Nesmie kolidovaÅ¥ s existujúcim menom pre global constant." #: editor/editor_autoload_settings.cpp msgid "Keyword cannot be used as an autoload name." -msgstr "" +msgstr "KľúÄové slovo nemožno použiÅ¥ ako AutoLoad názvu." #: editor/editor_autoload_settings.cpp msgid "Autoload '%s' already exists!" -msgstr "" +msgstr "AutoLoad '%s' už existujuje!" #: editor/editor_autoload_settings.cpp msgid "Rename Autoload" -msgstr "" +msgstr "PremenovaÅ¥ AutoLoad" #: editor/editor_autoload_settings.cpp msgid "Toggle AutoLoad Globals" -msgstr "" +msgstr "Prepnúť globálne AutoLoad-y" #: editor/editor_autoload_settings.cpp msgid "Move Autoload" -msgstr "" +msgstr "Presunúť AutoLoad-y" #: editor/editor_autoload_settings.cpp msgid "Remove Autoload" -msgstr "" +msgstr "VymazaÅ¥ AutoLoad" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" -msgstr "" +msgstr "PovoliÅ¥" #: editor/editor_autoload_settings.cpp msgid "Rearrange Autoloads" -msgstr "" +msgstr "RearandžovaÅ¥ AutoLoad-y" #: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid path." -msgstr "Neplatný Názov." +msgstr "Neplatná cesta." #: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp msgid "File does not exist." -msgstr "" +msgstr "Súbor neexistuje." #: editor/editor_autoload_settings.cpp msgid "Not in resource path." -msgstr "" +msgstr "Nieje v resource path." #: editor/editor_autoload_settings.cpp msgid "Add AutoLoad" -msgstr "" +msgstr "PridaÅ¥ AutoLoad" #: editor/editor_autoload_settings.cpp editor/editor_file_dialog.cpp #: editor/editor_plugin_settings.cpp @@ -1499,49 +1472,49 @@ msgstr "Cesta:" #: editor/editor_autoload_settings.cpp msgid "Node Name:" -msgstr "" +msgstr "Meno Node-u:" #: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp #: editor/editor_profiler.cpp editor/project_manager.cpp #: editor/settings_config_dialog.cpp msgid "Name" -msgstr "" +msgstr "Meno" #: editor/editor_autoload_settings.cpp msgid "Singleton" -msgstr "" +msgstr "Singleton" #: editor/editor_data.cpp editor/inspector_dock.cpp msgid "Paste Params" -msgstr "" +msgstr "VložiÅ¥ Params" #: editor/editor_data.cpp msgid "Updating Scene" -msgstr "" +msgstr "AktualizovaÅ¥ Scénu" #: editor/editor_data.cpp msgid "Storing local changes..." -msgstr "" +msgstr "Ukladanie lokálnych zmien..." #: editor/editor_data.cpp msgid "Updating scene..." -msgstr "" +msgstr "Aktualizovanie scény..." #: editor/editor_data.cpp editor/editor_properties.cpp msgid "[empty]" -msgstr "" +msgstr "[Prázdne]" #: editor/editor_data.cpp msgid "[unsaved]" -msgstr "" +msgstr "[Neuložené]" #: editor/editor_dir_dialog.cpp msgid "Please select a base directory first." -msgstr "" +msgstr "Najprv vyberte základný adresár." #: editor/editor_dir_dialog.cpp msgid "Choose a Directory" -msgstr "" +msgstr "Vyberte adresár" #: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp #: editor/filesystem_dock.cpp editor/project_manager.cpp @@ -1559,35 +1532,39 @@ msgstr "Meno:" #: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp #: editor/filesystem_dock.cpp scene/gui/file_dialog.cpp msgid "Could not create folder." -msgstr "" +msgstr "PrieÄinok sa nepodarilo vytvoriÅ¥." #: editor/editor_dir_dialog.cpp msgid "Choose" -msgstr "" +msgstr "Vyberte" #: editor/editor_export.cpp msgid "Storing File:" -msgstr "" +msgstr "Ukladanie súboru:" #: editor/editor_export.cpp msgid "No export template found at the expected path:" -msgstr "" +msgstr "Na oÄakávanej ceste sa nenaÅ¡la žiadna exportná cesta:" #: editor/editor_export.cpp msgid "Packing" -msgstr "" +msgstr "Zabalovanie" #: editor/editor_export.cpp msgid "" "Target platform requires 'ETC' texture compression for GLES2. Enable 'Import " "Etc' in Project Settings." msgstr "" +"Target platforma potrebuje 'ETC' kompresor textúr pre GLES2. PovoliÅ¥ 'Import " +"Etc' v Nastaveniach Projektu." #: editor/editor_export.cpp msgid "" "Target platform requires 'ETC2' texture compression for GLES3. Enable " "'Import Etc 2' in Project Settings." msgstr "" +"Target platforma potrebuje 'ETC2' kompresor textúr pre GLES3. PovoliÅ¥'Import " +"Etc 2' v Nastaveniach Projektu." #: editor/editor_export.cpp msgid "" @@ -1596,107 +1573,106 @@ msgid "" "Enable 'Import Etc' in Project Settings, or disable 'Driver Fallback " "Enabled'." msgstr "" +"Target platform potrebuje'ETC' kompresor textúr pre driver fallback do " +"GLES2.\n" +"Povoľte 'Import Etc' v Nastaveniach Projektu, alebo vipnite 'Driver Fallback " +"Enabled'." #: editor/editor_export.cpp platform/android/export/export.cpp #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp #: platform/osx/export/export.cpp platform/uwp/export/export.cpp msgid "Custom debug template not found." -msgstr "" +msgstr "Vlastná debug Å¡ablóna sa nenaÅ¡la." #: editor/editor_export.cpp platform/android/export/export.cpp #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp #: platform/osx/export/export.cpp platform/uwp/export/export.cpp msgid "Custom release template not found." -msgstr "" +msgstr "Vlastná release Å¡ablóna sa nenaÅ¡la." #: editor/editor_export.cpp platform/javascript/export/export.cpp msgid "Template file not found:" -msgstr "" +msgstr "Súbor Å ablóny sa nenaÅ¡iel:" #: editor/editor_export.cpp msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." -msgstr "" +msgstr "Pri 32-bitovom exporte nemôže byÅ¥ vložená PCK väÄÅ¡ia ako 4 GiB." #: editor/editor_feature_profile.cpp -#, fuzzy msgid "3D Editor" -msgstr "Otvorit prieÄinok" +msgstr "3D Editor" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Script Editor" -msgstr "Otvorit prieÄinok" +msgstr "Script Editor" #: editor/editor_feature_profile.cpp msgid "Asset Library" -msgstr "" +msgstr "Asset Library" #: editor/editor_feature_profile.cpp msgid "Scene Tree Editing" -msgstr "" +msgstr "Editovanie Stromu Scén" #: editor/editor_feature_profile.cpp msgid "Import Dock" -msgstr "" +msgstr "ImportovaÅ¥ Dock" #: editor/editor_feature_profile.cpp msgid "Node Dock" -msgstr "" +msgstr "Node Dock" #: editor/editor_feature_profile.cpp msgid "FileSystem and Import Docks" -msgstr "" +msgstr "Systém súborov a Import Dock-y" #: editor/editor_feature_profile.cpp msgid "Erase profile '%s'? (no undo)" -msgstr "" +msgstr "VymazaÅ¥ profil '%s'? (Nedá sa vrátiÅ¥ späť)" #: editor/editor_feature_profile.cpp msgid "Profile must be a valid filename and must not contain '.'" -msgstr "" +msgstr "Profil musà maÅ¥ platný názov súboru a musà obsahovaÅ¥ '.'" #: editor/editor_feature_profile.cpp msgid "Profile with this name already exists." -msgstr "" +msgstr "Profil s týmto menom už existuje." #: editor/editor_feature_profile.cpp msgid "(Editor Disabled, Properties Disabled)" -msgstr "" +msgstr "(Editor je vypnutý, Vlastnosti sú vypnuté)" #: editor/editor_feature_profile.cpp msgid "(Properties Disabled)" -msgstr "" +msgstr "(Vlastnosi sú vypnuté)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Editor Disabled)" -msgstr "Vypnuté" +msgstr "(Editor je vypnutý)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options:" -msgstr "Popis:" +msgstr "Možnosti pre Class:" #: editor/editor_feature_profile.cpp msgid "Enable Contextual Editor" -msgstr "" +msgstr "PovoliÅ¥ Kontextuálny Editor" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Properties:" -msgstr "Filter:" +msgstr "Povolené Vlastnosti:" #: editor/editor_feature_profile.cpp msgid "Enabled Features:" -msgstr "" +msgstr "Povolené Funkcie:" #: editor/editor_feature_profile.cpp msgid "Enabled Classes:" -msgstr "" +msgstr "Povolené Class-y:" #: editor/editor_feature_profile.cpp msgid "File '%s' format is invalid, import aborted." -msgstr "" +msgstr "Formát súboru '%s' je neplatny, Import bol preruÅ¡ený." #: editor/editor_feature_profile.cpp msgid "" @@ -2841,7 +2817,7 @@ msgstr "" #: editor/editor_node.cpp editor/script_create_dialog.cpp msgid "Editor" -msgstr "" +msgstr "Editor" #: editor/editor_node.cpp #, fuzzy @@ -2912,7 +2888,11 @@ msgid "Q&A" msgstr "" #: editor/editor_node.cpp -msgid "Issue Tracker" +msgid "Report a Bug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp @@ -3972,7 +3952,7 @@ msgid "Reimport" msgstr "" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -4518,7 +4498,7 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation" -msgstr "" +msgstr "Animácie" #: editor/plugins/animation_player_editor_plugin.cpp #, fuzzy @@ -6858,14 +6838,6 @@ msgid "Open Godot online documentation." msgstr "Popis:" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7310,6 +7282,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7400,13 +7376,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -10198,7 +10174,7 @@ msgstr "" #: editor/project_settings_editor.cpp msgid "Plugins" -msgstr "" +msgstr "Pluginy" #: editor/property_editor.cpp msgid "Preset..." @@ -10860,6 +10836,12 @@ msgid "Script file already exists." msgstr "" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp #, fuzzy msgid "Class Name:" msgstr "Trieda:" @@ -12542,6 +12524,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." diff --git a/editor/translations/sl.po b/editor/translations/sl.po index e8a0b4c2a1..8145e5e5d9 100644 --- a/editor/translations/sl.po +++ b/editor/translations/sl.po @@ -1515,7 +1515,7 @@ msgstr "Premakni SamodejnoNalaganje" msgid "Remove Autoload" msgstr "Odstrani SamodejnoNalaganje" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "OmogoÄi" @@ -3066,8 +3066,13 @@ msgid "Q&A" msgstr "V&O" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "Sledilnik Napak" +#, fuzzy +msgid "Report a Bug" +msgstr "Ponovno Uvozi" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4155,7 +4160,7 @@ msgid "Reimport" msgstr "Ponovno Uvozi" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -7140,14 +7145,6 @@ msgid "Open Godot online documentation." msgstr "Odpri Nedavne" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7599,6 +7596,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7689,13 +7690,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -11215,6 +11216,12 @@ msgid "Script file already exists." msgstr "SamodejnoNalaganje '%s' že obstaja!" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp #, fuzzy msgid "Class Name:" msgstr "Razred:" @@ -12926,6 +12933,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." @@ -12956,6 +12967,9 @@ msgstr "" msgid "Constants cannot be modified." msgstr "Konstante ni možno spreminjati." +#~ msgid "Issue Tracker" +#~ msgstr "Sledilnik Napak" + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "Zamenjana %d ponovitev/e." diff --git a/editor/translations/sq.po b/editor/translations/sq.po index 60ac25f6f4..19b13a126b 100644 --- a/editor/translations/sq.po +++ b/editor/translations/sq.po @@ -1452,7 +1452,7 @@ msgstr "Lëviz Autoload-in" msgid "Remove Autoload" msgstr "Hiq Autoload-in" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "Lejo" @@ -2991,8 +2991,13 @@ msgid "Q&A" msgstr "Pyetje&Përgjigje" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "Gjurmuesi i Problemeve" +#, fuzzy +msgid "Report a Bug" +msgstr "Ri-importo" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4066,7 +4071,8 @@ msgid "Reimport" msgstr "Ri-importo" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +#, fuzzy +msgid "Save Scenes, Re-Import, and Restart" msgstr "Ruaj skenat, ri-importo dhe rifillo" #: editor/import_dock.cpp @@ -6897,14 +6903,6 @@ msgid "Open Godot online documentation." msgstr "" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7343,6 +7341,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7432,13 +7434,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -10835,6 +10837,12 @@ msgid "Script file already exists." msgstr "Emri i grupit ekziston që më parë." #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp #, fuzzy msgid "Class Name:" msgstr "Klasa:" @@ -12481,6 +12489,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" @@ -12509,6 +12521,9 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#~ msgid "Issue Tracker" +#~ msgstr "Gjurmuesi i Problemeve" + #~ msgid "" #~ "There are currently no tutorials for this class, you can [color=$color]" #~ "[url=$url]contribute one[/url][/color] or [color=$color][url=" diff --git a/editor/translations/sr_Cyrl.po b/editor/translations/sr_Cyrl.po index 5f5f3786a7..f83bc8bcd1 100644 --- a/editor/translations/sr_Cyrl.po +++ b/editor/translations/sr_Cyrl.po @@ -1516,7 +1516,7 @@ msgstr "Помери аутоматÑко учитавање" msgid "Remove Autoload" msgstr "Обриши аутоматÑко учитавање" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "Укључи" @@ -3073,8 +3073,13 @@ msgid "Q&A" msgstr "Питања и одговори" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "Пратилац грешака" +#, fuzzy +msgid "Report a Bug" +msgstr "Поново увези" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4181,7 +4186,7 @@ msgid "Reimport" msgstr "Поново увези" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -7191,14 +7196,6 @@ msgid "Open Godot online documentation." msgstr "Отвори Godot онлајн документацију" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "Претражи документацију." @@ -7666,6 +7663,11 @@ msgstr "Ова операција захтева један изабран чвР#: editor/plugins/spatial_editor_plugin.cpp #, fuzzy +msgid "Auto Orthogonal Enabled" +msgstr "Ортогонална пројекција" + +#: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy msgid "Lock View Rotation" msgstr "Прикажи информације" @@ -7757,17 +7759,17 @@ msgid "Freelook Slow Modifier" msgstr "Брзина Ñлободног погледа" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "View Rotation Locked" +msgstr "Прикажи информације" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy -msgid "View Rotation Locked" -msgstr "Прикажи информације" - -#: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "XForm дијалог" @@ -11343,6 +11345,12 @@ msgid "Script file already exists." msgstr "ÐутоматÑко учитавање '%s' већ поÑтоји!" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp #, fuzzy msgid "Class Name:" msgstr "КлаÑа:" @@ -13031,6 +13039,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." @@ -13062,6 +13074,9 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#~ msgid "Issue Tracker" +#~ msgstr "Пратилац грешака" + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "Замени %d појаве/а." diff --git a/editor/translations/sr_Latn.po b/editor/translations/sr_Latn.po index c36e64d459..80ff3bc4fa 100644 --- a/editor/translations/sr_Latn.po +++ b/editor/translations/sr_Latn.po @@ -1437,7 +1437,7 @@ msgstr "" msgid "Remove Autoload" msgstr "" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "" @@ -2848,7 +2848,11 @@ msgid "Q&A" msgstr "" #: editor/editor_node.cpp -msgid "Issue Tracker" +msgid "Report a Bug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp @@ -3873,7 +3877,7 @@ msgid "Reimport" msgstr "" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -6698,14 +6702,6 @@ msgid "Open Godot online documentation." msgstr "" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7142,6 +7138,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7230,13 +7230,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -10621,6 +10621,12 @@ msgid "Script file already exists." msgstr "" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "" @@ -12253,6 +12259,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/sv.po b/editor/translations/sv.po index 3f7fee23b7..cb1d4c22d6 100644 --- a/editor/translations/sv.po +++ b/editor/translations/sv.po @@ -1507,7 +1507,7 @@ msgstr "Flytta Autoload" msgid "Remove Autoload" msgstr "Ta bort Autoload" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "Aktivera" @@ -3043,7 +3043,12 @@ msgid "Q&A" msgstr "FrÃ¥gor och svar" #: editor/editor_node.cpp -msgid "Issue Tracker" +#, fuzzy +msgid "Report a Bug" +msgstr "Importera om" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp @@ -4139,7 +4144,7 @@ msgid "Reimport" msgstr "Importera om" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -7086,14 +7091,6 @@ msgid "Open Godot online documentation." msgstr "Öppna Senaste" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7550,6 +7547,10 @@ msgid "This operation requires a single selected node." msgstr "Ã…tgärden kräver en enstaka vald Node." #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp #, fuzzy msgid "Lock View Rotation" msgstr "Visa Information" @@ -7640,17 +7641,17 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "View Rotation Locked" +msgstr "Visa Information" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy -msgid "View Rotation Locked" -msgstr "Visa Information" - -#: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "" @@ -11166,6 +11167,12 @@ msgid "Script file already exists." msgstr "Autoload '%s' finns redan!" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp #, fuzzy msgid "Class Name:" msgstr "Klassnamn" @@ -12871,6 +12878,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." diff --git a/editor/translations/ta.po b/editor/translations/ta.po index 5300f984bb..b93e16a597 100644 --- a/editor/translations/ta.po +++ b/editor/translations/ta.po @@ -1429,7 +1429,7 @@ msgstr "" msgid "Remove Autoload" msgstr "" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "" @@ -2836,7 +2836,11 @@ msgid "Q&A" msgstr "" #: editor/editor_node.cpp -msgid "Issue Tracker" +msgid "Report a Bug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp @@ -3860,7 +3864,7 @@ msgid "Reimport" msgstr "" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -6663,14 +6667,6 @@ msgid "Open Godot online documentation." msgstr "" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7101,6 +7097,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7189,13 +7189,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -10537,6 +10537,12 @@ msgid "Script file already exists." msgstr "" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "" @@ -12160,6 +12166,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/te.po b/editor/translations/te.po index d76be13ec1..38d8b80709 100644 --- a/editor/translations/te.po +++ b/editor/translations/te.po @@ -1407,7 +1407,7 @@ msgstr "" msgid "Remove Autoload" msgstr "" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "" @@ -2810,7 +2810,11 @@ msgid "Q&A" msgstr "" #: editor/editor_node.cpp -msgid "Issue Tracker" +msgid "Report a Bug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp @@ -3831,7 +3835,7 @@ msgid "Reimport" msgstr "" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -6613,14 +6617,6 @@ msgid "Open Godot online documentation." msgstr "" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7050,6 +7046,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7138,13 +7138,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -10463,6 +10463,12 @@ msgid "Script file already exists." msgstr "" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "" @@ -12076,6 +12082,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/th.po b/editor/translations/th.po index a56f6338ab..3ad01b7d05 100644 --- a/editor/translations/th.po +++ b/editor/translations/th.po @@ -5,11 +5,12 @@ # Kaveeta Vivatchai <goodytong@gmail.com>, 2017. # Poommetee Ketson (Noshyaar) <poommetee@protonmail.com>, 2017-2018. # Thanachart Monpassorn <nunf_2539@hotmail.com>, 2020. +# anonymous <noreply@weblate.org>, 2020. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-01-03 21:21+0000\n" +"PO-Revision-Date: 2020-03-31 02:26+0000\n" "Last-Translator: Thanachart Monpassorn <nunf_2539@hotmail.com>\n" "Language-Team: Thai <https://hosted.weblate.org/projects/godot-engine/godot/" "th/>\n" @@ -18,7 +19,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 3.10\n" +"X-Generator: Weblate 4.0-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -41,30 +42,27 @@ msgstr "ค่าà¸à¸´à¸™à¸žà¸¸à¸•ผิดพลาด %i (ไม่ผ่าà #: core/math/expression.cpp msgid "self can't be used because instance is null (not passed)" -msgstr "self ไม่สามารถใช้ได้เนื่à¸à¸‡à¸ˆà¸²à¸ instance มีค่า null (ไม่ผ่าน)" +msgstr "self ไม่สามารถใช้ได้เนื่à¸à¸‡à¸ˆà¸²à¸à¸à¸´à¸™à¸ªà¹à¸•นซ์มีค่า null (ไม่ผ่าน)" #: core/math/expression.cpp -#, fuzzy msgid "Invalid operands to operator %s, %s and %s." -msgstr "ไม่พบคุณสมบัติ '%s' ในโหนด %s" +msgstr "ดำเนินà¸à¸²à¸£à¸œà¸´à¸”พลาดที่ตัวดำเนินà¸à¸²à¸£ %s, %s à¹à¸¥à¸° %s" #: core/math/expression.cpp -#, fuzzy msgid "Invalid index of type %s for base type %s" -msgstr "ไม่พบคุณสมบัติ '%s' ในโหนด %s" +msgstr "ดัชนีขà¸à¸‡à¸Šà¸™à¸´à¸” '%s' ผิดพลาด ในชนิดà¸à¸²à¸™ %s" #: core/math/expression.cpp msgid "Invalid named index '%s' for base type %s" -msgstr "" +msgstr "ชื่à¸à¸”ัชนีขà¸à¸‡ '%s' ผิดพลาด สำหรับà¸à¸²à¸™ %s" #: core/math/expression.cpp -#, fuzzy msgid "Invalid arguments to construct '%s'" -msgstr ": ประเภทตัวà¹à¸›à¸£à¹„ม่ถูà¸à¸•้à¸à¸‡: " +msgstr "à¸à¸²à¸à¸´à¸§à¹€à¸¡à¸™à¸•์ไม่ถูà¸à¸•้à¸à¸‡à¹ƒà¸™à¸„à¸à¸™à¸ªà¸•รัภ'%s'" #: core/math/expression.cpp msgid "On call to '%s':" -msgstr "" +msgstr "เรียภ'%s':" #: core/ustring.cpp msgid "B" @@ -103,9 +101,8 @@ msgid "Balanced" msgstr "สมดุล" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Mirror" -msgstr "สะท้à¸à¸™à¸‹à¹‰à¸²à¸¢à¸‚วา" +msgstr "à¸à¸£à¸°à¸ˆà¸" #: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp msgid "Time:" @@ -116,29 +113,24 @@ msgid "Value:" msgstr "ค่า:" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Insert Key Here" -msgstr "เพิ่มคีย์" +msgstr "เพิ่มคีย์ที่นี่" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Duplicate Selected Key(s)" -msgstr "ทำซ้ำที่เลืà¸à¸" +msgstr "ทำซ้ำคีย์ที่เลืà¸à¸" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Delete Selected Key(s)" -msgstr "ลบสิ่งที่เลืà¸à¸" +msgstr "ลบคีย์ที่เลืà¸à¸" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Add Bezier Point" -msgstr "เพิ่มจุด" +msgstr "เพิ่มจุดเบซิเยร์" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Move Bezier Points" -msgstr "ย้ายจุด" +msgstr "ย้ายจุดเบซิเยร์" #: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp msgid "Anim Duplicate Keys" @@ -169,34 +161,28 @@ msgid "Anim Change Call" msgstr "à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸à¸Ÿà¸±à¸‡à¸à¹Œà¸Šà¸±à¸™à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Multi Change Keyframe Time" -msgstr "à¹à¸à¹‰à¹„ขเวลาคีย์เฟรมà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" +msgstr "à¹à¸à¹‰à¹„ขเวลาคีย์เฟรมà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹à¸šà¸šà¸«à¸¥à¸²à¸¢à¸„รั้ง" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Multi Change Transition" -msgstr "à¹à¸à¹‰à¹„ขทรานสิชันà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" +msgstr "à¹à¸à¹‰à¹„ขทรานสิชันà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹à¸šà¸šà¸«à¸¥à¸²à¸¢à¸„รั้ง" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Multi Change Transform" -msgstr "เคลื่à¸à¸™à¸¢à¹‰à¸²à¸¢à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" +msgstr "à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹à¸šà¸šà¸«à¸¥à¸²à¸¢à¸„รั้ง" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Multi Change Keyframe Value" -msgstr "à¹à¸à¹‰à¹„ขค่าคีย์เฟรมà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" +msgstr "à¹à¸à¹‰à¹„ขคีย์เฟรมà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹à¸šà¸šà¸«à¸¥à¸²à¸¢à¸„รั้ง" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Multi Change Call" -msgstr "à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸à¸Ÿà¸±à¸‡à¸à¹Œà¸Šà¸±à¸™à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" +msgstr "à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹à¸šà¸šà¸«à¸¥à¸²à¸¢à¸„รั้ง" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Change Animation Length" -msgstr "à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¸§à¸™à¸‹à¹‰à¸³à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" +msgstr "à¹à¸à¹‰à¹„ขความยาวà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" #: editor/animation_track_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp @@ -204,51 +190,44 @@ msgid "Change Animation Loop" msgstr "à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¸§à¸™à¸‹à¹‰à¸³à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Property Track" -msgstr "คุณสมบัติ:" +msgstr "คุณสมบัติà¹à¸—ร็à¸" #: editor/animation_track_editor.cpp -#, fuzzy msgid "3D Transform Track" -msgstr "ประเภทà¸à¸²à¸£à¹€à¸„ลื่à¸à¸™à¸¢à¹‰à¸²à¸¢" +msgstr "à¹à¸—ร็ภ3D Transform" #: editor/animation_track_editor.cpp msgid "Call Method Track" -msgstr "" +msgstr "เรียà¸à¹à¸—ร็à¸à¹€à¸¡à¸˜à¸à¸”" #: editor/animation_track_editor.cpp msgid "Bezier Curve Track" -msgstr "" +msgstr "à¹à¸—ร็à¸à¹€à¸ªà¹‰à¸™à¹‚ค้งเบซิเยร์" #: editor/animation_track_editor.cpp msgid "Audio Playback Track" -msgstr "" +msgstr "à¹à¸—ร็à¸à¸à¸²à¸£à¹€à¸¥à¹ˆà¸™à¹€à¸ªà¸µà¸¢à¸‡" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Animation Playback Track" -msgstr "หยุดà¸à¸²à¸£à¹€à¸¥à¹ˆà¸™à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™ (S)" +msgstr "à¹à¸—ร็à¸à¸à¸²à¸£à¹€à¸¥à¹ˆà¸™à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Animation length (frames)" -msgstr "ความยาวà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™ (วินาที)" +msgstr "ความยาวà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™ (เฟรม)" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Animation length (seconds)" msgstr "ความยาวà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™ (วินาที)" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Add Track" -msgstr "เพิ่มà¹à¸—ร็à¸à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" +msgstr "เพิ่มà¹à¸—ร็à¸" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Animation Looping" -msgstr "ซูมà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" +msgstr "à¸à¸²à¸£à¸§à¸™à¸‹à¹‰à¸³à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" #: editor/animation_track_editor.cpp #: modules/visual_script/visual_script_editor.cpp @@ -256,52 +235,44 @@ msgid "Functions:" msgstr "ฟังà¸à¹Œà¸Šà¸±à¸™:" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Audio Clips:" -msgstr "ตัวรับเสียง" +msgstr "คลิปเสียง:" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Anim Clips:" -msgstr "คลิป" +msgstr "คลิปà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¹ˆà¸™:" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Change Track Path" -msgstr "เปลี่ยนค่าในà¸à¸²à¸£à¹Œà¹€à¸£à¸¢à¹Œ" +msgstr "เปลี่ยนที่à¸à¸¢à¸¹à¹ˆà¹à¸—ร็à¸" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Toggle this track on/off." -msgstr "โหมดไร้สิ่งรบà¸à¸§à¸™" +msgstr "เปิด/ปิดà¸à¸²à¸£à¸•ิดตามà¹à¸—ร็à¸à¸™à¸µà¹‰" #: editor/animation_track_editor.cpp msgid "Update Mode (How this property is set)" -msgstr "" +msgstr "โหมดà¸à¸±à¸žà¹€à¸”ท (วิธีตั้งค่าคุณสมบัตินี้)" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Interpolation Mode" -msgstr "โหนดà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" +msgstr "โหมดà¸à¸²à¸£à¹à¸à¹‰à¹„ข" #: editor/animation_track_editor.cpp msgid "Loop Wrap Mode (Interpolate end with beginning on loop)" -msgstr "" +msgstr "โหมดวนรà¸à¸š (ต่à¸à¸ˆà¸¸à¸”สิ้นสุดด้วยจุดเริ่มต้นขà¸à¸‡à¸¥à¸¹à¸›)" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Remove this track." -msgstr "ลบà¹à¸—ร็à¸à¸—ี่เลืà¸à¸" +msgstr "ลบà¹à¸—ร็à¸à¸™à¸µà¹‰" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Time (s): " -msgstr "ระยะเวลาเฟด (วิ):" +msgstr "เวลา (วินาที): " #: editor/animation_track_editor.cpp -#, fuzzy msgid "Toggle Track Enabled" -msgstr "เปิดดà¸à¸›à¹€à¸žà¸¥à¸à¸£à¹Œ" +msgstr "เปิดà¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™à¸à¸²à¸£à¸•ิดตามà¹à¸—ร็à¸" #: editor/animation_track_editor.cpp msgid "Continuous" @@ -316,13 +287,12 @@ msgid "Trigger" msgstr "ทริà¸à¹€à¸à¸à¸£à¹Œ" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Capture" -msgstr "ฟีเจà¸à¸£à¹Œ" +msgstr "จับ" #: editor/animation_track_editor.cpp msgid "Nearest" -msgstr "" +msgstr "ใà¸à¸¥à¹‰à¸—ี่สุด" #: editor/animation_track_editor.cpp editor/plugins/curve_editor_plugin.cpp #: editor/property_editor.cpp @@ -331,15 +301,15 @@ msgstr "เส้นตรง" #: editor/animation_track_editor.cpp msgid "Cubic" -msgstr "" +msgstr "ลูà¸à¸šà¸²à¸¨à¸à¹Œ" #: editor/animation_track_editor.cpp msgid "Clamp Loop Interp" -msgstr "" +msgstr "à¸à¸²à¸£à¸ˆà¸³à¸à¸±à¸”à¸à¸²à¸£à¸§à¸™à¸¥à¸¹à¸›" #: editor/animation_track_editor.cpp msgid "Wrap Loop Interp" -msgstr "" +msgstr "ล้à¸à¸¡à¸à¸²à¸£à¸§à¸™à¸‹à¹‰à¸³" #: editor/animation_track_editor.cpp #: editor/plugins/canvas_item_editor_plugin.cpp @@ -347,19 +317,16 @@ msgid "Insert Key" msgstr "เพิ่มคีย์" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Duplicate Key(s)" -msgstr "ทำซ้ำโหนด" +msgstr "สร้างคีย์ซ้ำà¸à¸µà¸à¸à¸±à¸™" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Delete Key(s)" -msgstr "ลบโหนด" +msgstr "ลบคีย์" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Change Animation Update Mode" -msgstr "เปลี่ยนชื่à¸à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™:" +msgstr "เปลี่ยนโหมดà¸à¸²à¸£à¸à¸±à¸žà¹€à¸”ทà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" #: editor/animation_track_editor.cpp #, fuzzy @@ -367,9 +334,8 @@ msgid "Change Animation Interpolation Mode" msgstr "โหนดà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Change Animation Loop Mode" -msgstr "à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¸§à¸™à¸‹à¹‰à¸³à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" +msgstr "เปลี่ยนโหมดà¸à¸²à¸£à¸§à¸™à¸‹à¹‰à¸³à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" #: editor/animation_track_editor.cpp msgid "Remove Anim Track" @@ -401,7 +367,7 @@ msgstr "à¹à¸—รà¸à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" #: editor/animation_track_editor.cpp msgid "AnimationPlayer can't animate itself, only other players." -msgstr "" +msgstr "ตัวเล่นà¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¹ˆà¸™à¹„ม่สามารถเล่นà¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¹ˆà¸™à¸”้วยตัวมันเà¸à¸‡à¹„ด้ เล่นได้เฉพาะตัวเล่นà¸à¸·à¹ˆà¸™à¹€à¸—่านั้น" #: editor/animation_track_editor.cpp msgid "Anim Create & Insert" @@ -421,9 +387,8 @@ msgid "Change Animation Step" msgstr "à¹à¸à¹‰à¹„ขความเร็วà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Rearrange Tracks" -msgstr "จัดลำดับà¸à¸à¹‚ต้โหลด" +msgstr "จัดเรียงà¹à¸—ร็à¸" #: editor/animation_track_editor.cpp msgid "Transform tracks only apply to Spatial-based nodes." @@ -436,73 +401,70 @@ msgid "" "-AudioStreamPlayer2D\n" "-AudioStreamPlayer3D" msgstr "" +"à¹à¸—ร็à¸à¹€à¸ªà¸µà¸¢à¸‡à¸ªà¸²à¸¡à¸²à¸£à¸–ติดไว้บนโหนดชนิดเหล่านี้เท่านั้น:\n" +"-AudioStreamPlayer\n" +"-AudioStreamPlayer2D\n" +"-AudioStreamPlayer3D" #: editor/animation_track_editor.cpp msgid "Animation tracks can only point to AnimationPlayer nodes." -msgstr "" +msgstr "à¹à¸—ร็à¸à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¹ˆà¸™à¸ªà¸²à¸¡à¸²à¸£à¸–ติดไว้บนโหนด AnimationPlayer เท่านั้น" #: editor/animation_track_editor.cpp msgid "An animation player can't animate itself, only other players." -msgstr "" +msgstr "à¹à¸—ร็à¸à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¹ˆà¸™à¹„ม่สามารถเล่นตัวมันเà¸à¸‡à¹„ด้ à¹à¸•่สามารถเล่นตัวเล่นà¸à¸·à¹ˆà¸™à¹„ด้" #: editor/animation_track_editor.cpp msgid "Not possible to add a new track without a root" -msgstr "" +msgstr "ไม่สามารถที่จะเพิ่มà¹à¸—ร็à¸à¹ƒà¸«à¸¡à¹ˆà¹‚ดยที่ไม่มีรูท" #: editor/animation_track_editor.cpp msgid "Invalid track for Bezier (no suitable sub-properties)" -msgstr "" +msgstr "à¹à¸—ร็à¸à¸œà¸´à¸”พลาดสำหรับเบซิเยร์ (ไม่มีคุณสมบัติย่à¸à¸¢à¸—ี่เข้าà¸à¸±à¸™à¹„ด้)" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Add Bezier Track" -msgstr "เพิ่มà¹à¸—ร็à¸à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" +msgstr "เพิ่มà¹à¸—ร็à¸à¹€à¸šà¸‹à¸´à¹€à¸¢à¸£à¹Œ" #: editor/animation_track_editor.cpp msgid "Track path is invalid, so can't add a key." -msgstr "" +msgstr "ที่à¸à¸¢à¸¹à¹ˆà¹à¸—ร็à¸à¸œà¸´à¸”พลาด ไม่สามารถเพิ่มคีย์ได้" #: editor/animation_track_editor.cpp msgid "Track is not of type Spatial, can't insert key" -msgstr "" +msgstr "à¹à¸—ร็à¸à¹„ม่ใช่ชนิด Spatial, ไม่สามารถเพิ่มคีย์ได้" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Add Transform Track Key" -msgstr "ประเภทà¸à¸²à¸£à¹€à¸„ลื่à¸à¸™à¸¢à¹‰à¸²à¸¢" +msgstr "เพิ่มคีย์à¹à¸—ร็à¸à¸à¸²à¸£à¹à¸›à¸¥à¸‡" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Add Track Key" -msgstr "เพิ่มà¹à¸—ร็à¸à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" +msgstr "เพิ่มà¹à¸—ร็à¸à¸„ีย์" #: editor/animation_track_editor.cpp msgid "Track path is invalid, so can't add a method key." -msgstr "" +msgstr "ที่à¸à¸¢à¸¹à¹ˆà¹à¸—ร็à¸à¸œà¸´à¸”พลาด ไม่สามารถเพิ่มคีย์เมธà¸à¸”ได้" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Add Method Track Key" -msgstr "เพิ่มà¹à¸—ร็à¸à¹à¸¥à¸°à¸„ีย์à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" +msgstr "เพิ่มคีย์à¹à¸—ร็à¸à¹€à¸¡à¸˜à¸à¸”" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Method not found in object: " -msgstr "ไม่พบ VariableGet ในสคริปต์: " +msgstr "ไม่พบเมธà¸à¸”ในà¸à¸à¸šà¹€à¸ˆà¸à¸•์: " #: editor/animation_track_editor.cpp msgid "Anim Move Keys" msgstr "ย้ายคีย์à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Clipboard is empty" -msgstr "คลิปบà¸à¸£à¹Œà¸”ว่างเปล่า!" +msgstr "คลิปบà¸à¸£à¹Œà¸”ว่างเปล่า" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Paste Tracks" -msgstr "วางตัวà¹à¸›à¸£" +msgstr "วางà¹à¸—ร็à¸" #: editor/animation_track_editor.cpp msgid "Anim Scale Keys" @@ -511,7 +473,7 @@ msgstr "ปรับคีย์à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" #: editor/animation_track_editor.cpp msgid "" "This option does not work for Bezier editing, as it's only a single track." -msgstr "" +msgstr "ตัวเลืà¸à¸à¸™à¸µà¹‰à¹„ม่สามารถทำงานà¸à¸±à¸šà¹à¸—ร็à¸à¹€à¸šà¸‹à¸´à¹€à¸¢à¸£à¹Œ เนื่à¸à¸‡à¸ˆà¸²à¸à¹€à¸›à¹‡à¸™à¹à¸„่à¹à¸—ร็à¸à¹€à¸”ี่ยว" #: editor/animation_track_editor.cpp msgid "" @@ -528,16 +490,15 @@ msgstr "" #: editor/animation_track_editor.cpp msgid "Warning: Editing imported animation" -msgstr "" +msgstr "คำเตืà¸à¸™: à¸à¸³à¸¥à¸±à¸‡à¹à¸à¹‰à¹„ขà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¸—ี่นำเข้ามา" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Select an AnimationPlayer node to create and edit animations." -msgstr "เลืà¸à¸ AnimationPlayer จาà¸à¸œà¸±à¸‡à¸‰à¸²à¸à¹€à¸žà¸·à¹ˆà¸à¹à¸à¹‰à¹„ขà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" +msgstr "เลืà¸à¸à¹‚หนด AnimationPlayer เพื่à¸à¸ªà¸£à¹‰à¸²à¸‡à¹à¸¥à¸°à¹à¸à¹‰à¹„ขà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." -msgstr "" +msgstr "โชว์à¹à¸—ร็à¸à¸ˆà¸²à¸à¹‚หนดที่เลืà¸à¸à¹ƒà¸™à¸œà¸±à¸‡à¹€à¸—่านั้น" #: editor/animation_track_editor.cpp msgid "Group tracks by node or display them as plain list." @@ -555,11 +516,11 @@ msgstr "ผังà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¸–ูà¸à¸•้à¸à¸‡" #: editor/animation_track_editor.cpp msgid "Seconds" -msgstr "" +msgstr "วินาที" #: editor/animation_track_editor.cpp msgid "FPS" -msgstr "เฟรมต่à¸à¸§à¸´à¸™à¸²à¸—ี" +msgstr "เฟรมเรท" #: editor/animation_track_editor.cpp editor/editor_properties.cpp #: editor/plugins/polygon_2d_editor_plugin.cpp @@ -572,14 +533,12 @@ msgid "Edit" msgstr "à¹à¸à¹‰à¹„ข" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Animation properties." -msgstr "ผังà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" +msgstr "คุณสมบัติà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Copy Tracks" -msgstr "คัดลà¸à¸à¸•ัวà¹à¸›à¸£" +msgstr "คัดลà¸à¸à¹à¸—ร็à¸" #: editor/animation_track_editor.cpp msgid "Scale Selection" @@ -598,19 +557,16 @@ msgid "Duplicate Transposed" msgstr "ทำซ้ำเปลี่ยนà¹à¸—ร็à¸" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Delete Selection" -msgstr "ลบสิ่งที่เลืà¸à¸" +msgstr "ลบที่เลืà¸à¸" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Go to Next Step" -msgstr "ถัดไป" +msgstr "ไปยังขั้นถัดไป" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Go to Previous Step" -msgstr "à¸à¹ˆà¸à¸™à¸«à¸™à¹‰à¸²" +msgstr "ไปยังขั้นà¸à¹ˆà¸à¸™à¸«à¸™à¹‰à¸²" #: editor/animation_track_editor.cpp msgid "Optimize Animation" @@ -622,11 +578,11 @@ msgstr "เà¸à¹‡à¸šà¸à¸§à¸²à¸”à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" #: editor/animation_track_editor.cpp msgid "Pick the node that will be animated:" -msgstr "" +msgstr "เลืà¸à¸à¹‚หนดที่จะให้เคลื่à¸à¸™à¹„หว:" #: editor/animation_track_editor.cpp msgid "Use Bezier Curves" -msgstr "" +msgstr "ใช้เส้นโค้งเบซิเยร์" #: editor/animation_track_editor.cpp msgid "Anim. Optimizer" @@ -673,9 +629,8 @@ msgid "Scale Ratio:" msgstr "à¸à¸±à¸•ราส่วนเวลา:" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Select Tracks to Copy" -msgstr "เลืà¸à¸à¸„ุณสมบัติ" +msgstr "เลืà¸à¸à¹à¸—ร็à¸à¸—ี่จะคัดลà¸à¸" #: editor/animation_track_editor.cpp editor/editor_log.cpp #: editor/editor_properties.cpp @@ -687,22 +642,20 @@ msgid "Copy" msgstr "คัดลà¸à¸" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Select All/None" -msgstr "ไม่เลืà¸à¸" +msgstr "เลืà¸à¸à¸—ั้งหมด/ไม่เลืà¸à¸" #: editor/animation_track_editor_plugins.cpp -#, fuzzy msgid "Add Audio Track Clip" -msgstr "ตัวรับเสียง" +msgstr "เพิ่มคลิปà¹à¸—ร็à¸à¹€à¸ªà¸µà¸¢à¸‡" #: editor/animation_track_editor_plugins.cpp msgid "Change Audio Track Clip Start Offset" -msgstr "" +msgstr "เปลี่ยนà¸à¸à¸Ÿà¹€à¸‹à¹‡à¸•เริ่มต้นขà¸à¸‡à¸„ลิปà¹à¸—ร็à¸à¹€à¸ªà¸µà¸¢à¸‡" #: editor/animation_track_editor_plugins.cpp msgid "Change Audio Track Clip End Offset" -msgstr "" +msgstr "เปลี่ยนà¸à¸à¸Ÿà¹€à¸‹à¹‡à¸•ตà¸à¸™à¸ˆà¸šà¸‚à¸à¸‡à¸„ลิปà¹à¸—ร็à¸à¹€à¸ªà¸µà¸¢à¸‡" #: editor/array_property_edit.cpp msgid "Resize Array" @@ -725,18 +678,16 @@ msgid "Line Number:" msgstr "บรรทัดที่:" #: editor/code_editor.cpp -#, fuzzy msgid "%d replaced." -msgstr "à¹à¸—นที่..." +msgstr "à¹à¸—นที่ %d" #: editor/code_editor.cpp editor/editor_help.cpp msgid "%d match." -msgstr "" +msgstr "จับคู่ %d" #: editor/code_editor.cpp editor/editor_help.cpp -#, fuzzy msgid "%d matches." -msgstr "ไม่พบ" +msgstr "%d ตรงà¸à¸±à¸™" #: editor/code_editor.cpp editor/find_in_files.cpp msgid "Match Case" @@ -761,7 +712,7 @@ msgstr "เฉพาะที่à¸à¸³à¸¥à¸±à¸‡à¹€à¸¥à¸·à¸à¸" #: editor/code_editor.cpp editor/plugins/script_text_editor.cpp #: editor/plugins/text_editor.cpp msgid "Standard" -msgstr "" +msgstr "มาตรà¸à¸²à¸™" #: editor/code_editor.cpp editor/plugins/script_editor_plugin.cpp msgid "Toggle Scripts Panel" @@ -789,39 +740,33 @@ msgstr "คำเตืà¸à¸™" #: editor/code_editor.cpp msgid "Line and column numbers." -msgstr "" +msgstr "เลขบรรทัดà¹à¸¥à¸°à¸„à¸à¸¥à¸±à¸¡à¸™à¹Œ" #: editor/connections_dialog.cpp -#, fuzzy msgid "Method in target node must be specified." -msgstr "ต้à¸à¸‡à¸£à¸°à¸šà¸¸à¹€à¸¡à¸—็à¸à¸”ในโหนดปลายทาง!" +msgstr "ต้à¸à¸‡à¸£à¸°à¸šà¸¸à¹€à¸¡à¸˜à¸à¸”ในโหนดเป้าหมาย" #: editor/connections_dialog.cpp -#, fuzzy msgid "" "Target method not found. Specify a valid method or attach a script to the " "target node." -msgstr "ไม่พบเมท็à¸à¸”ปลายทาง! ระบุเมท็à¸à¸”ให้ถูà¸à¸•้à¸à¸‡à¸«à¸£à¸·à¸à¹€à¸žà¸´à¹ˆà¸¡à¸ªà¸„ริปต์ในโหนดปลายทาง" +msgstr "ไม่พบโหนดเป้าหมาย ระบุเมธà¸à¸”ที่ถูà¸à¸•้à¸à¸‡à¸«à¸£à¸·à¸à¹€à¸žà¸´à¹ˆà¸¡à¸ªà¸„ริปต์ในโหนดเป้าหมาย" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Node:" -msgstr "เชื่à¸à¸¡à¹„ปยังโหนด:" +msgstr "เชื่à¸à¸¡à¸•่à¸à¸à¸±à¸šà¹‚หนด:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Script:" -msgstr "ไม่สามารถเชื่à¸à¸¡à¸•่à¸à¸à¸±à¸šà¹‚ฮสต์:" +msgstr "เชื่à¸à¸¡à¸•่à¸à¸ªà¸„ริปต์:" #: editor/connections_dialog.cpp -#, fuzzy msgid "From Signal:" -msgstr "สัà¸à¸à¸²à¸“:" +msgstr "จาà¸à¸ªà¸±à¸à¸à¸²à¸“:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Scene does not contain any script." -msgstr "โหนดไม่มี geometry" +msgstr "ไม่มีสคริปต์ในฉาà¸" #: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp #: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp @@ -849,14 +794,12 @@ msgid "Extra Call Arguments:" msgstr "ตัวà¹à¸›à¸£à¹€à¸žà¸´à¹ˆà¸¡à¹€à¸•ิม:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Receiver Method:" -msgstr "เลืà¸à¸à¹€à¸¡à¸—็à¸à¸”" +msgstr "ตัวรับเมธà¸à¸”:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Advanced" -msgstr "ตัวเลืà¸à¸à¸à¸²à¸£à¸ˆà¸³à¸à¸±à¸”" +msgstr "ขั้นสูง" #: editor/connections_dialog.cpp msgid "Deferred" @@ -876,9 +819,8 @@ msgid "Disconnects the signal after its first emission." msgstr "" #: editor/connections_dialog.cpp -#, fuzzy msgid "Cannot connect signal" -msgstr "เชื่à¸à¸¡à¹‚ยงสัà¸à¸à¸²à¸“:" +msgstr "ไม่สามารถเชื่à¸à¸¡à¸•่à¸à¸ªà¸±à¸à¸à¸²à¸“" #: editor/connections_dialog.cpp editor/dependency_editor.cpp #: editor/export_template_manager.cpp editor/groups_editor.cpp @@ -900,7 +842,6 @@ msgid "Connect" msgstr "เชื่à¸à¸¡" #: editor/connections_dialog.cpp -#, fuzzy msgid "Signal:" msgstr "สัà¸à¸à¸²à¸“:" @@ -910,12 +851,11 @@ msgstr "เชื่à¸à¸¡ '%s' à¸à¸±à¸š '%s'" #: editor/connections_dialog.cpp msgid "Disconnect '%s' from '%s'" -msgstr "ลบà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸à¸¡à¹‚ยง '%s' à¸à¸±à¸š '%s'" +msgstr "ตัดà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸à¸¡à¸•่ภ'%s' à¸à¸±à¸š '%s'" #: editor/connections_dialog.cpp -#, fuzzy msgid "Disconnect all from signal: '%s'" -msgstr "ลบà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸à¸¡à¹‚ยง '%s' à¸à¸±à¸š '%s'" +msgstr "ตัดà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸à¸¡à¸•่à¸à¸—ั้งหมดจาà¸à¸ªà¸±à¸à¸à¸²à¸“: '%s'" #: editor/connections_dialog.cpp msgid "Connect..." @@ -927,19 +867,16 @@ msgid "Disconnect" msgstr "ลบà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸à¸¡à¹‚ยง" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect a Signal to a Method" -msgstr "เชื่à¸à¸¡à¹‚ยงสัà¸à¸à¸²à¸“:" +msgstr "เชื่à¸à¸¡à¸•่à¸à¸ªà¸±à¸à¸à¸²à¸“ไปยังเมธà¸à¸”" #: editor/connections_dialog.cpp -#, fuzzy msgid "Edit Connection:" -msgstr "à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸à¸¡à¹‚ยง" +msgstr "à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸à¸¡à¸•่à¸:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Are you sure you want to remove all connections from the \"%s\" signal?" -msgstr "ยืนยันà¸à¸²à¸£à¸£à¸±à¸™à¹‚ปรเจà¸à¸•์มาà¸à¸à¸§à¹ˆà¸² 1 โปรเจà¸à¸•์?" +msgstr "ยืนยันà¸à¸²à¸£à¸¥à¸šà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸à¸¡à¸•่à¸à¸ªà¸±à¸à¸à¸²à¸“จาภ\"%s\"?" #: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp msgid "Signals" @@ -950,19 +887,16 @@ msgid "Are you sure you want to remove all connections from this signal?" msgstr "" #: editor/connections_dialog.cpp -#, fuzzy msgid "Disconnect All" -msgstr "ลบà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸à¸¡à¹‚ยง" +msgstr "ตัดà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸à¸¡à¸•่à¸à¸—ั้งหมด" #: editor/connections_dialog.cpp -#, fuzzy msgid "Edit..." -msgstr "à¹à¸à¹‰à¹„ข" +msgstr "à¹à¸à¹‰à¹„ข..." #: editor/connections_dialog.cpp -#, fuzzy msgid "Go To Method" -msgstr "รายชื่à¸à¹€à¸¡à¸—็à¸à¸”" +msgstr "ไปยังเมธà¸à¸”" #: editor/create_dialog.cpp msgid "Change %s Type" @@ -1014,7 +948,6 @@ msgid "Dependencies For:" msgstr "à¸à¸²à¸£à¸à¹‰à¸²à¸‡à¸à¸´à¸‡à¸‚à¸à¸‡:" #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Scene '%s' is currently being edited.\n" "Changes will only take effect when reloaded." @@ -1023,12 +956,11 @@ msgstr "" "à¸à¸²à¸£à¹à¸à¹‰à¹„ขจะไม่ส่งผลจนà¸à¸§à¹ˆà¸²à¸ˆà¸°à¹‚หลดใหม่" #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Resource '%s' is in use.\n" "Changes will only take effect when reloaded." msgstr "" -"รีซà¸à¸£à¹Œà¸ª '%s' à¸à¸³à¸¥à¸±à¸‡à¸–ูà¸à¹ƒà¸Šà¹‰à¸‡à¸²à¸™\n" +"ทรัพยาà¸à¸£ '%s' à¸à¸³à¸¥à¸±à¸‡à¸–ูà¸à¹ƒà¸Šà¹‰à¸‡à¸²à¸™\n" "à¸à¸²à¸£à¹à¸à¹‰à¹„ขจะไม่ส่งผลจนà¸à¸§à¹ˆà¸²à¸ˆà¸°à¹‚หลดใหม่" #: editor/dependency_editor.cpp @@ -1038,12 +970,12 @@ msgstr "à¸à¸²à¸£à¸à¹‰à¸²à¸‡à¸à¸´à¸‡" #: editor/dependency_editor.cpp msgid "Resource" -msgstr "รีซà¸à¸£à¹Œà¸ª" +msgstr "ทรัพยาà¸à¸£" #: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp #: editor/project_manager.cpp editor/project_settings_editor.cpp msgid "Path" -msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡" +msgstr "เส้นทาง" #: editor/dependency_editor.cpp msgid "Dependencies:" @@ -1059,7 +991,7 @@ msgstr "à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¸à¹‰à¸²à¸‡à¸à¸´à¸‡" #: editor/dependency_editor.cpp msgid "Search Replacement Resource:" -msgstr "ค้นหารีซà¸à¸£à¹Œà¸ªà¸¡à¸²à¹à¸—นที่:" +msgstr "ค้นหาทรัพยาà¸à¸£à¸¡à¸²à¹à¸—นที่:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp @@ -1076,9 +1008,8 @@ msgid "Owners Of:" msgstr "เจ้าขà¸à¸‡à¸‚à¸à¸‡:" #: editor/dependency_editor.cpp -#, fuzzy msgid "Remove selected files from the project? (Can't be restored)" -msgstr "ลบไฟล์ที่เลืà¸à¸à¸à¸à¸à¸ˆà¸²à¸à¹‚ปรเจà¸à¸•์? (ย้à¸à¸™à¸à¸¥à¸±à¸šà¹„ม่ได้)" +msgstr "ลบไฟล์ที่เลืà¸à¸à¸à¸à¸à¸ˆà¸²à¸à¹‚ปรเจà¸à¸•์? (à¸à¸¹à¹‰à¸„ืนไม่ได้)" #: editor/dependency_editor.cpp msgid "" @@ -1086,8 +1017,8 @@ msgid "" "work.\n" "Remove them anyway? (no undo)" msgstr "" -"มีรีซà¸à¸£à¹Œà¸ªà¸à¸·à¹ˆà¸™à¸•้à¸à¸‡à¸à¸²à¸£à¹„ฟล์ที่à¸à¸³à¸¥à¸±à¸‡à¸¥à¸š\n" -"ยืนยันจะลบหรืà¸à¹„ม่? (ย้à¸à¸™à¸à¸¥à¸±à¸šà¹„ม่ได้)" +"ไฟล์ที่à¸à¸³à¸¥à¸±à¸‡à¸ˆà¸°à¸¥à¸š จำเป็นสำหรับใช้งานโดยทรัพยาà¸à¸£à¸à¸±à¸™à¸à¸·à¹ˆà¸™\n" +"จะทำà¸à¸²à¸£à¸¥à¸šà¸«à¸£à¸·à¸à¹„ม่? (คืนà¸à¸¥à¸±à¸šà¹„ม่ได้)" #: editor/dependency_editor.cpp msgid "Cannot remove:" @@ -1098,9 +1029,8 @@ msgid "Error loading:" msgstr "ผิดพลาดขณะโหลด:" #: editor/dependency_editor.cpp -#, fuzzy msgid "Load failed due to missing dependencies:" -msgstr "โหลดฉาà¸à¹„ม่ได้เนื่à¸à¸‡à¸ˆà¸²à¸à¸à¸²à¸£à¸à¹‰à¸²à¸‡à¸à¸´à¸‡à¸ªà¸¹à¸à¸«à¸²à¸¢:" +msgstr "โหลดผิดพลาดเนื่à¸à¸‡à¸ˆà¸²à¸à¸à¸²à¸£à¸à¹‰à¸²à¸‡à¸à¸´à¸‡à¸ªà¸¹à¸à¸«à¸²à¸¢:" #: editor/dependency_editor.cpp editor/editor_node.cpp msgid "Open Anyway" @@ -1120,16 +1050,15 @@ msgstr "ผิดพลาดขณะโหลด!" #: editor/dependency_editor.cpp msgid "Permanently delete %d item(s)? (No undo!)" -msgstr "ลบ %d ไฟล์ถาวร? (ย้à¸à¸™à¸à¸¥à¸±à¸šà¹„ม่ได้!)" +msgstr "ลบไà¸à¹€à¸—ม %d ถาวรหรืà¸à¹„ม่? (ย้à¸à¸™à¸à¸¥à¸±à¸šà¹„ม่ได้!)" #: editor/dependency_editor.cpp -#, fuzzy msgid "Show Dependencies" -msgstr "à¸à¸²à¸£à¸à¹‰à¸²à¸‡à¸à¸´à¸‡" +msgstr "à¹à¸ªà¸”งà¸à¸²à¸£à¸à¹‰à¸²à¸‡à¸à¸´à¸‡" #: editor/dependency_editor.cpp msgid "Orphan Resource Explorer" -msgstr "ตัวจัดà¸à¸²à¸£à¸£à¸µà¸‹à¸à¸£à¹Œà¸ªà¸—ี่ไม่มีเจ้าขà¸à¸‡" +msgstr "ทรัพยาà¸à¸£à¸—ี่ไม่ได้ใช้" #: editor/dependency_editor.cpp editor/editor_audio_buses.cpp #: editor/editor_file_dialog.cpp editor/editor_node.cpp @@ -1216,12 +1145,10 @@ msgid "License" msgstr "สัà¸à¸à¸²à¸à¸™à¸¸à¸à¸²à¸•" #: editor/editor_about.cpp -#, fuzzy msgid "Third-party Licenses" -msgstr "สัà¸à¸à¸²à¸à¸™à¸¸à¸à¸²à¸•ไลบรารี" +msgstr "สัà¸à¸à¸²à¸à¸™à¸¸à¸à¸²à¸•จาà¸à¸šà¸¸à¸„คลที่สาม" #: editor/editor_about.cpp -#, fuzzy msgid "" "Godot Engine relies on a number of third-party free and open source " "libraries, all compatible with the terms of its MIT license. The following " @@ -1229,8 +1156,8 @@ msgid "" "respective copyright statements and license terms." msgstr "" "Godot Engine à¸à¸²à¸¨à¸±à¸¢à¹„ลบรารีต่าง ๆ ที่นำมาใช้ได้à¸à¸¢à¹ˆà¸²à¸‡à¹€à¸ªà¸£à¸µà¹à¸¥à¸°à¹€à¸›à¸´à¸”เผยโค้ดเป็นจำนวนมาภ" -"ซึ่งเข้าà¸à¸±à¸™à¹„ด้à¸à¸±à¸šà¸ªà¸±à¸à¸à¸²à¸à¸™à¸¸à¸à¸²à¸• MIT ต่à¸à¹„ปนี้เป็นรายชื่à¸à¸‚à¸à¸‡à¹„ลบรารีทั้งหมด รวมถึงข้à¸à¸„วามลิขสิทธิ์ " -"à¹à¸¥à¸°à¸‚้à¸à¸à¸³à¸«à¸™à¸”à¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™à¸‚à¸à¸‡à¹à¸•่ละไลบรารี" +"ซึ่งเข้าà¸à¸±à¸™à¹„ด้à¸à¸±à¸šà¸ªà¸±à¸à¸à¸²à¸à¸™à¸¸à¸à¸²à¸• MIT ต่à¸à¹„ปนี้เป็นรายชื่à¸à¸‚à¸à¸‡à¹„ลบรารีทั้งหมดขà¸à¸‡à¸šà¸¸à¸„คลที่สาม " +"รวมถึงข้à¸à¸„วามลิขสิทธิ์ à¹à¸¥à¸°à¸‚้à¸à¸à¸³à¸«à¸™à¸”à¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™à¸‚à¸à¸‡à¹à¸•่ละไลบรารี" #: editor/editor_about.cpp msgid "All Components" @@ -1245,14 +1172,12 @@ msgid "Licenses" msgstr "สัà¸à¸à¸²à¸à¸™à¸¸à¸à¸²à¸•" #: editor/editor_asset_installer.cpp editor/project_manager.cpp -#, fuzzy msgid "Error opening package file, not in ZIP format." msgstr "ผิดพลาดขณะเปิดไฟล์à¹à¸žà¸„เà¸à¸ˆ, ไม่ใช่รูปà¹à¸šà¸š zip" #: editor/editor_asset_installer.cpp -#, fuzzy msgid "%s (Already Exists)" -msgstr "มีà¸à¸¢à¸¹à¹ˆà¸à¹ˆà¸à¸™à¹à¸¥à¹‰à¸§" +msgstr "%s (มีà¸à¸¢à¸¹à¹ˆà¸à¹ˆà¸à¸™à¹à¸¥à¹‰à¸§)" #: editor/editor_asset_installer.cpp msgid "Uncompressing Assets" @@ -1263,12 +1188,10 @@ msgid "The following files failed extraction from package:" msgstr "ผิดพลาดขณะà¹à¸¢à¸à¹„ฟล์ต่à¸à¹„ปนี้จาà¸à¹à¸žà¸„เà¸à¸ˆ:" #: editor/editor_asset_installer.cpp -#, fuzzy msgid "And %s more files." msgstr "à¹à¸¥à¸°à¸à¸µà¸ %d ไฟล์" #: editor/editor_asset_installer.cpp editor/project_manager.cpp -#, fuzzy msgid "Package installed successfully!" msgstr "ติดตั้งà¹à¸žà¸„เà¸à¸ˆà¹€à¸ªà¸£à¹‡à¸ˆà¸ªà¸¡à¸šà¸¹à¸£à¸“์!" @@ -1278,9 +1201,8 @@ msgid "Success!" msgstr "สำเร็จ!" #: editor/editor_asset_installer.cpp -#, fuzzy msgid "Package Contents:" -msgstr "ประà¸à¸à¸šà¸”้วย:" +msgstr "เนื้à¸à¸«à¸²à¹à¸žà¸„เà¸à¸ˆ:" #: editor/editor_asset_installer.cpp editor/editor_node.cpp msgid "Install" @@ -1296,7 +1218,7 @@ msgstr "ลำโพง" #: editor/editor_audio_buses.cpp msgid "Add Effect" -msgstr "เà¸à¸Ÿà¹€à¸Ÿà¸à¸•์" +msgstr "เพิ่มเà¸à¸Ÿà¹€à¸Ÿà¸à¸•์" #: editor/editor_audio_buses.cpp msgid "Rename Audio Bus" @@ -1324,20 +1246,19 @@ msgstr "เลืà¸à¸ Audio Bus ที่ส่งต่à¸" #: editor/editor_audio_buses.cpp msgid "Add Audio Bus Effect" -msgstr "เพิ่มเà¸à¸Ÿà¹€à¸Ÿà¸à¸•์เสียง" +msgstr "เพิ่มเà¸à¸Ÿà¹€à¸Ÿà¸à¸•์บัสเสียง" #: editor/editor_audio_buses.cpp msgid "Move Bus Effect" -msgstr "ย้ายเà¸à¸Ÿà¹€à¸Ÿà¸à¸•์เสียง" +msgstr "ย้ายเà¸à¸Ÿà¹€à¸Ÿà¸à¸•์บัสเสียง" #: editor/editor_audio_buses.cpp msgid "Delete Bus Effect" -msgstr "ลบเà¸à¸Ÿà¹€à¸Ÿà¸à¸•์เสียง" +msgstr "ลบเà¸à¸Ÿà¹€à¸Ÿà¸à¸•์บัสเสียง" #: editor/editor_audio_buses.cpp -#, fuzzy msgid "Drag & drop to rearrange." -msgstr "Audio Bus ลาà¸à¹à¸¥à¸°à¸§à¸²à¸‡à¹€à¸žà¸·à¹ˆà¸à¸¢à¹‰à¸²à¸¢à¸•ำà¹à¸«à¸™à¹ˆà¸‡" +msgstr "ลาà¸à¹à¸¥à¸°à¸§à¸²à¸‡à¹€à¸žà¸·à¹ˆà¸à¸ˆà¸±à¸”เรียง" #: editor/editor_audio_buses.cpp msgid "Solo" @@ -1378,15 +1299,15 @@ msgstr "เพิ่ม Audio Bus" #: editor/editor_audio_buses.cpp msgid "Master bus can't be deleted!" -msgstr "ลบ Bus หลัà¸à¹„ม่ได้!" +msgstr "ลบบัสหลัà¸à¹„ม่ได้!" #: editor/editor_audio_buses.cpp msgid "Delete Audio Bus" -msgstr "ลบ Audio Bus" +msgstr "ลบบัสเสียง" #: editor/editor_audio_buses.cpp msgid "Duplicate Audio Bus" -msgstr "ทำซ้ำ Audio Bus" +msgstr "ทำซ้ำบัสเสียง" #: editor/editor_audio_buses.cpp msgid "Reset Bus Volume" @@ -1394,11 +1315,11 @@ msgstr "รีเซ็ตระดับเสียงบัส" #: editor/editor_audio_buses.cpp msgid "Move Audio Bus" -msgstr "ย้าย Audio Bus" +msgstr "ย้ายบัสเสียง" #: editor/editor_audio_buses.cpp msgid "Save Audio Bus Layout As..." -msgstr "บันทึà¸à¹€à¸¥à¸¢à¹Œà¹€à¸à¸²à¸•์ขà¸à¸‡ Audio Bus เป็น..." +msgstr "บันทึà¸à¹€à¸¥à¸¢à¹Œà¹€à¸à¸²à¸•์ขà¸à¸‡à¸šà¸±à¸ªà¹€à¸ªà¸µà¸¢à¸‡à¹€à¸›à¹‡à¸™..." #: editor/editor_audio_buses.cpp msgid "Location for New Layout..." @@ -1406,11 +1327,11 @@ msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡à¸‚à¸à¸‡à¹€à¸¥à¸¢à¹Œà¹€à¸à¸²à¸•์ใหม่... #: editor/editor_audio_buses.cpp msgid "Open Audio Bus Layout" -msgstr "เปิดเลย์เà¸à¸²à¸•์ขà¸à¸‡ Audio Bus" +msgstr "เปิดเลย์เà¸à¸²à¸•์ขà¸à¸‡à¸šà¸±à¸ªà¹€à¸ªà¸µà¸¢à¸‡" #: editor/editor_audio_buses.cpp msgid "There is no '%s' file." -msgstr "" +msgstr "ไม่มีไฟล์ '%s'" #: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp msgid "Layout" @@ -1421,18 +1342,16 @@ msgid "Invalid file, not an audio bus layout." msgstr "ไฟล์ไม่ถูà¸à¸•้à¸à¸‡ ไม่ใช่เลย์เà¸à¸²à¸•์ขà¸à¸‡ Audio Bus" #: editor/editor_audio_buses.cpp -#, fuzzy msgid "Error saving file: %s" -msgstr "ผิดพลาดขณะบันทึภTileSet!" +msgstr "ผิดพลาดขณะบันทึà¸à¹„ฟล์: %s" #: editor/editor_audio_buses.cpp msgid "Add Bus" -msgstr "เพิ่ม Bus" +msgstr "เพิ่มบัส" #: editor/editor_audio_buses.cpp -#, fuzzy msgid "Add a new Audio Bus to this layout." -msgstr "บันทึà¸à¹€à¸¥à¸¢à¹Œà¹€à¸à¸²à¸•์ขà¸à¸‡ Audio Bus เป็น..." +msgstr "เพิ่มบัสเสียงไปยังเลย์เà¸à¸²à¸•์นี้" #: editor/editor_audio_buses.cpp editor/editor_properties.cpp #: editor/plugins/animation_player_editor_plugin.cpp editor/property_editor.cpp @@ -1442,7 +1361,7 @@ msgstr "โหลด" #: editor/editor_audio_buses.cpp msgid "Load an existing Bus Layout." -msgstr "โหลดเลย์เà¸à¸²à¸•์ Bus จาà¸à¸”ิสà¸à¹Œ" +msgstr "โหลดเลย์เà¸à¸²à¸•์บัสจาà¸à¸”ิสà¸à¹Œ" #: editor/editor_audio_buses.cpp msgid "Save As" @@ -1450,7 +1369,7 @@ msgstr "บันทึà¸à¹€à¸›à¹‡à¸™" #: editor/editor_audio_buses.cpp msgid "Save this Bus Layout to a file." -msgstr "บันทึà¸à¹€à¸¥à¸¢à¹Œà¹€à¸à¸²à¸•์ขà¸à¸‡ Bus นี้เป็นไฟล์" +msgstr "บันทึà¸à¹€à¸¥à¸¢à¹Œà¹€à¸à¸²à¸•์ขà¸à¸‡à¸šà¸±à¸ªà¸™à¸µà¹‰à¹€à¸›à¹‡à¸™à¹„ฟล์" #: editor/editor_audio_buses.cpp editor/import_dock.cpp msgid "Load Default" @@ -1458,11 +1377,11 @@ msgstr "โหลดค่าเริ่มต้น" #: editor/editor_audio_buses.cpp msgid "Load the default Bus Layout." -msgstr "โหลดค่าเริ่มต้นเลย์เà¸à¸²à¸•์ Bus" +msgstr "โหลดค่าเริ่มต้นเลย์เà¸à¸²à¸•์บัส" #: editor/editor_audio_buses.cpp msgid "Create a new Bus Layout." -msgstr "สร้างเลย์เà¸à¸²à¸•์ Bus ใหม่" +msgstr "สร้างเลย์เà¸à¸²à¸•์บัสใหม่" #: editor/editor_autoload_settings.cpp msgid "Invalid name." @@ -1473,19 +1392,16 @@ msgid "Valid characters:" msgstr "ตัวà¸à¸±à¸à¸©à¸£à¸—ี่ใช้ได้:" #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing engine class name." -msgstr "ชื่à¸à¸œà¸´à¸”พลาด ต้à¸à¸‡à¹„ม่ใช้ชื่à¸à¹€à¸”ียวà¸à¸±à¸šà¸„ลาสขà¸à¸‡à¹‚ปรà¹à¸à¸£à¸¡" +msgstr "ต้à¸à¸‡à¹„ม่ใช้ชื่à¸à¹€à¸”ียวà¸à¸±à¸šà¸Šà¸·à¹ˆà¸à¸„ลาสขà¸à¸‡à¹‚ปรà¹à¸à¸£à¸¡" #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing built-in type name." -msgstr "ชื่à¸à¸œà¸´à¸”พลาด ต้à¸à¸‡à¹„ม่ใช้ชื่à¸à¹€à¸”ียวà¸à¸±à¸šà¸Šà¸™à¸´à¸”ตัวà¹à¸›à¸£" +msgstr "ต้à¸à¸‡à¹„ม่ใช้ชื่à¸à¹€à¸”ียวà¸à¸±à¸šà¸Šà¸·à¹ˆà¸à¸Šà¸™à¸´à¸”บิวท์à¸à¸´à¸™à¸—ี่มีà¸à¸¢à¸¹à¹ˆà¹à¸¥à¹‰à¸§" #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing global constant name." -msgstr "ชื่à¸à¸œà¸´à¸”พลาด ต้à¸à¸‡à¹„ม่ใช้ชื่à¸à¹€à¸”ียวà¸à¸±à¸šà¸„่าคงที่" +msgstr "ต้à¸à¸‡à¹„ม่ใช้ชื่à¸à¹€à¸”ียวà¸à¸±à¸šà¸Šà¸·à¹ˆà¸à¸„่าคงที่โà¸à¸¥à¸šà¸à¸¥" #: editor/editor_autoload_settings.cpp msgid "Keyword cannot be used as an autoload name." @@ -1511,7 +1427,7 @@ msgstr "เลื่à¸à¸™à¸à¸à¹‚ต้โหลด" msgid "Remove Autoload" msgstr "ลบà¸à¸à¹‚ต้โหลด" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "เปิด" @@ -1520,7 +1436,6 @@ msgid "Rearrange Autoloads" msgstr "จัดลำดับà¸à¸à¹‚ต้โหลด" #: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid path." msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡à¸œà¸´à¸”พลาด" @@ -1582,7 +1497,6 @@ msgid "[unsaved]" msgstr "[ไฟล์ใหม่]" #: editor/editor_dir_dialog.cpp -#, fuzzy msgid "Please select a base directory first." msgstr "à¸à¸£à¸¸à¸“าเลืà¸à¸à¹‚ฟลเดà¸à¸£à¹Œà¹€à¸£à¸´à¹ˆà¸¡à¸•้นà¸à¹ˆà¸à¸™" @@ -1617,11 +1531,8 @@ msgid "Storing File:" msgstr "เà¸à¹‡à¸šà¹„ฟล์:" #: editor/editor_export.cpp -#, fuzzy msgid "No export template found at the expected path:" -msgstr "" -"ไม่มีà¹à¸¡à¹ˆà¹à¸šà¸šà¸ªà¸³à¸«à¸£à¸±à¸šà¸ªà¹ˆà¸‡à¸à¸à¸\n" -"ดาวน์โหลดà¹à¸¥à¸°à¸•ิดตั้งà¹à¸¡à¹ˆà¹à¸šà¸š" +msgstr "ไม่พบà¹à¸¡à¹ˆà¹à¸šà¸šà¸ªà¹ˆà¸‡à¸à¸à¸à¸—ี่ที่à¸à¸¢à¸¹à¹ˆà¸—ี่คาดไว้:" #: editor/editor_export.cpp msgid "Packing" @@ -1632,12 +1543,16 @@ msgid "" "Target platform requires 'ETC' texture compression for GLES2. Enable 'Import " "Etc' in Project Settings." msgstr "" +"à¹à¸žà¸¥à¸•ฟà¸à¸£à¹Œà¸¡à¹€à¸›à¹‰à¸²à¸«à¸¡à¸²à¸¢à¸•้à¸à¸‡à¸à¸²à¸£à¸à¸²à¸£à¸šà¸µà¸šà¸à¸±à¸”เทà¸à¹€à¸ˆà¸à¸£à¹Œ 'ETC' สำหรับ GLES2 เปิด 'Import Etc' " +"ในตั้งค่าโปรเจ็ค" #: editor/editor_export.cpp msgid "" "Target platform requires 'ETC2' texture compression for GLES3. Enable " "'Import Etc 2' in Project Settings." msgstr "" +"à¹à¸žà¸¥à¸•ฟà¸à¸£à¹Œà¸¡à¹€à¸›à¹‰à¸²à¸«à¸¡à¸²à¸¢à¸•้à¸à¸‡à¸à¸²à¸£à¸à¸²à¸£à¸šà¸µà¸šà¸à¸±à¸”เทà¸à¹€à¸ˆà¸à¸£à¹Œ 'ETC2' สำหรับ GLES3 เปิด 'Import Etc 2' " +"ในตั้งค่าโปรเจ็ค" #: editor/editor_export.cpp msgid "" @@ -1646,13 +1561,14 @@ msgid "" "Enable 'Import Etc' in Project Settings, or disable 'Driver Fallback " "Enabled'." msgstr "" +"à¹à¸žà¸¥à¸•ฟà¸à¸£à¹Œà¸¡à¹€à¸›à¹‰à¸²à¸«à¸¡à¸²à¸¢à¸•้à¸à¸‡à¸à¸²à¸£à¸à¸²à¸£à¸šà¸µà¸šà¸à¸±à¸”เทà¸à¹€à¸ˆà¸à¸£à¹Œ 'ETC' สำหรับà¸à¸²à¸£à¸à¸¥à¸±à¸šà¸¡à¸²à¹ƒà¸Šà¹‰ GLES2\n" +"เปิด 'Import Etc' ในตั้งค่าโปรเจ็คหรืà¸à¸›à¸´à¸” 'Driver Fallback Enabled'" #: editor/editor_export.cpp platform/android/export/export.cpp #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp #: platform/osx/export/export.cpp platform/uwp/export/export.cpp -#, fuzzy msgid "Custom debug template not found." -msgstr "ไม่พบà¹à¸žà¸„เà¸à¸ˆà¸”ีบัคที่à¸à¸³à¸«à¸™à¸”" +msgstr "ไม่พบà¹à¸¡à¹ˆà¹à¸šà¸šà¸à¸²à¸£à¸”ีบัà¸à¹à¸šà¸šà¸à¸³à¸«à¸™à¸”เà¸à¸‡" #: editor/editor_export.cpp platform/android/export/export.cpp #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp @@ -1663,31 +1579,27 @@ msgstr "ไม่พบà¹à¸žà¸„เà¸à¸ˆà¸ˆà¸³à¸«à¸™à¹ˆà¸²à¸¢à¸—ี่à¸à¸³à¸« #: editor/editor_export.cpp platform/javascript/export/export.cpp msgid "Template file not found:" -msgstr "ไม่พบà¹à¸¡à¹ˆà¹à¸šà¸š:" +msgstr "ไม่พบไฟล์à¹à¸¡à¹ˆà¹à¸šà¸š:" #: editor/editor_export.cpp msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." -msgstr "" +msgstr "à¸à¸²à¸£à¸ªà¹ˆà¸‡à¸à¸à¸à¹à¸šà¸š 32 bit PCK à¹à¸šà¸šà¸à¸±à¸‡à¸•ัวไม่สามารถใหà¸à¹ˆà¹„ด้เà¸à¸´à¸™ 4 GiB" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "3D Editor" -msgstr "โปรà¹à¸à¸£à¸¡" +msgstr "เà¸à¸”ิเตà¸à¸£à¹Œ 3D" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Script Editor" -msgstr "เปิดตัวà¹à¸à¹‰à¹„ขสคริปต์" +msgstr "เà¸à¸”ิเตà¸à¸£à¹Œà¸ªà¸„ริปต์" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Asset Library" -msgstr "เปิดà¹à¸«à¸¥à¹ˆà¸‡à¸£à¸§à¸¡à¸—รัพยาà¸à¸£" +msgstr "ไลบรารีทรัพยาà¸à¸£" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Scene Tree Editing" -msgstr "ผังฉาภ(โหนด):" +msgstr "à¹à¸à¹‰à¹„ขผังฉาà¸" #: editor/editor_feature_profile.cpp #, fuzzy @@ -1705,92 +1617,80 @@ msgid "FileSystem and Import Docks" msgstr "ระบบไฟล์" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase profile '%s'? (no undo)" -msgstr "à¹à¸—นที่ทั้งหมด" +msgstr "ลบโปรไฟล์ '%s' หรืà¸à¹„ม่? (ทำà¸à¸¥à¸±à¸šà¹„ม่ได้)" #: editor/editor_feature_profile.cpp msgid "Profile must be a valid filename and must not contain '.'" -msgstr "" +msgstr "โปรไฟล์จะต้à¸à¸‡à¸¡à¸µà¸Šà¸·à¹ˆà¸à¹„ฟล์ที่ถูà¸à¸•้à¸à¸‡ à¹à¸¥à¸°à¸•้à¸à¸‡à¹„ม่มี '.'" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Profile with this name already exists." -msgstr "มีชื่à¸à¸à¸¥à¸¸à¹ˆà¸¡à¸™à¸µà¹‰à¸à¸¢à¸¹à¹ˆà¹à¸¥à¹‰à¸§" +msgstr "มีโปรไฟล์ที่มีชื่à¸à¸™à¸µà¹‰à¸à¸¢à¸¹à¹‹à¹à¸¥à¹‰à¸§" #: editor/editor_feature_profile.cpp msgid "(Editor Disabled, Properties Disabled)" -msgstr "" +msgstr "(เà¸à¸”ิเตà¸à¸£à¹Œà¸–ูà¸à¸›à¸´à¸”à¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™, คุณสมบัติถูà¸à¸›à¸´à¸”à¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Properties Disabled)" -msgstr "คุณสมบัติ" +msgstr "(ปิดà¸à¸²à¸£à¸—ำงานคุณสมบัติ)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Editor Disabled)" -msgstr "ปิดà¸à¸²à¸£à¸•ัด" +msgstr "(เà¸à¸”ิเตà¸à¸£à¹Œà¸–ูà¸à¸›à¸´à¸”à¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options:" -msgstr "รายละเà¸à¸µà¸¢à¸”:" +msgstr "ตั้งค่าคลาส:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enable Contextual Editor" -msgstr "เปิดตัวà¹à¸à¹‰à¹„ขถัดไป" +msgstr "เปิดà¸à¸²à¸£à¸—ำงานเà¸à¸”ิเตà¸à¸£à¹Œà¸•ามบริบท" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Properties:" -msgstr "คุณสมบัติ:" +msgstr "เปิดà¸à¸²à¸£à¸—ำงานคุณสมบัติ:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Features:" -msgstr "ฟีเจà¸à¸£à¹Œ" +msgstr "เปิดà¸à¸²à¸£à¸—ำงานฟีเจà¸à¸£à¹Œ:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Classes:" -msgstr "ค้นหาคลาส" +msgstr "เปิดà¸à¸²à¸£à¸—ำงานคลาส:" #: editor/editor_feature_profile.cpp msgid "File '%s' format is invalid, import aborted." -msgstr "" +msgstr "นามสà¸à¸¸à¸¥à¸‚à¸à¸‡à¹„ฟล์ '%s' ผิดพลาด ยà¸à¹€à¸¥à¸´à¸à¸à¸²à¸£à¸™à¸³à¹€à¸‚้า" #: editor/editor_feature_profile.cpp msgid "" "Profile '%s' already exists. Remove it first before importing, import " "aborted." -msgstr "" +msgstr "มีโปรไฟล์ '%s' à¸à¸¢à¸¹à¹ˆà¹à¸¥à¹‰à¸§ à¸à¸£à¸¸à¸“าลบà¸à¹ˆà¸à¸™à¸—ี่จะนำเข้า, à¸à¸²à¸£à¸™à¸³à¹€à¸‚้าถูà¸à¸¢à¸à¹€à¸¥à¸´à¸" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Error saving profile to path: '%s'." -msgstr "ผิดพลาดขณะโหลดà¹à¸¡à¹ˆà¹à¸šà¸š '%s'" +msgstr "ผิดพลาดขณะบันทึà¸à¹‚ปรไฟล์ไปยังà¹à¸žà¸—ช์: '%s'" #: editor/editor_feature_profile.cpp msgid "Unset" -msgstr "" +msgstr "ยà¸à¹€à¸¥à¸´à¸à¸à¸²à¸£à¸•ั้งค่า" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Current Profile:" -msgstr "รุ่นปัจจุบัน:" +msgstr "โปรไฟล์ปัจจุบัน:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Make Current" -msgstr "ปัจจุบัน:" +msgstr "ทำให้เป็นปัจจุบัน" #: editor/editor_feature_profile.cpp #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/version_control_editor_plugin.cpp msgid "New" -msgstr "ไฟล์ใหม่" +msgstr "ใหม่" #: editor/editor_feature_profile.cpp editor/editor_node.cpp #: editor/project_manager.cpp @@ -1802,44 +1702,36 @@ msgid "Export" msgstr "ส่งà¸à¸à¸" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Available Profiles:" -msgstr "โหนดที่มีให้ใช้:" +msgstr "โปรไฟล์ที่มีให้ใช้:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" -msgstr "รายละเà¸à¸µà¸¢à¸”" +msgstr "ตั้งค่าคลาส" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "New profile name:" -msgstr "ชื่à¸à¹ƒà¸«à¸¡à¹ˆ:" +msgstr "ชื่à¸à¹‚ปรไฟล์ใหม่:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase Profile" -msgstr "ลบพื้นที่" +msgstr "ลบโปรไฟล์" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Godot Feature Profile" -msgstr "จัดà¸à¸²à¸£à¹à¸¡à¹ˆà¹à¸šà¸šà¸ªà¹ˆà¸‡à¸à¸à¸" +msgstr "รายละเà¸à¸µà¸¢à¸”คุณสมบัติ Godot" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Profile(s)" -msgstr "นำเข้าโปรเจà¸à¸•์à¹à¸¥à¹‰à¸§" +msgstr "นำเข้าโปรไฟล์" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Export Profile" -msgstr "ส่งà¸à¸à¸à¹‚ปรเจà¸à¸•์" +msgstr "ส่งà¸à¸à¸à¹‚ปรไฟล์" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Manage Editor Feature Profiles" -msgstr "จัดà¸à¸²à¸£à¹à¸¡à¹ˆà¹à¸šà¸šà¸ªà¹ˆà¸‡à¸à¸à¸" +msgstr "จัดà¸à¸²à¸£à¸£à¸²à¸¢à¸¥à¸°à¹€à¸à¸µà¸¢à¸”คุณสมบัติเà¸à¸”ิเตà¸à¸£à¹Œ" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Select Current Folder" @@ -1850,7 +1742,6 @@ msgid "File Exists, Overwrite?" msgstr "มีไฟล์นี้à¸à¸¢à¸¹à¹ˆà¹à¸¥à¹‰à¸§ จะเขียนทับหรืà¸à¹„ม่?" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -#, fuzzy msgid "Select This Folder" msgstr "เลืà¸à¸à¹‚ฟลเดà¸à¸£à¹Œà¸™à¸µà¹‰" @@ -1859,13 +1750,11 @@ msgid "Copy Path" msgstr "คัดลà¸à¸à¸•ำà¹à¸«à¸™à¹ˆà¸‡" #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp -#, fuzzy msgid "Open in File Manager" -msgstr "à¹à¸ªà¸”งในตัวจัดà¸à¸²à¸£à¹„ฟล์" +msgstr "เปิดโฟลเดà¸à¸£à¹Œ" #: editor/editor_file_dialog.cpp editor/editor_node.cpp #: editor/filesystem_dock.cpp editor/project_manager.cpp -#, fuzzy msgid "Show in File Manager" msgstr "à¹à¸ªà¸”งในตัวจัดà¸à¸²à¸£à¹„ฟล์" @@ -1950,44 +1839,36 @@ msgid "Move Favorite Down" msgstr "เลื่à¸à¸™à¹‚ฟลเดà¸à¸£à¹Œà¸—ี่ชà¸à¸šà¸¥à¸‡" #: editor/editor_file_dialog.cpp -#, fuzzy msgid "Go to previous folder." -msgstr "ไปยังโฟลเดà¸à¸£à¹Œà¸«à¸¥à¸±à¸" +msgstr "ไปยังโฟลเดà¸à¸£à¹Œà¸à¹ˆà¸à¸™à¸«à¸™à¹‰à¸²" #: editor/editor_file_dialog.cpp -#, fuzzy msgid "Go to next folder." -msgstr "ไปยังโฟลเดà¸à¸£à¹Œà¸«à¸¥à¸±à¸" +msgstr "ไปยังโฟลเดà¸à¸£à¹Œà¸–ัดไป" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -#, fuzzy msgid "Go to parent folder." msgstr "ไปยังโฟลเดà¸à¸£à¹Œà¸«à¸¥à¸±à¸" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -#, fuzzy msgid "Refresh files." -msgstr "ค้นหาคลาส" +msgstr "รีเฟรชไฟล์" #: editor/editor_file_dialog.cpp -#, fuzzy msgid "(Un)favorite current folder." -msgstr "ไม่สามารถสร้างโฟลเดà¸à¸£à¹Œ" +msgstr "เพิ่ม/ลบโฟลเดà¸à¸£à¹Œà¸›à¸±à¸ˆà¸ˆà¸¸à¸šà¸±à¸™à¹„ปยังที่ชื่นชà¸à¸š" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -#, fuzzy msgid "Toggle the visibility of hidden files." -msgstr "เปิด/ปิดไฟล์ที่ซ่à¸à¸™" +msgstr "เปิด/ปิดà¸à¸²à¸£à¹à¸ªà¸”งไฟล์ที่ซ่à¸à¸™" #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp -#, fuzzy msgid "View items as a grid of thumbnails." -msgstr "à¹à¸ªà¸”งเป็นภาพตัวà¸à¸¢à¹ˆà¸²à¸‡" +msgstr "à¹à¸ªà¸”งไà¸à¹€à¸—มในรูปà¹à¸šà¸šà¸•าราง" #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp -#, fuzzy msgid "View items as a list." -msgstr "à¹à¸ªà¸”งเป็นรายชื่à¸à¹„ฟล์" +msgstr "à¹à¸ªà¸”งไà¸à¹€à¸—มในรูปà¹à¸šà¸šà¸¥à¸´à¸ªà¸•์รายชื่à¸" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Directories & Files:" @@ -2015,7 +1896,7 @@ msgstr "สà¹à¸à¸™à¸•้นฉบับ" msgid "" "There are multiple importers for different types pointing to file %s, import " "aborted" -msgstr "" +msgstr "มีà¸à¸²à¸£à¸™à¸³à¹€à¸‚้าไฟล์ %s หลายà¸à¸±à¸™ à¸à¸²à¸£à¸™à¸³à¹€à¸‚้าถูà¸à¸¢à¸à¹€à¸¥à¸´à¸" #: editor/editor_file_system.cpp msgid "(Re)Importing Assets" @@ -2039,55 +1920,48 @@ msgid "Inherited by:" msgstr "สืบทà¸à¸”โดย:" #: editor/editor_help.cpp -#, fuzzy msgid "Description" -msgstr "รายละเà¸à¸µà¸¢à¸”:" +msgstr "รายละเà¸à¸µà¸¢à¸”" #: editor/editor_help.cpp -#, fuzzy msgid "Online Tutorials" -msgstr "สà¸à¸™à¹ƒà¸Šà¹‰à¸‡à¸²à¸™à¸à¸à¸™à¹„ลน์:" +msgstr "บทสà¸à¸™à¸à¸à¸™à¹„ลน์" #: editor/editor_help.cpp msgid "Properties" msgstr "คุณสมบัติ" #: editor/editor_help.cpp -#, fuzzy msgid "override:" -msgstr "à¸à¸³à¸«à¸™à¸”เฉพาะ..." +msgstr "à¹à¸—นที่:" #: editor/editor_help.cpp -#, fuzzy msgid "default:" -msgstr "ค่าเริ่มต้น" +msgstr "ค่าเริ่มต้น:" #: editor/editor_help.cpp msgid "Methods" msgstr "รายชื่à¸à¹€à¸¡à¸—็à¸à¸”" #: editor/editor_help.cpp -#, fuzzy msgid "Theme Properties" -msgstr "คุณสมบัติ" +msgstr "คุณสมบัติธีม" #: editor/editor_help.cpp msgid "Enumerations" -msgstr "ค่าคงที่" +msgstr "à¸à¸µà¸™à¸±à¸¡" #: editor/editor_help.cpp msgid "Constants" msgstr "ค่าคงที่" #: editor/editor_help.cpp -#, fuzzy msgid "Property Descriptions" -msgstr "รายละเà¸à¸µà¸¢à¸”ตัวà¹à¸›à¸£:" +msgstr "รายละเà¸à¸µà¸¢à¸”ขà¸à¸‡à¸„ุณสมบัติ" #: editor/editor_help.cpp -#, fuzzy msgid "(value)" -msgstr "ค่า" +msgstr "(ค่า)" #: editor/editor_help.cpp msgid "" @@ -2096,9 +1970,8 @@ msgid "" msgstr "คุณสมบัตินี้ยังไม่มีคำà¸à¸˜à¸´à¸šà¸²à¸¢ โปรดช่วย[color=$color][url=$url]à¹à¸à¹‰à¹„ข[/url][/color]!" #: editor/editor_help.cpp -#, fuzzy msgid "Method Descriptions" -msgstr "รายละเà¸à¸µà¸¢à¸”เมท็à¸à¸”:" +msgstr "รายละเà¸à¸µà¸¢à¸”เมท็à¸à¸”" #: editor/editor_help.cpp msgid "" @@ -2116,62 +1989,50 @@ msgid "Case Sensitive" msgstr "ตรงตามà¸à¸±à¸à¸©à¸£à¸žà¸´à¸¡à¸žà¹Œà¹€à¸¥à¹‡à¸-ใหà¸à¹ˆ" #: editor/editor_help_search.cpp -#, fuzzy msgid "Show Hierarchy" -msgstr "à¹à¸ªà¸”งตัวช่วย" +msgstr "à¹à¸ªà¸”งลำดับชั้น" #: editor/editor_help_search.cpp -#, fuzzy msgid "Display All" -msgstr "à¹à¸ªà¸”งปà¸à¸•ิ" +msgstr "à¹à¸ªà¸”งทั้งหมด" #: editor/editor_help_search.cpp -#, fuzzy msgid "Classes Only" -msgstr "คลาส" +msgstr "คลาสเท่านั้น" #: editor/editor_help_search.cpp -#, fuzzy msgid "Methods Only" -msgstr "รายชื่à¸à¹€à¸¡à¸—็à¸à¸”" +msgstr "เมท็à¸à¸”เท่านั้น" #: editor/editor_help_search.cpp -#, fuzzy msgid "Signals Only" -msgstr "สัà¸à¸à¸²à¸“" +msgstr "สัà¸à¸à¸²à¸“เท่านั้น" #: editor/editor_help_search.cpp -#, fuzzy msgid "Constants Only" -msgstr "ค่าคงที่" +msgstr "ค่าคงที่เท่านั้น" #: editor/editor_help_search.cpp -#, fuzzy msgid "Properties Only" -msgstr "คุณสมบัติ" +msgstr "คุณสมบัติเท่านั้น" #: editor/editor_help_search.cpp -#, fuzzy msgid "Theme Properties Only" -msgstr "คุณสมบัติ" +msgstr "คุณสมบัติธีมเท่านั้น" #: editor/editor_help_search.cpp -#, fuzzy msgid "Member Type" -msgstr "ตัวà¹à¸›à¸£" +msgstr "ชนิดสมาชิà¸" #: editor/editor_help_search.cpp -#, fuzzy msgid "Class" -msgstr "คลาส:" +msgstr "คลาส" #: editor/editor_help_search.cpp -#, fuzzy msgid "Method" -msgstr "รายชื่à¸à¹€à¸¡à¸—็à¸à¸”" +msgstr "เมธà¸à¸”" #: editor/editor_help_search.cpp editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Signal" msgstr "สัà¸à¸à¸²à¸“" @@ -2180,14 +2041,12 @@ msgid "Constant" msgstr "คงที่" #: editor/editor_help_search.cpp -#, fuzzy msgid "Property" -msgstr "คุณสมบัติ:" +msgstr "คุณสมบัติ" #: editor/editor_help_search.cpp -#, fuzzy msgid "Theme Property" -msgstr "คุณสมบัติ" +msgstr "คุณสมบัติธีม" #: editor/editor_inspector.cpp editor/project_settings_editor.cpp msgid "Property:" @@ -2203,12 +2062,11 @@ msgstr "" #: editor/editor_log.cpp msgid "Output:" -msgstr "ข้à¸à¸„วาม:" +msgstr "เà¸à¸²à¸—์พุต:" #: editor/editor_log.cpp editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Copy Selection" -msgstr "ลบที่เลืà¸à¸" +msgstr "คัดลà¸à¸à¸—ี่เลืà¸à¸" #: editor/editor_log.cpp editor/editor_network_profiler.cpp #: editor/editor_profiler.cpp editor/editor_properties.cpp @@ -2218,7 +2076,7 @@ msgstr "ลบที่เลืà¸à¸" #: modules/gdnative/gdnative_library_editor_plugin.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Clear" -msgstr "ลบ" +msgstr "เคลียร์" #: editor/editor_log.cpp msgid "Clear Output" @@ -2231,13 +2089,12 @@ msgstr "หยุด" #: editor/editor_network_profiler.cpp editor/editor_profiler.cpp #: editor/plugins/animation_state_machine_editor.cpp editor/rename_dialog.cpp -#, fuzzy msgid "Start" -msgstr "เริ่ม!" +msgstr "เริ่ม" #: editor/editor_network_profiler.cpp msgid "%s/s" -msgstr "" +msgstr "%s/s" #: editor/editor_network_profiler.cpp msgid "Down" @@ -2268,13 +2125,12 @@ msgid "Outgoing RSET" msgstr "" #: editor/editor_node.cpp editor/project_manager.cpp -#, fuzzy msgid "New Window" -msgstr "หน้าต่าง" +msgstr "หน้าต่างใหม่" #: editor/editor_node.cpp msgid "Imported resources can't be saved." -msgstr "" +msgstr "ทรัพยาà¸à¸£à¸—ี่นำเข้ามา ไม่สามารถบันทึà¸à¹„ด้" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: scene/gui/dialogs.cpp @@ -2283,7 +2139,7 @@ msgstr "ตà¸à¸¥à¸‡" #: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp msgid "Error saving resource!" -msgstr "บันทึà¸à¸£à¸µà¸‹à¸à¸£à¹Œà¸ªà¸œà¸´à¸”พลาด!" +msgstr "บันทึà¸à¸—รัพยาà¸à¸£à¸œà¸´à¸”พลาด!" #: editor/editor_node.cpp msgid "" @@ -2301,7 +2157,7 @@ msgstr "เปิดไฟล์เพื่à¸à¹€à¸‚ียนไม่ได้ #: editor/editor_node.cpp msgid "Requested file format unknown:" -msgstr "ไม่ทราบรูปà¹à¸šà¸šà¹„ฟล์ที่ร้à¸à¸‡à¸‚à¸:" +msgstr "ไม่ทราบนามสà¸à¸¸à¸¥à¹„ฟล์ที่ร้à¸à¸‡à¸‚à¸:" #: editor/editor_node.cpp msgid "Error while saving." @@ -2309,7 +2165,7 @@ msgstr "ผิดพลาดขณะบันทึà¸" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Can't open '%s'. The file could have been moved or deleted." -msgstr "" +msgstr "ไม่สามารถเปิด '%s' เนื่à¸à¸‡à¸ˆà¸²à¸à¹„ฟล์ถูà¸à¸¢à¹‰à¸²à¸¢à¸«à¸£à¸·à¸à¸–ูà¸à¸¥à¸š" #: editor/editor_node.cpp msgid "Error while parsing '%s'." @@ -2357,23 +2213,23 @@ msgstr "บันทึà¸à¸‰à¸²à¸à¹„ม่ได้ à¸à¸²à¸ˆà¸ˆà¸°à¸¡à¸µà¸à¸ #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "Can't overwrite scene that is still open!" -msgstr "" +msgstr "ไม่สามารถเขียนทับฉาà¸à¸—ี่à¸à¸³à¸¥à¸±à¸‡à¹€à¸›à¸´à¸”à¸à¸¢à¸¹à¹ˆà¹„ด้!" #: editor/editor_node.cpp msgid "Can't load MeshLibrary for merging!" -msgstr "โหลด MeshLibrary เพื่à¸à¸£à¸§à¸¡à¹„ม่ได้!" +msgstr "ไม่สามารถโหลดไลบรารี Mesh เพื่à¸à¸„วบรวม!" #: editor/editor_node.cpp msgid "Error saving MeshLibrary!" -msgstr "ผิดพลาดขณะบันทึภMeshLibrary!" +msgstr "ผิดพลาดขณะบันทึà¸à¹„ลบรารี Mesh!" #: editor/editor_node.cpp msgid "Can't load TileSet for merging!" -msgstr "โหลด TileSet เพื่à¸à¸£à¸§à¸¡à¹„ม่ได้!" +msgstr "โหลดไทล์เซตเพื่à¸à¸£à¸§à¸¡à¹„ม่ได้!" #: editor/editor_node.cpp msgid "Error saving TileSet!" -msgstr "ผิดพลาดขณะบันทึภTileSet!" +msgstr "ผิดพลาดขณะบันทึà¸à¹„ทล์เซต!" #: editor/editor_node.cpp msgid "Error trying to save layout!" @@ -2401,13 +2257,12 @@ msgstr "" "à¸à¹ˆà¸²à¸™à¸£à¸²à¸¢à¸¥à¸°à¹€à¸à¸µà¸¢à¸”เพิ่มเติมได้จาà¸à¸„ู่มืà¸à¹ƒà¸™à¸ªà¹ˆà¸§à¸™à¸‚à¸à¸‡à¸à¸²à¸£à¸™à¸³à¹€à¸‚้าฉาà¸" #: editor/editor_node.cpp -#, fuzzy msgid "" "This resource belongs to a scene that was instanced or inherited.\n" "Changes to it won't be kept when saving the current scene." msgstr "" -"รีซà¸à¸£à¹Œà¸ªà¸™à¸µà¹‰à¹€à¸›à¹‡à¸™à¸‚à¸à¸‡à¸‰à¸²à¸à¸—ี่ถูà¸à¸à¸´à¸™à¸ªà¹à¸•นซ์หรืà¸à¸ªà¸·à¸šà¸—à¸à¸”\n" -"à¸à¸²à¸£à¹à¸à¹‰à¹„ขจะไม่ถูà¸à¸šà¸±à¸™à¸—ึà¸" +"ทรัพยาà¸à¸£à¸™à¸µà¹‰à¹€à¸›à¹‡à¸™à¸‰à¸²à¸à¸—ี่เป็นà¸à¸´à¸™à¸ªà¹à¸•นซ์หรืà¸à¸ªà¸·à¸šà¸—à¸à¸”\n" +"à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸ˆà¸°à¹„ม่ถูà¸à¹€à¸à¹‡à¸šà¹„ว้ เมื่à¸à¸šà¸±à¸™à¸—ึà¸à¸‰à¸²à¸à¸›à¸±à¸ˆà¸ˆà¸¸à¸šà¸±à¸™" #: editor/editor_node.cpp msgid "" @@ -2458,17 +2313,16 @@ msgid "Open Base Scene" msgstr "เปิดไฟล์ฉาà¸à¸—ี่ใช้สืบทà¸à¸”" #: editor/editor_node.cpp -#, fuzzy msgid "Quick Open..." -msgstr "เปิดไฟล์ฉาà¸à¸”่วน..." +msgstr "เปิดด่วน..." #: editor/editor_node.cpp msgid "Quick Open Scene..." -msgstr "เปิดไฟล์ฉาà¸à¸”่วน..." +msgstr "เปิดฉาà¸à¸”่วน..." #: editor/editor_node.cpp msgid "Quick Open Script..." -msgstr "เปิดไฟล์สคริปต์ด่วน..." +msgstr "เปิดสคริปต์ด่วน..." #: editor/editor_node.cpp msgid "Save & Close" @@ -2479,14 +2333,12 @@ msgid "Save changes to '%s' before closing?" msgstr "บันทึภ'%s' à¸à¹ˆà¸à¸™à¸›à¸´à¸”โปรà¹à¸à¸£à¸¡à¸«à¸£à¸·à¸à¹„ม่?" #: editor/editor_node.cpp -#, fuzzy msgid "Saved %s modified resource(s)." -msgstr "โหลดรีซà¸à¸£à¹Œà¸ªà¹„ม่ได้" +msgstr "บันทึà¸à¸—รัพยาà¸à¸£ %s ที่ถูà¸à¹à¸à¹‰à¹„ขสำเร็จ" #: editor/editor_node.cpp -#, fuzzy msgid "A root node is required to save the scene." -msgstr "Texture ขนาดใหà¸à¹ˆà¸•้à¸à¸‡à¸à¸²à¸£à¹à¸„่ไฟล์เดียว" +msgstr "โหนดà¹à¸¡à¹ˆà¸ˆà¸³à¹€à¸›à¹‡à¸™à¸•้à¸à¸‡à¸—ำà¸à¸²à¸£à¸šà¸±à¸™à¸—ึà¸à¸‰à¸²à¸" #: editor/editor_node.cpp msgid "Save Scene As..." @@ -2510,11 +2362,11 @@ msgstr "ทำไม่ได้ถ้าไม่มีฉาà¸" #: editor/editor_node.cpp msgid "Export Mesh Library" -msgstr "ส่งà¸à¸à¸ Mesh Library" +msgstr "ส่งà¸à¸à¸à¹„ลบรารี Mesh" #: editor/editor_node.cpp msgid "This operation can't be done without a root node." -msgstr "ทำไม่ได้ถ้าไม่มีโหนดราà¸" +msgstr "ไม่สามารถà¸à¸£à¸°à¸—ำได้สำเร็จถ้าไม่มีโหนดà¹à¸¡à¹ˆ" #: editor/editor_node.cpp msgid "Export Tile Set" @@ -2584,9 +2436,8 @@ msgid "Close Scene" msgstr "ปิดไฟล์ฉาà¸" #: editor/editor_node.cpp -#, fuzzy msgid "Reopen Closed Scene" -msgstr "ปิดไฟล์ฉาà¸" +msgstr "เปิดไฟล์ฉาà¸à¸—ี่ปิดไปใหม่" #: editor/editor_node.cpp msgid "Unable to enable addon plugin at: '%s' parsing of config failed." @@ -2601,11 +2452,12 @@ msgid "Unable to load addon script from path: '%s'." msgstr "ไม่สามารถโหลดสคริปต์จาà¸: '%s'" #: editor/editor_node.cpp -#, fuzzy msgid "" "Unable to load addon script from path: '%s' There seems to be an error in " "the code, please check the syntax." -msgstr "ไม่สามารถโหลดสคริปต์จาà¸: '%s' ไม่ใช่สคริปต์ tool" +msgstr "" +"ไม่สามารถโหลดสคริปต์ส่วนเสริมจาà¸: '%s' เหมืà¸à¸™à¸§à¹ˆà¸²à¸ˆà¸°à¹€à¸à¸´à¸”ข้à¸à¸œà¸´à¸”พลาดขึ้นในโค้ด " +"à¸à¸£à¸¸à¸“าเช็ตรูปà¹à¸šà¸šà¸à¸²à¸£à¹€à¸‚ียนโค้ด" #: editor/editor_node.cpp msgid "" @@ -2682,24 +2534,20 @@ msgstr "ค่าเริ่มต้น" #: editor/editor_node.cpp editor/editor_properties.cpp #: editor/plugins/script_editor_plugin.cpp editor/property_editor.cpp -#, fuzzy msgid "Show in FileSystem" -msgstr "เปิดในตัวจัดà¸à¸²à¸£à¹„ฟล์" +msgstr "à¹à¸ªà¸”งในรูปà¹à¸šà¸šà¹„ฟล์" #: editor/editor_node.cpp -#, fuzzy msgid "Play This Scene" -msgstr "เล่น" +msgstr "เล่นฉาà¸à¸™à¸µà¹‰" #: editor/editor_node.cpp -#, fuzzy msgid "Close Tab" -msgstr "ปิดà¹à¸—็บà¸à¸·à¹ˆà¸™" +msgstr "ปิดà¹à¸—็บ" #: editor/editor_node.cpp -#, fuzzy msgid "Undo Close Tab" -msgstr "ปิดà¹à¸—็บà¸à¸·à¹ˆà¸™" +msgstr "เลิà¸à¸—ำà¹à¸—็บที่ปิด" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Close Other Tabs" @@ -2707,12 +2555,11 @@ msgstr "ปิดà¹à¸—็บà¸à¸·à¹ˆà¸™" #: editor/editor_node.cpp msgid "Close Tabs to the Right" -msgstr "" +msgstr "ปิดà¹à¸—็บทางด้านขวา" #: editor/editor_node.cpp -#, fuzzy msgid "Close All Tabs" -msgstr "ปิดทั้งหมด" +msgstr "ปิดà¹à¸—็บทั้งหมด" #: editor/editor_node.cpp msgid "Switch Scene Tab" @@ -2755,9 +2602,8 @@ msgid "Go to previously opened scene." msgstr "ไปยังฉาà¸à¸—ี่เพิ่งเปิด" #: editor/editor_node.cpp -#, fuzzy msgid "Copy Text" -msgstr "คัดลà¸à¸à¸•ำà¹à¸«à¸™à¹ˆà¸‡" +msgstr "คัดลà¸à¸à¸‚้à¸à¸„วาม" #: editor/editor_node.cpp msgid "Next tab" @@ -2796,9 +2642,8 @@ msgid "Save Scene" msgstr "บันทึà¸à¸‰à¸²à¸" #: editor/editor_node.cpp -#, fuzzy msgid "Save All Scenes" -msgstr "บันทึà¸à¸—ุà¸à¸‰à¸²à¸" +msgstr "บันทึà¸à¸‰à¸²à¸à¸—ั้งหมด" #: editor/editor_node.cpp msgid "Convert To..." @@ -2806,11 +2651,11 @@ msgstr "à¹à¸›à¸¥à¸‡à¹€à¸›à¹‡à¸™..." #: editor/editor_node.cpp msgid "MeshLibrary..." -msgstr "MeshLibrary..." +msgstr "ไลบรารี Mesh..." #: editor/editor_node.cpp msgid "TileSet..." -msgstr "TileSet..." +msgstr "ไทล์เซต..." #: editor/editor_node.cpp editor/plugins/script_text_editor.cpp #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp @@ -2836,22 +2681,20 @@ msgid "Project" msgstr "โปรเจà¸à¸•์" #: editor/editor_node.cpp -#, fuzzy msgid "Project Settings..." -msgstr "ตัวเลืà¸à¸à¹‚ปรเจà¸à¸•์" +msgstr "ตั้งค่าโปรเจà¸à¸•์" #: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Version Control" -msgstr "รุ่น:" +msgstr "เวà¸à¸£à¹Œà¸Šà¸±à¸™à¸„à¸à¸™à¹‚ทรล" #: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp msgid "Set Up Version Control" -msgstr "" +msgstr "ตั้งเวà¸à¸£à¹Œà¸Šà¸±à¸™à¸„à¸à¸™à¹‚ทรน" #: editor/editor_node.cpp msgid "Shut Down Version Control" -msgstr "" +msgstr "ปิดเวà¸à¸£à¹Œà¸Šà¸±à¸™à¸„à¸à¸™à¹‚ทรล" #: editor/editor_node.cpp msgid "Export..." @@ -2859,21 +2702,19 @@ msgstr "ส่งà¸à¸à¸..." #: editor/editor_node.cpp msgid "Install Android Build Template..." -msgstr "" +msgstr "ติดตั้งà¹à¸¡à¹ˆà¹à¸šà¸šà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¸‚à¸à¸‡à¹à¸à¸™à¸”รà¸à¸¢à¸”์" #: editor/editor_node.cpp -#, fuzzy msgid "Open Project Data Folder" -msgstr "เปิดตัวจัดà¸à¸²à¸£à¹‚ปรเจà¸à¸•์?" +msgstr "เปิดโฟลเดà¸à¸£à¹Œà¸‚้à¸à¸¡à¸¹à¸¥à¹‚ปรเจà¸à¸•์" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" msgstr "เครื่à¸à¸‡à¸¡à¸·à¸" #: editor/editor_node.cpp -#, fuzzy msgid "Orphan Resource Explorer..." -msgstr "ตัวจัดà¸à¸²à¸£à¸£à¸µà¸‹à¸à¸£à¹Œà¸ªà¸—ี่ไม่มีเจ้าขà¸à¸‡" +msgstr "à¸à¸²à¸£à¹ƒà¸Šà¹‰à¸—รัพยาà¸à¸£" #: editor/editor_node.cpp msgid "Quit to Project List" @@ -2882,7 +2723,7 @@ msgstr "ปิดà¹à¸¥à¸°à¸à¸¥à¸±à¸šà¸ªà¸¹à¹ˆà¸£à¸²à¸¢à¸Šà¸·à¹ˆà¸à¹‚ปรเ #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/project_export.cpp msgid "Debug" -msgstr "à¹à¸à¹‰à¸ˆà¸¸à¸”บà¸à¸žà¸£à¹ˆà¸à¸‡" +msgstr "ดีบัà¸" #: editor/editor_node.cpp msgid "Deploy with Remote Debug" @@ -2913,7 +2754,7 @@ msgstr "" #: editor/editor_node.cpp msgid "Visible Collision Shapes" -msgstr "รูปทรงà¸à¸²à¸¢à¸ าพมà¸à¸‡à¹€à¸«à¹‡à¸™à¹„ด้" +msgstr "ขà¸à¸šà¹€à¸‚ตà¸à¸²à¸£à¸Šà¸™à¸—ี่มà¸à¸‡à¹€à¸«à¹‡à¸™à¹„ด้" #: editor/editor_node.cpp msgid "" @@ -2923,7 +2764,7 @@ msgstr "รูปทรงà¸à¸²à¸¢à¸ าพà¹à¸¥à¸°à¸£à¸±à¸‡à¸ªà¸µ (2D à¹à¸¥à #: editor/editor_node.cpp msgid "Visible Navigation" -msgstr "เส้นนำทางมà¸à¸‡à¹€à¸«à¹‡à¸™à¹„ด้" +msgstr "à¹à¸ªà¸”งà¸à¸²à¸£à¸™à¸³à¸—าง" #: editor/editor_node.cpp msgid "" @@ -2947,7 +2788,7 @@ msgstr "" #: editor/editor_node.cpp msgid "Sync Script Changes" -msgstr "ซิงค์à¸à¸²à¸£à¹à¸à¹‰à¹„ขสคริปต์" +msgstr "ซิงค์à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸ªà¸„ริปต์" #: editor/editor_node.cpp msgid "" @@ -2961,59 +2802,51 @@ msgstr "" #: editor/editor_node.cpp editor/script_create_dialog.cpp msgid "Editor" -msgstr "โปรà¹à¸à¸£à¸¡" +msgstr "เà¸à¸”ิเตà¸à¸£à¹Œ" #: editor/editor_node.cpp -#, fuzzy msgid "Editor Settings..." -msgstr "ตัวเลืà¸à¸à¹‚ปรà¹à¸à¸£à¸¡à¸ªà¸£à¹‰à¸²à¸‡à¹€à¸à¸¡" +msgstr "ตั้งค่าเà¸à¸”ิเตà¸à¸£à¹Œ" #: editor/editor_node.cpp msgid "Editor Layout" -msgstr "เลย์เà¸à¸²à¸•์โปรà¹à¸à¸£à¸¡" +msgstr "เลย์เà¸à¸²à¸•์เà¸à¸”ิเตà¸à¸£à¹Œ" #: editor/editor_node.cpp -#, fuzzy msgid "Take Screenshot" -msgstr "เข้าใจ!" +msgstr "ถ่ายภาพหน้าจà¸" #: editor/editor_node.cpp -#, fuzzy msgid "Screenshots are stored in the Editor Data/Settings Folder." -msgstr "ตัวเลืà¸à¸à¹‚ปรà¹à¸à¸£à¸¡à¸ªà¸£à¹‰à¸²à¸‡à¹€à¸à¸¡" +msgstr "ภาพหน้าจà¸à¸ˆà¸°à¸–ูà¸à¹€à¸à¹‡à¸šà¹„ว้ในโฟลเดà¸à¸£à¹Œà¸‚้à¸à¸¡à¸¹à¸¥/à¸à¸²à¸£à¸•ั้งค่าขà¸à¸‡à¹€à¸à¸”ิเตà¸à¸£à¹Œ" #: editor/editor_node.cpp msgid "Toggle Fullscreen" -msgstr "สลับเต็มจà¸" +msgstr "เปิด/ปิด โหมดเต็มหน้าจà¸" #: editor/editor_node.cpp -#, fuzzy msgid "Toggle System Console" -msgstr "ซ่à¸à¸™/à¹à¸ªà¸”งโหนด CanvasItem" +msgstr "เปิด/ปิด คà¸à¸™à¹‚ซลระบบ" #: editor/editor_node.cpp -#, fuzzy msgid "Open Editor Data/Settings Folder" -msgstr "ตัวเลืà¸à¸à¹‚ปรà¹à¸à¸£à¸¡à¸ªà¸£à¹‰à¸²à¸‡à¹€à¸à¸¡" +msgstr "เปิดโฟลเดà¸à¸£à¹Œà¸‚้à¸à¸¡à¸¹à¸¥/ตั้งค่าขà¸à¸‡à¹€à¸à¸”ิเตà¸à¸£à¹Œ" #: editor/editor_node.cpp msgid "Open Editor Data Folder" -msgstr "" +msgstr "เปิดโฟลเดà¸à¸£à¹Œà¸‚à¸à¸‡à¹€à¸à¸”ิเตà¸à¸£à¹Œ" #: editor/editor_node.cpp -#, fuzzy msgid "Open Editor Settings Folder" -msgstr "ตัวเลืà¸à¸à¹‚ปรà¹à¸à¸£à¸¡à¸ªà¸£à¹‰à¸²à¸‡à¹€à¸à¸¡" +msgstr "เปิดโฟลเดà¸à¸£à¹Œà¸à¸²à¸£à¸•ั้งค่าขà¸à¸‡à¹€à¸à¸”ิเตà¸à¸£à¹Œ" #: editor/editor_node.cpp -#, fuzzy msgid "Manage Editor Features..." -msgstr "จัดà¸à¸²à¸£à¹à¸¡à¹ˆà¹à¸šà¸šà¸ªà¹ˆà¸‡à¸à¸à¸" +msgstr "จัดà¸à¸²à¸£à¸Ÿà¸µà¹€à¸ˆà¸à¸£à¹Œà¸‚à¸à¸‡à¹€à¸à¸”ิเตà¸à¸£à¹Œ..." #: editor/editor_node.cpp -#, fuzzy msgid "Manage Export Templates..." -msgstr "จัดà¸à¸²à¸£à¹à¸¡à¹ˆà¹à¸šà¸šà¸ªà¹ˆà¸‡à¸à¸à¸" +msgstr "จัดà¸à¸²à¸£à¹à¸¡à¹ˆà¹à¸šà¸šà¸à¸²à¸£à¸ªà¹ˆà¸‡à¸à¸à¸..." #: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp msgid "Help" @@ -3038,8 +2871,13 @@ msgid "Q&A" msgstr "ถาม/ตà¸à¸š" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "ระบบติดตามบัค" +#, fuzzy +msgid "Report a Bug" +msgstr "นำเข้าใหม่" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -3087,13 +2925,12 @@ msgstr "เลืà¸à¸à¹€à¸¥à¹ˆà¸™à¸‰à¸²à¸" #: editor/editor_node.cpp msgid "Changing the video driver requires restarting the editor." -msgstr "" +msgstr "à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹„ดรเวà¸à¸£à¹Œà¸à¸²à¸£à¹Œà¸”จà¸à¸ˆà¸³à¹€à¸›à¹‡à¸™à¸•้à¸à¸‡à¹€à¸£à¸´à¹ˆà¸¡à¹€à¸à¸”ิเตà¸à¸£à¹Œà¹ƒà¸«à¸¡à¹ˆ" #: editor/editor_node.cpp editor/project_settings_editor.cpp #: editor/settings_config_dialog.cpp -#, fuzzy msgid "Save & Restart" -msgstr "บันทึà¸à¹à¸¥à¸°à¸™à¸³à¹€à¸‚้าà¸à¸µà¸à¸„รั้ง" +msgstr "บันทึà¸à¹à¸¥à¸°à¹€à¸£à¸´à¹ˆà¸¡à¹ƒà¸«à¸¡à¹ˆ" #: editor/editor_node.cpp #, fuzzy @@ -3101,19 +2938,16 @@ msgid "Spins when the editor window redraws." msgstr "หมุนเมื่à¸à¸¡à¸µà¸à¸²à¸£à¸§à¸²à¸”หน้าต่างโปรà¹à¸à¸£à¸¡à¹ƒà¸«à¸¡à¹ˆ!" #: editor/editor_node.cpp -#, fuzzy msgid "Update Continuously" -msgstr "ต่à¸à¹€à¸™à¸·à¹ˆà¸à¸‡" +msgstr "à¸à¸±à¸žà¹€à¸”ทà¸à¸¢à¹ˆà¸²à¸‡à¸•่à¸à¹€à¸™à¸·à¹ˆà¸à¸‡" #: editor/editor_node.cpp -#, fuzzy msgid "Update When Changed" msgstr "à¸à¸±à¸žà¹€à¸”ทเมื่à¸à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡" #: editor/editor_node.cpp -#, fuzzy msgid "Hide Update Spinner" -msgstr "ปิดà¸à¸²à¸£à¸à¸±à¸žà¹€à¸”ทตัวหมุน" +msgstr "ซ่à¸à¸™à¸•ัวหมุนà¸à¸²à¸£à¸à¸±à¸žà¹€à¸”ท" #: editor/editor_node.cpp msgid "FileSystem" @@ -3124,9 +2958,8 @@ msgid "Inspector" msgstr "คุณสมบัติ" #: editor/editor_node.cpp -#, fuzzy msgid "Expand Bottom Panel" -msgstr "ขยายโฟลเดà¸à¸£à¹Œ" +msgstr "ขยายà¹à¸œà¸‡à¸¥à¹ˆà¸²à¸‡" #: editor/editor_node.cpp msgid "Output" @@ -3141,9 +2974,8 @@ msgid "Android build template is missing, please install relevant templates." msgstr "" #: editor/editor_node.cpp -#, fuzzy msgid "Manage Templates" -msgstr "จัดà¸à¸²à¸£à¹à¸¡à¹ˆà¹à¸šà¸šà¸ªà¹ˆà¸‡à¸à¸à¸" +msgstr "จัดà¸à¸²à¸£à¹à¸¡à¹ˆà¹à¸šà¸š" #: editor/editor_node.cpp msgid "" @@ -3169,9 +3001,8 @@ msgid "Import Templates From ZIP File" msgstr "นำเข้าà¹à¸¡à¹ˆà¹à¸šà¸šà¸ˆà¸²à¸à¹„ฟล์ ZIP" #: editor/editor_node.cpp -#, fuzzy msgid "Template Package" -msgstr "จัดà¸à¸²à¸£à¹à¸¡à¹ˆà¹à¸šà¸šà¸ªà¹ˆà¸‡à¸à¸à¸" +msgstr "à¹à¸žà¸„เà¸à¸ˆà¹à¸¡à¹ˆà¹à¸šà¸š" #: editor/editor_node.cpp msgid "Export Library" @@ -3199,15 +3030,15 @@ msgstr "เลืà¸à¸" #: editor/editor_node.cpp msgid "Open 2D Editor" -msgstr "เปิดตัวà¹à¸à¹‰à¹„ข 2 มิติ" +msgstr "เปิดเà¸à¸”ิเตà¸à¸£à¹Œ 2D" #: editor/editor_node.cpp msgid "Open 3D Editor" -msgstr "เปิดตัวà¹à¸à¹‰à¹„ข 3 มิติ" +msgstr "เปิดเà¸à¸”ิเตà¸à¸£à¹Œ 3D" #: editor/editor_node.cpp msgid "Open Script Editor" -msgstr "เปิดตัวà¹à¸à¹‰à¹„ขสคริปต์" +msgstr "เปิดเà¸à¸”ิเตà¸à¸£à¹Œà¸ªà¸„ริปต์" #: editor/editor_node.cpp editor/project_manager.cpp msgid "Open Asset Library" @@ -3215,16 +3046,15 @@ msgstr "เปิดà¹à¸«à¸¥à¹ˆà¸‡à¸£à¸§à¸¡à¸—รัพยาà¸à¸£" #: editor/editor_node.cpp msgid "Open the next Editor" -msgstr "เปิดตัวà¹à¸à¹‰à¹„ขถัดไป" +msgstr "เปิดเà¸à¸”ิเตà¸à¸£à¹Œà¸–ัดไป" #: editor/editor_node.cpp msgid "Open the previous Editor" -msgstr "เปิดตัวà¹à¸à¹‰à¹„ขà¸à¹ˆà¸à¸™à¸«à¸™à¹‰à¸²" +msgstr "เปิดเà¸à¸”ิเตà¸à¸£à¹Œà¸à¹ˆà¸à¸™à¸«à¸™à¹‰à¸²" #: editor/editor_node.h -#, fuzzy msgid "Warning!" -msgstr "คำเตืà¸à¸™" +msgstr "คำเตืà¸à¸™!" #: editor/editor_path.cpp #, fuzzy @@ -3240,14 +3070,12 @@ msgid "Thumbnail..." msgstr "รูปตัวà¸à¸¢à¹ˆà¸²à¸‡..." #: editor/editor_plugin_settings.cpp -#, fuzzy msgid "Main Script:" -msgstr "เปิดสคริปต์" +msgstr "สคริปต์หลัà¸:" #: editor/editor_plugin_settings.cpp -#, fuzzy msgid "Edit Plugin" -msgstr "à¹à¸à¹‰à¹„ขรูปหลายเหลี่ยม" +msgstr "à¹à¸à¹‰à¹„ขปลั๊à¸à¸à¸´à¸™" #: editor/editor_plugin_settings.cpp msgid "Installed Plugins:" @@ -3264,16 +3092,15 @@ msgstr "รุ่น:" #: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp msgid "Author:" -msgstr "โดย:" +msgstr "ผู้สร้าง:" #: editor/editor_plugin_settings.cpp msgid "Status:" msgstr "สถานะ:" #: editor/editor_plugin_settings.cpp -#, fuzzy msgid "Edit:" -msgstr "à¹à¸à¹‰à¹„ข" +msgstr "à¹à¸à¹‰à¹„ข:" #: editor/editor_profiler.cpp msgid "Measure:" @@ -3289,7 +3116,7 @@ msgstr "เวลาเฉลี่ย (วินาที)" #: editor/editor_profiler.cpp msgid "Frame %" -msgstr "% ขà¸à¸‡à¹€à¸Ÿà¸£à¸¡" +msgstr "เฟรม %" #: editor/editor_profiler.cpp msgid "Physics Frame %" @@ -3316,9 +3143,8 @@ msgid "Calls" msgstr "จำนวนครั้ง" #: editor/editor_properties.cpp -#, fuzzy msgid "Edit Text:" -msgstr "à¹à¸à¹‰à¹„ขธีม..." +msgstr "à¹à¸à¹‰à¹„ขข้à¸à¸„วาม:" #: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" @@ -3326,10 +3152,9 @@ msgstr "เปิด" #: editor/editor_properties.cpp msgid "Layer" -msgstr "" +msgstr "เลเยà¸à¸£à¹Œ" #: editor/editor_properties.cpp -#, fuzzy msgid "Bit %d, value %d" msgstr "บิต %d, ค่า %d" @@ -3338,14 +3163,12 @@ msgid "[Empty]" msgstr "[ว่างเปล่า]" #: editor/editor_properties.cpp editor/plugins/root_motion_editor_plugin.cpp -#, fuzzy msgid "Assign..." -msgstr "ระบุ" +msgstr "à¸à¸³à¸«à¸™à¸”..." #: editor/editor_properties.cpp -#, fuzzy msgid "Invalid RID" -msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡à¸œà¸´à¸”พลาด" +msgstr "RID ผิดพลาด" #: editor/editor_properties.cpp msgid "" @@ -3376,9 +3199,8 @@ msgid "New Script" msgstr "สคริปต์ใหม่" #: editor/editor_properties.cpp editor/scene_tree_dock.cpp -#, fuzzy msgid "Extend Script" -msgstr "เปิดสคริปต์" +msgstr "สคริปต์เสริม" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "New %s" @@ -3411,13 +3233,12 @@ msgid "Selected node is not a Viewport!" msgstr "โหนดที่เลืà¸à¸à¹„ม่ใช่ Viewport!" #: editor/editor_properties_array_dict.cpp -#, fuzzy msgid "Size: " -msgstr "ขนาดเซลล์:" +msgstr "ขนาด: " #: editor/editor_properties_array_dict.cpp msgid "Page: " -msgstr "" +msgstr "หน้า: " #: editor/editor_properties_array_dict.cpp #: editor/plugins/theme_editor_plugin.cpp @@ -3425,18 +3246,16 @@ msgid "Remove Item" msgstr "ลบไà¸à¹€à¸—ม" #: editor/editor_properties_array_dict.cpp -#, fuzzy msgid "New Key:" -msgstr "ชื่à¸à¹ƒà¸«à¸¡à¹ˆ:" +msgstr "คีย์ใหม่:" #: editor/editor_properties_array_dict.cpp -#, fuzzy msgid "New Value:" -msgstr "ชื่à¸à¹ƒà¸«à¸¡à¹ˆ:" +msgstr "ค่าใหม่:" #: editor/editor_properties_array_dict.cpp msgid "Add Key/Value Pair" -msgstr "" +msgstr "เพิ่มคู่ขà¸à¸‡à¸„ีย์/ค่า" #: editor/editor_run_native.cpp msgid "" @@ -3456,7 +3275,7 @@ msgstr "มีฉาà¸à¸—ี่à¹à¸à¹‰à¹„ขà¸à¸¢à¸¹à¹ˆà¹à¸¥à¹‰à¸§" #: editor/editor_run_script.cpp msgid "Couldn't instance script:" -msgstr "สร้างà¸à¸´à¸™à¸ªà¹à¸•นซ์ขà¸à¸‡à¸ªà¸„ริปต์ไม่ได้:" +msgstr "ไม่สามารถà¸à¸´à¸™à¸ªà¹à¸•นซ์สคริปต์ได้:" #: editor/editor_run_script.cpp msgid "Did you forget the 'tool' keyword?" @@ -3476,7 +3295,7 @@ msgstr "เลืà¸à¸à¹‚หนดเพื่à¸à¸™à¸³à¹€à¸‚้า" #: editor/editor_sub_scene.cpp editor/project_manager.cpp msgid "Browse" -msgstr "เลืà¸à¸" +msgstr "ค้นหา" #: editor/editor_sub_scene.cpp msgid "Scene Path:" @@ -3487,7 +3306,6 @@ msgid "Import From Node:" msgstr "นำเข้าจาà¸à¹‚หนด:" #: editor/export_template_manager.cpp -#, fuzzy msgid "Redownload" msgstr "ดาวน์โหลดà¸à¸µà¸à¸„รั้ง" @@ -3529,9 +3347,8 @@ msgid "Can't open export templates zip." msgstr "เปิดไฟล์ zip à¹à¸¡à¹ˆà¹à¸šà¸šà¸ªà¹ˆà¸‡à¸à¸à¸à¹„ม่ได้" #: editor/export_template_manager.cpp -#, fuzzy msgid "Invalid version.txt format inside templates: %s." -msgstr "รูปà¹à¸šà¸šà¸‚à¸à¸‡ version.txt ในà¹à¸¡à¹ˆà¹à¸šà¸šà¹„ม่ถูà¸à¸•้à¸à¸‡" +msgstr "รูปà¹à¸šà¸šà¸‚à¸à¸‡ version.txt ในà¹à¸¡à¹ˆà¹à¸šà¸š %s ไม่ถูà¸à¸•้à¸à¸‡" #: editor/export_template_manager.cpp msgid "No version.txt found inside templates." @@ -3550,9 +3367,8 @@ msgid "Importing:" msgstr "นำเข้า:" #: editor/export_template_manager.cpp -#, fuzzy msgid "Error getting the list of mirrors." -msgstr "ผิดพลาดขณะสร้าง signature object" +msgstr "ผิดพลาดขณะà¸à¸³à¸¥à¸±à¸‡à¸£à¸±à¸šà¸£à¸²à¸¢à¸Šà¸·à¹ˆà¸à¸‚à¸à¸‡ mirrors" #: editor/export_template_manager.cpp msgid "Error parsing JSON of mirror list. Please report this issue!" @@ -3597,9 +3413,8 @@ msgid "Download Complete." msgstr "ดาวน์โหลดเสร็จสิ้น" #: editor/export_template_manager.cpp -#, fuzzy msgid "Cannot remove temporary file:" -msgstr "บันทึà¸à¸˜à¸µà¸¡à¹„ม่ได้:" +msgstr "ไม่สามารถลบไฟล์ชั่วคราวได้:" #: editor/export_template_manager.cpp msgid "" @@ -3608,17 +3423,16 @@ msgid "" msgstr "" #: editor/export_template_manager.cpp -#, fuzzy msgid "Error requesting URL:" -msgstr "ผิดพลาดขณะร้à¸à¸‡à¸‚à¸à¸—ี่à¸à¸¢à¸¹à¹ˆ: " +msgstr "ผิดพลาดขณะà¸à¸³à¸¥à¸±à¸‡à¸£à¹‰à¸à¸‡à¸‚ภURL:" #: editor/export_template_manager.cpp msgid "Connecting to Mirror..." -msgstr "à¸à¸³à¸¥à¸±à¸‡à¹€à¸Šà¸·à¹ˆà¸à¸¡à¸•่à¸..." +msgstr "à¸à¸³à¸¥à¸±à¸‡à¹€à¸Šà¸·à¹ˆà¸à¸¡à¸•่à¸à¸à¸±à¸š Mirror" #: editor/export_template_manager.cpp msgid "Disconnected" -msgstr "à¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸à¸¡à¸•่à¸à¸ªà¸´à¹‰à¸™à¸ªà¸¸à¸”" +msgstr "ตัดà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸à¸¡à¸•่à¸à¹à¸¥à¹‰à¸§" #: editor/export_template_manager.cpp msgid "Resolving" @@ -3659,9 +3473,8 @@ msgid "SSL Handshake Error" msgstr "à¸à¸²à¸£à¸£à¸±à¸šà¸£à¸à¸‡à¸„วามปลà¸à¸”ภัยผิดพลาด" #: editor/export_template_manager.cpp -#, fuzzy msgid "Uncompressing Android Build Sources" -msgstr "à¸à¸³à¸¥à¸±à¸‡à¸„ลายบีบà¸à¸±à¸”" +msgstr "à¸à¸³à¸¥à¸±à¸‡à¸„ลาย Android Build Sources" #: editor/export_template_manager.cpp msgid "Current Version:" @@ -3680,14 +3493,12 @@ msgid "Remove Template" msgstr "ลบà¹à¸¡à¹ˆà¹à¸šà¸š" #: editor/export_template_manager.cpp -#, fuzzy msgid "Select Template File" msgstr "เลืà¸à¸à¹„ฟล์à¹à¸¡à¹ˆà¹à¸šà¸š" #: editor/export_template_manager.cpp -#, fuzzy msgid "Godot Export Templates" -msgstr "à¸à¸³à¸¥à¸±à¸‡à¹‚หลดà¹à¸¡à¹ˆà¹à¸šà¸šà¸ªà¹ˆà¸‡à¸à¸à¸" +msgstr "à¹à¸¡à¹ˆà¹à¸šà¸šà¸à¸²à¸£à¸ªà¹ˆà¸‡à¸à¸à¸ Godot" #: editor/export_template_manager.cpp msgid "Export Template Manager" @@ -3698,14 +3509,12 @@ msgid "Download Templates" msgstr "ดาวน์โหลดà¹à¸¡à¹ˆà¹à¸šà¸š" #: editor/export_template_manager.cpp -#, fuzzy msgid "Select mirror from list: (Shift+Click: Open in Browser)" -msgstr "เลืà¸à¸à¸¥à¸´à¸‡à¸à¹Œà¸”าวน์โหลด: " +msgstr "เลืà¸à¸ mirror จาà¸à¸£à¸²à¸¢à¸Šà¸·à¹ˆà¸: (Shift+คลิà¸: เปิดในเบราเซà¸à¸£à¹Œ)" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Favorites" -msgstr "ที่ชื่นชà¸à¸š:" +msgstr "ที่ชื่นชà¸à¸š" #: editor/filesystem_dock.cpp msgid "Status: Import of file failed. Please fix file and reimport manually." @@ -3736,9 +3545,8 @@ msgid "No name provided." msgstr "ไม่ได้ระบุชื่à¸" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Provided name contains invalid characters." -msgstr "ไม่สามารถใช้à¸à¸±à¸à¸©à¸£à¸šà¸²à¸‡à¸•ัวในชื่à¸à¹„ด้" +msgstr "ชื่à¸à¸—ี่ระบุประà¸à¸à¸šà¹„ปด้วยตัวà¸à¸±à¸à¸©à¸£à¸—ี่ไม่ถูà¸à¸•้à¸à¸‡" #: editor/filesystem_dock.cpp msgid "A file or folder with this name already exists." @@ -3765,33 +3573,28 @@ msgid "Duplicating folder:" msgstr "ทำซ้ำโฟลเดà¸à¸£à¹Œ:" #: editor/filesystem_dock.cpp -#, fuzzy msgid "New Inherited Scene" -msgstr "สืบทà¸à¸”ฉาà¸à¹ƒà¸«à¸¡à¹ˆ..." +msgstr "ฉาà¸à¸ªà¸·à¸šà¸—à¸à¸”ใหม่" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Set As Main Scene" -msgstr "ฉาà¸à¸«à¸¥à¸±à¸" +msgstr "ตั้งเป็นฉาà¸à¸«à¸¥à¸±à¸" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Open Scenes" -msgstr "เปิดไฟล์ฉาà¸" +msgstr "เปิดฉาà¸" #: editor/filesystem_dock.cpp msgid "Instance" msgstr "à¸à¸´à¸™à¸ªà¹à¸•นซ์" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Add to Favorites" -msgstr "ที่ชื่นชà¸à¸š:" +msgstr "เพิ่มไปยังที่ชื่นชà¸à¸š" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Remove from Favorites" -msgstr "ลบà¸à¸à¸à¸ˆà¸²à¸à¸à¸¥à¸¸à¹ˆà¸¡" +msgstr "ลบจาà¸à¸—ี่่ชื่นชà¸à¸š" #: editor/filesystem_dock.cpp msgid "Edit Dependencies..." @@ -3814,9 +3617,8 @@ msgid "Move To..." msgstr "ย้ายไป..." #: editor/filesystem_dock.cpp -#, fuzzy msgid "New Scene..." -msgstr "ฉาà¸à¹ƒà¸«à¸¡à¹ˆ" +msgstr "ฉาà¸à¹ƒà¸«à¸¡à¹ˆ..." #: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp msgid "New Script..." @@ -3861,9 +3663,8 @@ msgid "Toggle Split Mode" msgstr "สลับโหมด" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Search files" -msgstr "ค้นหาคลาส" +msgstr "ค้นหาไฟล์" #: editor/filesystem_dock.cpp msgid "" @@ -3886,9 +3687,8 @@ msgid "Overwrite" msgstr "เขียนทับ" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Create Scene" -msgstr "สร้างจาà¸à¸‰à¸²à¸" +msgstr "สร้างฉาà¸" #: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp msgid "Create Script" @@ -3900,16 +3700,15 @@ msgstr "ค้นหาในไฟล์" #: editor/find_in_files.cpp msgid "Find:" -msgstr "ค้นหา: " +msgstr "ค้นหา:" #: editor/find_in_files.cpp msgid "Folder:" -msgstr "โฟลเดà¸à¸£à¹Œ: " +msgstr "โฟลเดà¸à¸£à¹Œ:" #: editor/find_in_files.cpp -#, fuzzy msgid "Filters:" -msgstr "ตัวà¸à¸£à¸à¸‡" +msgstr "ตัวà¸à¸£à¸à¸‡:" #: editor/find_in_files.cpp msgid "" @@ -4084,9 +3883,8 @@ msgid "Saving..." msgstr "à¸à¸³à¸¥à¸±à¸‡à¸šà¸±à¸™à¸—ึà¸..." #: editor/import_dock.cpp -#, fuzzy msgid "%d Files" -msgstr " ไฟล์" +msgstr "ไฟล์ %d" #: editor/import_dock.cpp msgid "Set as Default for '%s'" @@ -4101,21 +3899,21 @@ msgid "Import As:" msgstr "นำเข้าเป็น:" #: editor/import_dock.cpp -#, fuzzy msgid "Preset" -msgstr "à¸à¸²à¸£à¸ªà¹ˆà¸‡à¸à¸à¸" +msgstr "ตั้งล่วงหน้า" #: editor/import_dock.cpp msgid "Reimport" msgstr "นำเข้าใหม่" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" -msgstr "" +#, fuzzy +msgid "Save Scenes, Re-Import, and Restart" +msgstr "บันทึà¸à¸‰à¸²à¸, นำเข้าà¹à¸¥à¸°à¹€à¸£à¸´à¹ˆà¸¡à¸•้นใหม่" #: editor/import_dock.cpp msgid "Changing the type of an imported file requires editor restart." -msgstr "" +msgstr "à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸Šà¸™à¸´à¸”ขà¸à¸‡à¹„ฟล์ที่นำเข้า จำเป็นต้à¸à¸‡à¹€à¸£à¸´à¹ˆà¸¡à¹€à¸à¸”ิเตà¸à¸£à¹Œà¹ƒà¸«à¸¡à¹ˆ" #: editor/import_dock.cpp msgid "" @@ -4124,15 +3922,13 @@ msgstr "" #: editor/inspector_dock.cpp msgid "Failed to load resource." -msgstr "โหลดรีซà¸à¸£à¹Œà¸ªà¹„ม่ได้" +msgstr "โหลดทรัพยาà¸à¸£à¹„ม่ได้" #: editor/inspector_dock.cpp -#, fuzzy msgid "Expand All Properties" msgstr "ขยายคุณสมบัติทั้งหมด" #: editor/inspector_dock.cpp -#, fuzzy msgid "Collapse All Properties" msgstr "ยุบคุณสมบัติทั้งหมด" @@ -4143,12 +3939,11 @@ msgstr "บันทึà¸à¹€à¸›à¹‡à¸™..." #: editor/inspector_dock.cpp msgid "Copy Params" -msgstr "คัดลà¸à¸à¸•ัวà¹à¸›à¸£" +msgstr "คัดลà¸à¸à¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•à¸à¸£à¹Œ" #: editor/inspector_dock.cpp -#, fuzzy msgid "Edit Resource Clipboard" -msgstr "คลิปบà¸à¸£à¹Œà¸”ไม่มีรีซà¸à¸£à¹Œà¸ª!" +msgstr "à¹à¸à¹‰à¹„ขคลิปบà¸à¸£à¹Œà¸”ทรัพยาà¸à¸£" #: editor/inspector_dock.cpp msgid "Copy Resource" @@ -4195,9 +3990,8 @@ msgid "Object properties." msgstr "คุณสมบัติวัตถุ" #: editor/inspector_dock.cpp -#, fuzzy msgid "Filter properties" -msgstr "ตัวà¸à¸£à¸à¸‡" +msgstr "คุà¸à¸ªà¸¡à¸šà¸±à¸•ิตัวà¸à¸£à¸à¸‡" #: editor/inspector_dock.cpp msgid "Changes may be lost!" @@ -4222,15 +4016,15 @@ msgstr "สร้างปลั๊à¸à¸à¸´à¸™" #: editor/plugin_config_dialog.cpp msgid "Plugin Name:" -msgstr "ชื่à¸à¸›à¸¥à¸±à¹Šà¸à¸à¸´à¸™" +msgstr "ชื่à¸à¸›à¸¥à¸±à¹Šà¸à¸à¸´à¸™:" #: editor/plugin_config_dialog.cpp msgid "Subfolder:" -msgstr "โฟลเดà¸à¸£à¹Œà¸¢à¹ˆà¸à¸¢: " +msgstr "โฟลเดà¸à¸£à¹Œà¸¢à¹ˆà¸à¸¢:" #: editor/plugin_config_dialog.cpp editor/script_create_dialog.cpp msgid "Language:" -msgstr "ภาษา: " +msgstr "ภาษา:" #: editor/plugin_config_dialog.cpp msgid "Script Name:" @@ -4238,7 +4032,7 @@ msgstr "ชื่à¸à¸ªà¸„ริปต์:" #: editor/plugin_config_dialog.cpp msgid "Activate now?" -msgstr "" +msgstr "เปิดใช้งานตà¸à¸™à¸™à¸µà¹‰?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/polygon_2d_editor_plugin.cpp @@ -4252,25 +4046,21 @@ msgid "Create points." msgstr "สร้างจุด" #: editor/plugins/abstract_polygon_2d_editor.cpp -#, fuzzy msgid "" "Edit points.\n" "LMB: Move Point\n" "RMB: Erase Point" msgstr "" -"à¹à¸à¹‰à¹„ขรูปหลายเหลี่ยม:\n" -"เมาส์ซ้าย: ย้ายจุด\n" -"Ctrl+เมาส์ซ้าย: à¹à¸¢à¸à¸ªà¹ˆà¸§à¸™\n" -"เมาส์ขวา: ลบจุด" +"à¹à¸à¹‰à¹„ขจุด:\n" +"คลิà¸à¸‹à¹‰à¸²à¸¢: ย้ายจุด\n" +"คลิà¸à¸‚วา: ลบจุด" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/animation_blend_space_1d_editor.cpp -#, fuzzy msgid "Erase points." -msgstr "คลิà¸à¸‚วา: ลบจุด" +msgstr "ลบจุด" #: editor/plugins/abstract_polygon_2d_editor.cpp -#, fuzzy msgid "Edit Polygon" msgstr "à¹à¸à¹‰à¹„ขรูปหลายเหลี่ยม" @@ -4279,12 +4069,10 @@ msgid "Insert Point" msgstr "à¹à¸—รà¸à¸ˆà¸¸à¸”" #: editor/plugins/abstract_polygon_2d_editor.cpp -#, fuzzy msgid "Edit Polygon (Remove Point)" msgstr "à¹à¸à¹‰à¹„ขรูปหลายเหลี่ยม (ลบจุด)" #: editor/plugins/abstract_polygon_2d_editor.cpp -#, fuzzy msgid "Remove Polygon And Point" msgstr "ลบรูปหลายเหลี่ยมà¹à¸¥à¸°à¸ˆà¸¸à¸”" @@ -4300,52 +4088,45 @@ msgstr "เพิ่มà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" #: editor/plugins/animation_blend_space_2d_editor.cpp #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Load..." -msgstr "โหลด" +msgstr "โหลด..." #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Move Node Point" -msgstr "ย้ายจุด" +msgstr "สร้างจุดโหนด" #: editor/plugins/animation_blend_space_1d_editor.cpp -#, fuzzy msgid "Change BlendSpace1D Limits" -msgstr "à¹à¸à¹‰à¹„ขระยะเวลาà¸à¸²à¸£à¸œà¸ªà¸²à¸™" +msgstr "เปลี่ยนค่าจำà¸à¸±à¸”ขà¸à¸‡ BlendSpace1D" #: editor/plugins/animation_blend_space_1d_editor.cpp -#, fuzzy msgid "Change BlendSpace1D Labels" -msgstr "à¹à¸à¹‰à¹„ขระยะเวลาà¸à¸²à¸£à¸œà¸ªà¸²à¸™" +msgstr "เปลี่ยนป้ายà¸à¸³à¸à¸±à¸š BlendSpace1D" #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp #: editor/plugins/animation_state_machine_editor.cpp msgid "This type of node can't be used. Only root nodes are allowed." -msgstr "" +msgstr "โหนดชนิดนี้ไม่สามารถใช้ได้ มีà¹à¸„่โหนดà¹à¸¡à¹ˆà¹€à¸—่านั้นที่สามารถใช้ได้" #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Add Node Point" -msgstr "เพิ่มโหนด" +msgstr "เพิ่มจุดโหนด" #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Add Animation Point" -msgstr "เพิ่มà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" +msgstr "เพิ่มจุดà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" #: editor/plugins/animation_blend_space_1d_editor.cpp -#, fuzzy msgid "Remove BlendSpace1D Point" -msgstr "ลบจุด" +msgstr "ลบจุด BlendSpace1D" #: editor/plugins/animation_blend_space_1d_editor.cpp msgid "Move BlendSpace1D Node Point" -msgstr "" +msgstr "ย้ายจุดโหนด BlendSpace1D" #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp @@ -4369,38 +4150,33 @@ msgstr "" #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp scene/gui/graph_edit.cpp msgid "Enable snap and show grid." -msgstr "" +msgstr "เปิà¸à¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™à¸à¸²à¸£à¹€à¸‚้าหาà¹à¸¥à¹à¸ªà¸”งเส้นà¸à¸£à¸´à¸”" #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Point" -msgstr "ย้ายจุด" +msgstr "จุด" #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Open Editor" -msgstr "เปิดในโปรà¹à¸à¸£à¸¡à¹à¸à¹‰à¹„ข" +msgstr "เปิดเà¸à¸”ิเตà¸à¸£à¹Œ" #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Open Animation Node" -msgstr "โหนดà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" +msgstr "เปิดโหนดà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Triangle already exists." -msgstr "มีà¸à¸²à¸£à¸à¸£à¸°à¸—ำ '%s' à¸à¸¢à¸¹à¹ˆà¹à¸¥à¹‰à¸§!" +msgstr "มีสามเหลี่ยมà¸à¸¢à¸¹à¹ˆà¹à¸¥à¹‰à¸§" #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Add Triangle" -msgstr "เพิ่มตัวà¹à¸›à¸£" +msgstr "เพิ่มสามเหลี่ยม" #: editor/plugins/animation_blend_space_2d_editor.cpp #, fuzzy @@ -4440,9 +4216,8 @@ msgid "Create triangles by connecting points." msgstr "" #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Erase points and triangles." -msgstr "วิเคราะห์สามเหลี่ยม %d à¸à¸±à¸™:" +msgstr "ลบจุดà¹à¸¥à¸°à¸ªà¸²à¸¡à¹€à¸«à¸¥à¸µà¹ˆà¸¢à¸¡" #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Generate blend triangles automatically (instead of manually)" @@ -4491,9 +4266,8 @@ msgid "Nodes Disconnected" msgstr "ตัดà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸à¸¡à¸•่à¸à¹‚หนดà¹à¸¥à¹‰à¸§" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Set Animation" -msgstr "à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" +msgstr "ตั้งà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp @@ -4512,9 +4286,8 @@ msgid "Toggle Filter On/Off" msgstr "โหมดไร้สิ่งรบà¸à¸§à¸™" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Change Filter" -msgstr "à¹à¸à¹‰à¹„ขตัวà¸à¸£à¸à¸‡à¸ ูมิภาค" +msgstr "à¹à¸à¹‰à¹„ขตัวà¸à¸£à¸à¸‡" #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "No animation player set, so unable to retrieve track names." @@ -4532,31 +4305,26 @@ msgid "" msgstr "" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Anim Clips" -msgstr "คลิป" +msgstr "คลิปà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Audio Clips" -msgstr "ตัวรับเสียง" +msgstr "คลิปเสียง" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Functions" -msgstr "ฟังà¸à¹Œà¸Šà¸±à¸™:" +msgstr "ฟังà¸à¹Œà¸Šà¸±à¸™" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Node Renamed" -msgstr "ชื่à¸à¹‚หนด:" +msgstr "เปลี่ยนชื่à¸à¹‚หนดà¹à¸¥à¹‰à¸§" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add Node..." -msgstr "เพิ่มโหนด" +msgstr "เพิ่มโหนด..." #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/root_motion_editor_plugin.cpp @@ -4565,9 +4333,8 @@ msgid "Edit Filtered Tracks:" msgstr "à¹à¸à¹‰à¹„ขตัวà¸à¸£à¸à¸‡" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Enable Filtering" -msgstr "à¹à¸à¹‰à¹„ขโหนดลูà¸à¹„ด้" +msgstr "เปิดà¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™à¸•ัวà¸à¸£à¸à¸‡" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Toggle Autoplay" @@ -4596,14 +4363,12 @@ msgid "Remove Animation" msgstr "ลบà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Invalid animation name!" -msgstr "ผิดพลาด: ชื่à¸à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹„ม่ถูà¸à¸•้à¸à¸‡!" +msgstr "ชื่à¸à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹„ม่ถูà¸à¸•้à¸à¸‡!" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Animation name already exists!" -msgstr "ผิดพลาด: มีชื่à¸à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¸™à¸µà¹‰à¸à¸¢à¸¹à¹ˆà¹à¸¥à¹‰à¸§!" +msgstr "ชื่à¸à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¸™à¸µà¹‰ มีà¸à¸¢à¸¹à¹ˆà¹à¸¥à¹‰à¸§!" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp @@ -4627,14 +4392,12 @@ msgid "Duplicate Animation" msgstr "ทำซ้ำà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "No animation to copy!" -msgstr "ผิดพลาด: ไม่มีà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹ƒà¸«à¹‰à¸„ัดลà¸à¸!" +msgstr "ไม่มีà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹ƒà¸«à¹‰à¸„ัดลà¸à¸!" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "No animation resource on clipboard!" -msgstr "ผิดพลาด: ไม่มีà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹ƒà¸™à¸„ลิปบà¸à¸£à¹Œà¸”!" +msgstr "ไม่มีà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹ƒà¸™à¸„ลิปบà¸à¸£à¹Œà¸”!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Pasted Animation" @@ -4645,9 +4408,8 @@ msgid "Paste Animation" msgstr "วางà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "No animation to edit!" -msgstr "ผิดพลาด: ไม่มีà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹ƒà¸«à¹‰à¹à¸à¹‰à¹„ข!" +msgstr "ไม่มีà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹ƒà¸«à¹‰à¹à¸à¹‰à¹„ข!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation backwards from current pos. (A)" @@ -4753,9 +4515,8 @@ msgid "Include Gizmos (3D)" msgstr "รวมสัà¸à¸¥à¸±à¸à¸©à¸“์ (3D)" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Pin AnimationPlayer" -msgstr "วางà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" +msgstr "ปัà¸à¸«à¸¡à¸¸à¸” AnimationPlayer" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Create New Animation" @@ -4785,9 +4546,8 @@ msgid "Cross-Animation Blend Times" msgstr "ระยะเวลาà¸à¸²à¸£à¸œà¸ªà¸²à¸™ Cross-Animation" #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Move Node" -msgstr "โหมดเคลื่à¸à¸™à¸¢à¹‰à¸²à¸¢" +msgstr "เคลื่à¸à¸™à¸¢à¹‰à¸²à¸¢à¹‚หนด" #: editor/plugins/animation_state_machine_editor.cpp #, fuzzy @@ -4815,7 +4575,7 @@ msgstr "" #: editor/plugins/animation_state_machine_editor.cpp msgid "Sync" -msgstr "" +msgstr "ซิงค์" #: editor/plugins/animation_state_machine_editor.cpp msgid "At End" @@ -4835,9 +4595,8 @@ msgid "No playback resource set at path: %s." msgstr "ไม่à¸à¸¢à¸¹à¹ˆà¹ƒà¸™à¹‚ฟลเดà¸à¸£à¹Œà¸£à¸µà¸‹à¸à¸£à¹Œà¸ª" #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Node Removed" -msgstr "ลบ:" +msgstr "ลบโหนดà¹à¸¥à¹‰à¸§" #: editor/plugins/animation_state_machine_editor.cpp #, fuzzy @@ -4856,9 +4615,8 @@ msgid "" msgstr "" #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Create new nodes." -msgstr "สร้าง %s ใหม่" +msgstr "สร้างโหนดใหม่" #: editor/plugins/animation_state_machine_editor.cpp #, fuzzy @@ -4884,9 +4642,8 @@ msgid "Transition: " msgstr "ทรานสิชัน" #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Play Mode:" -msgstr "โหมดมุมมà¸à¸‡" +msgstr "โหมดà¸à¸²à¸£à¹€à¸¥à¹ˆà¸™:" #: editor/plugins/animation_tree_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp @@ -5058,7 +4815,6 @@ msgid "Request failed, return code:" msgstr "à¸à¸²à¸£à¸£à¹‰à¸à¸‡à¸‚à¸à¸œà¸´à¸”พลาด รหัส:" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Request failed." msgstr "ร้à¸à¸‡à¸‚à¸à¸œà¸´à¸”พลาด" @@ -5069,7 +4825,7 @@ msgstr "บันทึà¸à¸˜à¸µà¸¡à¹„ม่ได้:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Write error." -msgstr "" +msgstr "à¸à¸²à¸£à¹€à¸‚ียนผิดพลาด" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Request failed, too many redirects" @@ -5086,9 +4842,8 @@ msgid "Request failed, timeout" msgstr "à¸à¸²à¸£à¸£à¹‰à¸à¸‡à¸‚à¸à¸œà¸´à¸”พลาด รหัส:" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Timeout." -msgstr "เวลา" +msgstr "หมดเวลา" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Bad download hash, assuming file has been tampered with." @@ -5111,9 +4866,8 @@ msgid "Asset Download Error:" msgstr "ดาวน์โหลดทรัพยาà¸à¸£à¸œà¸´à¸”พลาด:" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Downloading (%s / %s)..." -msgstr "à¸à¸³à¸¥à¸±à¸‡à¸”าวน์โหลด" +msgstr "à¸à¸³à¸¥à¸±à¸‡à¸”าวน์โหลด (%s / %s)..." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Downloading..." @@ -5149,32 +4903,29 @@ msgstr "à¸à¸³à¸¥à¸±à¸‡à¸”าวน์โหลดไฟล์นี้à¸à¸¢à¸¹ #: editor/plugins/asset_library_editor_plugin.cpp msgid "Recently Updated" -msgstr "" +msgstr "à¸à¸±à¸žà¹€à¸”ทล่าสุด" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Least Recently Updated" -msgstr "" +msgstr "à¸à¸±à¸žà¹€à¸”ทน้à¸à¸¢à¸ªà¸¸à¸”" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Name (A-Z)" -msgstr "" +msgstr "ชื่ภ(A-Z)" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Name (Z-A)" -msgstr "" +msgstr "ชื่ภ(Z-A)" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "License (A-Z)" -msgstr "สัà¸à¸à¸²à¸à¸™à¸¸à¸à¸²à¸•" +msgstr "สัà¸à¸à¸²à¸à¸™à¸¸à¸à¸²à¸• (A-Z)" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "License (Z-A)" -msgstr "สัà¸à¸à¸²à¸à¸™à¸¸à¸à¸²à¸•" +msgstr "สัà¸à¸à¸²à¸à¸™à¸¸à¸à¸²à¸• (Z-A)" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "First" msgstr "à¹à¸£à¸à¸ªà¸¸à¸”" @@ -5196,7 +4947,7 @@ msgstr "ทั้งหมด" #: editor/plugins/asset_library_editor_plugin.cpp msgid "No results for \"%s\"." -msgstr "" +msgstr "ไม่มีผลลัพธ์สำหรับ \"%s\"" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Import..." @@ -5237,7 +4988,7 @@ msgstr "à¸à¸³à¸¥à¸±à¸‡à¹‚หลด..." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Assets ZIP File" -msgstr "ไฟล์ ZIP" +msgstr "ทรัพยาà¸à¸£à¹„ฟล์ ZIP" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" @@ -5278,7 +5029,7 @@ msgstr "จุดà¸à¸³à¹€à¸™à¸´à¸”ตาราง:" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Grid Step:" -msgstr "ระยะห่างเส้น:" +msgstr "ระยะห่างเส้นà¸à¸£à¸´à¸”:" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Primary Line Every:" @@ -5384,63 +5135,52 @@ msgid "" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Top Left" -msgstr "ซ้าย" +msgstr "บนซ้าย" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Top Right" -msgstr "ขวา" +msgstr "บนขวา" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Bottom Right" -msgstr "ย้ายไปขวา" +msgstr "ล่างขวา" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Bottom Left" -msgstr "มุมล่าง" +msgstr "ล่างซ้าย" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Center Left" -msgstr "ย่à¸à¸«à¸™à¹‰à¸²à¸‹à¹‰à¸²à¸¢" +msgstr "à¸à¸¥à¸²à¸‡à¸‹à¹‰à¸²à¸¢" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Center Top" -msgstr "ให้สิ่งที่เลืà¸à¸à¸à¸¢à¸¹à¹ˆà¸à¸¥à¸²à¸‡à¸ˆà¸" +msgstr "à¸à¸¥à¸²à¸‡à¸šà¸™" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Center Right" -msgstr "ย่à¸à¸«à¸™à¹‰à¸²à¸‚วา" +msgstr "à¸à¸¥à¸²à¸‡à¸‚วา" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Center Bottom" -msgstr "ล่าง" +msgstr "à¸à¸¥à¸²à¸‡à¸¥à¹ˆà¸²à¸‡" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Center" -msgstr "" +msgstr "à¸à¸¥à¸²à¸‡" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Left Wide" -msgstr "มุมซ้าย" +msgstr "ความà¸à¸§à¹‰à¸²à¸‡à¸‹à¹‰à¸²à¸¢" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Top Wide" -msgstr "มุมบน" +msgstr "ความà¸à¸§à¹‰à¸²à¸‡à¸šà¸™" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Right Wide" -msgstr "มุมขวา" +msgstr "ความà¸à¸§à¹‰à¸²à¸‡à¸‚วา" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy @@ -5449,11 +5189,11 @@ msgstr "มุมล่าง" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "VCenter Wide" -msgstr "" +msgstr "ความà¸à¸§à¹‰à¸²à¸‡ VCenter" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "HCenter Wide" -msgstr "" +msgstr "ความà¸à¸§à¹‰à¸²à¸‡ HCenter" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy @@ -5461,9 +5201,8 @@ msgid "Full Rect" msgstr "ชื่à¸à¹€à¸•็ม" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Keep Ratio" -msgstr "à¸à¸±à¸•ราส่วนเวลา:" +msgstr "รัà¸à¸©à¸²à¸à¸±à¸•ราส่วน" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Anchors only" @@ -5483,6 +5222,8 @@ msgid "" "Game Camera Override\n" "Overrides game camera with editor viewport camera." msgstr "" +"เขียนทับà¸à¸¥à¹‰à¸à¸‡à¸‚à¸à¸‡à¹€à¸à¸¡à¸ªà¹Œ\n" +"เขียนทับà¸à¸¥à¹‰à¸à¸‡à¸‚à¸à¸‡à¹€à¸à¸¡à¸ªà¹Œà¸”้วยเà¸à¸”ิเตà¸à¸£à¹Œà¸‚à¸à¸‡à¸§à¸´à¸§à¸žà¸à¸£à¹Œà¸•ขà¸à¸‡à¸à¸¥à¹‰à¸à¸‡" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -5490,18 +5231,18 @@ msgid "" "Game Camera Override\n" "No game instance running." msgstr "" +"เขียนทับà¸à¸¥à¹‰à¸à¸‡à¸‚à¸à¸‡à¹€à¸à¸¡à¸ªà¹Œ\n" +"ไม่มีà¸à¸´à¸™à¸ªà¹à¸•นซ์ขà¸à¸‡à¹€à¸à¸¡à¸ªà¹Œà¸—ำงานà¸à¸¢à¸¹à¹ˆ" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Lock Selected" -msgstr "เครื่à¸à¸‡à¸¡à¸·à¸à¹€à¸¥à¸·à¸à¸" +msgstr "ล็à¸à¸à¸—ี่เลืà¸à¸" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Unlock Selected" -msgstr "ลบสิ่งที่เลืà¸à¸" +msgstr "ปลดล็à¸à¸„ที่เลืà¸à¸" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -5551,7 +5292,6 @@ msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/texture_region_editor_plugin.cpp #: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp -#, fuzzy msgid "Zoom Reset" msgstr "รีเซ็ตà¸à¸²à¸£à¸‹à¸¹à¸¡" @@ -5588,9 +5328,8 @@ msgstr "โหมดหมุน" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Scale Mode" -msgstr "โหมดปรับขนาด (R)" +msgstr "โหมดปรับขนาด" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -5610,9 +5349,8 @@ msgid "Pan Mode" msgstr "โหมดมุมมà¸à¸‡" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Ruler Mode" -msgstr "โหมดà¸à¸²à¸£à¸—ำงาน:" +msgstr "โหมดไม้บรรทัด" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy @@ -5630,9 +5368,8 @@ msgid "Toggle grid snapping." msgstr "เปิด/ปิด à¸à¸²à¸£à¸ˆà¸³à¸à¸±à¸”" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Use Grid Snap" -msgstr "จำà¸à¸±à¸”ด้วยเส้นตาราง" +msgstr "ใช้à¸à¸²à¸£à¹€à¸‚้าหาเส้นà¸à¸£à¸´à¸”" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy @@ -5709,12 +5446,12 @@ msgstr "ปลดล็à¸à¸„วัตถุที่เลืà¸à¸" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Makes sure the object's children are not selectable." -msgstr "ทำให้เลืà¸à¸à¹‚หนดลูà¸à¹„ม่ได้" +msgstr "เลืà¸à¸à¹‚หนดลูà¸à¹„ม่ได้" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Restores the object's children's ability to be selected." -msgstr "ทำให้เลืà¸à¸à¹‚หนดลูà¸à¹„ด้เหมืà¸à¸™à¹€à¸”ิม" +msgstr "เลืà¸à¸à¹‚หนดลูà¸à¹„ด้" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy @@ -5740,9 +5477,8 @@ msgid "View" msgstr "มุมมà¸à¸‡" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Always Show Grid" -msgstr "à¹à¸ªà¸”งเส้นตาราง" +msgstr "à¹à¸ªà¸”งเส้นà¸à¸£à¸´à¸”" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Helpers" @@ -5768,7 +5504,7 @@ msgstr "1 มุมมà¸à¸‡" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Group And Lock Icons" -msgstr "" +msgstr "à¹à¸ªà¸”งà¸à¸¥à¸¸à¹ˆà¸¡à¹à¸¥à¸°à¸¥à¹‡à¸à¸„ไà¸à¸„à¸à¸™" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Center Selection" @@ -5832,11 +5568,11 @@ msgstr "ลบท่าทาง" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Multiply grid step by 2" -msgstr "เพิ่มความถี่เส้นตารางขึ้น 2 เท่า" +msgstr "เพิ่มความถี่เส้นà¸à¸£à¸´à¸”ขึ้น 2 เท่า" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Divide grid step by 2" -msgstr "ลดความถี่เส้นตารางลงครึ่งหนึ่ง" +msgstr "ลดความถี่à¸à¸£à¸´à¸”ลงครึ่งหนึ่ง" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy @@ -5853,7 +5589,7 @@ msgstr "à¸à¸³à¸¥à¸±à¸‡à¹€à¸žà¸´à¹ˆà¸¡ %s..." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Cannot instantiate multiple nodes without root." -msgstr "à¸à¸´à¸™à¸ªà¹à¸•นซ์หลาย ๆ โหนดโดยที่ไม่มีโหนดราà¸à¹„ม่ได้" +msgstr "à¸à¸´à¸™à¸ªà¹à¸•นซ์หลาย ๆ โหนดโดยที่ไม่มีโหนดà¹à¸¡à¹ˆà¹„ม่ได้" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp @@ -5879,9 +5615,8 @@ msgstr "" "ลาภ& วาง + Alt: เปลี่ยนประเภทโหนด" #: editor/plugins/collision_polygon_editor_plugin.cpp -#, fuzzy msgid "Create Polygon3D" -msgstr "สร้างรูปหลายเหลี่ยม" +msgstr "สร้าง Polygon3D" #: editor/plugins/collision_polygon_editor_plugin.cpp msgid "Edit Poly" @@ -5904,9 +5639,8 @@ msgstr "โหลด Mask à¸à¸²à¸£à¸›à¸°à¸—ุ" #: editor/plugins/cpu_particles_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp -#, fuzzy msgid "Restart" -msgstr "เริ่มใหม่ทันที" +msgstr "เริ่มใหม่" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp @@ -5938,7 +5672,7 @@ msgstr "Snap (พิà¸à¹€à¸‹à¸¥):" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Border Pixels" -msgstr "" +msgstr "พิà¸à¹€à¸‹à¸¥à¸‚à¸à¸š" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp @@ -6006,12 +5740,10 @@ msgid "Load Curve Preset" msgstr "โหลดเส้นโค้งตัวà¸à¸¢à¹ˆà¸²à¸‡" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Add Point" msgstr "เพิ่มจุด" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Remove Point" msgstr "ลบจุด" @@ -6053,7 +5785,7 @@ msgstr "สร้าง GI Probe" #: editor/plugins/gradient_editor_plugin.cpp msgid "Gradient Edited" -msgstr "" +msgstr "à¹à¸à¹‰à¹„ขเà¸à¸£à¹€à¸”ียนต์" #: editor/plugins/item_list_editor_plugin.cpp msgid "Item %d" @@ -6408,7 +6140,7 @@ msgstr "โหนดไม่มี geometry (หน้า)" #: editor/plugins/particles_editor_plugin.cpp msgid "\"%s\" doesn't inherit from Spatial." -msgstr "" +msgstr "\"%s\" ไม่ได้สืบทà¸à¸”มาจาภSpatial" #: editor/plugins/particles_editor_plugin.cpp #, fuzzy @@ -6610,6 +6342,8 @@ msgid "" "No texture in this polygon.\n" "Set a texture to be able to edit UV." msgstr "" +"ไม่มีเทà¸à¹€à¸ˆà¸à¸£à¹Œà¹ƒà¸™à¸£à¸¹à¸›à¸«à¸¥à¸²à¸¢à¹€à¸«à¸¥à¸µà¹ˆà¸¢à¸¡à¸™à¸µà¹‰\n" +"ตั้งเทà¸à¹€à¸ˆà¸à¸£à¹Œà¹€à¸žà¸·à¹ˆà¸à¸—ี่จะà¹à¸à¹‰à¹„ข UV ได้" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Create UV Map" @@ -6622,9 +6356,8 @@ msgid "" msgstr "" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Create Polygon & UV" -msgstr "สร้างรูปหลายเหลี่ยม" +msgstr "สร้าง Polygon à¹à¸¥à¸° UV" #: editor/plugins/polygon_2d_editor_plugin.cpp #, fuzzy @@ -6674,7 +6407,7 @@ msgstr "à¹à¸à¹‰à¹„ข UV รูปหลายเหลี่ยม 2D" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "UV" -msgstr "" +msgstr "UV" #: editor/plugins/polygon_2d_editor_plugin.cpp #, fuzzy @@ -6722,13 +6455,15 @@ msgstr "ปรับขนาดรูปหลายเหลี่ยม" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Create a custom polygon. Enables custom polygon rendering." -msgstr "" +msgstr "สร้างรูปหลายเหลี่ยมà¹à¸šà¸šà¸à¸³à¸«à¸™à¸”เà¸à¸‡ เปิดà¸à¸²à¸£à¹€à¸£à¸™à¹€à¸”à¸à¸£à¹Œà¸£à¸¹à¸›à¸«à¸¥à¸²à¸¢à¹€à¸«à¸¥à¸µà¹ˆà¸¢à¸¡à¹à¸šà¸šà¸à¸³à¸«à¸™à¸”เà¸à¸‡" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "" "Remove a custom polygon. If none remain, custom polygon rendering is " "disabled." msgstr "" +"ลบรูปหลายเหลี่ยมà¹à¸šà¸šà¸à¸³à¸«à¸™à¸”เà¸à¸‡ " +"ถ้าไม่มีรูปหลายเหลี่ยมà¸à¸¢à¸¹à¹ˆà¸ˆà¸°à¸›à¸´à¸”à¸à¸²à¸£à¹€à¸£à¸™à¹€à¸”à¸à¸£à¹Œà¸£à¸¹à¸›à¸«à¸¥à¸²à¸¢à¹€à¸«à¸¥à¸µà¹ˆà¸¢à¸¡à¹à¸šà¸šà¸à¸³à¸«à¸™à¸”เà¸à¸‡" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Paint weights with specified intensity." @@ -6740,7 +6475,7 @@ msgstr "" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Radius:" -msgstr "" +msgstr "รัศมี:" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Polygon->UV" @@ -6755,9 +6490,8 @@ msgid "Clear UV" msgstr "ลบ UV" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Grid Settings" -msgstr "à¸à¸²à¸£à¸•ั้งค่า GridMap" +msgstr "ตั้งค่าเส้นà¸à¸£à¸´à¸”" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Snap" @@ -6769,36 +6503,31 @@ msgstr "จำà¸à¸±à¸”à¸à¸²à¸£à¹€à¸„ลื่à¸à¸™à¸¢à¹‰à¸²à¸¢" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Grid" -msgstr "เส้นตาราง" +msgstr "เส้นà¸à¸£à¸´à¸”" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Show Grid" -msgstr "à¹à¸ªà¸”งเส้นตาราง" +msgstr "à¹à¸ªà¸”งเส้นà¸à¸£à¸´à¸”" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Configure Grid:" -msgstr "ตั้งค่าà¸à¸²à¸£à¸ˆà¸³à¸à¸±à¸”" +msgstr "ตั้งค่าเส้นà¸à¸£à¸´à¸”:" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Grid Offset X:" -msgstr "จุดà¸à¸³à¹€à¸™à¸´à¸”ตาราง:" +msgstr "จุดเริ่มเส้นà¸à¸£à¸´à¸”à¹à¸à¸™ X:" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Grid Offset Y:" -msgstr "จุดà¸à¸³à¹€à¸™à¸´à¸”ตาราง:" +msgstr "จุดเริ่มเส้นà¸à¸£à¸´à¸”à¹à¸à¸™ Y:" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Grid Step X:" -msgstr "ระยะห่างเส้น:" +msgstr "ระยะห่างà¸à¸£à¸´à¸”à¹à¸à¸™ X:" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Grid Step Y:" -msgstr "ระยะห่างเส้น:" +msgstr "ระยะห่างà¸à¸£à¸´à¸”à¹à¸à¸™ Y:" #: editor/plugins/polygon_2d_editor_plugin.cpp #, fuzzy @@ -6898,33 +6627,28 @@ msgid "Error Saving" msgstr "ผิดพลาดขณะบันทึà¸" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Error importing theme." msgstr "ผิดพลาดขณะนำเข้าธีม" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Error Importing" msgstr "ผิดพลาดขณะนำเข้า" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "New Text File..." -msgstr "สร้างโฟลเดà¸à¸£à¹Œ..." +msgstr "สร้างไฟล์ข้à¸à¸„วามใหม่" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Open File" msgstr "เปิดไฟล์" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Save File As..." -msgstr "บันทึà¸à¹€à¸›à¹‡à¸™..." +msgstr "บันทึà¸à¹„ฟล์เป็น..." #: editor/plugins/script_editor_plugin.cpp msgid "Can't obtain the script for running." -msgstr "" +msgstr "ไม่สามารถเรียà¸à¹ƒà¸Šà¹‰à¸ªà¸„ริปต์ได้" #: editor/plugins/script_editor_plugin.cpp msgid "Script failed reloading, check console for errors." @@ -6956,9 +6680,8 @@ msgid "Save Theme As..." msgstr "บันทึà¸à¸˜à¸µà¸¡à¹€à¸›à¹‡à¸™" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "%s Class Reference" -msgstr " ตำราà¸à¹‰à¸²à¸‡à¸à¸´à¸‡à¸„ลาส" +msgstr "%s à¸à¹‰à¸²à¸‡à¸à¸´à¸‡à¸„ลาส" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp @@ -7013,9 +6736,8 @@ msgid "File" msgstr "ไฟล์" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Open..." -msgstr "เปิด" +msgstr "เปิด..." #: editor/plugins/script_editor_plugin.cpp msgid "Reopen Closed Script" @@ -7047,9 +6769,8 @@ msgid "Theme" msgstr "ธีม" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Import Theme..." -msgstr "นำเข้าธีม" +msgstr "นำเข้าธีม..." #: editor/plugins/script_editor_plugin.cpp msgid "Reload Theme" @@ -7069,7 +6790,7 @@ msgstr "ปิดคู่มืà¸" #: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp msgid "Run" -msgstr "รัน" +msgstr "เริ่ม" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Into" @@ -7090,25 +6811,15 @@ msgstr "ทำต่à¸à¹„ป" #: editor/plugins/script_editor_plugin.cpp msgid "Keep Debugger Open" -msgstr "เปิดตัวà¹à¸à¹‰à¹„ขจุดบà¸à¸žà¸£à¹ˆà¸à¸‡à¸„้างไว้" +msgstr "เปิดตัวดีบัà¸à¸„้างไว้" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Debug with External Editor" -msgstr "à¹à¸à¹‰à¸ˆà¸¸à¸”บà¸à¸žà¸£à¹ˆà¸à¸‡à¸”้วยโปรà¹à¸à¸£à¸¡à¸à¸·à¹ˆà¸™" +msgstr "ดีบัà¸à¸”้วยเà¸à¸”ิเตà¸à¸£à¹Œà¸à¸·à¹ˆà¸™" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Open Godot online documentation." -msgstr "เปิดคู่มืà¸" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" +msgstr "เปิดคู่มืà¸à¸à¸à¸™à¹„ลน์" #: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." @@ -7146,22 +6857,19 @@ msgstr "บันทึà¸à¸à¸µà¸à¸„รั้ง" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" -msgstr "ตัวà¹à¸à¹‰à¹„ขจุดบà¸à¸žà¸£à¹ˆà¸à¸‡" +msgstr "ตัวดีบัà¸" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Search Results" -msgstr "ค้นหาในคู่มืà¸" +msgstr "ผลà¸à¸²à¸£à¸„้นหา" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Clear Recent Scripts" -msgstr "ล้างรายà¸à¸²à¸£à¸‰à¸²à¸à¸¥à¹ˆà¸²à¸ªà¸¸à¸”" +msgstr "เคลียร์สคริปต์ล่าสุด" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Connections to method:" -msgstr "เชื่à¸à¸¡à¹„ปยังโหนด:" +msgstr "เชื่à¸à¸¡à¹„ปยังเมธà¸à¸”:" #: editor/plugins/script_text_editor.cpp editor/script_editor_debugger.cpp #, fuzzy @@ -7169,9 +6877,8 @@ msgid "Source" msgstr "ต้นฉบับ:" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Target" -msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡à¸—ี่à¸à¸¢à¸¹à¹ˆ:" +msgstr "เป้าหมาย" #: editor/plugins/script_text_editor.cpp #, fuzzy @@ -7186,7 +6893,7 @@ msgstr "บรรทัด:" #: editor/plugins/script_text_editor.cpp msgid "(ignore)" -msgstr "" +msgstr "(ละเว้น)" #: editor/plugins/script_text_editor.cpp #, fuzzy @@ -7229,17 +6936,17 @@ msgstr "à¸à¸±à¸à¸©à¸£à¹à¸£à¸à¸žà¸´à¸¡à¸žà¹Œà¹ƒà¸«à¸à¹ˆ" #: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp msgid "Syntax Highlighter" -msgstr "" +msgstr "ไฮไลท์ไวยาà¸à¸£à¸“์" #: editor/plugins/script_text_editor.cpp #: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp msgid "Go To" -msgstr "" +msgstr "ไปยัง" #: editor/plugins/script_text_editor.cpp #: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp msgid "Bookmarks" -msgstr "" +msgstr "บุ๊คมาร์ค" #: editor/plugins/script_text_editor.cpp #, fuzzy @@ -7576,6 +7283,11 @@ msgstr "ต้à¸à¸‡à¹€à¸¥à¸·à¸à¸à¹€à¸žà¸µà¸¢à¸‡à¹‚หนดเดียว" #: editor/plugins/spatial_editor_plugin.cpp #, fuzzy +msgid "Auto Orthogonal Enabled" +msgstr "ขนาน" + +#: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy msgid "Lock View Rotation" msgstr "à¹à¸ªà¸”งข้à¸à¸¡à¸¹à¸¥" @@ -7667,17 +7379,17 @@ msgid "Freelook Slow Modifier" msgstr "ปรับความเร็วมุมมà¸à¸‡à¸à¸´à¸ªà¸£à¸°" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "View Rotation Locked" +msgstr "à¹à¸ªà¸”งข้à¸à¸¡à¸¹à¸¥" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy -msgid "View Rotation Locked" -msgstr "à¹à¸ªà¸”งข้à¸à¸¡à¸¹à¸¥" - -#: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "เครื่à¸à¸‡à¸¡à¸·à¸à¹€à¸„ลื่à¸à¸™à¸¢à¹‰à¸²à¸¢" @@ -7807,9 +7519,8 @@ msgstr "à¹à¸ªà¸”งเส้นตาราง" #: editor/plugins/spatial_editor_plugin.cpp #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Settings..." -msgstr "ตัวเลืà¸à¸" +msgstr "ตั้งค่า..." #: editor/plugins/spatial_editor_plugin.cpp msgid "Snap Settings" @@ -7915,9 +7626,8 @@ msgid "LightOccluder2D Preview" msgstr "สร้างรูปหลายเหลี่ยมà¸à¸±à¹‰à¸™à¹à¸ªà¸‡" #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Sprite is empty!" -msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡à¸šà¸±à¸™à¸—ึà¸à¸§à¹ˆà¸²à¸‡à¹€à¸›à¸¥à¹ˆà¸²!" +msgstr "สไปรต์ว่างเปล่า!" #: editor/plugins/sprite_editor_plugin.cpp msgid "Can't convert a sprite using animation frames to mesh." @@ -7937,9 +7647,8 @@ msgid "Invalid geometry, can't create polygon." msgstr "" #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Convert to Polygon2D" -msgstr "ย้ายรูปหลายเหลี่ยม" +msgstr "à¹à¸›à¸¥à¸‡à¹€à¸›à¹‡à¸™ Polygon2D" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't create collision polygon." @@ -7960,23 +7669,20 @@ msgid "Create LightOccluder2D Sibling" msgstr "สร้างรูปหลายเหลี่ยมà¸à¸±à¹‰à¸™à¹à¸ªà¸‡" #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Sprite" -msgstr "SpriteFrames" +msgstr "สไปรต์" #: editor/plugins/sprite_editor_plugin.cpp msgid "Simplification: " -msgstr "" +msgstr "ลดความซับซ้à¸à¸™: " #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Shrink (Pixels): " -msgstr "Snap (พิà¸à¹€à¸‹à¸¥):" +msgstr "หด (พิà¸à¹€à¸‹à¸¥): " #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Grow (Pixels): " -msgstr "Snap (พิà¸à¹€à¸‹à¸¥):" +msgstr "ขยาย (พิà¸à¹€à¸‹à¸¥): " #: editor/plugins/sprite_editor_plugin.cpp #, fuzzy @@ -7984,28 +7690,24 @@ msgid "Update Preview" msgstr "ตัวà¸à¸¢à¹ˆà¸²à¸‡ Atlas" #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Settings:" -msgstr "ตัวเลืà¸à¸" +msgstr "ตั้งค่า:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "No Frames Selected" -msgstr "ให้สิ่งที่เลืà¸à¸à¹€à¸•็มจà¸" +msgstr "ไม่มีเฟรมที่เลืà¸à¸" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Add %d Frame(s)" -msgstr "เพิ่มเฟรม" +msgstr "เพิ่ม %d เฟรม(วินาที)" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frame" msgstr "เพิ่มเฟรม" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Unable to load images" -msgstr "โหลดรูปไม่ได้:" +msgstr "โหลดรูปไม่ได้" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "ERROR: Couldn't load frame resource!" @@ -8032,19 +7734,16 @@ msgid "(empty)" msgstr "(ว่างเปล่า)" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Move Frame" -msgstr "วางเฟรม" +msgstr "เลื่à¸à¸™à¹€à¸Ÿà¸£à¸¡" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Animations:" -msgstr "à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" +msgstr "à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "New Animation" -msgstr "à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" +msgstr "à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹ƒà¸«à¸¡à¹ˆ" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed (FPS):" @@ -8055,18 +7754,16 @@ msgid "Loop" msgstr "วน" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Animation Frames:" -msgstr "เฟรมà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" +msgstr "เฟรมà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Add a Texture from File" -msgstr "เพิ่มโหนดจาà¸à¸œà¸±à¸‡" +msgstr "เพิ่มเทà¸à¹€à¸ˆà¸à¸£à¹Œà¸ˆà¸²à¸à¹„ฟล์" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frames from a Sprite Sheet" -msgstr "" +msgstr "เพิ่มเฟรมจาà¸à¸ªà¹„ปรต์ชีต" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Insert Empty (Before)" @@ -8085,32 +7782,28 @@ msgid "Move (After)" msgstr "ย้าย (หลัง)" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Select Frames" -msgstr "สà¹à¸•ค" +msgstr "เลืà¸à¸à¹€à¸Ÿà¸£à¸¡" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Horizontal:" -msgstr "" +msgstr "à¹à¸™à¸§à¸™à¸à¸™:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Vertical:" -msgstr "มุมรูปทรง" +msgstr "à¹à¸™à¸§à¸•ั้ง:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Select/Clear All Frames" -msgstr "เลืà¸à¸à¸—ั้งหมด" +msgstr "เลืà¸à¸/เคลียร์เฟรมทั้งหมด" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Create Frames from Sprite Sheet" -msgstr "สร้างจาà¸à¸‰à¸²à¸" +msgstr "สร้างเฟรมจาà¸à¸ªà¹„ปรต์ชีต" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "SpriteFrames" -msgstr "SpriteFrames" +msgstr "สไปรต์เฟรม" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Set Region Rect" @@ -8127,9 +7820,8 @@ msgstr "โหมดà¸à¸²à¸£à¸ˆà¸³à¸à¸±à¸”:" #: editor/plugins/texture_region_editor_plugin.cpp #: scene/resources/visual_shader.cpp -#, fuzzy msgid "None" -msgstr "<ไม่มี>" +msgstr "ไม่มี" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Pixel Snap" @@ -8137,7 +7829,7 @@ msgstr "จำà¸à¸±à¸”ให้ย้ายเป็นพิà¸à¹€à¸‹à¸¥" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Grid Snap" -msgstr "จำà¸à¸±à¸”ด้วยเส้นตาราง" +msgstr "เข้าหาเส้นà¸à¸£à¸´à¸”" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Auto Slice" @@ -8177,9 +7869,8 @@ msgid "Remove All" msgstr "ลบทั้งหมด" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Edit Theme" -msgstr "à¹à¸à¹‰à¹„ขธีม..." +msgstr "à¹à¸à¹‰à¹„ขธีม" #: editor/plugins/theme_editor_plugin.cpp msgid "Theme editing menu." @@ -8211,9 +7902,8 @@ msgid "Toggle Button" msgstr "ปุ่มเมาส์" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled Button" -msgstr "เมาส์à¸à¸¥à¸²à¸‡" +msgstr "ปิดà¸à¸²à¸£à¸—ำงานปุ่ม" #: editor/plugins/theme_editor_plugin.cpp msgid "Item" @@ -8248,17 +7938,15 @@ msgstr "" #: editor/plugins/theme_editor_plugin.cpp msgid "Submenu" -msgstr "" +msgstr "เมนูย่à¸à¸¢" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Subitem 1" -msgstr "ไà¸à¹€à¸—ม" +msgstr "ไà¸à¹€à¸—มย่à¸à¸¢ 1" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Subitem 2" -msgstr "ไà¸à¹€à¸—ม" +msgstr "ไà¸à¹€à¸—มย่à¸à¸¢ 2" #: editor/plugins/theme_editor_plugin.cpp msgid "Has" @@ -8286,18 +7974,16 @@ msgid "Tab 3" msgstr "à¹à¸—็บ 3" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Editable Item" -msgstr "à¹à¸à¹‰à¹„ขโหนดลูà¸à¹„ด้" +msgstr "ไà¸à¹€à¸—มที่สามารถà¹à¸à¹‰à¹„ขได้" #: editor/plugins/theme_editor_plugin.cpp msgid "Subtree" -msgstr "" +msgstr "ผังย่à¸à¸¢" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Has,Many,Options" -msgstr "มี,มาà¸à¸¡à¸²à¸¢,หลาย,ตัวเลืà¸à¸!" +msgstr "มี,หลาย,ตัวเลืà¸à¸" #: editor/plugins/theme_editor_plugin.cpp msgid "Data Type:" @@ -8321,28 +8007,25 @@ msgid "Color" msgstr "สี" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Theme File" -msgstr "ธีม" +msgstr "ไฟล์ธีม" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Erase Selection" msgstr "ลบที่เลืà¸à¸" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Fix Invalid Tiles" -msgstr "ชื่à¸à¸œà¸´à¸”พลาด" +msgstr "à¹à¸à¹‰à¹„ขไทล์ที่ไม่ถูà¸à¸•้à¸à¸‡" #: editor/plugins/tile_map_editor_plugin.cpp #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Cut Selection" -msgstr "ให้สิ่งที่เลืà¸à¸à¸à¸¢à¸¹à¹ˆà¸à¸¥à¸²à¸‡à¸ˆà¸" +msgstr "ตัดที่เลืà¸à¸" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Paint TileMap" -msgstr "วาด TileMap" +msgstr "วาดไทล์à¹à¸¡à¸ž" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Line Draw" @@ -8354,16 +8037,15 @@ msgstr "วาดสี่เหลี่ยม" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Bucket Fill" -msgstr "ถมเต็ม" +msgstr "เทสี" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Erase TileMap" -msgstr "ลบ TileMap" +msgstr "ลบไทล์à¹à¸¡à¸ž" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Find Tile" -msgstr "ค้นหา tile" +msgstr "ค้นหาไทล์" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Transpose" @@ -8375,14 +8057,12 @@ msgid "Disable Autotile" msgstr "Autotiles" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Enable Priority" -msgstr "à¹à¸à¹‰à¹„ขตัวà¸à¸£à¸à¸‡" +msgstr "เปิดà¸à¸²à¸£à¸ˆà¸±à¸”ลำดับความสำคัà¸" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Filter tiles" -msgstr "คัดà¸à¸£à¸à¸‡à¹„ฟล์..." +msgstr "ตัวà¸à¸£à¸à¸‡à¹„ทล์" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Give a TileSet resource to this TileMap to use its tiles." @@ -8390,35 +8070,35 @@ msgstr "" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Paint Tile" -msgstr "วาด Tile" +msgstr "วาดไทล์" #: editor/plugins/tile_map_editor_plugin.cpp msgid "" "Shift+LMB: Line Draw\n" "Shift+Ctrl+LMB: Rectangle Paint" msgstr "" +"Shift+LMB: วาดเส้น\n" +"Shift+Ctrl+LMB: วาดสี่เหลี่ยม" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Pick Tile" -msgstr "เลืà¸à¸ Tile" +msgstr "เลืà¸à¸à¹„ทล์" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Rotate Left" -msgstr "โหมดหมุน" +msgstr "หมุนซ้าย" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Rotate Right" -msgstr "ย้ายไปขวา" +msgstr "หมุนขวา" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Flip Horizontally" -msgstr "" +msgstr "พลิà¸à¹à¸™à¸§à¸™à¸à¸™" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Flip Vertically" -msgstr "" +msgstr "พลิà¸à¹à¸™à¸§à¸•ั้ง" #: editor/plugins/tile_map_editor_plugin.cpp #, fuzzy @@ -8426,14 +8106,12 @@ msgid "Clear Transform" msgstr "เคลื่à¸à¸™à¸¢à¹‰à¸²à¸¢" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Add Texture(s) to TileSet." -msgstr "เพิ่มโหนดจาà¸à¸œà¸±à¸‡" +msgstr "เพิ่มเทà¸à¹€à¸ˆà¸à¸£à¹Œà¹ƒà¸«à¹‰à¹„ทล์เซต" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Remove selected Texture from TileSet." -msgstr "ลบรายà¸à¸²à¸£" +msgstr "ลบเทà¸à¹€à¸ˆà¸à¸£à¹Œà¸—ี่เลืà¸à¸à¸ˆà¸²à¸à¹„ทล์เซต" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Create from Scene" @@ -8445,7 +8123,7 @@ msgstr "รวมจาà¸à¸‰à¸²à¸" #: editor/plugins/tile_set_editor_plugin.cpp msgid "New Single Tile" -msgstr "" +msgstr "ไทล์เดี่ยวใหม่" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -8458,22 +8136,20 @@ msgid "New Atlas" msgstr "%s ใหม่" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Next Coordinate" -msgstr "ไปชั้นบน" +msgstr "พิà¸à¸±à¸”ถัดไป" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Select the next shape, subtile, or Tile." -msgstr "" +msgstr "เลืà¸à¸à¸£à¸¹à¸›à¸£à¹ˆà¸²à¸‡, ไทล์ย่à¸à¸¢ หรืà¸à¹„ทล์à¸à¸±à¸™à¸–ัดไป" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Previous Coordinate" -msgstr "ไปชั้นล่าง" +msgstr "พิà¸à¸±à¸”à¸à¹ˆà¸à¸™à¸«à¸™à¹‰à¸²" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Select the previous shape, subtile, or Tile." -msgstr "" +msgstr "เลืà¸à¸à¸£à¸¹à¸›à¸£à¹ˆà¸²à¸‡, ไทล์ย่à¸à¸¢à¸«à¸£à¸·à¸à¹„ทล์à¸à¹ˆà¸à¸™à¸«à¸™à¹‰à¸²" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -8481,9 +8157,8 @@ msgid "Region" msgstr "โหมดà¸à¸²à¸£à¸—ำงาน:" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Collision" -msgstr "โหนดà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" +msgstr "ขà¸à¸šà¹€à¸‚ตà¸à¸²à¸£à¸Šà¸™" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -8501,9 +8176,8 @@ msgid "Bitmask" msgstr "โหมดหมุน" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Priority" -msgstr "วิธีà¸à¸²à¸£à¸ªà¹ˆà¸‡à¸à¸à¸:" +msgstr "à¸à¸²à¸£à¸ˆà¸±à¸”ลำดับความสำคัà¸" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -8516,9 +8190,8 @@ msgid "Region Mode" msgstr "โหมดà¸à¸²à¸£à¸—ำงาน:" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Collision Mode" -msgstr "โหนดà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" +msgstr "โหมดขà¸à¸šà¹€à¸‚ตà¸à¸²à¸£à¸Šà¸™" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -8536,14 +8209,12 @@ msgid "Bitmask Mode" msgstr "โหมดหมุน" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Priority Mode" -msgstr "วิธีà¸à¸²à¸£à¸ªà¹ˆà¸‡à¸à¸à¸:" +msgstr "โหมดà¸à¸²à¸£à¸ˆà¸±à¸”ลำดับความสำคัà¸" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Icon Mode" -msgstr "โหมดมุมมà¸à¸‡" +msgstr "โหมดไà¸à¸„à¸à¸™" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -8565,26 +8236,24 @@ msgid "Erase bitmask." msgstr "คลิà¸à¸‚วา: ลบจุด" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Create a new rectangle." -msgstr "สร้าง %s ใหม่" +msgstr "สร้างสี่เหลี่ยมใหม่" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Create a new polygon." -msgstr "สร้างรูปหลายเหลี่ยมจาà¸à¸„วามว่างเปล่า" +msgstr "สร้างรูปหลายเหลี่ยมใหม่" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Keep polygon inside region Rect." -msgstr "" +msgstr "ให้รูปหลายเหลี่ยมà¸à¸¢à¸¹à¹ˆà¹ƒà¸™à¸‚à¸à¸šà¹€à¸‚ตขà¸à¸‡à¸ªà¸µà¹ˆà¹€à¸«à¸¥à¸µà¹ˆà¸¢à¸¡" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Enable snap and show grid (configurable via the Inspector)." -msgstr "" +msgstr "โชว์เส้นà¸à¸£à¸´à¸” à¹à¸¥à¸° จุดตามà¸à¸£à¸´à¸” (ตั้งค่าใน Inspector)" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Display Tile Names (Hold Alt Key)" -msgstr "" +msgstr "à¹à¸ªà¸”งชื่à¸à¹„ทล์ (à¸à¸”Altค้างไว้)" #: editor/plugins/tile_set_editor_plugin.cpp msgid "" @@ -8609,13 +8278,12 @@ msgid "Merge from scene?" msgstr "รวมจาà¸à¸‰à¸²à¸?" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Remove Texture" -msgstr "ลบà¹à¸¡à¹ˆà¹à¸šà¸š" +msgstr "ลบเทà¸à¹€à¸ˆà¸à¸£à¹Œ" #: editor/plugins/tile_set_editor_plugin.cpp msgid "%s file(s) were not added because was already on the list." -msgstr "" +msgstr "%s ไฟล์ไม่สามารถเพิ่มเข้าได้ เนื่à¸à¸‡à¸ˆà¸²à¸à¸à¸¢à¸¹à¹ˆà¹ƒà¸™à¸¥à¸´à¸ªà¸•์เรียบร้à¸à¸¢à¹à¸¥à¹‰à¸§" #: editor/plugins/tile_set_editor_plugin.cpp msgid "" @@ -8636,20 +8304,20 @@ msgid "" msgstr "เลืà¸à¸à¹„ทล์ย่à¸à¸¢à¸—ี่à¸à¸³à¸¥à¸±à¸‡à¸›à¸£à¸±à¸šà¹à¸•่ง" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Delete polygon." -msgstr "ลบจุด" +msgstr "ลบรูปหลายเหลี่ยม" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "" "LMB: Set bit on.\n" "RMB: Set bit off.\n" "Shift+LMB: Set wildcard bit.\n" "Click on another Tile to edit it." msgstr "" -"คลิà¸à¸‹à¹‰à¸²à¸¢: à¸à¸³à¸«à¸™à¸”ค่าบิต เปิด\n" -"คลิà¸à¸‚วา: à¸à¸³à¸«à¸™à¸”ค่าบิต ปิด" +"คลิà¸à¸‹à¹‰à¸²à¸¢: เปิด bit.\n" +"คลิà¸à¸‚วา: ปิด bit.\n" +"Shift+คลิà¸à¸‹à¹‰à¸²à¸¢: ตั้ง wildcard bit.\n" +"คลิà¸à¹„ทล์à¸à¸±à¸™à¸à¸·à¹ˆà¸™à¹€à¸žà¸·à¹ˆà¸à¸›à¸£à¸±à¸šà¹à¸•่ง" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -8660,11 +8328,12 @@ msgid "" msgstr "เลืà¸à¸à¸£à¸¹à¸›à¸ าพย่à¸à¸¢à¹€à¸žà¸·à¹ˆà¸à¸—ำเป็นไà¸à¸„à¸à¸™ ภาพนี้จะใช้à¹à¸ªà¸”งเมื่à¸à¸à¸²à¸£" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "" "Select sub-tile to change its priority.\n" "Click on another Tile to edit it." -msgstr "เลืà¸à¸à¹„ทล์ย่à¸à¸¢à¹€à¸žà¸·à¹ˆà¸à¸ˆà¸±à¸”ลำดับความสำคัà¸" +msgstr "" +"เลืà¸à¸à¹„ทล์ย่à¸à¸¢à¹€à¸žà¸·à¹ˆà¸à¸ˆà¸±à¸”ลำดับความสำคัà¸\n" +"คลิà¸à¹„ทล์à¸à¸±à¸™à¸à¸·à¹ˆà¸™à¹€à¸žà¸·à¹ˆà¸à¹à¸à¹‰à¹„ขไทล์นั้น" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -8674,18 +8343,16 @@ msgid "" msgstr "เลืà¸à¸à¹„ทล์ย่à¸à¸¢à¹€à¸žà¸·à¹ˆà¸à¸ˆà¸±à¸”ลำดับความสำคัà¸" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Set Tile Region" -msgstr "à¸à¸³à¸«à¸™à¸”ขà¸à¸šà¹€à¸‚ต Texture" +msgstr "ตั้งขà¸à¸šà¹€à¸‚ตไทล์" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Create Tile" -msgstr "สร้างโฟลเดà¸à¸£à¹Œ" +msgstr "สร้างไทล์" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Set Tile Icon" -msgstr "" +msgstr "ตั้งไà¸à¸„à¸à¸™à¹„ทล์" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -8727,9 +8394,8 @@ msgid "Make Polygon Convex" msgstr "ย้ายรูปหลายเหลี่ยม" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Remove Tile" -msgstr "ลบà¹à¸¡à¹ˆà¹à¸šà¸š" +msgstr "ลบไทล์" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -8747,13 +8413,12 @@ msgid "Remove Navigation Polygon" msgstr "สร้างรูปทรงนำทาง" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Edit Tile Priority" -msgstr "à¹à¸à¹‰à¹„ขตัวà¸à¸£à¸à¸‡" +msgstr "à¹à¸à¹‰à¸¥à¸³à¸”ับความสำคัà¸à¸‚à¸à¸‡à¹„ทล์" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Edit Tile Z Index" -msgstr "" +msgstr "à¹à¸à¹‰à¹„ขดัชนี Z ขà¸à¸‡à¹„ทล์" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -8761,14 +8426,12 @@ msgid "Make Convex" msgstr "ย้ายรูปหลายเหลี่ยม" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Make Concave" -msgstr "ย้ายรูปหลายเหลี่ยม" +msgstr "ทำให้เว้า" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Create Collision Polygon" -msgstr "สร้างรูปทรงนำทาง" +msgstr "สร้างรูปหลายเหลี่ยมขà¸à¸‡à¹€à¸‚ตà¸à¸²à¸£à¸Šà¸™" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -8776,18 +8439,16 @@ msgid "Create Occlusion Polygon" msgstr "สร้างรูปหลายเหลี่ยมà¸à¸±à¹‰à¸™à¹à¸ªà¸‡" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "This property can't be changed." -msgstr "ทำไม่ได้ถ้าไม่มีฉาà¸" +msgstr "ไม่สามารถเปลี่ยนà¹à¸›à¸¥à¸‡à¸„ุณสมบัติได้" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "TileSet" -msgstr "Tile Set" +msgstr "ไทล์เซต" #: editor/plugins/version_control_editor_plugin.cpp msgid "No VCS addons are available." -msgstr "" +msgstr "ไม่พบส่วนเสริม VCS" #: editor/plugins/version_control_editor_plugin.cpp msgid "Error" @@ -8816,9 +8477,8 @@ msgid "Version Control System" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Initialize" -msgstr "à¸à¸±à¸à¸©à¸£à¹à¸£à¸à¸žà¸´à¸¡à¸žà¹Œà¹ƒà¸«à¸à¹ˆ" +msgstr "เริ่มต้น" #: editor/plugins/version_control_editor_plugin.cpp msgid "Staging area" @@ -8830,7 +8490,6 @@ msgid "Detect new changes" msgstr "สร้าง %s ใหม่" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Changes" msgstr "เปลี่ยน" @@ -8839,14 +8498,12 @@ msgid "Modified" msgstr "" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Renamed" -msgstr "เปลี่ยนชื่à¸" +msgstr "เปลี่ยนชื่à¸à¹à¸¥à¹‰à¸§" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "Deleted" -msgstr "ลบ" +msgstr "ลบà¹à¸¥à¹‰à¸§" #: editor/plugins/version_control_editor_plugin.cpp #, fuzzy @@ -8892,26 +8549,23 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only)" -msgstr "" +msgstr "(GLES3 เท่านั้น)" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add Output" -msgstr "เพิ่มà¸à¸´à¸™à¸žà¸¸à¸•" +msgstr "เพิ่มเà¸à¸²à¸—์พุต" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar" -msgstr "à¸à¸±à¸•ราส่วน:" +msgstr "สเà¸à¸¥à¸²à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector" -msgstr "คุณสมบัติ" +msgstr "เวà¸à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Boolean" -msgstr "" +msgstr "บูลีน" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8919,43 +8573,36 @@ msgid "Sampler" msgstr "ไฟล์เสียง" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add input port" -msgstr "เพิ่มà¸à¸´à¸™à¸žà¸¸à¸•" +msgstr "เพิ่มพà¸à¸£à¹Œà¸•à¸à¸´à¸™à¸žà¸¸à¸•" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Add output port" -msgstr "" +msgstr "เพิ่มพà¸à¸£à¹Œà¸•เà¸à¸²à¸•์พุต" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change input port type" -msgstr "เปลี่ยนประเภท" +msgstr "เปลี่ยนชนิดพà¸à¸£à¹Œà¸•à¸à¸´à¸™à¸žà¸¸à¸•" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change output port type" -msgstr "เปลี่ยนประเภท" +msgstr "เปลี่ยนชนิดพà¸à¸£à¹Œà¸•เà¸à¸²à¸•์พุต" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change input port name" -msgstr "เปลี่ยนชื่à¸à¸à¸´à¸™à¸žà¸¸à¸•" +msgstr "เปลี่ยนชื่à¸à¸žà¸à¸£à¹Œà¸•à¸à¸´à¸™à¸žà¸¸à¸•" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change output port name" -msgstr "เปลี่ยนชื่à¸à¸à¸´à¸™à¸žà¸¸à¸•" +msgstr "เปลี่ยนชื่à¸à¸žà¸à¸£à¹Œà¸•เà¸à¸²à¸•์พุต" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Remove input port" -msgstr "ลบจุด" +msgstr "ลบพà¸à¸£à¹Œà¸•à¸à¸´à¸™à¸žà¸¸à¸•" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Remove output port" -msgstr "ลบจุด" +msgstr "ลบพà¸à¸£à¹Œà¸•เà¸à¸²à¸•์พุต" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8963,26 +8610,22 @@ msgid "Set expression" msgstr "à¹à¸à¹‰à¹„ขสมà¸à¸²à¸£" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Resize VisualShader node" -msgstr "Shader" +msgstr "ปรับขนาดโหนดเวà¸à¸£à¹Œà¸Šà¸§à¸¥à¹€à¸Šà¸”เดà¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Set Uniform Name" -msgstr "" +msgstr "ตั้งชื่à¸à¸¢à¸¹à¸™à¸´à¸Ÿà¸à¸£à¹Œà¸¡" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Set Input Default Port" -msgstr "à¸à¸³à¸«à¸™à¸”เป็นค่าเริ่มต้นขà¸à¸‡ '%s'" +msgstr "à¸à¸³à¸«à¸™à¸”พà¸à¸£à¹Œà¸•à¸à¸´à¸™à¸žà¸¸à¸•เริ่มต้น" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add Node to Visual Shader" -msgstr "Shader" +msgstr "เพิ่มโหนดไปยังเวà¸à¸£à¹Œà¸Šà¸§à¸¥à¹€à¸Šà¸”เดà¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Duplicate Nodes" msgstr "ทำซ้ำโหนด" @@ -8992,13 +8635,12 @@ msgid "Paste Nodes" msgstr "วางโหนด" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Delete Nodes" msgstr "ลบโหนด" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Visual Shader Input Type Changed" -msgstr "" +msgstr "เปลี่ยนชนิดขà¸à¸‡à¸à¸´à¸™à¸žà¸¸à¸•เวà¸à¸£à¹Œà¸Šà¸§à¸¥à¹€à¸Šà¸”เดà¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -9006,9 +8648,8 @@ msgid "Vertex" msgstr "มุมรูปทรง" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Fragment" -msgstr "ตัวà¹à¸›à¸£:" +msgstr "à¹à¸Ÿà¸£à¸à¹€à¸¡à¸™à¸•์" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -9021,44 +8662,40 @@ msgid "Show resulted shader code." msgstr "สร้างโหนด" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Create Shader Node" -msgstr "สร้างโหนด" +msgstr "สร้างโหนดเชดเดà¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Color function." -msgstr "ไปยังฟังà¸à¹Œà¸Šà¸±à¸™..." +msgstr "ฟังà¸à¹Œà¸Šà¸±à¸™à¸ªà¸µ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Color operator." -msgstr "" +msgstr "à¸à¸²à¸£à¸”ำเนินà¸à¸²à¸£à¸ªà¸µ" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Grayscale function." -msgstr "สร้างฟังà¸à¹Œà¸Šà¸±à¸™" +msgstr "ฟังà¸à¹Œà¸Šà¸±à¸™à¸‚าว-ดำ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts HSV vector to RGB equivalent." -msgstr "" +msgstr "à¹à¸›à¸¥à¸‡à¹€à¸§à¸à¹€à¸•à¸à¸£à¹Œ HSV เป็น RGB" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts RGB vector to HSV equivalent." -msgstr "" +msgstr "à¹à¸›à¸¥à¸‡à¹€à¸§à¸à¹€à¸•à¸à¸£à¹Œ RGB เป็น HSV" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Sepia function." -msgstr "เปลี่ยนชื่à¸à¸Ÿà¸±à¸‡à¸à¹Œà¸Šà¸±à¸™" +msgstr "ฟังà¸à¹Œà¸Šà¸±à¸™à¸‹à¸µà¹€à¸›à¸µà¸¢" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Burn operator." -msgstr "" +msgstr "ดำเนินà¸à¸²à¸£ Burn" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Darken operator." -msgstr "" +msgstr "ดำเนินà¸à¸²à¸£ Darken" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -9067,7 +8704,7 @@ msgstr "เฉพาะที่à¹à¸•à¸à¸•่าง" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Dodge operator." -msgstr "" +msgstr "ดำเนินà¸à¸²à¸£ Dodge" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -9076,19 +8713,19 @@ msgstr "à¹à¸à¹‰à¹„ขเครื่à¸à¸‡à¸«à¸¡à¸²à¸¢à¸ªà¹€à¸à¸¥à¸²à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Lighten operator." -msgstr "" +msgstr "ดำเนินà¸à¸²à¸£ Lighten" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Overlay operator." -msgstr "" +msgstr "ดำเนินà¸à¸²à¸£ Overlay" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Screen operator." -msgstr "" +msgstr "ดำเนินà¸à¸²à¸£ Screen" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "SoftLight operator." -msgstr "" +msgstr "ดำเนินà¸à¸²à¸£ SoftLight" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -9102,165 +8739,161 @@ msgstr "เคลื่à¸à¸™à¸¢à¹‰à¸²à¸¢" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the boolean result of the %s comparison between two parameters." -msgstr "" +msgstr "คืนค่าผลบูลีนจาà¸à¸à¸²à¸£à¹€à¸›à¸£à¸µà¸¢à¸šà¹€à¸—ียบระหว่างสà¸à¸‡à¸•ัวà¹à¸›à¸£à¸‚à¸à¸‡ %s" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Equal (==)" -msgstr "" +msgstr "เทียบเท่า (==)" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Greater Than (>)" -msgstr "" +msgstr "มาà¸à¸à¸§à¹ˆà¸² (>)" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Greater Than or Equal (>=)" -msgstr "" +msgstr "มาà¸à¸à¸§à¹ˆà¸²à¸«à¸£à¸·à¸à¹€à¸—่าà¸à¸±à¸š (>=)" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns an associated vector if the provided scalars are equal, greater or " "less." -msgstr "" +msgstr "คืนค่าเวà¸à¹€à¸•à¸à¸£à¹Œà¸—ี่เà¸à¸µà¹ˆà¸¢à¸§à¸‚้à¸à¸‡à¸–้าสเà¸à¸¥à¸²à¸£à¹Œà¸—ี่ให้มีค่าเท่าà¸à¸±à¸š มาà¸à¸à¸§à¹ˆà¸²à¸«à¸£à¸·à¸à¸™à¹‰à¸à¸¢à¸à¸§à¹ˆà¸²" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns the boolean result of the comparison between INF and a scalar " "parameter." -msgstr "" +msgstr "คืนค่าบูลีนจาà¸à¸à¸²à¸£à¹€à¸›à¸£à¸µà¸¢à¸šà¹€à¸—ียบค่า INF à¸à¸±à¸šà¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•à¸à¸£à¹Œà¸Šà¸™à¸´à¸”สเà¸à¸¥à¸²à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns the boolean result of the comparison between NaN and a scalar " "parameter." -msgstr "" +msgstr "คืนค่าบูลีนซึ่งเปรียบเทียบค่าระหว่าง NaN à¸à¸±à¸šà¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•à¸à¸£à¹Œà¸ªà¹€à¸à¸¥à¸²à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Less Than (<)" -msgstr "" +msgstr "น้à¸à¸¢à¸à¸§à¹ˆà¸²(<)" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Less Than or Equal (<=)" -msgstr "" +msgstr "น้à¸à¸¢à¸à¸§à¹ˆà¸²à¸«à¸£à¸·à¸à¹€à¸—่าà¸à¸±à¸š(<=)" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Not Equal (!=)" -msgstr "" +msgstr "ไม่เท่าà¸à¸±à¸š (!=)" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns an associated vector if the provided boolean value is true or false." -msgstr "" +msgstr "คืนค่าเวà¸à¹€à¸•à¸à¸£à¹Œà¸—ี่เà¸à¸µà¹ˆà¸¢à¸§à¸‚้à¸à¸‡à¸–้าบูลีนที่ให้มีค่าเท่าà¸à¸±à¸š true หรืภfalse" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns an associated scalar if the provided boolean value is true or false." -msgstr "" +msgstr "คืนค่าสเà¸à¸¥à¸²à¸£à¹Œà¸—ี่เà¸à¸µà¹ˆà¸¢à¸§à¸‚้à¸à¸‡à¸–้าต่าบูลีนที่ให้มีค่า true หรืภfalse" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the boolean result of the comparison between two parameters." -msgstr "" +msgstr "คืนค่าบูลีนจาà¸à¸à¸²à¸£à¹€à¸›à¸£à¸µà¸¢à¸šà¹€à¸—ียบพารามิเตà¸à¸£à¹Œà¸ªà¸à¸‡à¸•ัว" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns the boolean result of the comparison between INF (or NaN) and a " "scalar parameter." -msgstr "" +msgstr "คืนค่าบูลีนจาà¸à¸à¸²à¸£à¹€à¸›à¸£à¸µà¸¢à¸šà¹€à¸—ียบค่า INF (หรืภNaN) à¹à¸¥à¸°à¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•à¸à¸£à¹Œà¸ªà¹€à¸à¸¥à¸²à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Boolean constant." -msgstr "à¹à¸à¹‰à¹„ขค่าคงที่เวà¸à¹€à¸•à¸à¸£à¹Œ" +msgstr "ค่าคงที่บูลีน" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Boolean uniform." -msgstr "" +msgstr "ยูนิฟà¸à¸£à¹Œà¸¡à¸šà¸¹à¸¥à¸µà¸™" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "'%s' input parameter for all shader modes." -msgstr "" +msgstr "'%s' พารามิเตà¸à¸£à¹Œà¸‚à¸à¸‡à¸à¸´à¸™à¸žà¸¸à¸•สำหรับโหมดเชดเดà¸à¸£à¹Œà¸—ั้งหมด" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Input parameter." -msgstr "จำà¸à¸±à¸”ด้วยโหนดà¹à¸¡à¹ˆ" +msgstr "พารามิเตà¸à¸£à¹Œà¸à¸´à¸™à¸žà¸¸à¸•" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "'%s' input parameter for vertex and fragment shader modes." -msgstr "" +msgstr "'%s' พารามิเตà¸à¸£à¹Œà¸à¸´à¸™à¸žà¸¸à¸•สำหรับโหมดเวà¸à¸£à¹Œà¹€à¸—็à¸à¸‹à¹Œà¹€à¸Šà¸”เดà¸à¸£à¹Œà¹à¸¥à¸°à¹à¸Ÿà¸£à¸à¹€à¸¡à¸™à¸•์เชดเดà¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "'%s' input parameter for fragment and light shader modes." -msgstr "" +msgstr "'%s' พารามิเตà¸à¸£à¹Œà¸à¸´à¸™à¸žà¸¸à¸•สำหรับโหมดà¹à¸Ÿà¸£à¸à¹€à¸¡à¸™à¸•์เชดเดà¸à¸£à¹Œà¹à¸¥à¸°à¹‚หมดไลท์เชดเดà¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "'%s' input parameter for fragment shader mode." -msgstr "" +msgstr "'%s' พารามิเตà¸à¸£à¹Œà¸à¸´à¸™à¸žà¸¸à¸•สำหรับโหมดà¹à¸Ÿà¸£à¸à¹€à¸¡à¸™à¸•์เชดเดà¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "'%s' input parameter for light shader mode." -msgstr "" +msgstr "'%s' พารามิเตà¸à¸£à¹Œà¸à¸´à¸™à¸žà¸¸à¸•สำหรับโหมดไลท์เชดเดà¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "'%s' input parameter for vertex shader mode." -msgstr "" +msgstr "'%s' พารามิเตà¸à¸£à¹Œà¸à¸´à¸™à¸žà¸¸à¸•สำหรับโหมดเวà¸à¸£à¹Œà¹€à¸—็à¸à¸‹à¹Œà¹€à¸Šà¸”เดà¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "'%s' input parameter for vertex and fragment shader mode." -msgstr "" +msgstr "'%s' พารามิเตà¸à¸£à¹Œà¸à¸´à¸™à¸žà¸¸à¸•สำหรับโหมดเวà¸à¸£à¹Œà¹€à¸—็à¸à¸‹à¹Œà¹€à¸Šà¸”เดà¸à¸£à¹Œà¹à¸¥à¸°à¹à¸Ÿà¸£à¸à¹€à¸¡à¸™à¸•์เชดเดà¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar function." -msgstr "à¹à¸à¹‰à¹„ขฟังà¸à¹Œà¸Šà¸±à¸™à¸ªà¹€à¸à¸¥à¸²à¸£à¹Œ" +msgstr "ฟังà¸à¹Œà¸Šà¸±à¸™à¸ªà¹€à¸à¸¥à¸²à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar operator." -msgstr "à¹à¸à¹‰à¹„ขเครื่à¸à¸‡à¸«à¸¡à¸²à¸¢à¸ªà¹€à¸à¸¥à¸²à¸£à¹Œ" +msgstr "ตัวดำเนินà¸à¸²à¸£à¸ªà¹€à¸à¸¥à¸²à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "E constant (2.718282). Represents the base of the natural logarithm." -msgstr "" +msgstr "ค่าคงที่ E (2.718282) à¹à¸ªà¸”งในรูปลà¸à¸à¸²à¸¥à¸´à¸—ึมà¸à¸²à¸™à¸˜à¸£à¸£à¸¡à¸Šà¸²à¸•ิ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Epsilon constant (0.00001). Smallest possible scalar number." -msgstr "" +msgstr "ค่าคงที่เà¸à¸žà¸‹à¸´à¸¥à¸à¸™ (0.00001) ค่าที่เล็à¸à¸—ี่สุดขà¸à¸‡à¸ªà¹€à¸à¸¥à¸²à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Phi constant (1.618034). Golden ratio." -msgstr "" +msgstr "ค่าฟาย (1.618034) สัดส่วนทà¸à¸‡à¸„ำ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi/4 constant (0.785398) or 45 degrees." -msgstr "" +msgstr "ค่าพายส่วน 4 (0.785398) หรืภ45à¸à¸‡à¸¨à¸²" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi/2 constant (1.570796) or 90 degrees." -msgstr "" +msgstr "ค่าพายส่วน2 (1.570796) หรืภ90 à¸à¸‡à¸¨à¸²" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi constant (3.141593) or 180 degrees." -msgstr "" +msgstr "ค่าพาย (3.141593) หรืภ180 à¸à¸‡à¸¨à¸²" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Tau constant (6.283185) or 360 degrees." -msgstr "" +msgstr "ค่าเทา (6.283185) หรืภ360 à¸à¸‡à¸¨à¸²" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Sqrt2 constant (1.414214). Square root of 2." -msgstr "" +msgstr "ค่ารูท2 (1.414214)" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the absolute value of the parameter." -msgstr "" +msgstr "คืนค่าสัมบูรณ์ขà¸à¸‡à¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-cosine of the parameter." -msgstr "" +msgstr "คืนค่า arc-cosine ขà¸à¸‡à¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the inverse hyperbolic cosine of the parameter." -msgstr "" +msgstr "คืนค่า arc cosh ขà¸à¸‡à¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-sine of the parameter." @@ -9276,121 +8909,121 @@ msgstr "คืนค่า arc tan ขà¸à¸‡à¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-tangent of the parameters." -msgstr "" +msgstr "คืนค่า arc tan ขà¸à¸‡à¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the inverse hyperbolic tangent of the parameter." -msgstr "" +msgstr "คืนค่า tanh ขà¸à¸‡à¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Finds the nearest integer that is greater than or equal to the parameter." -msgstr "" +msgstr "หาจำนวนเต็มใà¸à¸¥à¹‰à¸—ี่สุดที่มาà¸à¸à¸§à¹ˆà¸²à¸«à¸£à¸·à¸à¹€à¸—่าà¸à¸±à¸šà¸„่าพารามิเตà¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Constrains a value to lie between two further values." -msgstr "" +msgstr "จำà¸à¸±à¸”ค่าไว้ระหว่างà¸à¸µà¸à¸ªà¸à¸‡à¸„่า" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the cosine of the parameter." -msgstr "" +msgstr "คืนค่า cos ขà¸à¸‡à¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the hyperbolic cosine of the parameter." -msgstr "" +msgstr "คืนค่า cosh ขà¸à¸‡à¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts a quantity in radians to degrees." -msgstr "" +msgstr "à¹à¸›à¸¥à¸‡à¹€à¸£à¹€à¸”ียนเป็นà¸à¸‡à¸¨à¸²" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-e Exponential." -msgstr "" +msgstr "เลขยà¸à¸à¸³à¸¥à¸±à¸‡à¸à¸²à¸™ e" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-2 Exponential." -msgstr "" +msgstr "เลขยà¸à¸à¸³à¸¥à¸±à¸‡à¸à¸²à¸™ 2" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Finds the nearest integer less than or equal to the parameter." -msgstr "" +msgstr "หาค่าจำนวนเต็มที่ใà¸à¸¥à¹‰à¸—ี่สุดที่น้à¸à¸¢à¸à¸§à¹ˆà¸²à¸«à¸£à¸·à¸à¹€à¸—่าà¸à¸±à¸šà¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Computes the fractional part of the argument." -msgstr "" +msgstr "คำนวณสัดส่วนจาà¸à¸à¸²à¸à¸´à¸§à¹€à¸¡à¸™à¸•์" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the inverse of the square root of the parameter." -msgstr "" +msgstr "คืนค่ารูทสà¸à¸‡à¸‚à¸à¸‡à¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Natural logarithm." -msgstr "" +msgstr "ลà¸à¸à¸²à¸¥à¸´à¸—ึมà¸à¸²à¸™à¸˜à¸£à¸£à¸¡à¸Šà¸²à¸•ิ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-2 logarithm." -msgstr "" +msgstr "ลà¸à¸à¸²à¸¥à¸´à¸—ึมà¸à¸²à¸™ 2" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the greater of two values." -msgstr "" +msgstr "คืนค่ามาà¸à¸ªà¸¸à¸” จาà¸à¸ªà¸à¸‡à¸„่า" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the lesser of two values." -msgstr "" +msgstr "คืนค่าน้à¸à¸¢à¸ªà¸¸à¸” จาà¸à¸ªà¸à¸‡à¸„่า" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Linear interpolation between two scalars." -msgstr "" +msgstr "ค่าประมาณเชิงเส้นระหว่างสเà¸à¸¥à¸²à¸£à¹Œà¸ªà¸à¸‡à¸„่า" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the opposite value of the parameter." -msgstr "" +msgstr "คืนค่าตรงà¸à¸±à¸™à¸‚้ามจาà¸à¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 - scalar" -msgstr "" +msgstr "1.0 - สเà¸à¸¥à¸²à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns the value of the first parameter raised to the power of the second." -msgstr "" +msgstr "คืนค่าพารามิเตà¸à¸£à¹Œà¸•ัวà¹à¸£à¸à¸¢à¸à¸à¸³à¸¥à¸±à¸‡à¸”้วยพารามิเตà¸à¸£à¹Œà¸•ัวที่สà¸à¸‡" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts a quantity in degrees to radians." -msgstr "" +msgstr "à¹à¸›à¸¥à¸‡à¸„่าà¸à¸‡à¸¨à¸²à¹€à¸›à¹‡à¸™à¹€à¸£à¹€à¸”ียน" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 / scalar" -msgstr "" +msgstr "1.0 / สเà¸à¸¥à¸²à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Finds the nearest integer to the parameter." -msgstr "" +msgstr "หาจำนวนเต็มที่ใà¸à¸¥à¹‰à¸à¸±à¸šà¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•à¸à¸£à¹Œà¸¡à¸²à¸à¸—ี่สุด" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Finds the nearest even integer to the parameter." -msgstr "" +msgstr "หาเลขคู่ที่ใà¸à¸¥à¹‰à¸à¸±à¸šà¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•à¸à¸£à¹Œà¸¡à¸²à¸à¸—ี่สุด" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Clamps the value between 0.0 and 1.0." -msgstr "" +msgstr "จำà¸à¸±à¸”ค่าให้à¸à¸¢à¸¹à¹‹à¸£à¸°à¸«à¸§à¹ˆà¸²à¸‡ 0.0 à¸à¸±à¸š 1.0" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Extracts the sign of the parameter." -msgstr "" +msgstr "หาเครื่à¸à¸‡à¸«à¸¡à¸²à¸¢à¸‚à¸à¸‡à¸žà¸²à¸£à¸²à¸žà¸´à¹€à¸•à¸à¸£à¹Œ (บวà¸/ลบ)" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the sine of the parameter." -msgstr "" +msgstr "คืนค่า sine ขà¸à¸‡à¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the hyperbolic sine of the parameter." -msgstr "" +msgstr "คืนค่า sinh ขà¸à¸‡à¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the square root of the parameter." -msgstr "" +msgstr "คืนค่ารูทสà¸à¸‡à¸‚à¸à¸‡à¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -9400,6 +9033,10 @@ msgid "" "'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " "using Hermite polynomials." msgstr "" +"SmoothStep function( สเà¸à¸¥à¸²à¸£à¹Œ(edge0), สเà¸à¸¥à¸²à¸£à¹Œ(edge1), สเà¸à¸¥à¸²à¸£à¹Œ(x) )\n" +"\n" +"คืนค่า 0.0 ถ้า x น้à¸à¸¢à¸à¸§à¹ˆà¸² 'edge0' à¹à¸¥à¸° 1.0 ถ้ามาà¸à¸à¸§à¹ˆà¸² 'edge1' หรืà¸à¸„ืนค่าระหว่าง 0.0 - " +"1.0 โดยใช้ Hermite polynomials" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -9407,56 +9044,57 @@ msgid "" "\n" "Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0." msgstr "" +"Step function( สเà¸à¸¥à¸²à¸£à¹Œ(edge), สเà¸à¸¥à¸²à¸£à¹Œ(x) )\n" +"\n" +"คืนค่า 0.0 ถ้า x น้à¸à¸¢à¸à¸§à¹ˆà¸² edge ถ้าไม่ใช่จะคืนค่า 1.0" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the tangent of the parameter." -msgstr "" +msgstr "คืนค่า tan ขà¸à¸‡à¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the hyperbolic tangent of the parameter." -msgstr "" +msgstr "คืนค่า tanh ขà¸à¸‡à¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Finds the truncated value of the parameter." -msgstr "" +msgstr "หาค่าตัดหลัà¸à¸—ศนิยม(truncated value) ขà¸à¸‡à¸žà¸²à¸£à¸²à¸¡à¸´à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Adds scalar to scalar." -msgstr "" +msgstr "บวà¸à¸ªà¹€à¸à¸¥à¸²à¸£à¹Œà¸”้วยสเà¸à¸¥à¸²à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Divides scalar by scalar." -msgstr "" +msgstr "หารสเà¸à¸¥à¸²à¸£à¹Œà¸”้วยสเà¸à¸¥à¸²à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies scalar by scalar." -msgstr "" +msgstr "คูณสเà¸à¸¥à¸²à¸£à¹Œà¸”้วยสเà¸à¸¥à¸²à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the remainder of the two scalars." -msgstr "" +msgstr "คืนค่าเศษผลหารขà¸à¸‡à¸ªà¹€à¸à¸¥à¸²à¸£à¹Œà¸ªà¸à¸‡à¸à¸±à¸™" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Subtracts scalar from scalar." -msgstr "" +msgstr "ลบสเà¸à¸¥à¸²à¸£à¹Œà¸”้วยสเà¸à¸¥à¸²à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar constant." -msgstr "à¹à¸à¹‰à¹„ขค่าคงที่สเà¸à¸¥à¸²à¸£à¹Œ" +msgstr "ค่าคงที่สเà¸à¸¥à¸²à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar uniform." -msgstr "à¹à¸à¹‰à¹„ขสเà¸à¸¥à¸²à¸£à¹Œ Uniform" +msgstr "ยูนิฟà¸à¸£à¹Œà¸¡à¸ªà¹€à¸à¸¥à¸²à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Perform the cubic texture lookup." -msgstr "" +msgstr "ทำà¸à¸²à¸£à¸„้นหาเทà¸à¹€à¸ˆà¸à¸£à¹Œà¸¥à¸¹à¸à¸šà¸²à¸¨à¸à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Perform the texture lookup." -msgstr "" +msgstr "ทำà¸à¸²à¸£à¸„้นหาเทà¸à¹€à¸ˆà¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -9499,23 +9137,23 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the determinant of a transform." -msgstr "" +msgstr "คำนวณดีเทà¸à¸£à¹Œà¸¡à¸´à¹à¸™à¸™à¸•์ขà¸à¸‡à¸—รานฟà¸à¸£à¹Œà¸¡" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the inverse of a transform." -msgstr "" +msgstr "คำนวณà¸à¸´à¸™à¹€à¸§à¸à¸£à¹Œà¸ªà¸‚à¸à¸‡à¸—รานฟà¸à¸£à¹Œà¸¡" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the transpose of a transform." -msgstr "" +msgstr "คำนวณทรานสโพสขà¸à¸‡à¸—รานฟà¸à¸£à¹Œà¸¡" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies transform by transform." -msgstr "" +msgstr "คูณทรานฟà¸à¸£à¹Œà¸¡à¸”้วยทรานฟà¸à¸£à¹Œà¸¡" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies vector by transform." -msgstr "" +msgstr "คูณเวà¸à¹€à¸•à¸à¸£à¹Œà¸”้วยทรานฟà¸à¸£à¹Œà¸¡" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -9528,34 +9166,32 @@ msgid "Transform uniform." msgstr "ยà¸à¹€à¸¥à¸´à¸à¸à¸²à¸£à¹€à¸„ลื่à¸à¸™à¸¢à¹‰à¸²à¸¢" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector function." -msgstr "ไปยังฟังà¸à¹Œà¸Šà¸±à¸™..." +msgstr "ฟังà¸à¹Œà¸Šà¸±à¸™à¹€à¸§à¸à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector operator." -msgstr "à¹à¸à¹‰à¹„ขเครื่à¸à¸‡à¸«à¸¡à¸²à¸¢à¹€à¸§à¸à¹€à¸•à¸à¸£à¹Œ" +msgstr "ตัวดำเนินà¸à¸²à¸£à¹€à¸§à¸à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Composes vector from three scalars." -msgstr "" +msgstr "สร้างเวà¸à¹€à¸•à¸à¸£à¹Œà¸ˆà¸²à¸à¸ªà¹€à¸à¸¥à¸²à¸£à¹Œà¸ªà¸²à¸¡à¸•ัว" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Decomposes vector to three scalars." -msgstr "" +msgstr "สร้างสเà¸à¸¥à¸²à¸£à¹Œà¸ªà¸²à¸¡à¸•ัวจาà¸à¹€à¸§à¸à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the cross product of two vectors." -msgstr "" +msgstr "หาผลคูณเชิงเวà¸à¹€à¸•à¸à¸£à¹Œ(cross product) ขà¸à¸‡à¹€à¸§à¸à¹€à¸•à¸à¸£à¹Œà¸ªà¸à¸‡à¸•ัว" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the distance between two points." -msgstr "" +msgstr "คืนค่าระยะห่างระหว่างสà¸à¸‡à¸ˆà¸¸à¸”" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the dot product of two vectors." -msgstr "" +msgstr "คำนวณผลคูณเชิงสเà¸à¸¥à¸¥à¸²à¸£à¹Œ (dot) ขà¸à¸‡à¹€à¸§à¸à¹€à¸•à¸à¸£à¹Œà¸ªà¸à¸‡à¸•ัว" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -9567,27 +9203,27 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the length of a vector." -msgstr "" +msgstr "หาขนาดเวà¸à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Linear interpolation between two vectors." -msgstr "" +msgstr "à¸à¸²à¸£à¸›à¸£à¸°à¸¡à¸²à¸“ค่าเชิงเส้นระหว่างสà¸à¸‡à¹€à¸§à¸à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Linear interpolation between two vectors using scalar." -msgstr "" +msgstr "à¸à¸²à¸£à¸›à¸£à¸°à¸¡à¸²à¸“ค่าเชิงเส้นระหว่างสà¸à¸‡à¹€à¸§à¸à¹€à¸•à¸à¸£à¹Œà¹‚ดยใช้สเà¸à¸¥à¸²à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the normalize product of vector." -msgstr "" +msgstr "คำนวณหาเวà¸à¹€à¸•à¸à¸£à¹Œà¸«à¸™à¹ˆà¸§à¸¢à¸‚à¸à¸‡à¹€à¸§à¸à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 - vector" -msgstr "" +msgstr "1.0 - เวà¸à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 / vector" -msgstr "" +msgstr "1.0 / เวà¸à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -9597,7 +9233,7 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the vector that points in the direction of refraction." -msgstr "" +msgstr "คืนค่าเวà¸à¹€à¸•à¸à¸£à¹Œà¸—ี่มีทิศทางที่เà¸à¸´à¸”จาà¸à¸à¸²à¸£à¸«à¸±à¸à¹€à¸«" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -9607,6 +9243,10 @@ msgid "" "'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " "using Hermite polynomials." msgstr "" +"SmoothStep function( เวà¸à¹€à¸•à¸à¸£à¹Œ(edge0), เวà¸à¹€à¸•à¸à¸£à¹Œ(edge1), เวà¸à¹€à¸•à¸à¸£à¹Œ(x) ).\n" +"\n" +"คืนค่า 0.0 ถ้า 'x' น้à¸à¸¢à¸à¸§à¹ˆà¸² 'edge0' à¹à¸¥à¸° 1.0 ถ้า 'x' มาà¸à¸à¸§à¹ˆà¸² 'edge1' " +"นà¸à¸à¸™à¸±à¹‰à¸™à¸ˆà¸°à¸„ืนค่าระหว่าง 0.0 à¸à¸±à¸š 1.0 โดยใช้สูตรพหุนามเฮà¸à¹„มท์ (Hermite polynomials)" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -9616,6 +9256,10 @@ msgid "" "'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " "using Hermite polynomials." msgstr "" +"SmoothStep function( สเà¸à¸¥à¸²à¸£à¹Œ(edge0), สเà¸à¸¥à¸²à¸£à¹Œ(edge1), เวà¸à¹€à¸•à¸à¸£à¹Œ(x) )\n" +"\n" +"คืนค่า 0.0 ถ้า 'x' น้à¸à¸¢à¸à¸§à¹ˆà¸² 'edge0' à¹à¸¥à¸° 1.0 ถ้า 'x' มาà¸à¸à¸§à¹ˆà¸² 'edge1' " +"นà¸à¸à¸™à¸±à¹‰à¸™à¸ˆà¸°à¸„ืนค่าระหว่าง 0.0 à¸à¸±à¸š 1.0 โดยใช้สูตรพหุนามเฮà¸à¹„มท์ (Hermite polynomials)" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -9623,6 +9267,9 @@ msgid "" "\n" "Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0." msgstr "" +"Step function( เวà¸à¹€à¸•à¸à¸£à¹Œ(edge), เวà¸à¹€à¸•à¸à¸£à¹Œ(x) ).\n" +"\n" +"คืนค่า 0.0 ถ้า x น้à¸à¸¢à¸à¸§à¹ˆà¸² edge ถ้าไม่ใช่ คืนค่า 1.0" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -9630,36 +9277,37 @@ msgid "" "\n" "Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0." msgstr "" +"Step function( สเà¸à¸¥à¸²à¸£à¹Œ(edge), เวà¸à¹€à¸•à¸à¸£à¹Œ(x) ).\n" +"\n" +"คืนค่า 0.0 ถ้า 'x' น้à¸à¸¢à¸à¸§à¹ˆà¸² 'edge' ถ้าไม่ใช่จะคืนค่า 1.0" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Adds vector to vector." -msgstr "" +msgstr "บวà¸à¹€à¸§à¸à¹€à¸•à¸à¸£à¹Œà¸”้วยเวà¸à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Divides vector by vector." -msgstr "" +msgstr "หารเวà¸à¹€à¸•à¸à¸£à¹Œà¸”้วยเวà¸à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies vector by vector." -msgstr "" +msgstr "คูณเวà¸à¹€à¸•à¸à¸£à¹Œà¸”้วยเวà¸à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the remainder of the two vectors." -msgstr "" +msgstr "คืนค่าเศษหารขà¸à¸‡à¹€à¸§à¸à¹€à¸•à¸à¸£à¹Œà¸ªà¸à¸‡à¹€à¸§à¸à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Subtracts vector from vector." -msgstr "" +msgstr "ลบเวà¸à¹€à¸•à¸à¸£à¹Œà¸”้วยเวà¸à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector constant." -msgstr "à¹à¸à¹‰à¹„ขค่าคงที่เวà¸à¹€à¸•à¸à¸£à¹Œ" +msgstr "ค่าคงที่เวà¸à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector uniform." -msgstr "à¹à¸à¹‰à¹„ขเวà¸à¹€à¸•à¸à¸£à¹Œ Uniform" +msgstr "ยูนิฟà¸à¸£à¹Œà¸¡à¹€à¸§à¸à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -9684,11 +9332,11 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(Fragment/Light mode only) Scalar derivative function." -msgstr "" +msgstr "(โหมดà¹à¸Ÿà¸£à¸à¹€à¸¡à¸™à¸•์/à¹à¸ªà¸‡ เท่านั้น) ฟังà¸à¹Œà¸Šà¸±à¸™à¸à¸™à¸¸à¸žà¸±à¸™à¸˜à¹Œà¸ªà¹€à¸à¸¥à¸²à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(Fragment/Light mode only) Vector derivative function." -msgstr "" +msgstr "(โหมดà¹à¸Ÿà¸£à¸à¹€à¸¡à¸™à¸•์/à¹à¸ªà¸‡ เท่านั้น) ฟังà¸à¹Œà¸Šà¸±à¸™à¸à¸™à¸¸à¸žà¸±à¸™à¸˜à¹Œà¹€à¸§à¸à¹€à¸•à¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -9718,41 +9366,37 @@ msgstr "" msgid "" "(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and " "'y'." -msgstr "" +msgstr "(โหมดà¹à¸Ÿà¸£à¸à¹€à¸¡à¸™à¸•์/à¹à¸ªà¸‡ เท่านั้น) (เวà¸à¹€à¸•à¸à¸£à¹Œ) ผลรวมขà¸à¸‡à¸à¸™à¸¸à¸žà¸±à¸™à¸˜à¹Œà¸ªà¸±à¸¡à¸šà¸¹à¸£à¸“์ใน 'x' à¹à¸¥à¸° 'y'" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and " "'y'." -msgstr "" +msgstr "(โหมดà¹à¸Ÿà¸£à¸à¹€à¸¡à¸™à¸•์/à¹à¸ªà¸‡ เท่านั้น) (สเà¸à¸¥à¸²à¸£à¹Œ) ผลรวมขà¸à¸‡à¸à¸™à¸¸à¸žà¸±à¸™à¸˜à¹Œà¸ªà¸±à¸¡à¸šà¸¹à¸£à¸“์ใน 'x' à¹à¸¥à¸° 'y'" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "VisualShader" -msgstr "Shader" +msgstr "เวà¸à¸£à¹Œà¸Šà¸§à¸¥à¹€à¸Šà¸”เดà¸à¸£à¹Œ" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Edit Visual Property" -msgstr "à¹à¸à¹‰à¹„ขตัวà¸à¸£à¸à¸‡" +msgstr "à¹à¸à¹‰à¹„ขคุณสมบัติเวà¸à¸£à¹Œà¸Šà¸§à¸¥" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Visual Shader Mode Changed" -msgstr "จำนวนครั้งที่เปลี่ยน Shader" +msgstr "เปลี่ยนโหมดเวà¸à¸£à¹Œà¸Šà¸§à¸¥à¹€à¸Šà¸”เดà¸à¸£à¹Œà¹à¸¥à¹‰à¸§" #: editor/project_export.cpp msgid "Runnable" -msgstr "รันได้" +msgstr "สามารถรันได้" #: editor/project_export.cpp -#, fuzzy msgid "Add initial export..." -msgstr "เพิ่มà¸à¸´à¸™à¸žà¸¸à¸•" +msgstr "เพิ่มà¸à¸²à¸£à¸ªà¹ˆà¸‡à¸à¸à¸à¹€à¸£à¸´à¹ˆà¸¡à¸•้น..." #: editor/project_export.cpp msgid "Add previous patches..." -msgstr "" +msgstr "เพิ่มà¹à¸žà¸—ช์à¸à¹ˆà¸à¸™à¸«à¸™à¹‰à¸²..." #: editor/project_export.cpp msgid "Delete patch '%s' from list?" @@ -9776,19 +9420,16 @@ msgid "" msgstr "" #: editor/project_export.cpp -#, fuzzy msgid "Release" -msgstr "เพิ่งปล่à¸à¸¢" +msgstr "เผยà¹à¸žà¸£à¹ˆ" #: editor/project_export.cpp -#, fuzzy msgid "Exporting All" -msgstr "ส่งà¸à¸à¸à¸ªà¸³à¸«à¸£à¸±à¸š %s" +msgstr "ส่งà¸à¸à¸à¸—ั้งหมด" #: editor/project_export.cpp -#, fuzzy msgid "The given export path doesn't exist:" -msgstr "ไม่พบไฟล์" +msgstr "ไม่พบที่à¸à¸¢à¸¹à¹ˆà¸ªà¹ˆà¸‡à¸à¸à¸:" #: editor/project_export.cpp msgid "Export templates for this platform are missing/corrupted:" @@ -9809,17 +9450,16 @@ msgid "" msgstr "" #: editor/project_export.cpp -#, fuzzy msgid "Export Path" -msgstr "ส่งà¸à¸à¸à¹‚ปรเจà¸à¸•์" +msgstr "ไดเรà¸à¸—à¸à¸£à¸µà¸ªà¹ˆà¸‡à¸à¸à¸" #: editor/project_export.cpp msgid "Resources" -msgstr "รีซà¸à¸£à¹Œà¸ª" +msgstr "ทรัพยาà¸à¸£" #: editor/project_export.cpp msgid "Export all resources in the project" -msgstr "ส่งà¸à¸à¸à¸—ุà¸à¸£à¸µà¸‹à¸à¸£à¹Œà¸ªà¹ƒà¸™à¹‚ปรเจà¸à¸•์" +msgstr "ส่งà¸à¸à¸à¸—รัพยาà¸à¸£à¸—ั้งหมดในโปรเจà¸à¸•์" #: editor/project_export.cpp msgid "Export selected scenes (and dependencies)" @@ -9877,9 +9517,8 @@ msgid "Feature List:" msgstr "รายชื่à¸à¸Ÿà¸µà¹€à¸ˆà¸à¸£à¹Œ:" #: editor/project_export.cpp -#, fuzzy msgid "Script" -msgstr "สคริปต์ใหม่" +msgstr "สคริปต์" #: editor/project_export.cpp msgid "Script Export Mode:" @@ -9899,7 +9538,7 @@ msgstr "เข้ารหัส (ใส่คีย์ด้านล่าง) #: editor/project_export.cpp msgid "Invalid Encryption Key (must be 64 characters long)" -msgstr "" +msgstr "คีย์เข้ารหัสไม่ถูà¸à¸•้à¸à¸‡ (ต้à¸à¸‡à¸¡à¸µ 64 à¸à¸±à¸à¸©à¸£)" #: editor/project_export.cpp msgid "Script Encryption Key (256-bits as hex):" @@ -9914,23 +9553,20 @@ msgid "Export Project" msgstr "ส่งà¸à¸à¸à¹‚ปรเจà¸à¸•์" #: editor/project_export.cpp -#, fuzzy msgid "Export mode?" -msgstr "วิธีà¸à¸²à¸£à¸ªà¹ˆà¸‡à¸à¸à¸:" +msgstr "ส่งà¸à¸à¸à¹‚หมด?" #: editor/project_export.cpp -#, fuzzy msgid "Export All" -msgstr "ส่งà¸à¸à¸" +msgstr "ส่งà¸à¸à¸à¸—ั้งหมด" #: editor/project_export.cpp editor/project_manager.cpp -#, fuzzy msgid "ZIP File" -msgstr " ไฟล์" +msgstr "ไฟล์ ZIP" #: editor/project_export.cpp msgid "Godot Game Pack" -msgstr "" +msgstr "Godot เà¸à¸¡à¹à¸žà¹‡à¸„" #: editor/project_export.cpp msgid "Export templates for this platform are missing:" @@ -9945,50 +9581,45 @@ msgid "Export With Debug" msgstr "ส่งà¸à¸à¸à¸žà¸£à¹‰à¸à¸¡à¸à¸²à¸£à¹à¸à¹‰à¹„ขจุดบà¸à¸žà¸£à¹ˆà¸à¸‡" #: editor/project_manager.cpp -#, fuzzy msgid "The path specified doesn't exist." -msgstr "ไม่พบไฟล์" +msgstr "ไม่พบที่à¸à¸¢à¸¹à¹ˆà¸—ี่ระบุเà¸à¸²à¹„ว้" #: editor/project_manager.cpp -#, fuzzy msgid "Error opening package file (it's not in ZIP format)." -msgstr "ผิดพลาดขณะเปิดไฟล์à¹à¸žà¸„เà¸à¸ˆ, ไม่ใช่รูปà¹à¸šà¸š zip" +msgstr "ผิดพลาดขณะเปิดไฟล์à¹à¸žà¸„เà¸à¸ˆ (ไม่ใช่ไฟล์นามสà¸à¸¸à¸¥ zip)" #: editor/project_manager.cpp -#, fuzzy msgid "" "Invalid \".zip\" project file; it doesn't contain a \"project.godot\" file." -msgstr "à¸à¸£à¸¸à¸“าเลืà¸à¸à¹‚ฟลเดà¸à¸£à¹Œà¸—ี่ไม่มีไฟล์ 'project.godot'" +msgstr "ไฟล์โปรเจà¸à¸•์ \".zip\" ผิดพลาด เนื่à¸à¸‡à¸ˆà¸²à¸à¹„ม่มีไฟล์ \"project.godot\"" #: editor/project_manager.cpp msgid "Please choose an empty folder." msgstr "à¸à¸£à¸¸à¸“าเลืà¸à¸à¹‚ฟลเดà¸à¸£à¹Œà¸§à¹ˆà¸²à¸‡à¹€à¸›à¸¥à¹ˆà¸²" #: editor/project_manager.cpp -#, fuzzy msgid "Please choose a \"project.godot\" or \".zip\" file." -msgstr "à¸à¸£à¸¸à¸“าเลืà¸à¸à¹„ฟล์ 'project.godot'" +msgstr "à¸à¸£à¸¸à¸“าเลืà¸à¸à¹„ฟล์ \"project.godot\" หรืà¸à¹„ฟล์ \".zip\"" #: editor/project_manager.cpp msgid "This directory already contains a Godot project." -msgstr "" +msgstr "ไดเรà¸à¸—à¸à¸£à¸µà¸™à¸µà¹‰à¸¡à¸µà¹‚ปรเจà¸à¸•์ Godot à¸à¸¢à¸¹à¹ˆà¹à¸¥à¹‰à¸§" #: editor/project_manager.cpp msgid "New Game Project" -msgstr "โปรเจà¸à¸•์ใหม่" +msgstr "โปรเจà¸à¸•์เà¸à¸¡à¹ƒà¸«à¸¡à¹ˆ" #: editor/project_manager.cpp msgid "Imported Project" msgstr "นำเข้าโปรเจà¸à¸•์à¹à¸¥à¹‰à¸§" #: editor/project_manager.cpp -#, fuzzy msgid "Invalid Project Name." -msgstr "ชื่à¸à¹‚ปรเจà¸à¸•์:" +msgstr "ชื่à¸à¹‚ปรเจà¸à¸•์ไม่ถูà¸à¸•้à¸à¸‡" #: editor/project_manager.cpp msgid "Couldn't create folder." -msgstr "ไม่สามารถสร้างโฟลเดà¸à¸£à¹Œ" +msgstr "ไม่สามารถสร้างโฟลเดà¸à¸£à¹Œà¹„ด้" #: editor/project_manager.cpp msgid "There is already a folder in this path with the specified name." @@ -10054,17 +9685,16 @@ msgid "Project Path:" msgstr "ที่à¸à¸¢à¸¹à¹ˆà¹‚ปรเจà¸à¸•์:" #: editor/project_manager.cpp -#, fuzzy msgid "Project Installation Path:" -msgstr "ที่à¸à¸¢à¸¹à¹ˆà¹‚ปรเจà¸à¸•์:" +msgstr "ที่à¸à¸¢à¸¹à¹ˆà¸—ี่ใช้ติดตั้งโปรเจà¸à¸•์:" #: editor/project_manager.cpp msgid "Renderer:" -msgstr "" +msgstr "ตัวเรนเดà¸à¸£à¹Œ:" #: editor/project_manager.cpp msgid "OpenGL ES 3.0" -msgstr "" +msgstr "OpenGL ES 3.0" #: editor/project_manager.cpp msgid "" @@ -10073,10 +9703,14 @@ msgid "" "Incompatible with older hardware\n" "Not recommended for web games" msgstr "" +"à¸à¸²à¸£à¹à¸ªà¸”งผลที่ดีà¸à¸§à¹ˆà¸²\n" +"คุณสมบัติที่มาà¸à¸à¸§à¹ˆà¸²\n" +"ไม่รà¸à¸‡à¸£à¸±à¸šà¸®à¸²à¸£à¹Œà¸”à¹à¸§à¸£à¹Œà¸£à¸¸à¹ˆà¸™à¹€à¸à¹ˆà¸²\n" +"ไม่เหมาะสำหรับเà¸à¸¡à¸ªà¹Œà¸šà¸™à¹€à¸§à¹‡à¸š" #: editor/project_manager.cpp msgid "OpenGL ES 2.0" -msgstr "" +msgstr "OpenGL ES 2.0" #: editor/project_manager.cpp msgid "" @@ -10085,28 +9719,30 @@ msgid "" "Works on most hardware\n" "Recommended for web games" msgstr "" +"คุณภาพà¸à¸²à¸£à¹à¸ªà¸”งผลน้à¸à¸¢à¸à¸§à¹ˆà¸²\n" +"ระบบที่น้à¸à¸¢à¸à¸§à¹ˆà¸²\n" +"ทำงานได้บนฮาร์ดà¹à¸§à¸£à¹Œà¸ªà¹ˆà¸§à¸™à¹ƒà¸«à¸à¹ˆ\n" +"เหมาะสำหรับสร้างเà¸à¸¡à¸ªà¹Œà¸šà¸™à¹€à¸§à¹‡à¸š" #: editor/project_manager.cpp msgid "Renderer can be changed later, but scenes may need to be adjusted." -msgstr "" +msgstr "ตัวเรนเดà¸à¸£à¹Œà¸ªà¸²à¸¡à¸²à¸£à¸–เปลี่ยนทีหลังได้ à¹à¸•่ฉาà¸à¸ˆà¸³à¹€à¸›à¹‡à¸™à¸•้à¸à¸‡à¸›à¸£à¸±à¸šà¹à¸•่ง" #: editor/project_manager.cpp msgid "Unnamed Project" msgstr "โปรเจà¸à¸•์ไม่มีชื่à¸" #: editor/project_manager.cpp -#, fuzzy msgid "Missing Project" -msgstr "นำเข้าโปรเจà¸à¸•์ที่มีà¸à¸¢à¸¹à¹ˆà¹€à¸”ิม" +msgstr "โปรเจà¸à¸•์หายไป" #: editor/project_manager.cpp msgid "Error: Project is missing on the filesystem." -msgstr "" +msgstr "Error:โปรเจà¸à¸•์หายไปจาà¸à¸£à¸°à¸šà¸šà¹„ฟล์" #: editor/project_manager.cpp -#, fuzzy msgid "Can't open project at '%s'." -msgstr "ไม่สามารถเปิดโปรเจà¸à¸•์" +msgstr "ไม่สามารถเปิดโปรเจà¸à¸•์ที่ '%s'" #: editor/project_manager.cpp msgid "Are you sure to open more than one project?" @@ -10142,6 +9778,7 @@ msgid "" "The project settings were created by a newer engine version, whose settings " "are not compatible with this version." msgstr "" +"à¸à¸²à¸£à¸•ั้งค่าโปรเจà¸à¸•์ถูà¸à¸ªà¸£à¹‰à¸²à¸‡à¹‚ดยโดยเà¸à¸™à¸ˆà¸´à¹‰à¸™à¸£à¸¸à¹ˆà¸™à¹ƒà¸«à¸¡à¹ˆà¸à¸§à¹ˆà¸² ซึ่งà¸à¸²à¸£à¸•ั้งค่านี้ไม่สามารถเข้าà¸à¸±à¸™à¹„ด้à¸à¸±à¸šà¹€à¸à¸™à¸ˆà¸´à¹‰à¸™à¸£à¸¸à¹ˆà¸™à¸™à¸µà¹‰" #: editor/project_manager.cpp #, fuzzy @@ -10162,9 +9799,8 @@ msgstr "" "à¸à¸£à¸¸à¸“าเปิดà¹à¸à¹‰à¹„ขโปรเจà¸à¸•์เพื่à¸à¸™à¸³à¹€à¸‚้าไฟล์" #: editor/project_manager.cpp -#, fuzzy msgid "Are you sure to run %d projects at once?" -msgstr "ยืนยันà¸à¸²à¸£à¸£à¸±à¸™à¹‚ปรเจà¸à¸•์มาà¸à¸à¸§à¹ˆà¸² 1 โปรเจà¸à¸•์?" +msgstr "ยืนยันà¸à¸²à¸£à¸£à¸±à¸™à¹‚ปรเจà¸à¸•์ %d โปรเจà¸à¸•์ทีเดียว?" #: editor/project_manager.cpp #, fuzzy @@ -10181,40 +9817,40 @@ msgid "" msgstr "ลบโปรเจà¸à¸•์à¸à¸à¸à¸ˆà¸²à¸à¸£à¸²à¸¢à¸Šà¸·à¹ˆà¸? (โฟลเดà¸à¸£à¹Œà¸ˆà¸°à¹„ม่ถูà¸à¸¥à¸š)" #: editor/project_manager.cpp -#, fuzzy msgid "" "Remove all missing projects from the list?\n" "The project folders' contents won't be modified." -msgstr "ลบโปรเจà¸à¸•์à¸à¸à¸à¸ˆà¸²à¸à¸£à¸²à¸¢à¸Šà¸·à¹ˆà¸? (โฟลเดà¸à¸£à¹Œà¸ˆà¸°à¹„ม่ถูà¸à¸¥à¸š)" +msgstr "" +"ลบโปรเจà¸à¸•์ที่หายไปà¸à¸à¸à¸ˆà¸²à¸à¸£à¸²à¸¢à¸Šà¸·à¹ˆà¸à¸«à¸£à¸·à¸à¹„ม่?\n" +"เนื้à¸à¸«à¸²à¹‚ฟลเดà¸à¸£à¹Œà¹‚ปรเจà¸à¸•์จะไม่ถูà¸à¹à¸à¹‰à¹„ข" #: editor/project_manager.cpp -#, fuzzy msgid "" "Language changed.\n" "The interface will update after restarting the editor or project manager." msgstr "" "เปลี่ยนภาษาà¹à¸¥à¹‰à¸§\n" -"à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸ˆà¸°à¸¡à¸µà¸œà¸¥à¹€à¸¡à¸·à¹ˆà¸à¹€à¸›à¸´à¸”โปรà¹à¸à¸£à¸¡à¹à¸à¹‰à¹„ขหรืà¸à¸•ัวจัดà¸à¸²à¸£à¹‚ปรเจà¸à¸•์ใหม่" +"à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸ˆà¸°à¸¡à¸µà¸œà¸¥à¹€à¸¡à¸·à¹ˆà¸à¹€à¸›à¸´à¸”เà¸à¸”ิเตà¸à¸£à¹Œà¸«à¸£à¸·à¸à¸•ัวจัดà¸à¸²à¸£à¹‚ปรเจà¸à¸•์ใหม่" #: editor/project_manager.cpp -#, fuzzy msgid "" "Are you sure to scan %s folders for existing Godot projects?\n" "This could take a while." -msgstr "จะทำà¸à¸²à¸£à¸ªà¹à¸à¸™à¸«à¸²à¹‚ปรเจà¸à¸•์ใน %s โฟลเดà¸à¸£à¹Œ ยืนยัน?" +msgstr "" +"ทำà¸à¸²à¸£à¸ªà¹à¸à¸™à¸«à¸²à¹‚ปรเจà¸à¸•์ ในโฟลเดà¸à¸£à¹Œ %s หรืà¸à¹„ม่?\n" +"à¸à¸²à¸ˆà¸ˆà¸°à¹ƒà¸Šà¹‰à¹€à¸§à¸¥à¸²à¸ªà¸±à¸à¸„รู่" #: editor/project_manager.cpp msgid "Project Manager" msgstr "ตัวจัดà¸à¸²à¸£à¹‚ปรเจà¸à¸•์" #: editor/project_manager.cpp -#, fuzzy msgid "Projects" msgstr "โปรเจà¸à¸•์" #: editor/project_manager.cpp msgid "Last Modified" -msgstr "" +msgstr "à¹à¸à¹‰à¹„ขล่าสุด" #: editor/project_manager.cpp msgid "Scan" @@ -10229,9 +9865,8 @@ msgid "New Project" msgstr "โปรเจà¸à¸•์ใหม่" #: editor/project_manager.cpp -#, fuzzy msgid "Remove Missing" -msgstr "ลบจุด" +msgstr "ลบที่หายไป" #: editor/project_manager.cpp msgid "Templates" @@ -10295,9 +9930,8 @@ msgid "Add Input Action Event" msgstr "เพิ่มปุ่มà¸à¸”ขà¸à¸‡à¸à¸²à¸£à¸à¸£à¸°à¸—ำ" #: editor/project_settings_editor.cpp -#, fuzzy msgid "All Devices" -msgstr "à¸à¸¸à¸›à¸à¸£à¸“์" +msgstr "à¸à¸¸à¸›à¸à¸£à¸“์ทั้งหมด" #: editor/project_settings_editor.cpp msgid "Device" @@ -10342,14 +9976,12 @@ msgid "Wheel Right Button" msgstr "เมาส์ขวา" #: editor/project_settings_editor.cpp -#, fuzzy msgid "X Button 1" -msgstr "ปุ่ม 6" +msgstr "X ปุ่ม 1" #: editor/project_settings_editor.cpp -#, fuzzy msgid "X Button 2" -msgstr "ปุ่ม 6" +msgstr "X ปุ่ม 2" #: editor/project_settings_editor.cpp msgid "Joypad Axis Index:" @@ -10435,7 +10067,7 @@ msgstr "ผิดพลาดขณะบันทึà¸à¸„่า" #: editor/project_settings_editor.cpp msgid "Settings saved OK." -msgstr "บันทึà¸à¹à¸¥à¹‰à¸§" +msgstr "บันทึà¸à¸à¸²à¸£à¸•ั้งค่าà¹à¸¥à¹‰à¸§" #: editor/project_settings_editor.cpp #, fuzzy @@ -10496,7 +10128,7 @@ msgstr "à¸à¸³à¸«à¸™à¸”เฉพาะ..." #: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp msgid "The editor must be restarted for changes to take effect." -msgstr "" +msgstr "ต้à¸à¸‡à¹€à¸›à¸´à¸”เà¸à¸”ิเตà¸à¸£à¹Œà¹ƒà¸«à¸¡à¹ˆà¹€à¸žà¸·à¹ˆà¸à¹ƒà¸«à¹‰à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸¡à¸µà¸œà¸¥" #: editor/project_settings_editor.cpp msgid "Input Map" @@ -10507,9 +10139,8 @@ msgid "Action:" msgstr "à¸à¸²à¸£à¸à¸£à¸°à¸—ำ:" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Action" -msgstr "à¸à¸²à¸£à¸à¸£à¸°à¸—ำ:" +msgstr "à¸à¸²à¸£à¸à¸£à¸°à¸—ำ" #: editor/project_settings_editor.cpp msgid "Deadzone" @@ -10541,7 +10172,7 @@ msgstr "à¸à¸²à¸£à¹à¸—นที่" #: editor/project_settings_editor.cpp msgid "Resources:" -msgstr "รีซà¸à¸£à¹Œà¸ª:" +msgstr "ทรัพยาà¸à¸£:" #: editor/project_settings_editor.cpp msgid "Remaps by Locale:" @@ -10556,7 +10187,6 @@ msgid "Locales Filter" msgstr "ตัวà¸à¸£à¸à¸‡à¸ ูมิภาค" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Show All Locales" msgstr "à¹à¸ªà¸”งทุà¸à¸ ูมิภาค" @@ -10603,7 +10233,7 @@ msgstr "ไฟล์..." #: editor/property_editor.cpp msgid "Dir..." -msgstr "โฟลเดà¸à¸£à¹Œ..." +msgstr "ไดเรà¸à¸—à¸à¸£à¸µ..." #: editor/property_editor.cpp msgid "Assign" @@ -10644,11 +10274,11 @@ msgstr "เปลี่ยนชื่à¸" #: editor/rename_dialog.cpp msgid "Prefix" -msgstr "" +msgstr "คำนำหน้า" #: editor/rename_dialog.cpp msgid "Suffix" -msgstr "" +msgstr "คำต่à¸à¸—้าย" #: editor/rename_dialog.cpp #, fuzzy @@ -10656,37 +10286,32 @@ msgid "Use Regular Expressions" msgstr "à¹à¸à¹‰à¹„ขสมà¸à¸²à¸£" #: editor/rename_dialog.cpp -#, fuzzy msgid "Advanced Options" -msgstr "ตัวเลืà¸à¸à¸à¸²à¸£à¸ˆà¸³à¸à¸±à¸”" +msgstr "ตัวเลืà¸à¸à¸‚ั้นสูง" #: editor/rename_dialog.cpp msgid "Substitute" -msgstr "" +msgstr "à¸à¸²à¸£à¹à¸—นที่" #: editor/rename_dialog.cpp -#, fuzzy msgid "Node name" -msgstr "ชื่à¸à¹‚หนด:" +msgstr "ชื่à¸à¹‚หนด" #: editor/rename_dialog.cpp msgid "Node's parent name, if available" -msgstr "" +msgstr "ชื่à¸à¹‚หนดà¹à¸¡à¹ˆ (ถ้ามี)" #: editor/rename_dialog.cpp -#, fuzzy msgid "Node type" -msgstr "หาประเภทขà¸à¸‡à¹‚หนด" +msgstr "ชนิดโหนด" #: editor/rename_dialog.cpp -#, fuzzy msgid "Current scene name" -msgstr "ฉาà¸à¸›à¸±à¸ˆà¸ˆà¸¸à¸šà¸±à¸™" +msgstr "ชื่à¸à¸‰à¸²à¸à¸›à¸±à¸ˆà¸ˆà¸¸à¸šà¸±à¸™" #: editor/rename_dialog.cpp -#, fuzzy msgid "Root node name" -msgstr "ชื่à¸à¹‚หนดราà¸:" +msgstr "ชื่à¸à¹‚หนดà¹à¸¡à¹ˆ" #: editor/rename_dialog.cpp msgid "" @@ -10696,7 +10321,7 @@ msgstr "" #: editor/rename_dialog.cpp msgid "Per-level Counter" -msgstr "" +msgstr "ตัวนับต่à¸à¹€à¸¥à¹€à¸§à¸¥" #: editor/rename_dialog.cpp msgid "If set the counter restarts for each group of child nodes" @@ -10704,12 +10329,11 @@ msgstr "" #: editor/rename_dialog.cpp msgid "Initial value for the counter" -msgstr "" +msgstr "ค่าเริ่มต้นในà¸à¸²à¸£à¸™à¸±à¸š" #: editor/rename_dialog.cpp -#, fuzzy msgid "Step" -msgstr "ขนาด:" +msgstr "ขั้น" #: editor/rename_dialog.cpp msgid "Amount by which counter is incremented for each node" @@ -10747,14 +10371,12 @@ msgid "Case" msgstr "" #: editor/rename_dialog.cpp -#, fuzzy msgid "To Lowercase" -msgstr "ตัวพิมพ์เล็à¸" +msgstr "ไปตัวพิมพ์เล็à¸" #: editor/rename_dialog.cpp -#, fuzzy msgid "To Uppercase" -msgstr "ตัวพิมพ์ใหà¸à¹ˆ" +msgstr "ไปตัวพิมพ์ใหà¸à¹ˆ" #: editor/rename_dialog.cpp #, fuzzy @@ -10767,9 +10389,8 @@ msgid "Regular Expression Error" msgstr "à¹à¸à¹‰à¹„ขสมà¸à¸²à¸£" #: editor/rename_dialog.cpp -#, fuzzy msgid "At character %s" -msgstr "ตัวà¸à¸±à¸à¸©à¸£à¸—ี่ใช้ได้:" +msgstr "ตัวà¸à¸±à¸à¸©à¸£à¸—ี่ใช้ได้ %s" #: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp msgid "Reparent Node" @@ -10826,9 +10447,8 @@ msgid "Instance Scene(s)" msgstr "à¸à¸´à¸™à¸ªà¹à¸•นซ์ฉาà¸" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Replace with Branch Scene" -msgstr "บันทึà¸à¸à¸´à¹ˆà¸‡à¹€à¸›à¹‡à¸™à¸‰à¸²à¸" +msgstr "à¹à¸—นที่ด้วยฉาà¸à¸¢à¹ˆà¸à¸¢" #: editor/scene_tree_dock.cpp msgid "Instance Child Scene" @@ -10867,32 +10487,28 @@ msgid "Instantiated scenes can't become root" msgstr "" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Make node as Root" -msgstr "เข้าใจ!" +msgstr "ทำโหนดให้เป็นโหนดà¹à¸¡à¹ˆ" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Delete %d nodes?" -msgstr "ลบโหนด" +msgstr "ลบโหนด %d ?" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Delete the root node \"%s\"?" -msgstr "ลบโหนด" +msgstr "ลบโหนดà¹à¸¡à¹ˆ \"%s\"?" #: editor/scene_tree_dock.cpp msgid "Delete node \"%s\" and its children?" -msgstr "" +msgstr "ลบโหนด \"%s\" à¹à¸¥à¸°à¹‚หนดลูà¸?" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Delete node \"%s\"?" -msgstr "ลบโหนด" +msgstr "ลบโหนด \"%s\"?" #: editor/scene_tree_dock.cpp msgid "Can not perform with the root node." -msgstr "ทำà¸à¸±à¸šà¹‚หนดราà¸à¹„ม่ได้" +msgstr "ไม่สามารถà¸à¸£à¸°à¸—ำà¸à¸±à¸šà¹‚หนดà¹à¸¡à¹ˆà¹„ด้" #: editor/scene_tree_dock.cpp msgid "This operation can't be done on instanced scenes." @@ -10920,34 +10536,28 @@ msgid "Make Local" msgstr "ระยะใà¸à¸¥à¹‰" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "New Scene Root" -msgstr "เข้าใจ!" +msgstr "ฉาà¸à¹à¸¡à¹ˆà¹ƒà¸«à¸¡à¹ˆ" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Create Root Node:" -msgstr "สร้างโหนด" +msgstr "สร้างโหนดà¹à¸¡à¹ˆ:" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "2D Scene" -msgstr "ฉาà¸" +msgstr "ฉาภ2D" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "3D Scene" -msgstr "ฉาà¸" +msgstr "ฉาภ3D" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "User Interface" -msgstr "ลบà¸à¸²à¸£à¸ªà¸·à¸šà¸—à¸à¸”" +msgstr "à¸à¸´à¸™à¹€à¸•à¸à¸£à¹Œà¹€à¸Ÿà¸ª" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Other Node" -msgstr "ลบโหนด" +msgstr "โหนดà¸à¸·à¹ˆà¸™à¹†" #: editor/scene_tree_dock.cpp msgid "Can't operate on nodes from a foreign scene!" @@ -10959,16 +10569,15 @@ msgstr "ทำà¸à¸±à¸šà¹‚หนดที่ฉาà¸à¸›à¸±à¸ˆà¸ˆà¸¸à¸šà¸±à¸™à¸ª #: editor/scene_tree_dock.cpp msgid "Attach Script" -msgstr "เชื่à¸à¸¡à¸ªà¸„ริปต์" +msgstr "à¹à¸™à¸šà¸ªà¸„ริปต์" #: editor/scene_tree_dock.cpp msgid "Remove Node(s)" msgstr "ลบโหนด" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Change type of node(s)" -msgstr "เปลี่ยนชื่à¸à¸à¸´à¸™à¸žà¸¸à¸•" +msgstr "เปลี่ยนชนิดขà¸à¸‡à¹‚หนด" #: editor/scene_tree_dock.cpp msgid "" @@ -11001,7 +10610,6 @@ msgid "Load As Placeholder" msgstr "โหลดเป็นตัวà¹à¸—น" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Open Documentation" msgstr "เปิดคู่มืà¸" @@ -11010,23 +10618,20 @@ msgid "Add Child Node" msgstr "เพิ่มโหนดลูà¸" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Expand/Collapse All" -msgstr "ยุบโฟลเดà¸à¸£à¹Œ" +msgstr "ขยาย/ยุบทั้งหมด" #: editor/scene_tree_dock.cpp msgid "Change Type" -msgstr "เปลี่ยนประเภท" +msgstr "เปลี่ยนชนิด" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Reparent to New Node" msgstr "หาโหนดà¹à¸¡à¹ˆà¹ƒà¸«à¸¡à¹ˆ" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Make Scene Root" -msgstr "เข้าใจ!" +msgstr "ตั้งเป็นฉาà¸à¹à¸¡à¹ˆ" #: editor/scene_tree_dock.cpp msgid "Merge From Scene" @@ -11045,7 +10650,6 @@ msgid "Delete (No Confirm)" msgstr "ลบ (ไม่ยืนยัน)" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Add/Create a New Node." msgstr "เพิ่ม/สร้างโหนดใหม่" @@ -11057,7 +10661,7 @@ msgstr "à¸à¸´à¸™à¸ªà¹à¸•นซ์ฉาà¸à¹€à¸›à¹‡à¸™à¹‚หนด สร้ภ#: editor/scene_tree_dock.cpp msgid "Attach a new or existing script for the selected node." -msgstr "เชื่à¸à¸¡à¸ªà¸„ริปต์ใหม่หรืà¸à¸—ี่มีà¸à¸¢à¸¹à¹ˆà¹€à¸”ิมให้à¸à¸±à¸šà¹‚หนดที่เลืà¸à¸" +msgstr "สร้างสคริปต์ให้โหนดที่เลืà¸à¸" #: editor/scene_tree_dock.cpp msgid "Clear a script for the selected node." @@ -11081,9 +10685,8 @@ msgid "Toggle Visible" msgstr "ซ่à¸à¸™/à¹à¸ªà¸”ง" #: editor/scene_tree_editor.cpp -#, fuzzy msgid "Unlock Node" -msgstr "เลืà¸à¸à¹‚หนด" +msgstr "ปลดล็à¸à¸„โหนด" #: editor/scene_tree_editor.cpp #, fuzzy @@ -11091,9 +10694,8 @@ msgid "Button Group" msgstr "ปุ่ม 7" #: editor/scene_tree_editor.cpp -#, fuzzy msgid "(Connecting From)" -msgstr "เชื่à¸à¸¡à¸•่à¸à¸œà¸´à¸”พลาด" +msgstr "(เชื่à¸à¸¡à¸•่à¸à¸ˆà¸²à¸)" #: editor/scene_tree_editor.cpp msgid "Node configuration warning:" @@ -11127,12 +10729,10 @@ msgstr "" "คลิà¸à¹€à¸žà¸·à¹ˆà¸à¹à¸ªà¸”งà¹à¸œà¸‡à¸à¸¥à¸¸à¹ˆà¸¡" #: editor/scene_tree_editor.cpp -#, fuzzy msgid "Open Script:" -msgstr "เปิดสคริปต์" +msgstr "เปิดสคริปต์:" #: editor/scene_tree_editor.cpp -#, fuzzy msgid "" "Node is locked.\n" "Click to unlock it." @@ -11158,6 +10758,8 @@ msgid "" "AnimationPlayer is pinned.\n" "Click to unpin." msgstr "" +"ปัà¸à¸«à¸¡à¸¸à¸” AnimationPlayer à¹à¸¥à¹‰à¸§\n" +"คลิà¸à¹€à¸žà¸·à¹ˆà¸à¹€à¸¥à¸´à¸à¸›à¸±à¸à¸«à¸¡à¸¸à¸”" #: editor/scene_tree_editor.cpp msgid "Invalid node name, the following characters are not allowed:" @@ -11180,14 +10782,12 @@ msgid "Select a Node" msgstr "เลืà¸à¸à¹‚หนด" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Path is empty." -msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡à¸—ี่à¸à¸¢à¸¹à¹ˆà¸§à¹ˆà¸²à¸‡à¹€à¸›à¸¥à¹ˆà¸²" +msgstr "ที่à¸à¸¢à¸¹à¹ˆà¸§à¹ˆà¸²à¸‡à¹€à¸›à¸¥à¹ˆà¸²" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Filename is empty." -msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡à¸šà¸±à¸™à¸—ึà¸à¸§à¹ˆà¸²à¸‡à¹€à¸›à¸¥à¹ˆà¸²!" +msgstr "ชื่à¸à¹„ฟล์ว่างเปล่า" #: editor/script_create_dialog.cpp #, fuzzy @@ -11200,9 +10800,8 @@ msgid "Invalid base path." msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡à¹€à¸£à¸´à¹ˆà¸¡à¸•้นไม่ถูà¸à¸•้à¸à¸‡" #: editor/script_create_dialog.cpp -#, fuzzy msgid "A directory with the same name exists." -msgstr "มีโฟลเดà¸à¸£à¹Œà¸Šà¸·à¹ˆà¸à¸™à¸µà¹‰à¸à¸¢à¸¹à¹ˆà¹à¸¥à¹‰à¸§" +msgstr "มีไดเรà¸à¸—à¸à¸£à¸µà¸Šà¸·à¹ˆà¸à¸™à¸µà¹‰à¸à¸¢à¸¹à¹ˆà¹à¸¥à¹‰à¸§" #: editor/script_create_dialog.cpp #, fuzzy @@ -11227,21 +10826,18 @@ msgid "Error loading script from %s" msgstr "ผิดพลาดขณะโหลดสคริปต์จาภ%s" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Overrides" -msgstr "à¸à¸³à¸«à¸™à¸”เฉพาะ..." +msgstr "à¹à¸—นที่" #: editor/script_create_dialog.cpp msgid "N/A" msgstr "ไม่มี" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Open Script / Choose Location" -msgstr "เปิดตัวà¹à¸à¹‰à¹„ขสคริปต์" +msgstr "เปิดสคริปต์ / เลืà¸à¸à¸—ี่à¸à¸¢à¸¹à¹ˆ" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Open Script" msgstr "เปิดสคริปต์" @@ -11251,19 +10847,16 @@ msgid "File exists, it will be reused." msgstr "มีไฟล์นี้à¸à¸¢à¸¹à¹ˆà¹à¸¥à¹‰à¸§ จะนำมาใช้" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid class name." msgstr "ชื่à¸à¸„ลาสไม่ถูà¸à¸•้à¸à¸‡" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid inherited parent name or path." msgstr "ชื่à¸à¸«à¸£à¸·à¸à¸•ำà¹à¸«à¸™à¹ˆà¸‡à¸—ีสืบทà¸à¸”ไม่ถูà¸à¸•้à¸à¸‡" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Script path/name is valid." -msgstr "สคริปต์ถูà¸à¸•้à¸à¸‡" +msgstr "ที่à¸à¸¢à¸¹à¹ˆ/ชื่à¸à¸‚à¸à¸‡à¸ªà¸„ริปต์ถูà¸à¸•้à¸à¸‡" #: editor/script_create_dialog.cpp #, fuzzy @@ -11276,29 +10869,30 @@ msgid "Built-in script (into scene file)." msgstr "à¸à¸±à¸‡à¸ªà¸„ริปต์ในไฟล์ฉาà¸" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Will create a new script file." -msgstr "สร้างสคริปต์ใหม่" +msgstr "จะทำà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¸ªà¸„ริปต์ใหม่" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Will load an existing script file." -msgstr "โหลดสคริปต์จาà¸à¸”ิสà¸à¹Œ" +msgstr "จะทำà¸à¸²à¸£à¹‚หลดไฟล์สคริปต์ที่มีà¸à¸¢à¸¹à¹ˆ" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Script file already exists." -msgstr "มีà¸à¸²à¸£à¸à¸£à¸°à¸—ำ '%s' à¸à¸¢à¸¹à¹ˆà¹à¸¥à¹‰à¸§!" +msgstr "ไฟล์สคริปต์มีà¸à¸¢à¸¹à¹ˆà¹à¸¥à¹‰à¸§" + +#: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Class Name:" -msgstr "ชื่à¸à¸„ลาส" +msgstr "ชื่à¸à¸„ลาส:" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Template:" -msgstr "à¹à¸¡à¹ˆà¹à¸šà¸š" +msgstr "à¹à¸¡à¹ˆà¹à¸šà¸š:" #: editor/script_create_dialog.cpp #, fuzzy @@ -11318,38 +10912,32 @@ msgid "Bytes:" msgstr "ไบต์:" #: editor/script_editor_debugger.cpp -#, fuzzy msgid "Warning:" -msgstr "คำเตืà¸à¸™" +msgstr "คำเตืà¸à¸™:" #: editor/script_editor_debugger.cpp msgid "Error:" msgstr "ผิดพลาด:" #: editor/script_editor_debugger.cpp -#, fuzzy msgid "C++ Error" -msgstr "คัดลà¸à¸à¸œà¸´à¸”พลาด" +msgstr "C++ ผิดพลาด" #: editor/script_editor_debugger.cpp -#, fuzzy msgid "C++ Error:" -msgstr "ผิดพลาด:" +msgstr "C++ ผิดพลาด:" #: editor/script_editor_debugger.cpp -#, fuzzy msgid "C++ Source" -msgstr "ต้นฉบับ:" +msgstr "C++ ต้นฉบับ" #: editor/script_editor_debugger.cpp -#, fuzzy msgid "Source:" msgstr "ต้นฉบับ:" #: editor/script_editor_debugger.cpp -#, fuzzy msgid "C++ Source:" -msgstr "ต้นฉบับ:" +msgstr "C++ ต้นฉบับ:" #: editor/script_editor_debugger.cpp #, fuzzy @@ -11375,9 +10963,8 @@ msgid "Video RAM" msgstr "หน่วยความจำวีดีโà¸" #: editor/script_editor_debugger.cpp -#, fuzzy msgid "Skip Breakpoints" -msgstr "ลบจุด" +msgstr "ข้ามเบรà¸à¸žà¸à¸¢à¸•์" #: editor/script_editor_debugger.cpp msgid "Inspect Previous Instance" @@ -11393,7 +10980,7 @@ msgstr "สà¹à¸•ค" #: editor/script_editor_debugger.cpp msgid "Profiler" -msgstr "ประสิทธิภาพ" +msgstr "ตัวตรวจวิเคราะห์ประสิทธิภาพ (Profiler)" #: editor/script_editor_debugger.cpp #, fuzzy @@ -11430,7 +11017,7 @@ msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡à¸£à¸µà¸‹à¸à¸£à¹Œà¸ª" #: editor/script_editor_debugger.cpp msgid "Type" -msgstr "ประเภท" +msgstr "ชนิด" #: editor/script_editor_debugger.cpp msgid "Format" @@ -11438,7 +11025,7 @@ msgstr "รูปà¹à¸šà¸š" #: editor/script_editor_debugger.cpp msgid "Usage" -msgstr "ใช้" +msgstr "à¸à¸²à¸£à¹ƒà¸Šà¹‰" #: editor/script_editor_debugger.cpp msgid "Misc" @@ -11462,26 +11049,23 @@ msgstr "à¸à¸³à¸«à¸™à¸”จาà¸à¸œà¸±à¸‡" #: editor/script_editor_debugger.cpp msgid "Export measures as CSV" -msgstr "" +msgstr "ส่งà¸à¸à¸à¸„่าเป็น CSV" #: editor/settings_config_dialog.cpp -#, fuzzy msgid "Erase Shortcut" -msgstr "à¸à¸à¸à¸™à¸¸à¹ˆà¸¡à¸™à¸§à¸¥" +msgstr "ลบทางลัด" #: editor/settings_config_dialog.cpp -#, fuzzy msgid "Restore Shortcut" -msgstr "ทางลัด" +msgstr "คืนค่าทางลัด" #: editor/settings_config_dialog.cpp -#, fuzzy msgid "Change Shortcut" -msgstr "à¹à¸à¹‰à¹„ขà¸à¸²à¸£à¸•รึง" +msgstr "à¹à¸à¹‰à¹„ขทางลัด" #: editor/settings_config_dialog.cpp msgid "Editor Settings" -msgstr "ตัวเลืà¸à¸à¹‚ปรà¹à¸à¸£à¸¡à¸ªà¸£à¹‰à¸²à¸‡à¹€à¸à¸¡" +msgstr "ตั้งค่าเà¸à¸”ิเตà¸à¸£à¹Œ" #: editor/settings_config_dialog.cpp msgid "Shortcuts" @@ -11501,11 +11085,11 @@ msgstr "à¹à¸à¹‰à¹„ขà¸à¸‡à¸¨à¸²à¸à¸²à¸£à¹€à¸›à¸¥à¹ˆà¸‡à¹€à¸ªà¸µà¸¢à¸‡à¸‚ภ#: editor/spatial_editor_gizmos.cpp msgid "Change Camera FOV" -msgstr "ปรับขà¸à¸šà¹€à¸‚ตà¸à¸²à¸£à¸¡à¸à¸‡à¹€à¸«à¹‡à¸™à¸‚à¸à¸‡à¸à¸¥à¹‰à¸à¸‡" +msgstr "ปรับà¸à¸¥à¹‰à¸à¸‡ FOV" #: editor/spatial_editor_gizmos.cpp msgid "Change Camera Size" -msgstr "ปรับขนาดà¸à¸¥à¹‰à¸à¸‡" +msgstr "เปลี่ยนขนาดà¸à¸¥à¹‰à¸à¸‡" #: editor/spatial_editor_gizmos.cpp #, fuzzy @@ -11537,7 +11121,6 @@ msgid "Change Capsule Shape Height" msgstr "ปรับความสูงทรงà¹à¸„ปซูล" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Change Cylinder Shape Radius" msgstr "ปรับรัศมีทรงà¹à¸„ปซูล" @@ -11551,14 +11134,12 @@ msgid "Change Ray Shape Length" msgstr "ปรับความยาวรังสี" #: modules/csg/csg_gizmos.cpp -#, fuzzy msgid "Change Cylinder Radius" -msgstr "ปรับรัศมีà¹à¸ªà¸‡" +msgstr "ปรับรัศมีทรงà¸à¸£à¸°à¸šà¸à¸" #: modules/csg/csg_gizmos.cpp -#, fuzzy msgid "Change Cylinder Height" -msgstr "ปรับความสูงทรงà¹à¸„ปซูล" +msgstr "ปรับความสูงทรงà¸à¸£à¸°à¸šà¸à¸" #: modules/csg/csg_gizmos.cpp #, fuzzy @@ -11608,12 +11189,11 @@ msgstr "GDNativeLibrary" #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Enabled GDNative Singleton" -msgstr "" +msgstr "เปิดà¸à¸²à¸£à¸—ำงานซิงเà¸à¸´à¸¥à¸•ัน GDNative" #: modules/gdnative/gdnative_library_singleton_editor.cpp -#, fuzzy msgid "Disabled GDNative Singleton" -msgstr "ปิดà¸à¸²à¸£à¸à¸±à¸žà¹€à¸”ทตัวหมุน" +msgstr "ปิดà¸à¸²à¸£à¸—ำงานซิงเà¸à¸´à¸¥à¸•ัน GDNative" #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Library" @@ -11628,9 +11208,8 @@ msgid "GDNative" msgstr "GDNative" #: modules/gdscript/gdscript_functions.cpp -#, fuzzy msgid "Step argument is zero!" -msgstr "ตัวà¹à¸›à¸£ step เป็นศูนย์!" +msgstr "ช่วงà¸à¸²à¸à¸´à¸§à¹€à¸¡à¸™à¸•์เป็นศูนย์!" #: modules/gdscript/gdscript_functions.cpp msgid "Not a script with an instance" @@ -11658,7 +11237,7 @@ msgstr "รูปà¹à¸šà¸šà¸”ิà¸à¸Šà¸±à¸™à¸™à¸²à¸£à¸µà¸—ี่เà¸à¹‡à¸šà¸ #: modules/gdscript/gdscript_functions.cpp msgid "Invalid instance dictionary (invalid subclasses)" -msgstr "ดิà¸à¸Šà¸±à¸™à¸™à¸²à¸£à¸µà¸—ี่เà¸à¹‡à¸šà¸à¸´à¸™à¸ªà¹à¸•นซ์ผิดพลาด (คลาสย่à¸à¸¢à¸œà¸´à¸”พลาด)" +msgstr "ดิà¸à¸Šà¸±à¸™à¸™à¸²à¸£à¸µà¸à¸´à¸™à¸ªà¹à¸•นซ์ผิดพลาด (คลาสย่à¸à¸¢à¸œà¸´à¸”พลาด)" #: modules/gdscript/gdscript_functions.cpp msgid "Object can't provide a length." @@ -11767,18 +11346,16 @@ msgid "Cursor Clear Rotation" msgstr "เคà¸à¸£à¹Œà¹€à¸‹à¸à¸£à¹Œà¸¥à¸šà¸à¸²à¸£à¸«à¸¡à¸¸à¸™" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Paste Selects" -msgstr "ลบที่เลืà¸à¸" +msgstr "วางที่เลืà¸à¸" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Clear Selection" msgstr "ลบที่เลืà¸à¸" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Fill Selection" -msgstr "เลืà¸à¸à¸—ั้งหมด" +msgstr "เติมส่วนที่เลืà¸à¸" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "GridMap Settings" @@ -11819,7 +11396,7 @@ msgstr "à¸à¸³à¸¥à¸±à¸‡à¸ˆà¸±à¸”à¸à¸²à¸£à¹‚ครงร่าง..." #: modules/recast/navigation_mesh_generator.cpp msgid "Calculating grid size..." -msgstr "à¸à¸³à¸¥à¸±à¸‡à¸„ำนวณขนาดตาราง..." +msgstr "à¸à¸³à¸¥à¸±à¸‡à¸„ำนวณขนาดà¸à¸£à¸´à¸”..." #: modules/recast/navigation_mesh_generator.cpp msgid "Creating heightfield..." @@ -11917,42 +11494,36 @@ msgid "Set Variable Type" msgstr "à¹à¸à¹‰à¹„ขประเภทตัวà¹à¸›à¸£" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Add Input Port" -msgstr "เพิ่มà¸à¸´à¸™à¸žà¸¸à¸•" +msgstr "เพิ่มพà¸à¸£à¹Œà¸•à¸à¸´à¸™à¸žà¸¸à¸•" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Add Output Port" -msgstr "เพิ่มà¸à¸´à¸™à¸žà¸¸à¸•" +msgstr "เพิ่มพà¸à¸£à¹Œà¸•เà¸à¸²à¸—์พุต" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Override an existing built-in function." -msgstr "ชื่à¸à¸œà¸´à¸”พลาด ต้à¸à¸‡à¹„ม่ใช้ชื่à¸à¹€à¸”ียวà¸à¸±à¸šà¸Šà¸™à¸´à¸”ตัวà¹à¸›à¸£" +msgstr "เขียนทับฟังà¸à¹Œà¸Šà¸±à¸™à¸šà¸´à¸§à¸—์à¸à¸´à¸™à¸—ี่มีà¸à¸¢à¸¹à¹ˆ" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Create a new function." -msgstr "สร้าง %s ใหม่" +msgstr "สร้างฟังà¸à¹Œà¸Šà¸±à¸™à¹ƒà¸«à¸¡à¹ˆ" #: modules/visual_script/visual_script_editor.cpp msgid "Variables:" msgstr "ตัวà¹à¸›à¸£:" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Create a new variable." -msgstr "สร้าง %s ใหม่" +msgstr "สร้างตัวà¹à¸›à¸£à¹ƒà¸«à¸¡à¹ˆ" #: modules/visual_script/visual_script_editor.cpp msgid "Signals:" msgstr "สัà¸à¸à¸²à¸“:" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Create a new signal." -msgstr "สร้างรูปหลายเหลี่ยมจาà¸à¸„วามว่างเปล่า" +msgstr "สร้างสัà¸à¸à¸²à¸“ใหม่" #: modules/visual_script/visual_script_editor.cpp msgid "Name is not a valid identifier:" @@ -11979,9 +11550,8 @@ msgid "Add Function" msgstr "เพิ่มฟังà¸à¹Œà¸Šà¸±à¸™" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Delete input port" -msgstr "ลบจุด" +msgstr "ลบพà¸à¸£à¹Œà¸•à¸à¸´à¸™à¸žà¸¸à¸•" #: modules/visual_script/visual_script_editor.cpp msgid "Add Variable" @@ -11992,14 +11562,12 @@ msgid "Add Signal" msgstr "เพิ่มสัà¸à¸à¸²à¸“" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Remove Input Port" -msgstr "ลบจุด" +msgstr "ลบพà¸à¸£à¹Œà¸•à¸à¸´à¸™à¸žà¸¸à¸•" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Remove Output Port" -msgstr "ลบจุด" +msgstr "ลบพà¸à¸£à¹Œà¸•เà¸à¸²à¸•์พุต" #: modules/visual_script/visual_script_editor.cpp msgid "Change Expression" @@ -12007,11 +11575,11 @@ msgstr "à¹à¸à¹‰à¹„ขสมà¸à¸²à¸£" #: modules/visual_script/visual_script_editor.cpp msgid "Remove VisualScript Nodes" -msgstr "ลบโหนด" +msgstr "ลบโหนด VisualScript" #: modules/visual_script/visual_script_editor.cpp msgid "Duplicate VisualScript Nodes" -msgstr "ทำซ้ำโหนด" +msgstr "ทำซ้ำโหนด VisualScript" #: modules/visual_script/visual_script_editor.cpp msgid "Hold %s to drop a Getter. Hold Shift to drop a generic signature." @@ -12069,26 +11637,23 @@ msgstr "ย้ายโหนด" #: modules/visual_script/visual_script_editor.cpp msgid "Remove VisualScript Node" -msgstr "ลบโหนด" +msgstr "ลบโหนด VisualScript" #: modules/visual_script/visual_script_editor.cpp msgid "Connect Nodes" msgstr "เชื่à¸à¸¡à¹‚หนด" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Disconnect Nodes" msgstr "ตัดà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸à¸¡à¸•่à¸à¹‚หนด" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Connect Node Data" -msgstr "เชื่à¸à¸¡à¹‚หนด" +msgstr "เชื่à¸à¸¡à¸•่à¸à¸‚้à¸à¸¡à¸¹à¸¥à¹‚หนด" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Connect Node Sequence" -msgstr "เชื่à¸à¸¡à¹‚หนด" +msgstr "เชื่à¸à¸¡à¸•่à¸à¸à¸±à¸šà¸¥à¸³à¸”ับขà¸à¸‡à¹‚หนด" #: modules/visual_script/visual_script_editor.cpp msgid "Script already has function '%s'" @@ -12099,9 +11664,8 @@ msgid "Change Input Value" msgstr "à¹à¸à¹‰à¹„ขค่าà¸à¸´à¸™à¸žà¸¸à¸•" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Resize Comment" -msgstr "à¹à¸à¹‰à¹„ข CanvasItem" +msgstr "à¹à¸à¹‰à¸‚นาดคà¸à¸¡à¹€à¸¡à¹‰à¸™à¸•์" #: modules/visual_script/visual_script_editor.cpp msgid "Can't copy the function node." @@ -12113,12 +11677,11 @@ msgstr "คลิปบà¸à¸£à¹Œà¸”ว่างเปล่า!" #: modules/visual_script/visual_script_editor.cpp msgid "Paste VisualScript Nodes" -msgstr "วางโหนด" +msgstr "วางโหนด VisualScript" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Can't create function with a function node." -msgstr "คัดลà¸à¸à¹‚หนดฟังà¸à¹Œà¸Šà¸±à¸™à¹„ม่ได้" +msgstr "ไม่สามารถสร้างฟังà¸à¹Œà¸Šà¸±à¸™à¹„ด้จาà¸à¹‚หนดฟังà¸à¹Œà¸Šà¸±à¸™" #: modules/visual_script/visual_script_editor.cpp msgid "Can't create function of nodes from nodes of multiple functions." @@ -12133,9 +11696,8 @@ msgid "Try to only have one sequence input in selection." msgstr "" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Create Function" -msgstr "เปลี่ยนชื่à¸à¸Ÿà¸±à¸‡à¸à¹Œà¸Šà¸±à¸™" +msgstr "สร้างฟังà¸à¹Œà¸Šà¸±à¸™" #: modules/visual_script/visual_script_editor.cpp msgid "Remove Function" @@ -12158,33 +11720,28 @@ msgid "Editing Signal:" msgstr "à¹à¸à¹‰à¹„ขสัà¸à¸à¸²à¸“:" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Make Tool:" -msgstr "ระยะใà¸à¸¥à¹‰" +msgstr "เครื่à¸à¸‡à¸¡à¸·à¸à¸ªà¸£à¹‰à¸²à¸‡:" #: modules/visual_script/visual_script_editor.cpp msgid "Members:" -msgstr "ตัวà¹à¸›à¸£:" +msgstr "สมาชิà¸:" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Change Base Type:" -msgstr "เปลี่ยนประเภท" +msgstr "เปลี่ยนประเภทà¸à¸²à¸™:" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Add Nodes..." -msgstr "เพิ่มโหนด" +msgstr "เพิ่มโหนด..." #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Add Function..." -msgstr "เพิ่มฟังà¸à¹Œà¸Šà¸±à¸™" +msgstr "เพิ่มฟังà¸à¹Œà¸Šà¸±à¸™..." #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "function_name" -msgstr "ฟังà¸à¹Œà¸Šà¸±à¸™:" +msgstr "ชื่à¸à¸Ÿà¸±à¸‡à¸à¹Œà¸Šà¸±à¹ˆà¸™" #: modules/visual_script/visual_script_editor.cpp #, fuzzy @@ -12208,19 +11765,16 @@ msgid "Cut Nodes" msgstr "ตัดโหนด" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Make Function" -msgstr "เปลี่ยนชื่à¸à¸Ÿà¸±à¸‡à¸à¹Œà¸Šà¸±à¸™" +msgstr "สร้างฟังà¸à¹Œà¸Šà¸±à¸™" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Refresh Graph" -msgstr "รีเฟรช" +msgstr "รีเฟรชà¸à¸£à¸²à¸Ÿ" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Edit Member" -msgstr "ตัวà¹à¸›à¸£" +msgstr "à¹à¸à¹‰à¹„ขสมาชิà¸" #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable: " @@ -12277,41 +11831,40 @@ msgid "" msgstr "ค่าคืนจาภ_step() ผิดพลาด ต้à¸à¸‡à¹€à¸›à¹‡à¸™à¸ˆà¸³à¸™à¸§à¸™à¹€à¸•็ม (ลำดับ) หรืà¸à¸ªà¸•ริง (ข้à¸à¸œà¸´à¸”พลาด)" #: modules/visual_script/visual_script_property_selector.cpp -#, fuzzy msgid "Search VisualScript" -msgstr "ลบโหนด" +msgstr "ค้นหาโหนด VisualScript" #: modules/visual_script/visual_script_property_selector.cpp msgid "Get %s" -msgstr "" +msgstr "รับ %s" #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" -msgstr "" +msgstr "ตั้ง %s" #: platform/android/export/export.cpp msgid "Package name is missing." -msgstr "" +msgstr "ชื่à¸à¹à¸žà¹‡à¸„เà¸à¸ˆà¸«à¸²à¸¢à¹„ป" #: platform/android/export/export.cpp msgid "Package segments must be of non-zero length." -msgstr "" +msgstr "ส่วนขà¸à¸‡à¹à¸žà¹‡à¸„เà¸à¸ˆà¸ˆà¸°à¸•้à¸à¸‡à¸¡à¸µà¸„วามยาวไม่เป็นศูนย์" #: platform/android/export/export.cpp msgid "The character '%s' is not allowed in Android application package names." -msgstr "" +msgstr "ตัวà¸à¸±à¸à¸©à¸£ '%s' ไม่à¸à¸™à¸¸à¸à¸²à¸•ให้ใช้ในชื่à¸à¸‚à¸à¸‡ Android application package" #: platform/android/export/export.cpp msgid "A digit cannot be the first character in a package segment." -msgstr "" +msgstr "ไม่สามารถใช้ตัวเลขเป็นตัวà¹à¸£à¸à¹ƒà¸™à¸ªà¹ˆà¸§à¸™à¸‚à¸à¸‡à¹à¸žà¹‡à¸„เà¸à¸ˆ" #: platform/android/export/export.cpp msgid "The character '%s' cannot be the first character in a package segment." -msgstr "" +msgstr "ตัวà¸à¸±à¸à¸©à¸£ '%s' ไม่สามารถเป็นตัวà¸à¸±à¸à¸©à¸£à¸•ัวà¹à¸£à¸à¹ƒà¸™à¸ªà¹ˆà¸§à¸™à¸‚à¸à¸‡à¹à¸žà¹‡à¸„เà¸à¸ˆ" #: platform/android/export/export.cpp msgid "The package must have at least one '.' separator." -msgstr "" +msgstr "à¹à¸žà¹‡à¸„เà¸à¸ˆà¸ˆà¸³à¹€à¸›à¹‡à¸™à¸•้à¸à¸‡à¸¡à¸µ '.' à¸à¸¢à¹ˆà¸²à¸‡à¸™à¹‰à¸à¸¢à¸«à¸™à¸¶à¹ˆà¸‡à¸•ัว" #: platform/android/export/export.cpp msgid "Select device from the list" @@ -12319,11 +11872,11 @@ msgstr "เลืà¸à¸à¸à¸¸à¸›à¸à¸£à¸“์จาà¸à¸£à¸²à¸¢à¸Šà¸·à¹ˆà¸" #: platform/android/export/export.cpp msgid "ADB executable not configured in the Editor Settings." -msgstr "" +msgstr "ADB executable ยังไม่ได้à¸à¸³à¸«à¸™à¸”ค่าในตั้งค่าเà¸à¸”ิเตà¸à¸£à¹Œ" #: platform/android/export/export.cpp msgid "OpenJDK jarsigner not configured in the Editor Settings." -msgstr "" +msgstr "OpenJDK jarsigner ยังไม่ได้à¸à¸³à¸«à¸™à¸”ค่าในตั้งค่าเà¸à¸”ิเตà¸à¸£à¹Œ" #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." @@ -12348,9 +11901,8 @@ msgid "Invalid public key for APK expansion." msgstr "" #: platform/android/export/export.cpp -#, fuzzy msgid "Invalid package name:" -msgstr "ชื่à¸à¸„ลาสไม่ถูà¸à¸•้à¸à¸‡" +msgstr "ชื่à¸à¹à¸žà¹‡à¸„เà¸à¸ˆà¸œà¸´à¸”พลาด:" #: platform/android/export/export.cpp msgid "" @@ -12368,7 +11920,7 @@ msgstr "" #: platform/android/export/export.cpp msgid "Building Android Project (gradle)" -msgstr "" +msgstr "à¸à¸³à¸¥à¸±à¸‡à¸ªà¸£à¹‰à¸²à¸‡à¹‚ปรเจคà¹à¸à¸™à¸”รà¸à¸¢à¸”์ (gradle)" #: platform/android/export/export.cpp msgid "" @@ -12391,7 +11943,7 @@ msgstr "ไม่สามารถใช้ชื่à¸à¸™à¸µà¹‰à¹„ด้:" #: platform/iphone/export/export.cpp msgid "App Store Team ID not specified - cannot configure the project." -msgstr "" +msgstr "App Store Team ID ยังไม่ได้ระบุ - ไม่สามารถà¸à¸³à¸«à¸™à¸”ค่าให้โปรเจà¸à¸•์ได้" #: platform/iphone/export/export.cpp #, fuzzy @@ -12404,7 +11956,7 @@ msgstr "" #: platform/javascript/export/export.cpp msgid "Stop HTTP Server" -msgstr "" +msgstr "หยุดเซิฟเวà¸à¸£à¹Œ HTTP" #: platform/javascript/export/export.cpp msgid "Run in Browser" @@ -12449,9 +12001,8 @@ msgid "Invalid package unique name." msgstr "ชื่à¸à¹€à¸‰à¸žà¸²à¸°à¹„ม่ถูà¸à¸•้à¸à¸‡" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Invalid package publisher display name." -msgstr "ชื่à¸à¹€à¸‰à¸žà¸²à¸°à¹„ม่ถูà¸à¸•้à¸à¸‡" +msgstr "ชื่à¸à¹à¸ªà¸”งผู้จัดจำหน่ายà¹à¸žà¸„เà¸à¸ˆà¹„ม่ถูà¸à¸•้à¸à¸‡" #: platform/uwp/export/export.cpp msgid "Invalid product GUID." @@ -12505,7 +12056,7 @@ msgid "" "Only one visible CanvasModulate is allowed per scene (or set of instanced " "scenes). The first created one will work, while the rest will be ignored." msgstr "" -"จะมี CanvasModulate ที่มà¸à¸‡à¹€à¸«à¹‡à¸™à¹„ด้เพียงโหนดเดียวในฉาภ(หรืà¸à¸à¸¥à¸¸à¹ˆà¸¡à¸‚à¸à¸‡à¸‰à¸²à¸à¸—ี่เป็นà¸à¸´à¸™à¸ªà¹à¸•นซ์) " +"จะมี CanvasModulate ที่มà¸à¸‡à¹€à¸«à¹‡à¸™à¹„ด้ เพียงโหนดเดียวในฉาภ(หรืà¸à¸à¸¥à¸¸à¹ˆà¸¡à¸‚à¸à¸‡à¸‰à¸²à¸à¸—ี่เป็นà¸à¸´à¸™à¸ªà¹à¸•นซ์) " "โหนดà¹à¸£à¸à¹€à¸—่านั้นที่จะทำงานได้ปà¸à¸•ิ ที่เหลืà¸à¸ˆà¸°à¹„ม่ทำงาน" #: scene/2d/collision_object_2d.cpp @@ -12584,7 +12135,7 @@ msgid "" "node. It only provides navigation data." msgstr "" "NavigationPolygonInstance ต้à¸à¸‡à¹€à¸›à¹‡à¸™à¹‚หนดลูà¸/หลานขà¸à¸‡à¹‚หนด Navigation2D " -"เนื่à¸à¸‡à¸ˆà¸²à¸à¹‚หนดนี้ใช้เà¸à¹‡à¸šà¸‚้à¸à¸¡à¸¹à¸¥à¸à¸²à¸£à¸™à¸³à¸—างเท่านั้น" +"โดยจะให้ข้à¸à¸¡à¸¹à¸¥à¸à¸²à¸£à¸™à¸³à¸—างเท่านั้น" #: scene/2d/parallax_layer.cpp msgid "" @@ -12633,7 +12184,7 @@ msgstr "" #: scene/2d/skeleton_2d.cpp msgid "A Bone2D only works with a Skeleton2D or another Bone2D as parent node." -msgstr "" +msgstr "Bone2D สามารถทำงานได้à¸à¸±à¸š Skeleton2D หรืภBone2D ตัวà¸à¸·à¹ˆà¸™à¹‚ดยเป็นโหนดà¹à¸¡à¹ˆ" #: scene/2d/skeleton_2d.cpp msgid "" @@ -12676,9 +12227,8 @@ msgid "" msgstr "Controller id ต้à¸à¸‡à¹„ม่เป็น 0 ไม่เช่นนั้นตัวควบคุมนี้จะไม่เชื่à¸à¸¡à¸à¸±à¸šà¸à¸¸à¸›à¸à¸£à¸“์จริง" #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "ARVRAnchor must have an ARVROrigin node as its parent." -msgstr "ARVRAnchor ต้à¸à¸‡à¸¡à¸µ ARVROrigin เป็นโหนดà¹à¸¡à¹ˆ" +msgstr "ARVRAnchor ต้à¸à¸‡à¸¡à¸µà¹‚หนด ARVROrigin เป็นโหนดà¹à¸¡à¹ˆ" #: scene/3d/arvr_nodes.cpp #, fuzzy @@ -12688,9 +12238,8 @@ msgid "" msgstr "Anchor id ต้à¸à¸‡à¹„ม่เป็น 0 ไม่เช่นนั้น anchor นี้จะไม่เชื่à¸à¸¡à¸à¸±à¸š anchor จริง" #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "ARVROrigin requires an ARVRCamera child node." -msgstr "ARVROrigin ต้à¸à¸‡à¸¡à¸µ ARVRCamera เป็นโหนดลูà¸" +msgstr "ARVROrigin จำเป็นต้à¸à¸‡à¸¡à¸µ ARVRCamera เป็นโหนดลูà¸" #: scene/3d/baked_lightmap.cpp msgid "%d%%" @@ -12786,6 +12335,8 @@ msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." msgstr "" +"ไดรเวà¸à¸£à¹Œà¸§à¸µà¸”ีโภGLES2 ไม่สนับสนุน GIProbe\n" +"ใช้ BakedLightmap à¹à¸—น" #: scene/3d/light.cpp msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows." @@ -12801,7 +12352,7 @@ msgid "" "It only provides navigation data." msgstr "" "NavigationMeshInstance ต้à¸à¸‡à¹€à¸›à¹‡à¸™à¹‚หนดลูà¸/หลานขà¸à¸‡à¹‚หนด Navigation " -"โหนดนี้ใช้เพื่à¸à¹€à¸›à¹‡à¸™à¸‚้à¸à¸¡à¸¹à¸¥à¹ƒà¸™à¸à¸²à¸£à¸™à¸³à¸—างเท่านั้น" +"โดยจะให้ข้à¸à¸¡à¸¹à¸¥à¸à¸²à¸£à¸™à¸³à¸—างเท่านั้น" #: scene/3d/particles.cpp msgid "" @@ -12884,7 +12435,7 @@ msgstr "" #: scene/3d/world_environment.cpp msgid "" "Only one WorldEnvironment is allowed per scene (or set of instanced scenes)." -msgstr "จะมี WorldEnvironment ได้เพียงโหนดเดียวในฉาภ(หรืà¸à¸à¸¥à¸¸à¹ˆà¸¡à¸‚à¸à¸‡à¸‰à¸²à¸à¸—ี่เป็นà¸à¸´à¸™à¸ªà¹à¸•นซ์)" +msgstr "จะมี WorldEnvironment ได้เพียงà¸à¸±à¸™à¹€à¸”ียวในฉาภ(หรืà¸à¸à¸¥à¸¸à¹ˆà¸¡à¸‚à¸à¸‡à¸‰à¸²à¸à¸—ี่เป็นà¸à¸´à¸™à¸ªà¹à¸•นซ์)" #: scene/3d/world_environment.cpp msgid "" @@ -12897,23 +12448,20 @@ msgid "On BlendTree node '%s', animation not found: '%s'" msgstr "" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Animation not found: '%s'" -msgstr "เครื่à¸à¸‡à¸¡à¸·à¸à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™" +msgstr "ไม่พบà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™: '%s'" #: scene/animation/animation_tree.cpp msgid "In node '%s', invalid animation: '%s'." msgstr "" #: scene/animation/animation_tree.cpp -#, fuzzy msgid "Invalid animation: '%s'." -msgstr "ผิดพลาด: ชื่à¸à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹„ม่ถูà¸à¸•้à¸à¸‡!" +msgstr "à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¸œà¸´à¸”พลาด: '%s'." #: scene/animation/animation_tree.cpp -#, fuzzy msgid "Nothing connected to input '%s' of node '%s'." -msgstr "ลบà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸à¸¡à¹‚ยง '%s' à¸à¸±à¸š '%s'" +msgstr "ไม่มีà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸à¸¡à¸•่à¸à¹„ปที่à¸à¸´à¸™à¸žà¸¸à¸• '%s' ขà¸à¸‡à¹‚หนด '%s'." #: scene/animation/animation_tree.cpp msgid "No root AnimationNode for the graph is set." @@ -12943,6 +12491,9 @@ msgid "" "LMB: Set color\n" "RMB: Remove preset" msgstr "" +"สี: #%s\n" +"คลิà¸à¸‹à¹‰à¸²à¸¢: เลืà¸à¸à¸ªà¸µ\n" +"คลิà¸à¸‚วา: ลบสี" #: scene/gui/color_picker.cpp msgid "Pick a color from the editor window." @@ -12950,11 +12501,11 @@ msgstr "" #: scene/gui/color_picker.cpp msgid "HSV" -msgstr "" +msgstr "HSV" #: scene/gui/color_picker.cpp msgid "Raw" -msgstr "" +msgstr "Raw" #: scene/gui/color_picker.cpp msgid "Switch between hexadecimal and code values." @@ -13034,6 +12585,10 @@ msgstr "" "ให้à¹à¸à¹‰à¹„ขโหนดนี้ให้เป็นโหนดลูà¸à¸‚à¸à¸‡ Control à¹à¸•่ถ้าไม่ ให้ปรับเป็น render target à¹à¸¥à¸°à¸™à¸³à¹„ปใช้เป็น " "texture ขà¸à¸‡à¹‚หนดà¸à¸·à¹ˆà¸™" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." @@ -13063,7 +12618,16 @@ msgstr "" #: servers/visual/shader_language.cpp msgid "Constants cannot be modified." -msgstr "" +msgstr "ค่าคงที่ไม่สามารถà¹à¸à¹‰à¹„ขได้" + +#~ msgid "Issue Tracker" +#~ msgstr "ติดตามปัà¸à¸«à¸²" + +#~ msgid "Request Docs" +#~ msgstr "ร้à¸à¸‡à¸‚à¸à¸„ู่มืà¸" + +#~ msgid "Help improve the Godot documentation by giving feedback." +#~ msgstr "ช่วยพัฒนาคู่มืà¸à¹‚ดยà¸à¸²à¸£à¹ƒà¸«à¹‰à¸‚้à¸à¹€à¸ªà¸™à¸à¹à¸™à¸°" #~ msgid "Replaced %d occurrence(s)." #~ msgstr "à¹à¸—นที่à¹à¸¥à¹‰à¸§ %d ครั้ง" diff --git a/editor/translations/tr.po b/editor/translations/tr.po index 83eb878d8c..e5e8f0ba97 100644 --- a/editor/translations/tr.po +++ b/editor/translations/tr.po @@ -1481,7 +1481,7 @@ msgstr "KendindenYüklenme'yi Taşı" msgid "Remove Autoload" msgstr "KendindenYüklenme'yi Kaldır" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "Etkin" @@ -2961,8 +2961,13 @@ msgid "Q&A" msgstr "S&C" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "Sorun İzleyici" +#, fuzzy +msgid "Report a Bug" +msgstr "Yeniden İçe Aktar" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4013,7 +4018,8 @@ msgid "Reimport" msgstr "Yeniden İçe Aktar" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +#, fuzzy +msgid "Save Scenes, Re-Import, and Restart" msgstr "Sahneleri kaydet, tekrar içe aktar ve baÅŸtan baÅŸlat" #: editor/import_dock.cpp @@ -6857,14 +6863,6 @@ msgid "Open Godot online documentation." msgstr "Çevrimiçi Godot dökümanlarını aç." #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "Belgeleri İste" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "Dönüt vererek Godot belgelerini iyileÅŸtirmeye yardımcı olun." - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "BaÅŸvuru belgelerinde arama yap." @@ -7300,6 +7298,11 @@ msgid "This operation requires a single selected node." msgstr "Bu iÅŸlem, seçilmiÅŸ tek bir düğüm gerektirir." #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Auto Orthogonal Enabled" +msgstr "Dikey" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "Dönüşü Görüntülemeyi kilitle" @@ -7388,6 +7391,10 @@ msgid "Freelook Slow Modifier" msgstr "Serbestbakış Hız DeÄŸiÅŸtirici" #: editor/plugins/spatial_editor_plugin.cpp +msgid "View Rotation Locked" +msgstr "Dönme Kilitli Görünüm" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." @@ -7396,10 +7403,6 @@ msgstr "" "Oyun içi performansın gösteri olarak ele alınamaz." #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" -msgstr "Dönme Kilitli Görünüm" - -#: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "XForm İletiÅŸim Kutusu" @@ -10911,6 +10914,12 @@ msgid "Script file already exists." msgstr "Betik dosyası zaten mevcut." #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "Sınıf İsmi:" @@ -12682,6 +12691,10 @@ msgstr "" "yapın böylece bir boyut elde edebilir. Aksi takdirde, Görüntüleme için bunu " "bir RenderTarget yap ve dahili dokusunu herhangi bir düğüme ata." +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "Önizleme için geçersiz kaynak." @@ -12710,6 +12723,15 @@ msgstr "varyings yalnızca vertex iÅŸlevinde atanabilir." msgid "Constants cannot be modified." msgstr "Sabit deÄŸerler deÄŸiÅŸtirilemez." +#~ msgid "Issue Tracker" +#~ msgstr "Sorun İzleyici" + +#~ msgid "Request Docs" +#~ msgstr "Belgeleri İste" + +#~ msgid "Help improve the Godot documentation by giving feedback." +#~ msgstr "Dönüt vererek Godot belgelerini iyileÅŸtirmeye yardımcı olun." + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "%d deÄŸiÅŸiklik gerçekleÅŸtirildi." diff --git a/editor/translations/uk.po b/editor/translations/uk.po index bfb614f493..60e61d3bf7 100644 --- a/editor/translations/uk.po +++ b/editor/translations/uk.po @@ -17,7 +17,7 @@ msgid "" msgstr "" "Project-Id-Version: Ukrainian (Godot Engine)\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2020-02-21 23:32+0000\n" +"PO-Revision-Date: 2020-03-18 00:10+0000\n" "Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n" "Language-Team: Ukrainian <https://hosted.weblate.org/projects/godot-engine/" "godot/uk/>\n" @@ -27,7 +27,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 3.11.1\n" +"X-Generator: Weblate 4.0-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -1458,7 +1458,7 @@ msgstr "ПереміÑтити автозавантаженнÑ" msgid "Remove Autoload" msgstr "Видалити автозавантаженнÑ" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "Ðктивувати" @@ -2945,8 +2945,13 @@ msgid "Q&A" msgstr "Ð—Ð°Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ Ñ‚Ð° відповіді" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "ВідÑÑ‚ÐµÐ¶ÐµÐ½Ð½Ñ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº" +#, fuzzy +msgid "Report a Bug" +msgstr "Переімпортувати" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4001,7 +4006,8 @@ msgid "Reimport" msgstr "Переімпортувати" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +#, fuzzy +msgid "Save Scenes, Re-Import, and Restart" msgstr "Зберегти Ñцени, повторно імпортувати Ñ– перезапуÑтити" #: editor/import_dock.cpp @@ -5974,9 +5980,8 @@ msgstr "" "Цей найточніший (але найповільніший) варіант Ð´Ð»Ñ Ð²Ð¸ÑÐ²Ð»ÐµÐ½Ð½Ñ Ð·Ñ–Ñ‚ÐºÐ½ÐµÐ½ÑŒ." #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Single Convex Collision Sibling" -msgstr "Створити єдині опуклі облаÑті зіткненнÑ" +msgstr "Створити єдину опуклу облаÑть зіткненнÑ" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "" @@ -6865,14 +6870,6 @@ msgid "Open Godot online documentation." msgstr "Відкрити онлайнову документацію Godot." #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "Запит щодо документації" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "Допоможіть у поліпшенні документації Godot наданнÑм відгуків." - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "Пошук довідкової документації." @@ -7310,6 +7307,11 @@ msgid "This operation requires a single selected node." msgstr "Ð¦Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð²Ð¸Ð¼Ð°Ð³Ð°Ñ” одного обраного вузла." #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Auto Orthogonal Enabled" +msgstr "Ортогонально" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "ЗафікÑувати Ð¾Ð±ÐµÑ€Ñ‚Ð°Ð½Ð½Ñ Ð¿ÐµÑ€ÐµÐ³Ð»Ñду" @@ -7398,6 +7400,10 @@ msgid "Freelook Slow Modifier" msgstr "Модифікатор швидкоÑті довільного оглÑду" #: editor/plugins/spatial_editor_plugin.cpp +msgid "View Rotation Locked" +msgstr "ÐžÐ±ÐµÑ€Ñ‚Ð°Ð½Ð½Ñ Ð¿ÐµÑ€ÐµÐ³Ð»Ñду заблоковано" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." @@ -7407,10 +7413,6 @@ msgstr "" "грі." #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" -msgstr "ÐžÐ±ÐµÑ€Ñ‚Ð°Ð½Ð½Ñ Ð¿ÐµÑ€ÐµÐ³Ð»Ñду заблоковано" - -#: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "Вікно XForm" @@ -10921,6 +10923,12 @@ msgid "Script file already exists." msgstr "Файл Ñкрипту вже Ñ–Ñнує." #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "Ðазва клаÑу:" @@ -12415,6 +12423,8 @@ msgstr "" msgid "" "ConcavePolygonShape doesn't support RigidBody in another mode than static." msgstr "" +"У ConcavePolygonShape не передбачено підтримки RigidBody у режимі, " +"відмінному від Ñтатичного." #: scene/3d/cpu_particles.cpp msgid "Nothing is visible because no mesh has been assigned." @@ -12715,6 +12725,10 @@ msgstr "" "Control, щоб у неї був розмір. Крім того, можна зробити Ñ—Ñ— RenderTarget Ñ– " "пов'Ñзати Ñ—Ñ— внутрішню текÑтуру з одним із вузлів Ð´Ð»Ñ Ð¿Ð¾ÐºÐ°Ð·Ñƒ." +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "Ðекоректне джерело Ð´Ð»Ñ Ð¿Ð¾Ð¿ÐµÑ€ÐµÐ´Ð½ÑŒÐ¾Ð³Ð¾ переглÑду." @@ -12743,6 +12757,15 @@ msgstr "Змінні величини можна пов'Ñзувати лише msgid "Constants cannot be modified." msgstr "Сталі не можна змінювати." +#~ msgid "Issue Tracker" +#~ msgstr "ВідÑÑ‚ÐµÐ¶ÐµÐ½Ð½Ñ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº" + +#~ msgid "Request Docs" +#~ msgstr "Запит щодо документації" + +#~ msgid "Help improve the Godot documentation by giving feedback." +#~ msgstr "Допоможіть у поліпшенні документації Godot наданнÑм відгуків." + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "Замінено %d випадок(-ів)." diff --git a/editor/translations/ur_PK.po b/editor/translations/ur_PK.po index 815f92af6a..1e2f87b352 100644 --- a/editor/translations/ur_PK.po +++ b/editor/translations/ur_PK.po @@ -1429,7 +1429,7 @@ msgstr "" msgid "Remove Autoload" msgstr "" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "" @@ -2862,7 +2862,11 @@ msgid "Q&A" msgstr "" #: editor/editor_node.cpp -msgid "Issue Tracker" +msgid "Report a Bug" +msgstr "" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp @@ -3907,7 +3911,7 @@ msgid "Reimport" msgstr "" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -6762,14 +6766,6 @@ msgid "Open Godot online documentation." msgstr "" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7209,6 +7205,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7298,13 +7298,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -10719,6 +10719,12 @@ msgid "Script file already exists." msgstr "" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "" @@ -12370,6 +12376,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "" diff --git a/editor/translations/vi.po b/editor/translations/vi.po index 31b7f3ceb7..88ca61847e 100644 --- a/editor/translations/vi.po +++ b/editor/translations/vi.po @@ -1455,7 +1455,7 @@ msgstr "" msgid "Remove Autoload" msgstr "" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "Mở" @@ -2927,8 +2927,13 @@ msgid "Q&A" msgstr "Há»i và Äáp" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "Theo dõi vấn Ä‘á»" +#, fuzzy +msgid "Report a Bug" +msgstr "Nháºp và o lại" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -3974,7 +3979,8 @@ msgid "Reimport" msgstr "Nháºp và o lại" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +#, fuzzy +msgid "Save Scenes, Re-Import, and Restart" msgstr "Lưu các cảnh, nháºp và o lại và khởi động lại" #: editor/import_dock.cpp @@ -6849,14 +6855,6 @@ msgid "Open Godot online documentation." msgstr "" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7303,6 +7301,10 @@ msgid "This operation requires a single selected node." msgstr "Hoạt động yêu cầu chá»n má»™t nút duy nhất." #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "" @@ -7392,13 +7394,13 @@ msgid "Freelook Slow Modifier" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "" -"Note: The FPS value displayed is the editor's framerate.\n" -"It cannot be used as a reliable indication of in-game performance." +msgid "View Rotation Locked" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" +msgid "" +"Note: The FPS value displayed is the editor's framerate.\n" +"It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp @@ -10857,6 +10859,12 @@ msgid "Script file already exists." msgstr "Tam giác đã tồn tại." #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp #, fuzzy msgid "Class Name:" msgstr "Lá»›p:" @@ -12521,6 +12529,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "nguồn vô hiệu cho xem trước" @@ -12550,6 +12562,9 @@ msgstr "" msgid "Constants cannot be modified." msgstr "Không thể chỉnh sá»a hằng số." +#~ msgid "Issue Tracker" +#~ msgstr "Theo dõi vấn Ä‘á»" + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "Äã thay thế %d biến cố." diff --git a/editor/translations/zh_CN.po b/editor/translations/zh_CN.po index e7108c6e61..df8b8e1725 100644 --- a/editor/translations/zh_CN.po +++ b/editor/translations/zh_CN.po @@ -64,8 +64,8 @@ msgid "" msgstr "" "Project-Id-Version: Chinese (Simplified) (Godot Engine)\n" "POT-Creation-Date: 2018-01-20 12:15+0200\n" -"PO-Revision-Date: 2020-03-08 22:33+0000\n" -"Last-Translator: Revan Ji <jiruifancr@gmail.com>\n" +"PO-Revision-Date: 2020-04-05 12:05+0000\n" +"Last-Translator: Haoyu Qiu <timothyqiu32@gmail.com>\n" "Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/" "godot-engine/godot/zh_Hans/>\n" "Language: zh_CN\n" @@ -1481,7 +1481,7 @@ msgstr "移动Autoload" msgid "Remove Autoload" msgstr "移除Autoload" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "å¯ç”¨" @@ -2919,8 +2919,13 @@ msgid "Q&A" msgstr "é—®ç”" #: editor/editor_node.cpp -msgid "Issue Tracker" -msgstr "问题跟踪器" +#, fuzzy +msgid "Report a Bug" +msgstr "釿–°å¯¼å…¥" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -3957,7 +3962,8 @@ msgid "Reimport" msgstr "釿–°å¯¼å…¥" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +#, fuzzy +msgid "Save Scenes, Re-Import, and Restart" msgstr "ä¿å˜åœºæ™¯ï¼Œé‡æ–°å¯¼å…¥ï¼Œä»Žå¤´å¼€å§‹" #: editor/import_dock.cpp @@ -6774,14 +6780,6 @@ msgid "Open Godot online documentation." msgstr "打开Godot在线文档。" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "请求文档" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "通过æä¾›å馈帮助改进godot文档。" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "æœç´¢æ–‡æ¡£ã€‚" @@ -7215,6 +7213,11 @@ msgid "This operation requires a single selected node." msgstr "æ¤æ“作åªèƒ½åº”用于å•个选ä¸èŠ‚ç‚¹ã€‚" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Auto Orthogonal Enabled" +msgstr "æ£äº¤" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "é”定视角旋转" @@ -7303,6 +7306,10 @@ msgid "Freelook Slow Modifier" msgstr "缓慢自由视图速度" #: editor/plugins/spatial_editor_plugin.cpp +msgid "View Rotation Locked" +msgstr "é”定视角旋转" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." @@ -7311,10 +7318,6 @@ msgstr "" "它ä¸èƒ½ç”¨äºŽè¡¨çŽ°æ¸¸æˆä¸çš„实际性能。" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" -msgstr "é”定视角旋转" - -#: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "XFormå¯¹è¯æ¡†" @@ -7906,7 +7909,7 @@ msgstr "å—体" #: editor/plugins/theme_editor_plugin.cpp msgid "Color" -msgstr "Color(颜色)" +msgstr "颜色" #: editor/plugins/theme_editor_plugin.cpp msgid "Theme File" @@ -10740,6 +10743,12 @@ msgid "Script file already exists." msgstr "脚本文件已å˜åœ¨ã€‚" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp msgid "Class Name:" msgstr "ç±»å:" @@ -12428,6 +12437,10 @@ msgstr "" "幕上显示其内容,使其æˆä¸ºå控件的所以它å¯ä»¥æœ‰ä¸€ä¸ªå°ºå¯¸å¤§å°å€¼ã€‚å¦åˆ™è¯·å°†å…¶è®¾ç½®ä¸º " "RenderTarget,并将其内部纹ç†åˆ†é…给其它节点显示。" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for preview." msgstr "预览的æºèµ„æºæ— 效。" @@ -12456,6 +12469,15 @@ msgstr "å˜é‡åªèƒ½åœ¨é¡¶ç‚¹å‡½æ•°ä¸æŒ‡å®šã€‚" msgid "Constants cannot be modified." msgstr "ä¸å…许修改常é‡ã€‚" +#~ msgid "Issue Tracker" +#~ msgstr "问题跟踪器" + +#~ msgid "Request Docs" +#~ msgstr "请求文档" + +#~ msgid "Help improve the Godot documentation by giving feedback." +#~ msgstr "通过æä¾›å馈帮助改进godot文档。" + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "替æ¢äº†%d项。" diff --git a/editor/translations/zh_HK.po b/editor/translations/zh_HK.po index a228d6ee60..31306885ae 100644 --- a/editor/translations/zh_HK.po +++ b/editor/translations/zh_HK.po @@ -1533,7 +1533,7 @@ msgstr "移動Autoload" msgid "Remove Autoload" msgstr "移除Autoload" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp #, fuzzy msgid "Enable" msgstr "啟用" @@ -3070,7 +3070,12 @@ msgid "Q&A" msgstr "Q&A" #: editor/editor_node.cpp -msgid "Issue Tracker" +#, fuzzy +msgid "Report a Bug" +msgstr "å°Žå…¥" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp @@ -4182,7 +4187,7 @@ msgid "Reimport" msgstr "å°Žå…¥" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +msgid "Save Scenes, Re-Import, and Restart" msgstr "" #: editor/import_dock.cpp @@ -7143,14 +7148,6 @@ msgid "Open Godot online documentation." msgstr "開啓最近的" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp -msgid "Help improve the Godot documentation by giving feedback." -msgstr "" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "" @@ -7611,6 +7608,10 @@ msgid "This operation requires a single selected node." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp +msgid "Auto Orthogonal Enabled" +msgstr "" + +#: editor/plugins/spatial_editor_plugin.cpp #, fuzzy msgid "Lock View Rotation" msgstr "本地化" @@ -7705,17 +7706,17 @@ msgid "Freelook Slow Modifier" msgstr "下滾" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "View Rotation Locked" +msgstr "本地化" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy -msgid "View Rotation Locked" -msgstr "本地化" - -#: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "" @@ -11249,6 +11250,12 @@ msgid "Script file already exists." msgstr "AutoLoad '%s'å·²å˜åœ¨ï¼" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp #, fuzzy msgid "Class Name:" msgstr "å稱:" @@ -12946,6 +12953,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." diff --git a/editor/translations/zh_TW.po b/editor/translations/zh_TW.po index 466e8db554..235ce0d023 100644 --- a/editor/translations/zh_TW.po +++ b/editor/translations/zh_TW.po @@ -1521,7 +1521,7 @@ msgstr "移動 Autoload" msgid "Remove Autoload" msgstr "刪除 Autoload" -#: editor/editor_autoload_settings.cpp +#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp msgid "Enable" msgstr "啟用" @@ -3062,8 +3062,12 @@ msgstr "Q&A" #: editor/editor_node.cpp #, fuzzy -msgid "Issue Tracker" -msgstr "å•題追蹤器" +msgid "Report a Bug" +msgstr "釿–°å°Žå…¥" + +#: editor/editor_node.cpp +msgid "Send Docs Feedback" +msgstr "" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -4155,7 +4159,8 @@ msgid "Reimport" msgstr "釿–°å°Žå…¥" #: editor/import_dock.cpp -msgid "Save scenes, re-import and restart" +#, fuzzy +msgid "Save Scenes, Re-Import, and Restart" msgstr "ä¿å˜å ´æ™¯ï¼Œé‡æ–°å°Žå…¥ä¸¦é‡æ–°å•Ÿå‹•" #: editor/import_dock.cpp @@ -7125,15 +7130,6 @@ msgid "Open Godot online documentation." msgstr "打開 Godot 線上文檔" #: editor/plugins/script_editor_plugin.cpp -msgid "Request Docs" -msgstr "請求檔案" - -#: editor/plugins/script_editor_plugin.cpp -#, fuzzy -msgid "Help improve the Godot documentation by giving feedback." -msgstr "é€šéŽæä¾›å›žé¥‹å¹«åŠ©æ”¹é€² Godot 文檔" - -#: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." msgstr "æœç´¢åƒè€ƒæ–‡æª”。" @@ -7589,6 +7585,11 @@ msgid "This operation requires a single selected node." msgstr "æ¤æ“作需è¦å–®å€‹é¸å®šçš„節點。" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy +msgid "Auto Orthogonal Enabled" +msgstr "æ£äº¤" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" msgstr "鎖定視圖旋轉" @@ -7680,16 +7681,16 @@ msgid "Freelook Slow Modifier" msgstr "自由視圖速度調節" #: editor/plugins/spatial_editor_plugin.cpp +msgid "View Rotation Locked" +msgstr "視圖旋轉已鎖定" + +#: editor/plugins/spatial_editor_plugin.cpp msgid "" "Note: The FPS value displayed is the editor's framerate.\n" "It cannot be used as a reliable indication of in-game performance." msgstr "注æ„: 顯示的FPS值是編輯器的幀率。 它ä¸èƒ½ç”¨äºŽè¡¨ç¾éŠæˆ²å…§çš„實際性能" #: editor/plugins/spatial_editor_plugin.cpp -msgid "View Rotation Locked" -msgstr "視圖旋轉已鎖定" - -#: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "XFormå°è©±æ¡†" @@ -11230,6 +11231,12 @@ msgid "Script file already exists." msgstr "Autoload「%sã€å·²ç¶“å˜åœ¨!" #: editor/script_create_dialog.cpp +msgid "" +"Note: Built-in scripts have some limitations and can't be edited using an " +"external editor." +msgstr "" + +#: editor/script_create_dialog.cpp #, fuzzy msgid "Class Name:" msgstr "Class:" @@ -12956,6 +12963,10 @@ msgid "" "texture to some node for display." msgstr "" +#: scene/main/viewport.cpp +msgid "Viewport size must be greater than 0 to render anything." +msgstr "" + #: scene/resources/visual_shader_nodes.cpp #, fuzzy msgid "Invalid source for preview." @@ -12987,6 +12998,17 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#, fuzzy +#~ msgid "Issue Tracker" +#~ msgstr "å•題追蹤器" + +#~ msgid "Request Docs" +#~ msgstr "請求檔案" + +#, fuzzy +#~ msgid "Help improve the Godot documentation by giving feedback." +#~ msgstr "é€šéŽæä¾›å›žé¥‹å¹«åŠ©æ”¹é€² Godot 文檔" + #~ msgid "Replaced %d occurrence(s)." #~ msgstr "å–代了 %d 個。" diff --git a/main/main.cpp b/main/main.cpp index a53e52e485..ad8e8dadfe 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -55,13 +55,13 @@ #include "main/splash.gen.h" #include "main/splash_editor.gen.h" #include "main/tests/test_main.h" +#include "modules/modules_enabled.gen.h" #include "modules/register_module_types.h" #include "platform/register_platform_apis.h" #include "scene/main/scene_tree.h" #include "scene/main/window.h" #include "scene/register_scene_types.h" #include "scene/resources/packed_scene.h" -#include "servers/arvr_server.h" #include "servers/audio_server.h" #include "servers/camera_server.h" #include "servers/display_server.h" @@ -72,6 +72,7 @@ #include "servers/register_server_types.h" #include "servers/rendering/rendering_server_raster.h" #include "servers/rendering/rendering_server_wrap_mt.h" +#include "servers/xr_server.h" #ifdef TOOLS_ENABLED #include "editor/doc_data.h" @@ -105,7 +106,7 @@ static AudioServer *audio_server = nullptr; static DisplayServer *display_server = nullptr; static RenderingServer *rendering_server = nullptr; static CameraServer *camera_server = nullptr; -static ARVRServer *arvr_server = nullptr; +static XRServer *xr_server = nullptr; static PhysicsServer3D *physics_server = nullptr; static PhysicsServer2D *physics_2d_server = nullptr; static NavigationServer3D *navigation_server = nullptr; @@ -478,6 +479,14 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph I = args.front(); while (I) { +#ifdef OSX_ENABLED + // Ignore the process serial number argument passed by macOS Gatekeeper. + // Otherwise, Godot would try to open a non-existent project on the first start and abort. + if (I->get().begins_with("-psn_")) { + I = I->next(); + continue; + } +#endif List<String>::Element *N = I->next(); @@ -1154,9 +1163,11 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph ProjectSettings::get_singleton()->set_custom_property_info("debug/settings/fps/force_fps", PropertyInfo(Variant::INT, "debug/settings/fps/force_fps", PROPERTY_HINT_RANGE, "0,120,1,or_greater")); GLOBAL_DEF("debug/settings/stdout/print_fps", false); + GLOBAL_DEF("debug/settings/stdout/verbose_stdout", false); - if (!OS::get_singleton()->_verbose_stdout) //overridden - OS::get_singleton()->_verbose_stdout = GLOBAL_DEF("debug/settings/stdout/verbose_stdout", false); + if (!OS::get_singleton()->_verbose_stdout) { // Not manually overridden. + OS::get_singleton()->_verbose_stdout = GLOBAL_GET("debug/settings/stdout/verbose_stdout"); + } if (frame_delay == 0) { frame_delay = GLOBAL_DEF("application/run/frame_delay_msec", 0); @@ -1297,8 +1308,8 @@ Error Main::setup2(Thread::ID p_main_tid_override) { audio_server = memnew(AudioServer); audio_server->init(); - // also init our arvr_server from here - arvr_server = memnew(ARVRServer); + // also init our xr_server from here + xr_server = memnew(XRServer); register_core_singletons(); @@ -1473,6 +1484,15 @@ Error Main::setup2(Thread::ID p_main_tid_override) { // We could add more, and make the CLI arg require a comma-separated list of profilers. EngineDebugger::get_singleton()->profiler_enable("scripts", true); } + + if (!project_manager) { + // If not running the project manager, and now that the engine is + // able to load resources, load the global shader variables. + // If running on editor, dont load the textures because the editor + // may want to import them first. Editor will reload those later. + rendering_server->global_variables_load_settings(!editor); + } + _start_success = true; locale = String(); @@ -1580,6 +1600,19 @@ bool Main::start() { DirAccessRef da = DirAccess::open(doc_tool); ERR_FAIL_COND_V_MSG(!da, false, "Argument supplied to --doctool must be a base Godot build directory."); } + +#ifndef MODULE_MONO_ENABLED + // Hack to define Mono-specific project settings even on non-Mono builds, + // so that we don't lose their descriptions and default values in DocData. + // Default values should be synced with mono_gd/gd_mono.cpp. + GLOBAL_DEF("mono/debugger_agent/port", 23685); + GLOBAL_DEF("mono/debugger_agent/wait_for_debugger", false); + GLOBAL_DEF("mono/debugger_agent/wait_timeout", 3000); + GLOBAL_DEF("mono/profiler/args", "log:calls,alloc,sample,output=output.mlpd"); + GLOBAL_DEF("mono/profiler/enabled", false); + GLOBAL_DEF("mono/unhandled_exception_policy", 0); +#endif + DocData doc; doc.generate(doc_base); @@ -1667,7 +1700,7 @@ bool Main::start() { return false; } - if (script_res->can_instance() /*&& script_res->inherits_from("SceneTreeScripted")*/) { + if (script_res->can_instance()) { StringName instance_type = script_res->get_instance_base_type(); Object *obj = ClassDB::instance(instance_type); @@ -1675,7 +1708,7 @@ bool Main::start() { if (!script_loop) { if (obj) memdelete(obj); - ERR_FAIL_V_MSG(false, "Can't load script '" + script + "', it does not inherit from a MainLoop type."); + ERR_FAIL_V_MSG(false, vformat("Can't load the script \"%s\" as it doesn't inherit from SceneTree or MainLoop.", script)); } script_loop->set_init_script(script_res); @@ -2272,13 +2305,16 @@ void Main::cleanup() { // Sync pending commands that may have been queued from a different thread during ScriptServer finalization RenderingServer::get_singleton()->sync(); + //clear global shader variables before scene and other graphics stuff is deinitialized. + rendering_server->global_variables_clear(); + #ifdef TOOLS_ENABLED EditorNode::unregister_editor_types(); #endif - if (arvr_server) { + if (xr_server) { // cleanup now before we pull the rug from underneath... - memdelete(arvr_server); + memdelete(xr_server); } ImageLoader::cleanup(); diff --git a/main/tests/test_shader_lang.cpp b/main/tests/test_shader_lang.cpp index 1e85f7f1d2..dbe2da86cf 100644 --- a/main/tests/test_shader_lang.cpp +++ b/main/tests/test_shader_lang.cpp @@ -342,7 +342,7 @@ MainLoop *test() { Set<String> types; types.insert("spatial"); - Error err = sl.compile(code, dt, rm, types); + Error err = sl.compile(code, dt, rm, types, NULL); if (err) { diff --git a/misc/travis/android-tools-linux.sh b/misc/travis/android-tools-linux.sh index d0c123ee6c..6114551861 100755 --- a/misc/travis/android-tools-linux.sh +++ b/misc/travis/android-tools-linux.sh @@ -24,12 +24,12 @@ ANDROID_SDK_URL=$ANDROID_BASE_URL/$ANDROID_SDK_FILENAME ANDROID_SDK_PATH=$GODOT_BUILD_TOOLS_PATH/$ANDROID_SDK_DIR ANDROID_SDK_SHA256=92ffee5a1d98d856634e8b71132e8a95d96c83a63fde1099be3d86df3106def9 -ANDROID_NDK_RELEASE=r20 +ANDROID_NDK_RELEASE=r21 ANDROID_NDK_DIR=android-ndk ANDROID_NDK_FILENAME=android-ndk-$ANDROID_NDK_RELEASE-linux-x86_64.zip ANDROID_NDK_URL=$ANDROID_BASE_URL/$ANDROID_NDK_FILENAME ANDROID_NDK_PATH=$GODOT_BUILD_TOOLS_PATH/$ANDROID_NDK_DIR -ANDROID_NDK_SHA1=8665fc84a1b1f0d6ab3b5fdd1e30200cc7b9adff +ANDROID_NDK_SHA1=afc9c0b9faad222898ac8168c78ad4ccac8a1b5c echo echo "Download and install Android development tools ..." @@ -76,7 +76,7 @@ yes | $ANDROID_SDK_DIR/tools/bin/sdkmanager --licenses > /dev/null echo "Installing: Android Build and Platform Tools ..." yes | $ANDROID_SDK_DIR/tools/bin/sdkmanager 'tools' > /dev/null yes | $ANDROID_SDK_DIR/tools/bin/sdkmanager 'platform-tools' > /dev/null -yes | $ANDROID_SDK_DIR/tools/bin/sdkmanager 'build-tools;28.0.3' > /dev/null +yes | $ANDROID_SDK_DIR/tools/bin/sdkmanager 'build-tools;29.0.3' > /dev/null echo EXPORT_VAL="export ANDROID_HOME=$ANDROID_SDK_PATH" diff --git a/modules/SCsub b/modules/SCsub index 1671b398e5..fb46c5f877 100644 --- a/modules/SCsub +++ b/modules/SCsub @@ -11,6 +11,7 @@ Export("env_modules") # Header with MODULE_*_ENABLED defines. env.CommandNoCache("modules_enabled.gen.h", Value(env.module_list), modules_builders.generate_modules_enabled) +vs_sources = [] # libmodule_<name>.a for each active module. for module in env.module_list: env.modules_sources = [] @@ -23,6 +24,8 @@ for module in env.module_list: lib = env_modules.add_library("module_%s" % module, env.modules_sources) env.Prepend(LIBS=[lib]) + if env["vsproj"]: + vs_sources += env.modules_sources # libmodules.a with only register_module_types. # Must be last so that all libmodule_<name>.a libraries are on the right side @@ -31,3 +34,5 @@ env.modules_sources = [] env_modules.add_source_files(env.modules_sources, "register_module_types.gen.cpp") lib = env_modules.add_library("modules", env.modules_sources) env.Prepend(LIBS=[lib]) +if env["vsproj"]: + env.modules_sources += vs_sources diff --git a/modules/arkit/arkit_interface.h b/modules/arkit/arkit_interface.h index 4f8f726816..1044f3cf6f 100644 --- a/modules/arkit/arkit_interface.h +++ b/modules/arkit/arkit_interface.h @@ -31,9 +31,9 @@ #ifndef ARKIT_INTERFACE_H #define ARKIT_INTERFACE_H -#include "servers/arvr/arvr_interface.h" -#include "servers/arvr/arvr_positional_tracker.h" #include "servers/camera/camera_feed.h" +#include "servers/xr/xr_interface.h" +#include "servers/xr/xr_positional_tracker.h" /** @author Bastiaan Olij <mux213@gmail.com> @@ -44,8 +44,8 @@ // forward declaration for some needed objects class ARKitShader; -class ARKitInterface : public ARVRInterface { - GDCLASS(ARKitInterface, ARVRInterface); +class ARKitInterface : public XRInterface { + GDCLASS(ARKitInterface, XRInterface); private: bool initialized; @@ -65,7 +65,7 @@ private: Vector<uint8_t> img_data[2]; struct anchor_map { - ARVRPositionalTracker *tracker; + XRPositionalTracker *tracker; unsigned char uuid[16]; }; @@ -73,7 +73,7 @@ private: unsigned int num_anchors; unsigned int max_anchors; anchor_map *anchors; - ARVRPositionalTracker *get_anchor_for_uuid(const unsigned char *p_uuid); + XRPositionalTracker *get_anchor_for_uuid(const unsigned char *p_uuid); void remove_anchor_for_uuid(const unsigned char *p_uuid); void remove_all_anchors(); @@ -108,9 +108,9 @@ public: virtual Size2 get_render_targetsize(); virtual bool is_stereo(); - virtual Transform get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform); - virtual CameraMatrix get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far); - virtual void commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect); + virtual Transform get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform); + virtual CameraMatrix get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far); + virtual void commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect); virtual void process(); diff --git a/modules/arkit/arkit_interface.mm b/modules/arkit/arkit_interface.mm index 031e1e115e..79f09e2a7e 100644 --- a/modules/arkit/arkit_interface.mm +++ b/modules/arkit/arkit_interface.mm @@ -158,7 +158,7 @@ StringName ARKitInterface::get_name() const { } int ARKitInterface::get_capabilities() const { - return ARKitInterface::ARVR_MONO + ARKitInterface::ARVR_AR; + return ARKitInterface::XR_MONO + ARKitInterface::XR_AR; } Array ARKitInterface::raycast(Vector2 p_screen_coord) { @@ -218,8 +218,8 @@ bool ARKitInterface::is_initialized() const { } bool ARKitInterface::initialize() { - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, false); + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, false); if (!initialized) { print_line("initializing ARKit"); @@ -244,7 +244,7 @@ bool ARKitInterface::initialize() { transform = Transform(); // make this our primary interface - arvr_server->set_primary_interface(this); + xr_server->set_primary_interface(this); // make sure we have our feed setup if (feed.is_null()) { @@ -270,10 +270,10 @@ bool ARKitInterface::initialize() { void ARKitInterface::uninitialize() { if (initialized) { - ARVRServer *arvr_server = ARVRServer::get_singleton(); - if (arvr_server != NULL) { + XRServer *xr_server = XRServer::get_singleton(); + if (xr_server != NULL) { // no longer our primary interface - arvr_server->clear_primary_interface_if(this); + xr_server->clear_primary_interface_if(this); } if (feed.is_valid()) { @@ -303,22 +303,22 @@ Size2 ARKitInterface::get_render_targetsize() { return target_size; } -Transform ARKitInterface::get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform) { +Transform ARKitInterface::get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform) { _THREAD_SAFE_METHOD_ Transform transform_for_eye; - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, transform_for_eye); + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, transform_for_eye); if (initialized) { - float world_scale = arvr_server->get_world_scale(); + float world_scale = xr_server->get_world_scale(); // just scale our origin point of our transform, note that we really shouldn't be using world_scale in ARKit but.... transform_for_eye = transform; transform_for_eye.origin *= world_scale; - transform_for_eye = p_cam_transform * arvr_server->get_reference_frame() * transform_for_eye; + transform_for_eye = p_cam_transform * xr_server->get_reference_frame() * transform_for_eye; } else { // huh? well just return what we got.... transform_for_eye = p_cam_transform; @@ -327,7 +327,7 @@ Transform ARKitInterface::get_transform_for_eye(ARVRInterface::Eyes p_eye, const return transform_for_eye; } -CameraMatrix ARKitInterface::get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) { +CameraMatrix ARKitInterface::get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) { // Remember our near and far, it will be used in process when we obtain our projection from our ARKit session. z_near = p_z_near; z_far = p_z_far; @@ -335,7 +335,7 @@ CameraMatrix ARKitInterface::get_projection_for_eye(ARVRInterface::Eyes p_eye, r return projection; } -void ARKitInterface::commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) { +void ARKitInterface::commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) { _THREAD_SAFE_METHOD_ // We must have a valid render target @@ -356,7 +356,7 @@ void ARKitInterface::commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_targ VSG::rasterizer->blit_render_target_to_screen(p_render_target, screen_rect, 0); } -ARVRPositionalTracker *ARKitInterface::get_anchor_for_uuid(const unsigned char *p_uuid) { +XRPositionalTracker *ARKitInterface::get_anchor_for_uuid(const unsigned char *p_uuid) { if (anchors == NULL) { num_anchors = 0; max_anchors = 10; @@ -377,8 +377,8 @@ ARVRPositionalTracker *ARKitInterface::get_anchor_for_uuid(const unsigned char * ERR_FAIL_NULL_V(anchors, NULL); } - ARVRPositionalTracker *new_tracker = memnew(ARVRPositionalTracker); - new_tracker->set_type(ARVRServer::TRACKER_ANCHOR); + XRPositionalTracker *new_tracker = memnew(XRPositionalTracker); + new_tracker->set_type(XRServer::TRACKER_ANCHOR); char tracker_name[256]; sprintf(tracker_name, "Anchor %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", p_uuid[0], p_uuid[1], p_uuid[2], p_uuid[3], p_uuid[4], p_uuid[5], p_uuid[6], p_uuid[7], p_uuid[8], p_uuid[9], p_uuid[10], p_uuid[11], p_uuid[12], p_uuid[13], p_uuid[14], p_uuid[15]); @@ -388,7 +388,7 @@ ARVRPositionalTracker *ARKitInterface::get_anchor_for_uuid(const unsigned char * new_tracker->set_name(name); // add our tracker - ARVRServer::get_singleton()->add_tracker(new_tracker); + XRServer::get_singleton()->add_tracker(new_tracker); anchors[num_anchors].tracker = new_tracker; memcpy(anchors[num_anchors].uuid, p_uuid, 16); num_anchors++; @@ -401,7 +401,7 @@ void ARKitInterface::remove_anchor_for_uuid(const unsigned char *p_uuid) { for (unsigned int i = 0; i < num_anchors; i++) { if (memcmp(anchors[i].uuid, p_uuid, 16) == 0) { // remove our tracker - ARVRServer::get_singleton()->remove_tracker(anchors[i].tracker); + XRServer::get_singleton()->remove_tracker(anchors[i].tracker); memdelete(anchors[i].tracker); // bring remaining forward @@ -421,7 +421,7 @@ void ARKitInterface::remove_all_anchors() { if (anchors != NULL) { for (unsigned int i = 0; i < num_anchors; i++) { // remove our tracker - ARVRServer::get_singleton()->remove_tracker(anchors[i].tracker); + XRServer::get_singleton()->remove_tracker(anchors[i].tracker); memdelete(anchors[i].tracker); }; @@ -582,16 +582,16 @@ void ARKitInterface::process() { // strangely enough we have to states, rolling them up into one if (camera.trackingState == ARTrackingStateNotAvailable) { // no tracking, would be good if we black out the screen or something... - tracking_state = ARVRInterface::ARVR_NOT_TRACKING; + tracking_state = XRInterface::XR_NOT_TRACKING; } else { if (camera.trackingState == ARTrackingStateNormal) { - tracking_state = ARVRInterface::ARVR_NORMAL_TRACKING; + tracking_state = XRInterface::XR_NORMAL_TRACKING; } else if (camera.trackingStateReason == ARTrackingStateReasonExcessiveMotion) { - tracking_state = ARVRInterface::ARVR_EXCESSIVE_MOTION; + tracking_state = XRInterface::XR_EXCESSIVE_MOTION; } else if (camera.trackingStateReason == ARTrackingStateReasonInsufficientFeatures) { - tracking_state = ARVRInterface::ARVR_INSUFFICIENT_FEATURES; + tracking_state = XRInterface::XR_INSUFFICIENT_FEATURES; } else { - tracking_state = ARVRInterface::ARVR_UNKNOWN_TRACKING; + tracking_state = XRInterface::XR_UNKNOWN_TRACKING; } // copy our current frame transform @@ -665,7 +665,7 @@ void ARKitInterface::_add_or_update_anchor(void *p_anchor) { unsigned char uuid[16]; [anchor.identifier getUUIDBytes:uuid]; - ARVRPositionalTracker *tracker = get_anchor_for_uuid(uuid); + XRPositionalTracker *tracker = get_anchor_for_uuid(uuid); if (tracker != NULL) { // lets update our mesh! (using Arjens code as is for now) // we should also probably limit how often we do this... @@ -695,7 +695,7 @@ void ARKitInterface::_add_or_update_anchor(void *p_anchor) { } // Note, this also contains a scale factor which gives us an idea of the size of the anchor - // We may extract that in our ARVRAnchor class + // We may extract that in our XRAnchor class Basis b; matrix_float4x4 m44 = anchor.transform; b.elements[0].x = m44.columns[0][0]; diff --git a/modules/arkit/register_types.cpp b/modules/arkit/register_types.cpp index c78b35529b..91069ab364 100644 --- a/modules/arkit/register_types.cpp +++ b/modules/arkit/register_types.cpp @@ -37,7 +37,7 @@ void register_arkit_types() { Ref<ARKitInterface> arkit_interface; arkit_interface.instance(); - ARVRServer::get_singleton()->add_interface(arkit_interface); + XRServer::get_singleton()->add_interface(arkit_interface); } void unregister_arkit_types() { diff --git a/modules/bullet/config.py b/modules/bullet/config.py index e8ca273f61..d22f9454ed 100644 --- a/modules/bullet/config.py +++ b/modules/bullet/config.py @@ -4,14 +4,3 @@ def can_build(env, platform): def configure(env): pass - - -def get_doc_classes(): - return [ - "BulletPhysicsDirectBodyState3D", - "BulletPhysicsServer3D", - ] - - -def get_doc_path(): - return "doc_classes" diff --git a/modules/bullet/doc_classes/BulletPhysicsDirectBodyState3D.xml b/modules/bullet/doc_classes/BulletPhysicsDirectBodyState3D.xml deleted file mode 100644 index 1c0181bd9c..0000000000 --- a/modules/bullet/doc_classes/BulletPhysicsDirectBodyState3D.xml +++ /dev/null @@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="BulletPhysicsDirectBodyState3D" inherits="PhysicsDirectBodyState3D" version="4.0"> - <brief_description> - </brief_description> - <description> - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp index fc4e1d57de..a4f9affa95 100644 --- a/modules/bullet/rigid_body_bullet.cpp +++ b/modules/bullet/rigid_body_bullet.cpp @@ -138,8 +138,8 @@ void BulletPhysicsDirectBodyState3D::apply_torque_impulse(const Vector3 &p_impul body->apply_torque_impulse(p_impulse); } -void BulletPhysicsDirectBodyState3D::set_sleep_state(bool p_enable) { - body->set_activation_state(p_enable); +void BulletPhysicsDirectBodyState3D::set_sleep_state(bool p_sleep) { + body->set_activation_state(!p_sleep); } bool BulletPhysicsDirectBodyState3D::is_sleeping() const { diff --git a/modules/bullet/rigid_body_bullet.h b/modules/bullet/rigid_body_bullet.h index 95491b1e62..420b5cc443 100644 --- a/modules/bullet/rigid_body_bullet.h +++ b/modules/bullet/rigid_body_bullet.h @@ -117,7 +117,7 @@ public: virtual void apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse); virtual void apply_torque_impulse(const Vector3 &p_impulse); - virtual void set_sleep_state(bool p_enable); + virtual void set_sleep_state(bool p_sleep); virtual bool is_sleeping() const; virtual int get_contact_count() const; diff --git a/modules/dds/texture_loader_dds.cpp b/modules/dds/texture_loader_dds.cpp index ae21156b8b..294d594135 100644 --- a/modules/dds/texture_loader_dds.cpp +++ b/modules/dds/texture_loader_dds.cpp @@ -94,7 +94,7 @@ static const DDSFormatInfo dds_format_info[DDS_MAX] = { { "GRAYSCALE_ALPHA", false, false, 1, 2, Image::FORMAT_LA8 } }; -RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) *r_error = ERR_CANT_OPEN; diff --git a/modules/dds/texture_loader_dds.h b/modules/dds/texture_loader_dds.h index 5b89f16277..ef08967df7 100644 --- a/modules/dds/texture_loader_dds.h +++ b/modules/dds/texture_loader_dds.h @@ -36,7 +36,7 @@ class ResourceFormatDDS : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/etc/texture_loader_pkm.cpp b/modules/etc/texture_loader_pkm.cpp index ad0cc91c96..bfb2098dff 100644 --- a/modules/etc/texture_loader_pkm.cpp +++ b/modules/etc/texture_loader_pkm.cpp @@ -42,7 +42,7 @@ struct ETC1Header { uint16_t origHeight; }; -RES ResourceFormatPKM::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatPKM::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) *r_error = ERR_CANT_OPEN; diff --git a/modules/etc/texture_loader_pkm.h b/modules/etc/texture_loader_pkm.h index 989e203994..6507e0bdec 100644 --- a/modules/etc/texture_loader_pkm.h +++ b/modules/etc/texture_loader_pkm.h @@ -36,7 +36,7 @@ class ResourceFormatPKM : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/gdnative/SCsub b/modules/gdnative/SCsub index a788175b07..cab05549d2 100644 --- a/modules/gdnative/SCsub +++ b/modules/gdnative/SCsub @@ -17,7 +17,7 @@ env_gdnative.Prepend(CPPPATH=["#modules/gdnative/include/"]) Export("env_gdnative") SConscript("net/SCsub") -SConscript("arvr/SCsub") +SConscript("xr/SCsub") SConscript("pluginscript/SCsub") SConscript("videodecoder/SCsub") diff --git a/modules/gdnative/config.py b/modules/gdnative/config.py index 37e25a46d4..4b997e4bfe 100644 --- a/modules/gdnative/config.py +++ b/modules/gdnative/config.py @@ -9,7 +9,7 @@ def configure(env): def get_doc_classes(): return [ "@NativeScript", - "ARVRInterfaceGDNative", + "XRInterfaceGDNative", "GDNative", "GDNativeLibrary", "MultiplayerPeerGDNative", diff --git a/modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml b/modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml deleted file mode 100644 index e8405b64a3..0000000000 --- a/modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="ARVRInterfaceGDNative" inherits="ARVRInterface" version="4.0"> - <brief_description> - GDNative wrapper for an ARVR interface. - </brief_description> - <description> - This is a wrapper class for GDNative implementations of the ARVR interface. To use a GDNative ARVR interface, simply instantiate this object and set your GDNative library containing the ARVR interface implementation. - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <constants> - </constants> -</class> diff --git a/modules/gdnative/doc_classes/GDNativeLibrary.xml b/modules/gdnative/doc_classes/GDNativeLibrary.xml index 601e132d42..1aab864102 100644 --- a/modules/gdnative/doc_classes/GDNativeLibrary.xml +++ b/modules/gdnative/doc_classes/GDNativeLibrary.xml @@ -4,7 +4,7 @@ An external library containing functions or script classes to use in Godot. </brief_description> <description> - A GDNative library can implement [NativeScript]s, global functions to call with the [GDNative] class, or low-level engine extensions through interfaces such as [ARVRInterfaceGDNative]. The library must be compiled for each platform and architecture that the project will run on. + A GDNative library can implement [NativeScript]s, global functions to call with the [GDNative] class, or low-level engine extensions through interfaces such as [XRInterfaceGDNative]. The library must be compiled for each platform and architecture that the project will run on. </description> <tutorials> <link>https://docs.godotengine.org/en/latest/tutorials/plugins/gdnative/gdnative-c-example.html</link> diff --git a/modules/gdnative/doc_classes/XRInterfaceGDNative.xml b/modules/gdnative/doc_classes/XRInterfaceGDNative.xml new file mode 100644 index 0000000000..13de815793 --- /dev/null +++ b/modules/gdnative/doc_classes/XRInterfaceGDNative.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="XRInterfaceGDNative" inherits="XRInterface" version="4.0"> + <brief_description> + GDNative wrapper for an XR interface. + </brief_description> + <description> + This is a wrapper class for GDNative implementations of the XR interface. To use a GDNative XR interface, simply instantiate this object and set your GDNative library containing the XR interface implementation. + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp index d3426044ec..a131e3a78f 100644 --- a/modules/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative.cpp @@ -493,7 +493,7 @@ Error GDNative::get_symbol(StringName p_procedure_name, void *&r_handle, bool p_ return result; } -RES GDNativeLibraryResourceLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES GDNativeLibraryResourceLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { Ref<GDNativeLibrary> lib; lib.instance(); diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h index 9ef9c706d1..6d26c2141d 100644 --- a/modules/gdnative/gdnative.h +++ b/modules/gdnative/gdnative.h @@ -166,7 +166,7 @@ public: class GDNativeLibraryResourceLoader : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json index e1d6c0c867..9473a3d419 100644 --- a/modules/gdnative/gdnative_api.json +++ b/modules/gdnative/gdnative_api.json @@ -5935,8 +5935,8 @@ ] }, { - "name": "arvr", - "type": "ARVR", + "name": "xr", + "type": "XR", "version": { "major": 1, "minor": 1 @@ -5944,24 +5944,24 @@ "next": null, "api": [ { - "name": "godot_arvr_register_interface", + "name": "godot_xr_register_interface", "return_type": "void", "arguments": [ - ["const godot_arvr_interface_gdnative *", "p_interface"] + ["const godot_xr_interface_gdnative *", "p_interface"] ] }, { - "name": "godot_arvr_get_worldscale", + "name": "godot_xr_get_worldscale", "return_type": "godot_real", "arguments": [] }, { - "name": "godot_arvr_get_reference_frame", + "name": "godot_xr_get_reference_frame", "return_type": "godot_transform", "arguments": [] }, { - "name": "godot_arvr_blit", + "name": "godot_xr_blit", "return_type": "void", "arguments": [ ["godot_int", "p_eye"], @@ -5970,14 +5970,14 @@ ] }, { - "name": "godot_arvr_get_texid", + "name": "godot_xr_get_texid", "return_type": "godot_int", "arguments": [ ["godot_rid *", "p_render_target"] ] }, { - "name": "godot_arvr_add_controller", + "name": "godot_xr_add_controller", "return_type": "godot_int", "arguments": [ ["char *", "p_device_name"], @@ -5987,14 +5987,14 @@ ] }, { - "name": "godot_arvr_remove_controller", + "name": "godot_xr_remove_controller", "return_type": "void", "arguments": [ ["godot_int", "p_controller_id"] ] }, { - "name": "godot_arvr_set_controller_transform", + "name": "godot_xr_set_controller_transform", "return_type": "void", "arguments": [ ["godot_int", "p_controller_id"], @@ -6004,7 +6004,7 @@ ] }, { - "name": "godot_arvr_set_controller_button", + "name": "godot_xr_set_controller_button", "return_type": "void", "arguments": [ ["godot_int", "p_controller_id"], @@ -6013,7 +6013,7 @@ ] }, { - "name": "godot_arvr_set_controller_axis", + "name": "godot_xr_set_controller_axis", "return_type": "void", "arguments": [ ["godot_int", "p_controller_id"], @@ -6023,7 +6023,7 @@ ] }, { - "name": "godot_arvr_get_controller_rumble", + "name": "godot_xr_get_controller_rumble", "return_type": "godot_real", "arguments": [ ["godot_int", "p_controller_id"] diff --git a/modules/gdnative/gdnative_builders.py b/modules/gdnative/gdnative_builders.py index 2d84f93d87..620935795f 100644 --- a/modules/gdnative/gdnative_builders.py +++ b/modules/gdnative/gdnative_builders.py @@ -19,7 +19,7 @@ def _build_gdnative_api_struct_header(api): "", "#include <gdnative/gdnative.h>", "#include <android/godot_android.h>", - "#include <arvr/godot_arvr.h>", + "#include <xr/godot_xr.h>", "#include <nativescript/godot_nativescript.h>", "#include <net/godot_net.h>", "#include <pluginscript/godot_pluginscript.h>", diff --git a/modules/gdnative/include/nativescript/godot_nativescript.h b/modules/gdnative/include/nativescript/godot_nativescript.h index 1b131c8cf0..0fb5180103 100644 --- a/modules/gdnative/include/nativescript/godot_nativescript.h +++ b/modules/gdnative/include/nativescript/godot_nativescript.h @@ -54,7 +54,6 @@ typedef enum { GODOT_PROPERTY_HINT_ENUM, ///< hint_text= "val1,val2,val3,etc" GODOT_PROPERTY_HINT_EXP_EASING, /// exponential easing function (Math::ease) GODOT_PROPERTY_HINT_LENGTH, ///< hint_text= "length" (as integer) - GODOT_PROPERTY_HINT_SPRITE_FRAME, // FIXME: Obsolete: drop whenever we can break compat GODOT_PROPERTY_HINT_KEY_ACCEL, ///< hint_text= "length" (as integer) GODOT_PROPERTY_HINT_FLAGS, ///< hint_text= "flag1,flag2,etc" (as bit flags) GODOT_PROPERTY_HINT_LAYERS_2D_RENDER, @@ -96,8 +95,7 @@ typedef enum { GODOT_PROPERTY_USAGE_INTERNATIONALIZED = 64, //hint for internationalized strings GODOT_PROPERTY_USAGE_GROUP = 128, //used for grouping props in the editor GODOT_PROPERTY_USAGE_CATEGORY = 256, - GODOT_PROPERTY_USAGE_STORE_IF_NONZERO = 512, // FIXME: Obsolete: drop whenever we can break compat - GODOT_PROPERTY_USAGE_STORE_IF_NONONE = 1024, // FIXME: Obsolete: drop whenever we can break compat + GODOT_PROPERTY_USAGE_SUBGROUP = 512, GODOT_PROPERTY_USAGE_NO_INSTANCE_STATE = 2048, GODOT_PROPERTY_USAGE_RESTART_IF_CHANGED = 4096, GODOT_PROPERTY_USAGE_SCRIPT_VARIABLE = 8192, diff --git a/modules/gdnative/include/arvr/godot_arvr.h b/modules/gdnative/include/xr/godot_xr.h index aaef31a855..22f7f021c4 100644 --- a/modules/gdnative/include/arvr/godot_arvr.h +++ b/modules/gdnative/include/xr/godot_xr.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* godot_arvr.h */ +/* godot_xr.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GODOT_NATIVEARVR_H -#define GODOT_NATIVEARVR_H +#ifndef GODOT_NATIVEXR_H +#define GODOT_NATIVEXR_H #include <gdnative/gdnative.h> @@ -61,32 +61,31 @@ typedef struct { void (*fill_projection_for_eye)(void *, godot_real *, godot_int, godot_real, godot_real, godot_real); void (*commit_for_eye)(void *, godot_int, godot_rid *, godot_rect2 *); void (*process)(void *); - // only in 1.1 onwards godot_int (*get_external_texture_for_eye)(void *, godot_int); void (*notification)(void *, godot_int); godot_int (*get_camera_feed_id)(void *); -} godot_arvr_interface_gdnative; +} godot_xr_interface_gdnative; -void GDAPI godot_arvr_register_interface(const godot_arvr_interface_gdnative *p_interface); +void GDAPI godot_xr_register_interface(const godot_xr_interface_gdnative *p_interface); -// helper functions to access ARVRServer data -godot_real GDAPI godot_arvr_get_worldscale(); -godot_transform GDAPI godot_arvr_get_reference_frame(); +// helper functions to access XRServer data +godot_real GDAPI godot_xr_get_worldscale(); +godot_transform GDAPI godot_xr_get_reference_frame(); // helper functions for rendering -void GDAPI godot_arvr_blit(godot_int p_eye, godot_rid *p_render_target, godot_rect2 *p_rect); -godot_int GDAPI godot_arvr_get_texid(godot_rid *p_render_target); +void GDAPI godot_xr_blit(godot_int p_eye, godot_rid *p_render_target, godot_rect2 *p_rect); +godot_int GDAPI godot_xr_get_texid(godot_rid *p_render_target); -// helper functions for updating ARVR controllers -godot_int GDAPI godot_arvr_add_controller(char *p_device_name, godot_int p_hand, godot_bool p_tracks_orientation, godot_bool p_tracks_position); -void GDAPI godot_arvr_remove_controller(godot_int p_controller_id); -void GDAPI godot_arvr_set_controller_transform(godot_int p_controller_id, godot_transform *p_transform, godot_bool p_tracks_orientation, godot_bool p_tracks_position); -void GDAPI godot_arvr_set_controller_button(godot_int p_controller_id, godot_int p_button, godot_bool p_is_pressed); -void GDAPI godot_arvr_set_controller_axis(godot_int p_controller_id, godot_int p_axis, godot_real p_value, godot_bool p_can_be_negative); -godot_real GDAPI godot_arvr_get_controller_rumble(godot_int p_controller_id); +// helper functions for updating XR controllers +godot_int GDAPI godot_xr_add_controller(char *p_device_name, godot_int p_hand, godot_bool p_tracks_orientation, godot_bool p_tracks_position); +void GDAPI godot_xr_remove_controller(godot_int p_controller_id); +void GDAPI godot_xr_set_controller_transform(godot_int p_controller_id, godot_transform *p_transform, godot_bool p_tracks_orientation, godot_bool p_tracks_position); +void GDAPI godot_xr_set_controller_button(godot_int p_controller_id, godot_int p_button, godot_bool p_is_pressed); +void GDAPI godot_xr_set_controller_axis(godot_int p_controller_id, godot_int p_axis, godot_real p_value, godot_bool p_can_be_negative); +godot_real GDAPI godot_xr_get_controller_rumble(godot_int p_controller_id); #ifdef __cplusplus } #endif -#endif /* !GODOT_NATIVEARVR_H */ +#endif /* !GODOT_NATIVEXR_H */ diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp index bf458c15ee..ed3ec44bf7 100644 --- a/modules/gdnative/nativescript/nativescript.cpp +++ b/modules/gdnative/nativescript/nativescript.cpp @@ -111,6 +111,13 @@ void NativeScript::_placeholder_erased(PlaceHolderScriptInstance *p_placeholder) #endif +bool NativeScript::inherits_script(const Ref<Script> &p_script) const { +#ifndef _MSC_VER +#warning inheritance needs to be implemented in NativeScript +#endif + return false; +} + void NativeScript::set_class_name(String p_class_name) { class_name = p_class_name; } @@ -1931,7 +1938,7 @@ void NativeReloadNode::_notification(int p_what) { #endif } -RES ResourceFormatLoaderNativeScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderNativeScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { return ResourceFormatLoaderText::singleton->load(p_path, p_original_path, r_error); } diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h index 75bbb42664..7e7598e06c 100644 --- a/modules/gdnative/nativescript/nativescript.h +++ b/modules/gdnative/nativescript/nativescript.h @@ -133,6 +133,8 @@ protected: public: inline NativeScriptDesc *get_script_desc() const; + bool inherits_script(const Ref<Script> &p_script) const; + void set_class_name(String p_class_name); String get_class_name() const; @@ -406,7 +408,7 @@ public: class ResourceFormatLoaderNativeScript : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/gdnative/pluginscript/pluginscript_loader.cpp b/modules/gdnative/pluginscript/pluginscript_loader.cpp index 3fb22b3f8d..64582cc517 100644 --- a/modules/gdnative/pluginscript/pluginscript_loader.cpp +++ b/modules/gdnative/pluginscript/pluginscript_loader.cpp @@ -39,7 +39,7 @@ ResourceFormatLoaderPluginScript::ResourceFormatLoaderPluginScript(PluginScriptL _language = language; } -RES ResourceFormatLoaderPluginScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderPluginScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) *r_error = ERR_FILE_CANT_OPEN; diff --git a/modules/gdnative/pluginscript/pluginscript_loader.h b/modules/gdnative/pluginscript/pluginscript_loader.h index c929be53bd..e47754490a 100644 --- a/modules/gdnative/pluginscript/pluginscript_loader.h +++ b/modules/gdnative/pluginscript/pluginscript_loader.h @@ -44,7 +44,7 @@ class ResourceFormatLoaderPluginScript : public ResourceFormatLoader { public: ResourceFormatLoaderPluginScript(PluginScriptLanguage *language); - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/gdnative/pluginscript/pluginscript_script.cpp b/modules/gdnative/pluginscript/pluginscript_script.cpp index a4c84dc0ca..6b303c8716 100644 --- a/modules/gdnative/pluginscript/pluginscript_script.cpp +++ b/modules/gdnative/pluginscript/pluginscript_script.cpp @@ -140,6 +140,13 @@ bool PluginScript::can_instance() const { return can; } +bool PluginScript::inherits_script(const Ref<Script> &p_script) const { +#ifndef _MSC_VER +#warning inheritance needs to be implemented in PluginScript +#endif + return false; +} + Ref<Script> PluginScript::get_base_script() const { if (_ref_base_parent.is_valid()) { return Ref<PluginScript>(_ref_base_parent); diff --git a/modules/gdnative/pluginscript/pluginscript_script.h b/modules/gdnative/pluginscript/pluginscript_script.h index 5c93ae38f5..70b9ca980b 100644 --- a/modules/gdnative/pluginscript/pluginscript_script.h +++ b/modules/gdnative/pluginscript/pluginscript_script.h @@ -72,6 +72,8 @@ private: protected: static void _bind_methods(); + bool inherits_script(const Ref<Script> &p_script) const; + PluginScriptInstance *_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, Callable::CallError &r_error); Variant _new(const Variant **p_args, int p_argcount, Callable::CallError &r_error); diff --git a/modules/gdnative/register_types.cpp b/modules/gdnative/register_types.cpp index 397a020689..67a286ee2e 100644 --- a/modules/gdnative/register_types.cpp +++ b/modules/gdnative/register_types.cpp @@ -34,11 +34,11 @@ #include "gdnative.h" -#include "arvr/register_types.h" #include "nativescript/register_types.h" #include "net/register_types.h" #include "pluginscript/register_types.h" #include "videodecoder/register_types.h" +#include "xr/register_types.h" #include "core/engine.h" #include "core/io/resource_loader.h" @@ -240,7 +240,7 @@ void register_gdnative_types() { GDNativeCallRegistry::singleton->register_native_call_type("standard_varcall", cb_standard_varcall); register_net_types(); - register_arvr_types(); + register_xr_types(); register_nativescript_types(); register_pluginscript_types(); register_videodecoder_types(); @@ -305,7 +305,7 @@ void unregister_gdnative_types() { unregister_videodecoder_types(); unregister_pluginscript_types(); unregister_nativescript_types(); - unregister_arvr_types(); + unregister_xr_types(); unregister_net_types(); memdelete(GDNativeCallRegistry::singleton); diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.cpp b/modules/gdnative/videodecoder/video_stream_gdnative.cpp index fa9f6be5c1..f7d87595af 100644 --- a/modules/gdnative/videodecoder/video_stream_gdnative.cpp +++ b/modules/gdnative/videodecoder/video_stream_gdnative.cpp @@ -373,7 +373,7 @@ void VideoStreamGDNative::set_audio_track(int p_track) { /* --- NOTE ResourceFormatLoaderVideoStreamGDNative starts here. ----- */ -RES ResourceFormatLoaderVideoStreamGDNative::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderVideoStreamGDNative::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ); if (!f) { if (r_error) { diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.h b/modules/gdnative/videodecoder/video_stream_gdnative.h index fbc0d4016f..092e10a0f5 100644 --- a/modules/gdnative/videodecoder/video_stream_gdnative.h +++ b/modules/gdnative/videodecoder/video_stream_gdnative.h @@ -199,7 +199,7 @@ public: class ResourceFormatLoaderVideoStreamGDNative : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/gdnative/arvr/SCsub b/modules/gdnative/xr/SCsub index 0b2db3b504..0b2db3b504 100644 --- a/modules/gdnative/arvr/SCsub +++ b/modules/gdnative/xr/SCsub diff --git a/modules/gdnative/arvr/config.py b/modules/gdnative/xr/config.py index d22f9454ed..d22f9454ed 100644 --- a/modules/gdnative/arvr/config.py +++ b/modules/gdnative/xr/config.py diff --git a/modules/gdnative/arvr/register_types.cpp b/modules/gdnative/xr/register_types.cpp index 0f6e2bca1a..da3a7dc4b8 100644 --- a/modules/gdnative/arvr/register_types.cpp +++ b/modules/gdnative/xr/register_types.cpp @@ -29,11 +29,12 @@ /*************************************************************************/ #include "register_types.h" -#include "arvr_interface_gdnative.h" +#include "xr_interface_gdnative.h" -void register_arvr_types() { - ClassDB::register_class<ARVRInterfaceGDNative>(); +void register_xr_types() { + ClassDB::register_class<XRInterfaceGDNative>(); + ClassDB::add_compatibility_class("ARVRInterfaceGDNative", "XRInterfaceGDNative"); } -void unregister_arvr_types() { +void unregister_xr_types() { } diff --git a/modules/gdnative/arvr/register_types.h b/modules/gdnative/xr/register_types.h index b0de6f7c14..2501d28651 100644 --- a/modules/gdnative/arvr/register_types.h +++ b/modules/gdnative/xr/register_types.h @@ -28,10 +28,10 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef ARVR_REGISTER_TYPES_H -#define ARVR_REGISTER_TYPES_H +#ifndef XR_REGISTER_TYPES_H +#define XR_REGISTER_TYPES_H -void register_arvr_types(); -void unregister_arvr_types(); +void register_xr_types(); +void unregister_xr_types(); -#endif // ARVR_REGISTER_TYPES_H +#endif // XR_REGISTER_TYPES_H diff --git a/modules/gdnative/arvr/arvr_interface_gdnative.cpp b/modules/gdnative/xr/xr_interface_gdnative.cpp index f14691027a..0451945139 100644 --- a/modules/gdnative/arvr/arvr_interface_gdnative.cpp +++ b/modules/gdnative/xr/xr_interface_gdnative.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* arvr_interface_gdnative.cpp */ +/* xr_interface_gdnative.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,17 +28,17 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "arvr_interface_gdnative.h" +#include "xr_interface_gdnative.h" #include "core/input/input_filter.h" -#include "servers/arvr/arvr_positional_tracker.h" #include "servers/rendering/rendering_server_globals.h" +#include "servers/xr/xr_positional_tracker.h" -void ARVRInterfaceGDNative::_bind_methods() { +void XRInterfaceGDNative::_bind_methods() { ADD_PROPERTY_DEFAULT("interface_is_initialized", false); ADD_PROPERTY_DEFAULT("ar_is_anchor_detection_enabled", false); } -ARVRInterfaceGDNative::ARVRInterfaceGDNative() { +XRInterfaceGDNative::XRInterfaceGDNative() { print_verbose("Construct gdnative interface\n"); // we won't have our data pointer until our library gets set @@ -47,7 +47,7 @@ ARVRInterfaceGDNative::ARVRInterfaceGDNative() { interface = nullptr; } -ARVRInterfaceGDNative::~ARVRInterfaceGDNative() { +XRInterfaceGDNative::~XRInterfaceGDNative() { print_verbose("Destruct gdnative interface\n"); if (interface != nullptr && is_initialized()) { @@ -58,7 +58,7 @@ ARVRInterfaceGDNative::~ARVRInterfaceGDNative() { cleanup(); } -void ARVRInterfaceGDNative::cleanup() { +void XRInterfaceGDNative::cleanup() { if (interface != nullptr) { interface->destructor(data); data = nullptr; @@ -66,7 +66,7 @@ void ARVRInterfaceGDNative::cleanup() { } } -void ARVRInterfaceGDNative::set_interface(const godot_arvr_interface_gdnative *p_interface) { +void XRInterfaceGDNative::set_interface(const godot_xr_interface_gdnative *p_interface) { // this should only be called once, just being paranoid.. if (interface) { cleanup(); @@ -79,7 +79,7 @@ void ARVRInterfaceGDNative::set_interface(const godot_arvr_interface_gdnative *p data = interface->constructor((godot_object *)this); } -StringName ARVRInterfaceGDNative::get_name() const { +StringName XRInterfaceGDNative::get_name() const { ERR_FAIL_COND_V(interface == nullptr, StringName()); @@ -92,7 +92,7 @@ StringName ARVRInterfaceGDNative::get_name() const { return name; } -int ARVRInterfaceGDNative::get_capabilities() const { +int XRInterfaceGDNative::get_capabilities() const { int capabilities; ERR_FAIL_COND_V(interface == nullptr, 0); // 0 = None @@ -102,32 +102,28 @@ int ARVRInterfaceGDNative::get_capabilities() const { return capabilities; } -bool ARVRInterfaceGDNative::get_anchor_detection_is_enabled() const { +bool XRInterfaceGDNative::get_anchor_detection_is_enabled() const { ERR_FAIL_COND_V(interface == nullptr, false); return interface->get_anchor_detection_is_enabled(data); } -void ARVRInterfaceGDNative::set_anchor_detection_is_enabled(bool p_enable) { +void XRInterfaceGDNative::set_anchor_detection_is_enabled(bool p_enable) { ERR_FAIL_COND(interface == nullptr); interface->set_anchor_detection_is_enabled(data, p_enable); } -int ARVRInterfaceGDNative::get_camera_feed_id() { +int XRInterfaceGDNative::get_camera_feed_id() { ERR_FAIL_COND_V(interface == nullptr, 0); - if ((interface->version.major > 1) || ((interface->version.major) == 1 && (interface->version.minor >= 1))) { - return (unsigned int)interface->get_camera_feed_id(data); - } else { - return 0; - } + return (unsigned int)interface->get_camera_feed_id(data); } -bool ARVRInterfaceGDNative::is_stereo() { +bool XRInterfaceGDNative::is_stereo() { bool stereo; ERR_FAIL_COND_V(interface == nullptr, false); @@ -137,14 +133,14 @@ bool ARVRInterfaceGDNative::is_stereo() { return stereo; } -bool ARVRInterfaceGDNative::is_initialized() const { +bool XRInterfaceGDNative::is_initialized() const { ERR_FAIL_COND_V(interface == nullptr, false); return interface->is_initialized(data); } -bool ARVRInterfaceGDNative::initialize() { +bool XRInterfaceGDNative::initialize() { ERR_FAIL_COND_V(interface == nullptr, false); bool initialized = interface->initialize(data); @@ -152,28 +148,28 @@ bool ARVRInterfaceGDNative::initialize() { if (initialized) { // if we successfully initialize our interface and we don't have a primary interface yet, this becomes our primary interface - ARVRServer *arvr_server = ARVRServer::get_singleton(); - if ((arvr_server != nullptr) && (arvr_server->get_primary_interface() == nullptr)) { - arvr_server->set_primary_interface(this); + XRServer *xr_server = XRServer::get_singleton(); + if ((xr_server != nullptr) && (xr_server->get_primary_interface() == nullptr)) { + xr_server->set_primary_interface(this); }; }; return initialized; } -void ARVRInterfaceGDNative::uninitialize() { +void XRInterfaceGDNative::uninitialize() { ERR_FAIL_COND(interface == nullptr); - ARVRServer *arvr_server = ARVRServer::get_singleton(); - if (arvr_server != nullptr) { + XRServer *xr_server = XRServer::get_singleton(); + if (xr_server != nullptr) { // Whatever happens, make sure this is no longer our primary interface - arvr_server->clear_primary_interface_if(this); + xr_server->clear_primary_interface_if(this); } interface->uninitialize(data); } -Size2 ARVRInterfaceGDNative::get_render_targetsize() { +Size2 XRInterfaceGDNative::get_render_targetsize() { ERR_FAIL_COND_V(interface == nullptr, Size2()); @@ -183,7 +179,7 @@ Size2 ARVRInterfaceGDNative::get_render_targetsize() { return *vec; } -Transform ARVRInterfaceGDNative::get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform) { +Transform XRInterfaceGDNative::get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform) { Transform *ret; ERR_FAIL_COND_V(interface == nullptr, Transform()); @@ -195,7 +191,7 @@ Transform ARVRInterfaceGDNative::get_transform_for_eye(ARVRInterface::Eyes p_eye return *ret; } -CameraMatrix ARVRInterfaceGDNative::get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) { +CameraMatrix XRInterfaceGDNative::get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) { CameraMatrix cm; ERR_FAIL_COND_V(interface == nullptr, CameraMatrix()); @@ -205,37 +201,30 @@ CameraMatrix ARVRInterfaceGDNative::get_projection_for_eye(ARVRInterface::Eyes p return cm; } -unsigned int ARVRInterfaceGDNative::get_external_texture_for_eye(ARVRInterface::Eyes p_eye) { +unsigned int XRInterfaceGDNative::get_external_texture_for_eye(XRInterface::Eyes p_eye) { ERR_FAIL_COND_V(interface == nullptr, 0); - if ((interface->version.major > 1) || ((interface->version.major) == 1 && (interface->version.minor >= 1))) { - return (unsigned int)interface->get_external_texture_for_eye(data, (godot_int)p_eye); - } else { - return 0; - } + return (unsigned int)interface->get_external_texture_for_eye(data, (godot_int)p_eye); } -void ARVRInterfaceGDNative::commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) { +void XRInterfaceGDNative::commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) { ERR_FAIL_COND(interface == nullptr); interface->commit_for_eye(data, (godot_int)p_eye, (godot_rid *)&p_render_target, (godot_rect2 *)&p_screen_rect); } -void ARVRInterfaceGDNative::process() { +void XRInterfaceGDNative::process() { ERR_FAIL_COND(interface == nullptr); interface->process(data); } -void ARVRInterfaceGDNative::notification(int p_what) { +void XRInterfaceGDNative::notification(int p_what) { ERR_FAIL_COND(interface == nullptr); - // this is only available in interfaces that implement 1.1 or later - if ((interface->version.major > 1) || ((interface->version.major == 1) && (interface->version.minor > 0))) { - interface->notification(data, p_what); - } + interface->notification(data, p_what); } ///////////////////////////////////////////////////////////////////////////////////// @@ -243,30 +232,30 @@ void ARVRInterfaceGDNative::notification(int p_what) { extern "C" { -void GDAPI godot_arvr_register_interface(const godot_arvr_interface_gdnative *p_interface) { - // If our major version is 0 or bigger then 10, we're likely looking at our constructor pointer from an older plugin - ERR_FAIL_COND_MSG((p_interface->version.major == 0) || (p_interface->version.major > 10), "GDNative ARVR interfaces build for Godot 3.0 are not supported."); +void GDAPI godot_xr_register_interface(const godot_xr_interface_gdnative *p_interface) { + // Must be on a version 4 plugin + ERR_FAIL_COND_MSG(p_interface->version.major < 4, "GDNative XR interfaces build for Godot 3.x are not supported."); - Ref<ARVRInterfaceGDNative> new_interface; + Ref<XRInterfaceGDNative> new_interface; new_interface.instance(); - new_interface->set_interface((const godot_arvr_interface_gdnative *)p_interface); - ARVRServer::get_singleton()->add_interface(new_interface); + new_interface->set_interface((const godot_xr_interface_gdnative *)p_interface); + XRServer::get_singleton()->add_interface(new_interface); } -godot_real GDAPI godot_arvr_get_worldscale() { - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, 1.0); +godot_real GDAPI godot_xr_get_worldscale() { + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, 1.0); - return arvr_server->get_world_scale(); + return xr_server->get_world_scale(); } -godot_transform GDAPI godot_arvr_get_reference_frame() { +godot_transform GDAPI godot_xr_get_reference_frame() { godot_transform reference_frame; Transform *reference_frame_ptr = (Transform *)&reference_frame; - ARVRServer *arvr_server = ARVRServer::get_singleton(); - if (arvr_server != nullptr) { - *reference_frame_ptr = arvr_server->get_reference_frame(); + XRServer *xr_server = XRServer::get_singleton(); + if (xr_server != nullptr) { + *reference_frame_ptr = xr_server->get_reference_frame(); } else { godot_transform_new_identity(&reference_frame); } @@ -274,17 +263,17 @@ godot_transform GDAPI godot_arvr_get_reference_frame() { return reference_frame; } -void GDAPI godot_arvr_blit(godot_int p_eye, godot_rid *p_render_target, godot_rect2 *p_rect) { +void GDAPI godot_xr_blit(godot_int p_eye, godot_rid *p_render_target, godot_rect2 *p_rect) { // blits out our texture as is, handy for preview display of one of the eyes that is already rendered with lens distortion on an external HMD - ARVRInterface::Eyes eye = (ARVRInterface::Eyes)p_eye; + XRInterface::Eyes eye = (XRInterface::Eyes)p_eye; #if 0 RID *render_target = (RID *)p_render_target; #endif Rect2 screen_rect = *(Rect2 *)p_rect; - if (eye == ARVRInterface::EYE_LEFT) { + if (eye == XRInterface::EYE_LEFT) { screen_rect.size.x /= 2.0; - } else if (p_eye == ARVRInterface::EYE_RIGHT) { + } else if (p_eye == XRInterface::EYE_RIGHT) { screen_rect.size.x /= 2.0; screen_rect.position.x += screen_rect.size.x; } @@ -296,7 +285,7 @@ void GDAPI godot_arvr_blit(godot_int p_eye, godot_rid *p_render_target, godot_re #endif } -godot_int GDAPI godot_arvr_get_texid(godot_rid *p_render_target) { +godot_int GDAPI godot_xr_get_texid(godot_rid *p_render_target) { // In order to send off our textures to display on our hardware we need the opengl texture ID instead of the render target RID // This is a handy function to expose that. #if 0 @@ -313,20 +302,20 @@ godot_int GDAPI godot_arvr_get_texid(godot_rid *p_render_target) { return texid; } -godot_int GDAPI godot_arvr_add_controller(char *p_device_name, godot_int p_hand, godot_bool p_tracks_orientation, godot_bool p_tracks_position) { - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, 0); +godot_int GDAPI godot_xr_add_controller(char *p_device_name, godot_int p_hand, godot_bool p_tracks_orientation, godot_bool p_tracks_position) { + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, 0); InputFilter *input = InputFilter::get_singleton(); ERR_FAIL_NULL_V(input, 0); - ARVRPositionalTracker *new_tracker = memnew(ARVRPositionalTracker); + XRPositionalTracker *new_tracker = memnew(XRPositionalTracker); new_tracker->set_name(p_device_name); - new_tracker->set_type(ARVRServer::TRACKER_CONTROLLER); + new_tracker->set_type(XRServer::TRACKER_CONTROLLER); if (p_hand == 1) { - new_tracker->set_hand(ARVRPositionalTracker::TRACKER_LEFT_HAND); + new_tracker->set_hand(XRPositionalTracker::TRACKER_LEFT_HAND); } else if (p_hand == 2) { - new_tracker->set_hand(ARVRPositionalTracker::TRACKER_RIGHT_HAND); + new_tracker->set_hand(XRPositionalTracker::TRACKER_RIGHT_HAND); } // also register as joystick... @@ -346,20 +335,20 @@ godot_int GDAPI godot_arvr_add_controller(char *p_device_name, godot_int p_hand, } // add our tracker to our server and remember its pointer - arvr_server->add_tracker(new_tracker); + xr_server->add_tracker(new_tracker); // note, this ID is only unique within controllers! return new_tracker->get_tracker_id(); } -void GDAPI godot_arvr_remove_controller(godot_int p_controller_id) { - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL(arvr_server); +void GDAPI godot_xr_remove_controller(godot_int p_controller_id) { + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); InputFilter *input = InputFilter::get_singleton(); ERR_FAIL_NULL(input); - ARVRPositionalTracker *remove_tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, p_controller_id); + XRPositionalTracker *remove_tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id); if (remove_tracker != nullptr) { // unset our joystick if applicable int joyid = remove_tracker->get_joy_id(); @@ -369,16 +358,16 @@ void GDAPI godot_arvr_remove_controller(godot_int p_controller_id) { } // remove our tracker from our server - arvr_server->remove_tracker(remove_tracker); + xr_server->remove_tracker(remove_tracker); memdelete(remove_tracker); } } -void GDAPI godot_arvr_set_controller_transform(godot_int p_controller_id, godot_transform *p_transform, godot_bool p_tracks_orientation, godot_bool p_tracks_position) { - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL(arvr_server); +void GDAPI godot_xr_set_controller_transform(godot_int p_controller_id, godot_transform *p_transform, godot_bool p_tracks_orientation, godot_bool p_tracks_position) { + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); - ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, p_controller_id); + XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id); if (tracker != nullptr) { Transform *transform = (Transform *)p_transform; if (p_tracks_orientation) { @@ -390,14 +379,14 @@ void GDAPI godot_arvr_set_controller_transform(godot_int p_controller_id, godot_ } } -void GDAPI godot_arvr_set_controller_button(godot_int p_controller_id, godot_int p_button, godot_bool p_is_pressed) { - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL(arvr_server); +void GDAPI godot_xr_set_controller_button(godot_int p_controller_id, godot_int p_button, godot_bool p_is_pressed) { + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); InputFilter *input = InputFilter::get_singleton(); ERR_FAIL_NULL(input); - ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, p_controller_id); + XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id); if (tracker != nullptr) { int joyid = tracker->get_joy_id(); if (joyid != -1) { @@ -406,14 +395,14 @@ void GDAPI godot_arvr_set_controller_button(godot_int p_controller_id, godot_int } } -void GDAPI godot_arvr_set_controller_axis(godot_int p_controller_id, godot_int p_axis, godot_real p_value, godot_bool p_can_be_negative) { - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL(arvr_server); +void GDAPI godot_xr_set_controller_axis(godot_int p_controller_id, godot_int p_axis, godot_real p_value, godot_bool p_can_be_negative) { + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); InputFilter *input = InputFilter::get_singleton(); ERR_FAIL_NULL(input); - ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, p_controller_id); + XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id); if (tracker != nullptr) { int joyid = tracker->get_joy_id(); if (joyid != -1) { @@ -425,11 +414,11 @@ void GDAPI godot_arvr_set_controller_axis(godot_int p_controller_id, godot_int p } } -godot_real GDAPI godot_arvr_get_controller_rumble(godot_int p_controller_id) { - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, 0.0); +godot_real GDAPI godot_xr_get_controller_rumble(godot_int p_controller_id) { + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, 0.0); - ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, p_controller_id); + XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id); if (tracker != nullptr) { return tracker->get_rumble(); } diff --git a/modules/gdnative/arvr/arvr_interface_gdnative.h b/modules/gdnative/xr/xr_interface_gdnative.h index e38eb435c6..64f1282a7e 100644 --- a/modules/gdnative/arvr/arvr_interface_gdnative.h +++ b/modules/gdnative/xr/xr_interface_gdnative.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* arvr_interface_gdnative.h */ +/* xr_interface_gdnative.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef ARVR_INTERFACE_GDNATIVE_H -#define ARVR_INTERFACE_GDNATIVE_H +#ifndef XR_INTERFACE_GDNATIVE_H +#define XR_INTERFACE_GDNATIVE_H #include "modules/gdnative/gdnative.h" -#include "servers/arvr/arvr_interface.h" +#include "servers/xr/xr_interface.h" /** @authors Hinsbart & Karroffel & Mux213 @@ -40,23 +40,23 @@ This subclass of our AR/VR interface forms a bridge to GDNative. */ -class ARVRInterfaceGDNative : public ARVRInterface { - GDCLASS(ARVRInterfaceGDNative, ARVRInterface); +class XRInterfaceGDNative : public XRInterface { + GDCLASS(XRInterfaceGDNative, XRInterface); void cleanup(); protected: - const godot_arvr_interface_gdnative *interface; + const godot_xr_interface_gdnative *interface; void *data; static void _bind_methods(); public: /** general interface information **/ - ARVRInterfaceGDNative(); - ~ARVRInterfaceGDNative(); + XRInterfaceGDNative(); + ~XRInterfaceGDNative(); - void set_interface(const godot_arvr_interface_gdnative *p_interface); + void set_interface(const godot_xr_interface_gdnative *p_interface); virtual StringName get_name() const; virtual int get_capabilities() const; @@ -73,19 +73,19 @@ public: /** rendering and internal **/ virtual Size2 get_render_targetsize(); virtual bool is_stereo(); - virtual Transform get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform); + virtual Transform get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform); // we expose a Vector<float> version of this function to GDNative - Vector<float> _get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far); + Vector<float> _get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far); - // and a CameraMatrix version to ARVRServer - virtual CameraMatrix get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far); + // and a CameraMatrix version to XRServer + virtual CameraMatrix get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far); - virtual unsigned int get_external_texture_for_eye(ARVRInterface::Eyes p_eye); - virtual void commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect); + virtual unsigned int get_external_texture_for_eye(XRInterface::Eyes p_eye); + virtual void commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect); virtual void process(); virtual void notification(int p_what); }; -#endif // ARVR_INTERFACE_GDNATIVE_H +#endif // XR_INTERFACE_GDNATIVE_H diff --git a/modules/gdscript/config.py b/modules/gdscript/config.py index 185a10bcb2..6fc227e7f5 100644 --- a/modules/gdscript/config.py +++ b/modules/gdscript/config.py @@ -11,7 +11,6 @@ def get_doc_classes(): "@GDScript", "GDScript", "GDScriptFunctionState", - "GDScriptNativeClass", ] diff --git a/modules/gdscript/doc_classes/GDScriptNativeClass.xml b/modules/gdscript/doc_classes/GDScriptNativeClass.xml deleted file mode 100644 index 0a8982de8e..0000000000 --- a/modules/gdscript/doc_classes/GDScriptNativeClass.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="GDScriptNativeClass" inherits="Reference" version="4.0"> - <brief_description> - </brief_description> - <description> - </description> - <tutorials> - </tutorials> - <methods> - <method name="new"> - <return type="Variant"> - </return> - <description> - </description> - </method> - </methods> - <constants> - </constants> -</class> diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 9a4fa5cc86..98366f7957 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -895,6 +895,24 @@ Ref<GDScript> GDScript::get_base() const { return base; } +bool GDScript::inherits_script(const Ref<Script> &p_script) const { + Ref<GDScript> gd = p_script; + if (gd.is_null()) { + return false; + } + + const GDScript *s = this; + + while (s) { + if (s == p_script.ptr()) { + return true; + } + s = s->_base; + } + + return false; +} + bool GDScript::has_script_signal(const StringName &p_signal) const { if (_signals.has(p_signal)) return true; @@ -2257,7 +2275,7 @@ Ref<GDScript> GDScriptLanguage::get_orphan_subclass(const String &p_qualified_na /*************** RESOURCE ***************/ -RES ResourceFormatLoaderGDScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderGDScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) *r_error = ERR_FILE_CANT_OPEN; diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 2c5876372b..5fdc25669f 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -151,6 +151,8 @@ protected: public: virtual bool is_valid() const { return valid; } + bool inherits_script(const Ref<Script> &p_script) const; + const Map<StringName, Ref<GDScript>> &get_subclasses() const { return subclasses; } const Map<StringName, Variant> &get_constants() const { return constants; } const Set<StringName> &get_members() const { return members; } @@ -545,7 +547,7 @@ public: class ResourceFormatLoaderGDScript : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 1e3cbd661e..221cce205a 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -2057,7 +2057,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context List<PropertyInfo> pinfo; ClassDB::get_property_list(type, &pinfo); for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - if (E->get().usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_CATEGORY)) { + if (E->get().usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP | PROPERTY_USAGE_CATEGORY)) { continue; } if (E->get().name.find("/") != -1) { @@ -2098,7 +2098,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context if (!p_only_functions) { List<PropertyInfo> members; - p_base.value.get_property_list(&members); + tmp.get_property_list(&members); for (List<PropertyInfo>::Element *E = members.front(); E; E = E->next()) { if (String(E->get().name).find("/") == -1) { @@ -2236,6 +2236,8 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\""; +#define IS_METHOD_SIGNAL(m_method) (m_method == "connect" || m_method == "disconnect" || m_method == "is_connected" || m_method == "emit_signal") + while (base_type.has_type) { switch (base_type.kind) { case GDScriptParser::DataType::CLASS: { @@ -2252,7 +2254,7 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con } } - if ((p_method == "connect" || p_method == "emit_signal") && p_argidx == 0) { + if (IS_METHOD_SIGNAL(p_method) && p_argidx == 0) { for (int i = 0; i < base_type.class_type->_signals.size(); i++) { ScriptCodeCompletionOption option(base_type.class_type->_signals[i].name.operator String(), ScriptCodeCompletionOption::KIND_SIGNAL); option.insert_text = quote_style + option.display + quote_style; @@ -2265,7 +2267,7 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con case GDScriptParser::DataType::GDSCRIPT: { Ref<GDScript> gds = base_type.script_type; if (gds.is_valid()) { - if ((p_method == "connect" || p_method == "emit_signal") && p_argidx == 0) { + if (IS_METHOD_SIGNAL(p_method) && p_argidx == 0) { List<MethodInfo> signals; gds->get_script_signal_list(&signals); for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) { @@ -2327,7 +2329,7 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con } } - if ((p_method == "connect" || p_method == "emit_signal") && p_argidx == 0) { + if (IS_METHOD_SIGNAL(p_method) && p_argidx == 0) { List<MethodInfo> signals; ClassDB::get_signal_list(class_name, &signals); for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) { @@ -2336,6 +2338,7 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con r_result.insert(option.display, option); } } +#undef IS_METHOD_SIGNAL if (ClassDB::is_parent_class(class_name, "Node") && (p_method == "get_node" || p_method == "has_node") && p_argidx == 0) { // Get autoloads diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp index ca4d6f6de9..4e0891921e 100644 --- a/modules/gdscript/gdscript_function.cpp +++ b/modules/gdscript/gdscript_function.cpp @@ -337,15 +337,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a } if (!argument_types[i].is_type(*p_args[i], true)) { - if (argument_types[i].is_type(Variant(), true)) { - memnew_placement(&stack[i], Variant); - continue; - } else { - r_err.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_err.argument = i; - r_err.expected = argument_types[i].kind == GDScriptDataType::BUILTIN ? argument_types[i].builtin_type : Variant::OBJECT; - return Variant(); - } + r_err.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_err.argument = i; + r_err.expected = argument_types[i].kind == GDScriptDataType::BUILTIN ? argument_types[i].builtin_type : Variant::OBJECT; + return Variant(); } if (argument_types[i].kind == GDScriptDataType::BUILTIN) { Variant arg = Variant::construct(argument_types[i].builtin_type, &p_args[i], 1, r_err); diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index a99d4b96f7..a83416375c 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -827,6 +827,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s //check from singletons ConstantNode *constant = alloc_node<ConstantNode>(); constant->value = GDScriptLanguage::get_singleton()->get_named_globals_map()[identifier]; + constant->datatype = _type_from_variant(constant->value); expr = constant; bfn = true; } @@ -837,6 +838,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s if (scr.is_valid() && scr->is_valid()) { ConstantNode *constant = alloc_node<ConstantNode>(); constant->value = scr; + constant->datatype = _type_from_variant(constant->value); expr = constant; bfn = true; } @@ -852,6 +854,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s if (parent_constants.has(identifier)) { ConstantNode *constant = alloc_node<ConstantNode>(); constant->value = parent_constants[identifier]; + constant->datatype = _type_from_variant(constant->value); expr = constant; bfn = true; } @@ -2386,6 +2389,7 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m // a bind always matches ConstantNode *true_value = alloc_node<ConstantNode>(); true_value->value = Variant(true); + true_value->datatype = _type_from_variant(true_value->value); p_resulting_node = true_value; } break; case PatternNode::PT_ARRAY: { @@ -2432,6 +2436,7 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m // size ConstantNode *length = alloc_node<ConstantNode>(); length->value = Variant(open_ended ? p_pattern->array.size() - 1 : p_pattern->array.size()); + length->datatype = _type_from_variant(length->value); OperatorNode *call = alloc_node<OperatorNode>(); call->op = OperatorNode::OP_CALL; @@ -2465,6 +2470,7 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m ConstantNode *index = alloc_node<ConstantNode>(); index->value = Variant(i); + index->datatype = _type_from_variant(index->value); OperatorNode *indexed_value = alloc_node<OperatorNode>(); indexed_value->op = OperatorNode::OP_INDEX; @@ -2525,6 +2531,7 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m // size ConstantNode *length = alloc_node<ConstantNode>(); length->value = Variant(open_ended ? p_pattern->dictionary.size() - 1 : p_pattern->dictionary.size()); + length->datatype = _type_from_variant(length->value); OperatorNode *call = alloc_node<OperatorNode>(); call->op = OperatorNode::OP_CALL; @@ -2601,6 +2608,7 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m // simply generate a `true` ConstantNode *true_value = alloc_node<ConstantNode>(); true_value->value = Variant(true); + true_value->datatype = _type_from_variant(true_value->value); p_resulting_node = true_value; } break; default: { @@ -2683,6 +2691,7 @@ void GDScriptParser::_transform_match_statment(MatchNode *p_match_statement) { LocalVarNode *local_var = branch->body->variables[e->key()]; local_var->assign = e->value(); local_var->set_datatype(local_var->assign->get_datatype()); + local_var->assignments++; IdentifierNode *id2 = alloc_node<IdentifierNode>(); id2->name = local_var->name; @@ -3319,6 +3328,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { } else { ConstantNode *message_node = alloc_node<ConstantNode>(); message_node->value = String(); + message_node->datatype = _type_from_variant(message_node->value); an->message = message_node; } @@ -3673,6 +3683,12 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { _set_error("A constant named \"" + String(name) + "\" already exists in the outer class scope (at line" + itos(outer_class->constant_expressions[name].expression->line) + ")."); return; } + for (int i = 0; i < outer_class->variables.size(); i++) { + if (outer_class->variables[i].identifier == name) { + _set_error("A variable named \"" + String(name) + "\" already exists in the outer class scope (at line " + itos(outer_class->variables[i].line) + ")."); + return; + } + } outer_class = outer_class->owner; } @@ -6229,11 +6245,13 @@ GDScriptParser::Node *GDScriptParser::_get_default_value_for_type(const DataType ConstantNode *c = alloc_node<ConstantNode>(); Callable::CallError err; c->value = Variant::construct(p_type.builtin_type, nullptr, 0, err); + c->datatype = _type_from_variant(c->value); result = c; } } else { ConstantNode *c = alloc_node<ConstantNode>(); c->value = Variant(); + c->datatype = _type_from_variant(c->value); result = c; } @@ -6562,6 +6580,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) { node_type = _reduce_identifier_type(&base_type, member_id->name, op->line, true); #ifdef DEBUG_ENABLED if (!node_type.has_type) { + _mark_line_as_unsafe(op->line); _add_warning(GDScriptWarning::UNSAFE_PROPERTY_ACCESS, op->line, member_id->name.operator String(), base_type.to_string()); } #endif // DEBUG_ENABLED @@ -7364,6 +7383,8 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN } } +#define IS_USAGE_MEMBER(m_usage) (!(m_usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP | PROPERTY_USAGE_CATEGORY))) + // Check other script types while (scr.is_valid()) { Map<StringName, Variant> constants; @@ -7376,7 +7397,7 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN List<PropertyInfo> properties; scr->get_script_property_list(&properties); for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) { - if (E->get().name == p_member) { + if (E->get().name == p_member && IS_USAGE_MEMBER(E->get().usage)) { r_member_type = _type_from_property(E->get()); return true; } @@ -7418,7 +7439,7 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN List<PropertyInfo> properties; ClassDB::get_property_list(native, &properties); for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) { - if (E->get().name == p_member) { + if (E->get().name == p_member && IS_USAGE_MEMBER(E->get().usage)) { // Check if a getter exists StringName getter_name = ClassDB::get_property_getter(native, p_member); if (getter_name != StringName()) { @@ -7458,7 +7479,7 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN List<PropertyInfo> properties; ClassDB::get_property_list(native, &properties); for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) { - if (E->get().name == p_member) { + if (E->get().name == p_member && IS_USAGE_MEMBER(E->get().usage)) { // Check if a getter exists StringName getter_name = ClassDB::get_property_getter(native, p_member); if (getter_name != StringName()) { @@ -7480,6 +7501,7 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN } } } +#undef IS_USAGE_MEMBER return false; } @@ -8107,6 +8129,7 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) { ConstantNode *tgt_type = alloc_node<ConstantNode>(); tgt_type->line = lv->line; tgt_type->value = (int)lv->datatype.builtin_type; + tgt_type->datatype = _type_from_variant(tgt_type->value); OperatorNode *convert_call = alloc_node<OperatorNode>(); convert_call->line = lv->line; @@ -8242,6 +8265,7 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) { ConstantNode *tgt_type = alloc_node<ConstantNode>(); tgt_type->line = op->line; tgt_type->value = (int)lh_type.builtin_type; + tgt_type->datatype = _type_from_variant(tgt_type->value); OperatorNode *convert_call = alloc_node<OperatorNode>(); convert_call->line = op->line; diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h index 1b432ae8c1..180ec3c77e 100644 --- a/modules/gdscript/gdscript_tokenizer.h +++ b/modules/gdscript/gdscript_tokenizer.h @@ -32,6 +32,7 @@ #define GDSCRIPT_TOKENIZER_H #include "core/pair.h" +#include "core/set.h" #include "core/string_name.h" #include "core/ustring.h" #include "core/variant.h" diff --git a/modules/mobile_vr/doc_classes/MobileVRInterface.xml b/modules/mobile_vr/doc_classes/MobileVRInterface.xml index 7552abe61d..120535bd41 100644 --- a/modules/mobile_vr/doc_classes/MobileVRInterface.xml +++ b/modules/mobile_vr/doc_classes/MobileVRInterface.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="MobileVRInterface" inherits="ARVRInterface" version="4.0"> +<class name="MobileVRInterface" inherits="XRInterface" version="4.0"> <brief_description> Generic mobile VR implementation. </brief_description> @@ -8,9 +8,9 @@ Note that even though there is no positional tracking, the camera will assume the headset is at a height of 1.85 meters. You can change this by setting [member eye_height]. You can initialise this interface as follows: [codeblock] - var interface = ARVRServer.find_interface("Native mobile") + var interface = XRServer.find_interface("Native mobile") if interface and interface.initialize(): - get_viewport().arvr = true + get_viewport().xr = true [/codeblock] </description> <tutorials> @@ -25,7 +25,7 @@ The width of the display in centimeters. </member> <member name="eye_height" type="float" setter="set_eye_height" getter="get_eye_height" default="1.85"> - The height at which the camera is placed in relation to the ground (i.e. [ARVROrigin] node). + The height at which the camera is placed in relation to the ground (i.e. [XROrigin3D] node). </member> <member name="iod" type="float" setter="set_iod" getter="get_iod" default="6.0"> The interocular distance, also known as the interpupillary distance. The distance between the pupils of the left and right eye. diff --git a/modules/mobile_vr/mobile_vr_interface.cpp b/modules/mobile_vr/mobile_vr_interface.cpp index 6b5a70435d..2f0a15f20b 100644 --- a/modules/mobile_vr/mobile_vr_interface.cpp +++ b/modules/mobile_vr/mobile_vr_interface.cpp @@ -39,7 +39,7 @@ StringName MobileVRInterface::get_name() const { }; int MobileVRInterface::get_capabilities() const { - return ARVRInterface::ARVR_STEREO; + return XRInterface::XR_STEREO; }; Vector3 MobileVRInterface::scale_magneto(const Vector3 &p_magnetometer) { @@ -165,7 +165,7 @@ void MobileVRInterface::set_position_from_sensors() { rotate.rotate(orientation.get_axis(2), gyro.z * delta_time); orientation = rotate * orientation; - tracking_state = ARVRInterface::ARVR_NORMAL_TRACKING; + tracking_state = XRInterface::XR_NORMAL_TRACKING; }; ///@TODO improve this, the magnetometer is very fidgity sometimes flipping the axis for no apparent reason (probably a bug on my part) @@ -177,7 +177,7 @@ void MobileVRInterface::set_position_from_sensors() { transform_quat = transform_quat.slerp(acc_mag_quat, 0.1); orientation = Basis(transform_quat); - tracking_state = ARVRInterface::ARVR_NORMAL_TRACKING; + tracking_state = XRInterface::XR_NORMAL_TRACKING; } else if (has_grav) { // use gravity vector to make sure down is down... // transform gravity into our world space @@ -297,8 +297,8 @@ bool MobileVRInterface::is_initialized() const { }; bool MobileVRInterface::initialize() { - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, false); + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, false); if (!initialized) { // reset our sensor data and orientation @@ -314,7 +314,7 @@ bool MobileVRInterface::initialize() { orientation = Basis(); // make this our primary interface - arvr_server->set_primary_interface(this); + xr_server->set_primary_interface(this); last_ticks = OS::get_singleton()->get_ticks_usec(); @@ -326,10 +326,10 @@ bool MobileVRInterface::initialize() { void MobileVRInterface::uninitialize() { if (initialized) { - ARVRServer *arvr_server = ARVRServer::get_singleton(); - if (arvr_server != nullptr) { + XRServer *xr_server = XRServer::get_singleton(); + if (xr_server != nullptr) { // no longer our primary interface - arvr_server->clear_primary_interface_if(this); + xr_server->clear_primary_interface_if(this); } initialized = false; @@ -348,22 +348,22 @@ Size2 MobileVRInterface::get_render_targetsize() { return target_size; }; -Transform MobileVRInterface::get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform) { +Transform MobileVRInterface::get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform) { _THREAD_SAFE_METHOD_ Transform transform_for_eye; - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, transform_for_eye); + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, transform_for_eye); if (initialized) { - float world_scale = arvr_server->get_world_scale(); + float world_scale = xr_server->get_world_scale(); // we don't need to check for the existence of our HMD, doesn't effect our values... // note * 0.01 to convert cm to m and * 0.5 as we're moving half in each direction... - if (p_eye == ARVRInterface::EYE_LEFT) { + if (p_eye == XRInterface::EYE_LEFT) { transform_for_eye.origin.x = -(intraocular_dist * 0.01 * 0.5 * world_scale); - } else if (p_eye == ARVRInterface::EYE_RIGHT) { + } else if (p_eye == XRInterface::EYE_RIGHT) { transform_for_eye.origin.x = intraocular_dist * 0.01 * 0.5 * world_scale; } else { // for mono we don't reposition, we want our center position. @@ -374,7 +374,7 @@ Transform MobileVRInterface::get_transform_for_eye(ARVRInterface::Eyes p_eye, co hmd_transform.basis = orientation; hmd_transform.origin = Vector3(0.0, eye_height * world_scale, 0.0); - transform_for_eye = p_cam_transform * (arvr_server->get_reference_frame()) * hmd_transform * transform_for_eye; + transform_for_eye = p_cam_transform * (xr_server->get_reference_frame()) * hmd_transform * transform_for_eye; } else { // huh? well just return what we got.... transform_for_eye = p_cam_transform; @@ -383,12 +383,12 @@ Transform MobileVRInterface::get_transform_for_eye(ARVRInterface::Eyes p_eye, co return transform_for_eye; }; -CameraMatrix MobileVRInterface::get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) { +CameraMatrix MobileVRInterface::get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) { _THREAD_SAFE_METHOD_ CameraMatrix eye; - if (p_eye == ARVRInterface::EYE_MONO) { + if (p_eye == XRInterface::EYE_MONO) { ///@TODO for now hardcode some of this, what is really needed here is that this needs to be in sync with the real cameras properties // which probably means implementing a specific class for iOS and Android. For now this is purely here as an example. // Note also that if you use a normal viewport with AR/VR turned off you can still use the tracker output of this interface @@ -396,13 +396,13 @@ CameraMatrix MobileVRInterface::get_projection_for_eye(ARVRInterface::Eyes p_eye // This will make more sense when we implement ARkit on iOS (probably a separate interface). eye.set_perspective(60.0, p_aspect, p_z_near, p_z_far, false); } else { - eye.set_for_hmd(p_eye == ARVRInterface::EYE_LEFT ? 1 : 2, p_aspect, intraocular_dist, display_width, display_to_lens, oversample, p_z_near, p_z_far); + eye.set_for_hmd(p_eye == XRInterface::EYE_LEFT ? 1 : 2, p_aspect, intraocular_dist, display_width, display_to_lens, oversample, p_z_near, p_z_far); }; return eye; }; -void MobileVRInterface::commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) { +void MobileVRInterface::commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) { _THREAD_SAFE_METHOD_ // We must have a valid render target @@ -417,9 +417,9 @@ void MobileVRInterface::commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_t // we output half a screen dest.size.x *= 0.5; - if (p_eye == ARVRInterface::EYE_LEFT) { + if (p_eye == XRInterface::EYE_LEFT) { eye_center.x = ((-intraocular_dist / 2.0) + (display_width / 4.0)) / (display_width / 2.0); - } else if (p_eye == ARVRInterface::EYE_RIGHT) { + } else if (p_eye == XRInterface::EYE_RIGHT) { dest.position.x = dest.size.x; eye_center.x = ((intraocular_dist / 2.0) - (display_width / 4.0)) / (display_width / 2.0); } diff --git a/modules/mobile_vr/mobile_vr_interface.h b/modules/mobile_vr/mobile_vr_interface.h index c762c9b799..3a9ed1314a 100644 --- a/modules/mobile_vr/mobile_vr_interface.h +++ b/modules/mobile_vr/mobile_vr_interface.h @@ -31,8 +31,8 @@ #ifndef MOBILE_VR_INTERFACE_H #define MOBILE_VR_INTERFACE_H -#include "servers/arvr/arvr_interface.h" -#include "servers/arvr/arvr_positional_tracker.h" +#include "servers/xr/xr_interface.h" +#include "servers/xr/xr_positional_tracker.h" /** @author Bastiaan Olij <mux213@gmail.com> @@ -47,8 +47,8 @@ more advanced interfaces. */ -class MobileVRInterface : public ARVRInterface { - GDCLASS(MobileVRInterface, ARVRInterface); +class MobileVRInterface : public XRInterface { + GDCLASS(MobileVRInterface, XRInterface); private: bool initialized; @@ -137,9 +137,9 @@ public: virtual Size2 get_render_targetsize(); virtual bool is_stereo(); - virtual Transform get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform); - virtual CameraMatrix get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far); - virtual void commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect); + virtual Transform get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform); + virtual CameraMatrix get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far); + virtual void commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect); virtual void process(); virtual void notification(int p_what); diff --git a/modules/mobile_vr/register_types.cpp b/modules/mobile_vr/register_types.cpp index faf6c3b151..75638d47c4 100644 --- a/modules/mobile_vr/register_types.cpp +++ b/modules/mobile_vr/register_types.cpp @@ -37,7 +37,7 @@ void register_mobile_vr_types() { Ref<MobileVRInterface> mobile_vr; mobile_vr.instance(); - ARVRServer::get_singleton()->add_interface(mobile_vr); + XRServer::get_singleton()->add_interface(mobile_vr); } void unregister_mobile_vr_types() { diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 0b5d3c8dbc..f5911275c9 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -3536,6 +3536,18 @@ void CSharpScript::get_script_signal_list(List<MethodInfo> *r_signals) const { } } +bool CSharpScript::inherits_script(const Ref<Script> &p_script) const { + Ref<CSharpScript> cs = p_script; + if (cs.is_null()) { + return false; + } + +#ifndef _MSC_VER +#warning TODO: Implement CSharpScript::inherits_script and other relevant changes after GH-38063. +#endif + return false; +} + Ref<Script> CSharpScript::get_base_script() const { // TODO search in metadata file once we have it, not important any way? @@ -3673,7 +3685,7 @@ CSharpScript::~CSharpScript() { /*************** RESOURCE ***************/ -RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) *r_error = ERR_FILE_CANT_OPEN; diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index 29c33b50bb..05e2857538 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -194,6 +194,8 @@ public: virtual bool is_tool() const { return tool; } virtual bool is_valid() const { return valid; } + bool inherits_script(const Ref<Script> &p_script) const; + virtual Ref<Script> get_base_script() const; virtual ScriptLanguage *get_language() const; @@ -530,7 +532,7 @@ public: class ResourceFormatLoaderCSharpScript : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/mono/editor/GodotTools/GodotTools.Core/FileUtils.cs b/modules/mono/editor/GodotTools/GodotTools.Core/FileUtils.cs new file mode 100644 index 0000000000..85760a3705 --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools.Core/FileUtils.cs @@ -0,0 +1,27 @@ +using System.IO; + +namespace GodotTools.Core +{ + public static class FileUtils + { + public static void SaveBackupCopy(string filePath) + { + string backupPathBase = filePath + ".old"; + string backupPath = backupPathBase; + + const int maxAttempts = 5; + int attempt = 1; + + while (File.Exists(backupPath) && attempt <= maxAttempts) + { + backupPath = backupPathBase + "." + (attempt); + attempt++; + } + + if (attempt > maxAttempts + 1) + return; + + File.Copy(filePath, backupPath, overwrite: true); + } + } +} diff --git a/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj b/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj index 2c35ef540a..c9ea7d3a2c 100644 --- a/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj +++ b/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj @@ -31,6 +31,7 @@ <Reference Include="System" /> </ItemGroup> <ItemGroup> + <Compile Include="FileUtils.cs" /> <Compile Include="ProcessExtensions.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="StringExtensions.cs" /> diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs index 9afd9adeb1..6f318aab4a 100644 --- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs +++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs @@ -153,7 +153,12 @@ EndProject"; var result = regex.Replace(input,m => dict[m.Value]); if (result != input) + { + // Save a copy of the solution before replacing it + FileUtils.SaveBackupCopy(slnPath); + File.WriteAllText(slnPath, result); + } } } } diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs index 1776b46e6a..a875e1c14f 100644 --- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs +++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs @@ -9,8 +9,28 @@ using Microsoft.Build.Construction; namespace GodotTools.ProjectEditor { + public sealed class MSBuildProject + { + public ProjectRootElement Root { get; } + + public bool HasUnsavedChanges => Root.HasUnsavedChanges; + + public void Save() => Root.Save(); + + public MSBuildProject(ProjectRootElement root) + { + Root = root; + } + } + public static class ProjectUtils { + public static MSBuildProject Open(string path) + { + var root = ProjectRootElement.Open(path); + return root != null ? new MSBuildProject(root) : null; + } + public static void AddItemToProjectChecked(string projectPath, string itemType, string include) { var dir = Directory.GetParent(projectPath).FullName; @@ -43,7 +63,6 @@ namespace GodotTools.ProjectEditor public static void RemoveItemFromProjectChecked(string projectPath, string itemType, string include) { - var dir = Directory.GetParent(projectPath).FullName; var root = ProjectRootElement.Open(projectPath); Debug.Assert(root != null); @@ -59,8 +78,6 @@ namespace GodotTools.ProjectEditor var root = ProjectRootElement.Open(projectPath); Debug.Assert(root != null); - bool dirty = false; - var oldFolderNormalized = oldFolder.NormalizePath(); var newFolderNormalized = newFolder.NormalizePath(); string absOldFolderNormalized = Path.GetFullPath(oldFolderNormalized).NormalizePath(); @@ -71,10 +88,9 @@ namespace GodotTools.ProjectEditor string absPathNormalized = Path.GetFullPath(item.Include).NormalizePath(); string absNewIncludeNormalized = absNewFolderNormalized + absPathNormalized.Substring(absOldFolderNormalized.Length); item.Include = absNewIncludeNormalized.RelativeToPath(dir).Replace("/", "\\"); - dirty = true; } - if (dirty) + if (root.HasUnsavedChanges) root.Save(); } @@ -150,12 +166,9 @@ namespace GodotTools.ProjectEditor } /// Simple function to make sure the Api assembly references are configured correctly - public static void FixApiHintPath(string projectPath) + public static void FixApiHintPath(MSBuildProject project) { - var root = ProjectRootElement.Open(projectPath); - Debug.Assert(root != null); - - bool dirty = false; + var root = project.Root; void AddPropertyIfNotPresent(string name, string condition, string value) { @@ -170,7 +183,6 @@ namespace GodotTools.ProjectEditor } root.AddProperty(name, value).Condition = " " + condition + " "; - dirty = true; } AddPropertyIfNotPresent(name: "ApiConfiguration", @@ -212,7 +224,6 @@ namespace GodotTools.ProjectEditor } referenceWithHintPath.AddMetadata("HintPath", hintPath); - dirty = true; return; } @@ -221,14 +232,12 @@ namespace GodotTools.ProjectEditor { // Found a Reference item without a HintPath referenceWithoutHintPath.AddMetadata("HintPath", hintPath); - dirty = true; return; } } // Found no Reference item at all. Add it. root.AddItem("Reference", referenceName).Condition = " " + condition + " "; - dirty = true; } const string coreProjectName = "GodotSharp"; @@ -242,17 +251,11 @@ namespace GodotTools.ProjectEditor SetReferenceHintPath(coreProjectName, coreCondition, coreHintPath); SetReferenceHintPath(editorProjectName, editorCondition, editorHintPath); - - if (dirty) - root.Save(); } - public static void MigrateFromOldConfigNames(string projectPath) + public static void MigrateFromOldConfigNames(MSBuildProject project) { - var root = ProjectRootElement.Open(projectPath); - Debug.Assert(root != null); - - bool dirty = false; + var root = project.Root; bool hasGodotProjectGeneratorVersion = false; bool foundOldConfiguration = false; @@ -267,7 +270,6 @@ namespace GodotTools.ProjectEditor { configItem.Value = "Debug"; foundOldConfiguration = true; - dirty = true; } } @@ -275,7 +277,6 @@ namespace GodotTools.ProjectEditor { root.PropertyGroups.First(g => g.Condition == string.Empty)? .AddProperty("GodotProjectGeneratorVersion", Assembly.GetExecutingAssembly().GetName().Version.ToString()); - dirty = true; } if (!foundOldConfiguration) @@ -299,33 +300,21 @@ namespace GodotTools.ProjectEditor void MigrateConditions(string oldCondition, string newCondition) { foreach (var propertyGroup in root.PropertyGroups.Where(g => g.Condition.Trim() == oldCondition)) - { propertyGroup.Condition = " " + newCondition + " "; - dirty = true; - } foreach (var propertyGroup in root.PropertyGroups) { foreach (var prop in propertyGroup.Properties.Where(p => p.Condition.Trim() == oldCondition)) - { prop.Condition = " " + newCondition + " "; - dirty = true; - } } foreach (var itemGroup in root.ItemGroups.Where(g => g.Condition.Trim() == oldCondition)) - { itemGroup.Condition = " " + newCondition + " "; - dirty = true; - } foreach (var itemGroup in root.ItemGroups) { foreach (var item in itemGroup.Items.Where(item => item.Condition.Trim() == oldCondition)) - { item.Condition = " " + newCondition + " "; - dirty = true; - } } } @@ -340,10 +329,6 @@ namespace GodotTools.ProjectEditor MigrateConfigurationConditions("Release", "ExportRelease"); MigrateConfigurationConditions("Tools", "Debug"); // Must be last } - - - if (dirty) - root.Save(); } } } diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs index d782d4e61b..2ceb4888a2 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs @@ -168,13 +168,13 @@ namespace GodotTools.Export // Add dependency assemblies - var dependencies = new Godot.Collections.Dictionary<string, string>(); + var assemblies = new Godot.Collections.Dictionary<string, string>(); string projectDllName = GodotSharpEditor.ProjectAssemblyName; string projectDllSrcDir = Path.Combine(GodotSharpDirs.ResTempAssembliesBaseDir, buildConfig); string projectDllSrcPath = Path.Combine(projectDllSrcDir, $"{projectDllName}.dll"); - dependencies[projectDllName] = projectDllSrcPath; + assemblies[projectDllName] = projectDllSrcPath; if (platform == OS.Platforms.Android) { @@ -184,15 +184,15 @@ namespace GodotTools.Export if (!File.Exists(monoAndroidAssemblyPath)) throw new FileNotFoundException("Assembly not found: 'Mono.Android'", monoAndroidAssemblyPath); - dependencies["Mono.Android"] = monoAndroidAssemblyPath; + assemblies["Mono.Android"] = monoAndroidAssemblyPath; } string bclDir = DeterminePlatformBclDir(platform); - var initialDependencies = dependencies.Duplicate(); - internal_GetExportedAssemblyDependencies(initialDependencies, buildConfig, bclDir, dependencies); + var initialAssemblies = assemblies.Duplicate(); + internal_GetExportedAssemblyDependencies(initialAssemblies, buildConfig, bclDir, assemblies); - AddI18NAssemblies(dependencies, bclDir); + AddI18NAssemblies(assemblies, bclDir); string outputDataDir = null; @@ -211,20 +211,32 @@ namespace GodotTools.Export Directory.CreateDirectory(outputDataGameAssembliesDir); } - foreach (var dependency in dependencies) + foreach (var assembly in assemblies) { - string dependSrcPath = dependency.Value; - - if (assembliesInsidePck) - { - string dependDstPath = Path.Combine(resAssembliesDir, dependSrcPath.GetFile()); - AddFile(dependSrcPath, dependDstPath); - } - else + void AddToAssembliesDir(string fileSrcPath) { - string dependDstPath = Path.Combine(outputDataDir, "Assemblies", dependSrcPath.GetFile()); - File.Copy(dependSrcPath, dependDstPath); + if (assembliesInsidePck) + { + string fileDstPath = Path.Combine(resAssembliesDir, fileSrcPath.GetFile()); + AddFile(fileSrcPath, fileDstPath); + } + else + { + Debug.Assert(outputDataDir != null); + string fileDstPath = Path.Combine(outputDataDir, "Assemblies", fileSrcPath.GetFile()); + File.Copy(fileSrcPath, fileDstPath); + } } + + string assemblySrcPath = assembly.Value; + + string assemblyPathWithoutExtension = Path.ChangeExtension(assemblySrcPath, null); + string pdbSrcPath = assemblyPathWithoutExtension + ".pdb"; + + AddToAssembliesDir(assemblySrcPath); + + if (File.Exists(pdbSrcPath)) + AddToAssembliesDir(pdbSrcPath); } // AOT compilation @@ -254,7 +266,7 @@ namespace GodotTools.Export ToolchainPath = aotToolchainPath }; - AotBuilder.CompileAssemblies(this, aotOpts, features, platform, isDebug, bclDir, outputDir, outputDataDir, dependencies); + AotBuilder.CompileAssemblies(this, aotOpts, features, platform, isDebug, bclDir, outputDir, outputDataDir, assemblies); } } @@ -366,7 +378,7 @@ namespace GodotTools.Export if (PlatformRequiresCustomBcl(platform)) throw new FileNotFoundException($"Missing BCL (Base Class Library) for platform: {platform}"); - platformBclDir = typeof(object).Assembly.Location; // Use the one we're running on + platformBclDir = typeof(object).Assembly.Location.GetBaseDir(); // Use the one we're running on } } @@ -425,7 +437,7 @@ namespace GodotTools.Export } [MethodImpl(MethodImplOptions.InternalCall)] - private static extern void internal_GetExportedAssemblyDependencies(Godot.Collections.Dictionary<string, string> initialDependencies, - string buildConfig, string customBclDir, Godot.Collections.Dictionary<string, string> dependencies); + private static extern void internal_GetExportedAssemblyDependencies(Godot.Collections.Dictionary<string, string> initialAssemblies, + string buildConfig, string customBclDir, Godot.Collections.Dictionary<string, string> dependencyAssemblies); } } diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs index c9d7dd26f8..c070cb16d9 100644 --- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs +++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs @@ -1,4 +1,5 @@ using Godot; +using GodotTools.Core; using GodotTools.Export; using GodotTools.Utils; using System; @@ -442,13 +443,27 @@ namespace GodotTools { // Migrate solution from old configuration names to: Debug, ExportDebug and ExportRelease DotNetSolution.MigrateFromOldConfigNames(GodotSharpDirs.ProjectSlnPath); + + var msbuildProject = ProjectUtils.Open(GodotSharpDirs.ProjectCsProjPath) + ?? throw new Exception("Cannot open C# project"); + + // NOTE: The order in which changes are made to the project is important + // Migrate csproj from old configuration names to: Debug, ExportDebug and ExportRelease - ProjectUtils.MigrateFromOldConfigNames(GodotSharpDirs.ProjectCsProjPath); + ProjectUtils.MigrateFromOldConfigNames(msbuildProject); - // Apply the other fixes after configurations are migrated + // Apply the other fixes only after configurations have been migrated // Make sure the existing project has Api assembly references configured correctly - ProjectUtils.FixApiHintPath(GodotSharpDirs.ProjectCsProjPath); + ProjectUtils.FixApiHintPath(msbuildProject); + + if (msbuildProject.HasUnsavedChanges) + { + // Save a copy of the project before replacing it + FileUtils.SaveBackupCopy(GodotSharpDirs.ProjectCsProjPath); + + msbuildProject.Save(); + } } catch (Exception e) { diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index 71bb8ff851..ee92a6234a 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -2383,7 +2383,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() { for (const List<PropertyInfo>::Element *E = property_list.front(); E; E = E->next()) { const PropertyInfo &property = E->get(); - if (property.usage & PROPERTY_USAGE_GROUP || property.usage & PROPERTY_USAGE_CATEGORY) + if (property.usage & PROPERTY_USAGE_GROUP || property.usage & PROPERTY_USAGE_SUBGROUP || property.usage & PROPERTY_USAGE_CATEGORY) continue; PropertyInterface iprop; diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp index 283d4beb8e..c3e7e67ae9 100644 --- a/modules/mono/editor/editor_internal_calls.cpp +++ b/modules/mono/editor/editor_internal_calls.cpp @@ -231,14 +231,14 @@ int32_t godot_icall_ScriptClassParser_ParseFile(MonoString *p_filepath, MonoObje return err; } -uint32_t godot_icall_ExportPlugin_GetExportedAssemblyDependencies(MonoObject *p_initial_dependencies, - MonoString *p_build_config, MonoString *p_custom_bcl_dir, MonoObject *r_dependencies) { - Dictionary initial_dependencies = GDMonoMarshal::mono_object_to_variant(p_initial_dependencies); +uint32_t godot_icall_ExportPlugin_GetExportedAssemblyDependencies(MonoObject *p_initial_assemblies, + MonoString *p_build_config, MonoString *p_custom_bcl_dir, MonoObject *r_assembly_dependencies) { + Dictionary initial_dependencies = GDMonoMarshal::mono_object_to_variant(p_initial_assemblies); String build_config = GDMonoMarshal::mono_string_to_godot(p_build_config); String custom_bcl_dir = GDMonoMarshal::mono_string_to_godot(p_custom_bcl_dir); - Dictionary dependencies = GDMonoMarshal::mono_object_to_variant(r_dependencies); + Dictionary assembly_dependencies = GDMonoMarshal::mono_object_to_variant(r_assembly_dependencies); - return GodotSharpExport::get_exported_assembly_dependencies(initial_dependencies, build_config, custom_bcl_dir, dependencies); + return GodotSharpExport::get_exported_assembly_dependencies(initial_dependencies, build_config, custom_bcl_dir, assembly_dependencies); } MonoString *godot_icall_Internal_UpdateApiAssembliesFromPrebuilt(MonoString *p_config) { diff --git a/modules/mono/editor/godotsharp_export.cpp b/modules/mono/editor/godotsharp_export.cpp index 324013e5e2..4126da16be 100644 --- a/modules/mono/editor/godotsharp_export.cpp +++ b/modules/mono/editor/godotsharp_export.cpp @@ -50,13 +50,13 @@ String get_assemblyref_name(MonoImage *p_image, int index) { return String::utf8(mono_metadata_string_heap(p_image, cols[MONO_ASSEMBLYREF_NAME])); } -Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Dictionary &r_dependencies) { +Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Dictionary &r_assembly_dependencies) { MonoImage *image = p_assembly->get_image(); for (int i = 0; i < mono_image_get_table_rows(image, MONO_TABLE_ASSEMBLYREF); i++) { String ref_name = get_assemblyref_name(image, i); - if (r_dependencies.has(ref_name)) + if (r_assembly_dependencies.has(ref_name)) continue; GDMonoAssembly *ref_assembly = nullptr; @@ -93,17 +93,17 @@ Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> ERR_FAIL_COND_V_MSG(!ref_assembly, ERR_CANT_RESOLVE, "Cannot load assembly (refonly): '" + ref_name + "'."); // Use the path we got from the search. Don't try to get the path from the loaded assembly as we can't trust it will be from the selected BCL dir. - r_dependencies[ref_name] = path; + r_assembly_dependencies[ref_name] = path; - Error err = get_assembly_dependencies(ref_assembly, p_search_dirs, r_dependencies); + Error err = get_assembly_dependencies(ref_assembly, p_search_dirs, r_assembly_dependencies); ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot load one of the dependencies for the assembly: '" + ref_name + "'."); } return OK; } -Error get_exported_assembly_dependencies(const Dictionary &p_initial_dependencies, - const String &p_build_config, const String &p_custom_bcl_dir, Dictionary &r_dependencies) { +Error get_exported_assembly_dependencies(const Dictionary &p_initial_assemblies, + const String &p_build_config, const String &p_custom_bcl_dir, Dictionary &r_assembly_dependencies) { MonoDomain *export_domain = GDMonoUtils::create_domain("GodotEngine.Domain.ProjectExport"); ERR_FAIL_NULL_V(export_domain, FAILED); _GDMONO_SCOPE_EXIT_DOMAIN_UNLOAD_(export_domain); @@ -113,16 +113,16 @@ Error get_exported_assembly_dependencies(const Dictionary &p_initial_dependencie Vector<String> search_dirs; GDMonoAssembly::fill_search_dirs(search_dirs, p_build_config, p_custom_bcl_dir); - for (const Variant *key = p_initial_dependencies.next(); key; key = p_initial_dependencies.next(key)) { + for (const Variant *key = p_initial_assemblies.next(); key; key = p_initial_assemblies.next(key)) { String assembly_name = *key; - String assembly_path = p_initial_dependencies[*key]; + String assembly_path = p_initial_assemblies[*key]; GDMonoAssembly *assembly = nullptr; bool load_success = GDMono::get_singleton()->load_assembly_from(assembly_name, assembly_path, &assembly, /* refonly: */ true); ERR_FAIL_COND_V_MSG(!load_success, ERR_CANT_RESOLVE, "Cannot load assembly (refonly): '" + assembly_name + "'."); - Error err = get_assembly_dependencies(assembly, search_dirs, r_dependencies); + Error err = get_assembly_dependencies(assembly, search_dirs, r_assembly_dependencies); if (err != OK) return err; } diff --git a/modules/mono/editor/godotsharp_export.h b/modules/mono/editor/godotsharp_export.h index 36138f81b7..9ab57755de 100644 --- a/modules/mono/editor/godotsharp_export.h +++ b/modules/mono/editor/godotsharp_export.h @@ -41,8 +41,8 @@ namespace GodotSharpExport { Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Dictionary &r_dependencies); -Error get_exported_assembly_dependencies(const Dictionary &p_initial_dependencies, - const String &p_build_config, const String &p_custom_lib_dir, Dictionary &r_dependencies); +Error get_exported_assembly_dependencies(const Dictionary &p_initial_assemblies, + const String &p_build_config, const String &p_custom_lib_dir, Dictionary &r_assembly_dependencies); } // namespace GodotSharpExport diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs index aba1065498..a963810d63 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs @@ -15,10 +15,7 @@ namespace Godot.Collections public override bool IsInvalid { - get - { - return handle == IntPtr.Zero; - } + get { return handle == IntPtr.Zero; } } protected override bool ReleaseHandle() @@ -43,7 +40,8 @@ namespace Godot.Collections if (collection == null) throw new NullReferenceException($"Parameter '{nameof(collection)} cannot be null.'"); - MarshalUtils.EnumerableToArray(collection, GetPtr()); + foreach (object element in collection) + Add(element); } internal Array(ArraySafeHandle handle) @@ -272,14 +270,8 @@ namespace Godot.Collections public T this[int index] { - get - { - return (T)Array.godot_icall_Array_At_Generic(GetPtr(), index, elemTypeEncoding, elemTypeClass); - } - set - { - objectArray[index] = value; - } + get { return (T)Array.godot_icall_Array_At_Generic(GetPtr(), index, elemTypeEncoding, elemTypeClass); } + set { objectArray[index] = value; } } public int IndexOf(T item) @@ -301,18 +293,12 @@ namespace Godot.Collections public int Count { - get - { - return objectArray.Count; - } + get { return objectArray.Count; } } public bool IsReadOnly { - get - { - return objectArray.IsReadOnly; - } + get { return objectArray.IsReadOnly; } } public void Add(T item) diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs index d72109de92..213fc181c1 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs @@ -15,10 +15,7 @@ namespace Godot.Collections public override bool IsInvalid { - get - { - return handle == IntPtr.Zero; - } + get { return handle == IntPtr.Zero; } } protected override bool ReleaseHandle() @@ -45,7 +42,8 @@ namespace Godot.Collections if (dictionary == null) throw new NullReferenceException($"Parameter '{nameof(dictionary)} cannot be null.'"); - MarshalUtils.IDictionaryToDictionary(dictionary, GetPtr()); + foreach (DictionaryEntry entry in dictionary) + Add(entry.Key, entry.Value); } internal Dictionary(DictionarySafeHandle handle) @@ -330,14 +328,8 @@ namespace Godot.Collections public TValue this[TKey key] { - get - { - return (TValue)Dictionary.godot_icall_Dictionary_GetValue_Generic(objectDict.GetPtr(), key, valTypeEncoding, valTypeClass); - } - set - { - objectDict[key] = value; - } + get { return (TValue)Dictionary.godot_icall_Dictionary_GetValue_Generic(objectDict.GetPtr(), key, valTypeEncoding, valTypeClass); } + set { objectDict[key] = value; } } public ICollection<TKey> Keys @@ -385,18 +377,12 @@ namespace Godot.Collections public int Count { - get - { - return objectDict.Count; - } + get { return objectDict.Count; } } public bool IsReadOnly { - get - { - return objectDict.IsReadOnly; - } + get { return objectDict.IsReadOnly; } } public void Add(KeyValuePair<TKey, TValue> item) @@ -440,7 +426,8 @@ namespace Godot.Collections public bool Remove(KeyValuePair<TKey, TValue> item) { - return Dictionary.godot_icall_Dictionary_Remove(GetPtr(), item.Key, item.Value); ; + return Dictionary.godot_icall_Dictionary_Remove(GetPtr(), item.Key, item.Value); + ; } // IEnumerable<KeyValuePair<TKey, TValue>> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs index a1d63a62ef..c59d083080 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs @@ -16,10 +16,8 @@ namespace Godot /// <exception cref="System.InvalidOperationException"> /// <paramref name="type"/> is not a generic type. That is, IsGenericType returns false. /// </exception> - static bool TypeIsGenericArray(Type type) - { - return type.GetGenericTypeDefinition() == typeof(Godot.Collections.Array<>); - } + static bool TypeIsGenericArray(Type type) => + type.GetGenericTypeDefinition() == typeof(Godot.Collections.Array<>); /// <summary> /// Returns <see langword="true"/> if the generic type definition of <paramref name="type"/> @@ -28,10 +26,20 @@ namespace Godot /// <exception cref="System.InvalidOperationException"> /// <paramref name="type"/> is not a generic type. That is, IsGenericType returns false. /// </exception> - static bool TypeIsGenericDictionary(Type type) - { - return type.GetGenericTypeDefinition() == typeof(Godot.Collections.Dictionary<,>); - } + static bool TypeIsGenericDictionary(Type type) => + type.GetGenericTypeDefinition() == typeof(Godot.Collections.Dictionary<,>); + + static bool TypeIsSystemGenericList(Type type) => + type.GetGenericTypeDefinition() == typeof(System.Collections.Generic.List<>); + + static bool TypeIsSystemGenericDictionary(Type type) => + type.GetGenericTypeDefinition() == typeof(System.Collections.Generic.Dictionary<,>); + + static bool TypeIsGenericIEnumerable(Type type) => type.GetGenericTypeDefinition() == typeof(IEnumerable<>); + + static bool TypeIsGenericICollection(Type type) => type.GetGenericTypeDefinition() == typeof(ICollection<>); + + static bool TypeIsGenericIDictionary(Type type) => type.GetGenericTypeDefinition() == typeof(IDictionary<,>); static void ArrayGetElementType(Type arrayType, out Type elementType) { @@ -45,105 +53,6 @@ namespace Godot valueType = genericArgs[1]; } - static bool GenericIEnumerableIsAssignableFromType(Type type) - { - if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>)) - return true; - - foreach (var interfaceType in type.GetInterfaces()) - { - if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) - return true; - } - - Type baseType = type.BaseType; - - if (baseType == null) - return false; - - return GenericIEnumerableIsAssignableFromType(baseType); - } - - static bool GenericIDictionaryIsAssignableFromType(Type type) - { - if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IDictionary<,>)) - return true; - - foreach (var interfaceType in type.GetInterfaces()) - { - if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IDictionary<,>)) - return true; - } - - Type baseType = type.BaseType; - - if (baseType == null) - return false; - - return GenericIDictionaryIsAssignableFromType(baseType); - } - - static bool GenericIEnumerableIsAssignableFromType(Type type, out Type elementType) - { - if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>)) - { - elementType = type.GetGenericArguments()[0]; - return true; - } - - foreach (var interfaceType in type.GetInterfaces()) - { - if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) - { - elementType = interfaceType.GetGenericArguments()[0]; - return true; - } - } - - Type baseType = type.BaseType; - - if (baseType == null) - { - elementType = null; - return false; - } - - return GenericIEnumerableIsAssignableFromType(baseType, out elementType); - } - - static bool GenericIDictionaryIsAssignableFromType(Type type, out Type keyType, out Type valueType) - { - if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IDictionary<,>)) - { - var genericArgs = type.GetGenericArguments(); - keyType = genericArgs[0]; - valueType = genericArgs[1]; - return true; - } - - foreach (var interfaceType in type.GetInterfaces()) - { - if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IDictionary<,>)) - { - var genericArgs = interfaceType.GetGenericArguments(); - keyType = genericArgs[0]; - valueType = genericArgs[1]; - return true; - } - } - - Type baseType = type.BaseType; - - if (baseType == null) - { - keyType = null; - valueType = null; - return false; - } - - return GenericIDictionaryIsAssignableFromType(baseType, out keyType, out valueType); - } - static Type MakeGenericArrayType(Type elemType) { return typeof(Godot.Collections.Array<>).MakeGenericType(elemType); @@ -153,60 +62,5 @@ namespace Godot { return typeof(Godot.Collections.Dictionary<,>).MakeGenericType(keyType, valueType); } - - // TODO Add support for IEnumerable<T> and IDictionary<TKey, TValue> - // TODO: EnumerableToArray and IDictionaryToDictionary can be optimized - - internal static void EnumerableToArray(IEnumerable enumerable, IntPtr godotArrayPtr) - { - if (enumerable is ICollection collection) - { - int count = collection.Count; - - object[] tempArray = new object[count]; - collection.CopyTo(tempArray, 0); - - for (int i = 0; i < count; i++) - { - Array.godot_icall_Array_Add(godotArrayPtr, tempArray[i]); - } - } - else - { - foreach (object element in enumerable) - { - Array.godot_icall_Array_Add(godotArrayPtr, element); - } - } - } - - internal static void IDictionaryToDictionary(IDictionary dictionary, IntPtr godotDictionaryPtr) - { - foreach (DictionaryEntry entry in dictionary) - { - Dictionary.godot_icall_Dictionary_Add(godotDictionaryPtr, entry.Key, entry.Value); - } - } - - internal static void GenericIDictionaryToDictionary(object dictionary, IntPtr godotDictionaryPtr) - { -#if DEBUG - if (!GenericIDictionaryIsAssignableFromType(dictionary.GetType())) - throw new InvalidOperationException("The type does not implement IDictionary<,>"); -#endif - - // TODO: Can we optimize this? - - var keys = ((IEnumerable)dictionary.GetType().GetProperty("Keys").GetValue(dictionary)).GetEnumerator(); - var values = ((IEnumerable)dictionary.GetType().GetProperty("Values").GetValue(dictionary)).GetEnumerator(); - - while (keys.MoveNext() && values.MoveNext()) - { - object key = keys.Current; - object value = values.Current; - - Dictionary.godot_icall_Dictionary_Add(godotDictionaryPtr, key, value); - } - } } } diff --git a/modules/mono/godotsharp_dirs.cpp b/modules/mono/godotsharp_dirs.cpp index fe8b925257..d596163926 100644 --- a/modules/mono/godotsharp_dirs.cpp +++ b/modules/mono/godotsharp_dirs.cpp @@ -40,7 +40,7 @@ #endif #ifdef ANDROID_ENABLED -#include "mono_gd/support/mono-support.h" +#include "mono_gd/support/android_support.h" #endif #include "mono_gd/gd_mono.h" diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index 306a1997ab..3298c5da4c 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -129,12 +129,8 @@ void gd_mono_profiler_init() { } } -#if defined(DEBUG_ENABLED) - void gd_mono_debug_init() { - mono_debug_init(MONO_DEBUG_FORMAT_MONO); - CharString da_args = OS::get_singleton()->get_environment("GODOT_MONO_DEBUGGER_AGENT").utf8(); #ifdef TOOLS_ENABLED @@ -159,6 +155,10 @@ void gd_mono_debug_init() { return; // Exported games don't use the project settings to setup the debugger agent #endif + // Debugging enabled + + mono_debug_init(MONO_DEBUG_FORMAT_MONO); + // --debugger-agent=help const char *options[] = { "--soft-breakpoints", @@ -167,7 +167,6 @@ void gd_mono_debug_init() { mono_jit_parse_options(2, (char **)options); } -#endif // defined(DEBUG_ENABLED) #endif // !defined(JAVASCRIPT_ENABLED) #if defined(JAVASCRIPT_ENABLED) @@ -175,6 +174,7 @@ MonoDomain *gd_initialize_mono_runtime() { const char *vfs_prefix = "managed"; int enable_debugging = 0; + // TODO: Provide a way to enable debugging on WASM release builds. #ifdef DEBUG_ENABLED enable_debugging = 1; #endif @@ -185,9 +185,7 @@ MonoDomain *gd_initialize_mono_runtime() { } #else MonoDomain *gd_initialize_mono_runtime() { -#ifdef DEBUG_ENABLED gd_mono_debug_init(); -#endif #if defined(IPHONE_ENABLED) || defined(ANDROID_ENABLED) // I don't know whether this actually matters or not @@ -1389,7 +1387,10 @@ bool _GodotSharp::is_runtime_initialized() { void _GodotSharp::_reload_assemblies(bool p_soft_reload) { #ifdef GD_MONO_HOT_RELOAD - CSharpLanguage::get_singleton()->reload_assemblies(p_soft_reload); + // This method may be called more than once with `call_deferred`, so we need to check + // again if reloading is needed to avoid reloading multiple times unnecessarily. + if (CSharpLanguage::get_singleton()->is_assembly_reloading_needed()) + CSharpLanguage::get_singleton()->reload_assemblies(p_soft_reload); #endif } diff --git a/modules/mono/mono_gd/gd_mono_cache.cpp b/modules/mono/mono_gd/gd_mono_cache.cpp index facc0da780..5ddf18d544 100644 --- a/modules/mono/mono_gd/gd_mono_cache.cpp +++ b/modules/mono/mono_gd/gd_mono_cache.cpp @@ -84,6 +84,7 @@ void CachedData::clear_corlib_cache() { class_IntPtr = nullptr; class_System_Collections_IEnumerable = nullptr; + class_System_Collections_ICollection = nullptr; class_System_Collections_IDictionary = nullptr; #ifdef DEBUG_ENABLED @@ -171,22 +172,18 @@ void CachedData::clear_godot_api_cache() { methodthunk_MarshalUtils_TypeIsGenericArray.nullify(); methodthunk_MarshalUtils_TypeIsGenericDictionary.nullify(); + methodthunk_MarshalUtils_TypeIsSystemGenericList.nullify(); + methodthunk_MarshalUtils_TypeIsSystemGenericDictionary.nullify(); + methodthunk_MarshalUtils_TypeIsGenericIEnumerable.nullify(); + methodthunk_MarshalUtils_TypeIsGenericICollection.nullify(); + methodthunk_MarshalUtils_TypeIsGenericIDictionary.nullify(); methodthunk_MarshalUtils_ArrayGetElementType.nullify(); methodthunk_MarshalUtils_DictionaryGetKeyValueTypes.nullify(); - methodthunk_MarshalUtils_GenericIEnumerableIsAssignableFromType.nullify(); - methodthunk_MarshalUtils_GenericIDictionaryIsAssignableFromType.nullify(); - methodthunk_MarshalUtils_GenericIEnumerableIsAssignableFromType_with_info.nullify(); - methodthunk_MarshalUtils_GenericIDictionaryIsAssignableFromType_with_info.nullify(); - methodthunk_MarshalUtils_MakeGenericArrayType.nullify(); methodthunk_MarshalUtils_MakeGenericDictionaryType.nullify(); - methodthunk_MarshalUtils_EnumerableToArray.nullify(); - methodthunk_MarshalUtils_IDictionaryToDictionary.nullify(); - methodthunk_MarshalUtils_GenericIDictionaryToDictionary.nullify(); - // End of MarshalUtils methods task_scheduler_handle = Ref<MonoGCHandleRef>(); @@ -213,6 +210,7 @@ void update_corlib_cache() { CACHE_CLASS_AND_CHECK(IntPtr, GDMono::get_singleton()->get_corlib_assembly()->get_class(mono_get_intptr_class())); CACHE_CLASS_AND_CHECK(System_Collections_IEnumerable, GDMono::get_singleton()->get_corlib_assembly()->get_class("System.Collections", "IEnumerable")); + CACHE_CLASS_AND_CHECK(System_Collections_ICollection, GDMono::get_singleton()->get_corlib_assembly()->get_class("System.Collections", "ICollection")); CACHE_CLASS_AND_CHECK(System_Collections_IDictionary, GDMono::get_singleton()->get_corlib_assembly()->get_class("System.Collections", "IDictionary")); #ifdef DEBUG_ENABLED @@ -297,22 +295,18 @@ void update_godot_api_cache() { CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericArray, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericArray", 1)); CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericDictionary, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericDictionary", 1)); + CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsSystemGenericList, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsSystemGenericList", 1)); + CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsSystemGenericDictionary, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsSystemGenericDictionary", 1)); + CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericIEnumerable, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericIEnumerable", 1)); + CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericICollection, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericICollection", 1)); + CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericIDictionary, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericIDictionary", 1)); CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, ArrayGetElementType, GODOT_API_CLASS(MarshalUtils)->get_method("ArrayGetElementType", 2)); CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, DictionaryGetKeyValueTypes, GODOT_API_CLASS(MarshalUtils)->get_method("DictionaryGetKeyValueTypes", 3)); - CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIEnumerableIsAssignableFromType, GODOT_API_CLASS(MarshalUtils)->get_method("GenericIEnumerableIsAssignableFromType", 1)); - CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIDictionaryIsAssignableFromType, GODOT_API_CLASS(MarshalUtils)->get_method("GenericIDictionaryIsAssignableFromType", 1)); - CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIEnumerableIsAssignableFromType_with_info, GODOT_API_CLASS(MarshalUtils)->get_method("GenericIEnumerableIsAssignableFromType", 2)); - CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIDictionaryIsAssignableFromType_with_info, GODOT_API_CLASS(MarshalUtils)->get_method("GenericIDictionaryIsAssignableFromType", 3)); - CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, MakeGenericArrayType, GODOT_API_CLASS(MarshalUtils)->get_method("MakeGenericArrayType", 1)); CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, MakeGenericDictionaryType, GODOT_API_CLASS(MarshalUtils)->get_method("MakeGenericDictionaryType", 2)); - CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, EnumerableToArray, GODOT_API_CLASS(MarshalUtils)->get_method("EnumerableToArray", 2)); - CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, IDictionaryToDictionary, GODOT_API_CLASS(MarshalUtils)->get_method("IDictionaryToDictionary", 2)); - CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIDictionaryToDictionary, GODOT_API_CLASS(MarshalUtils)->get_method("GenericIDictionaryToDictionary", 2)); - // End of MarshalUtils methods #ifdef DEBUG_ENABLED diff --git a/modules/mono/mono_gd/gd_mono_cache.h b/modules/mono/mono_gd/gd_mono_cache.h index 21c8ed4efe..3cf2bd6ce5 100644 --- a/modules/mono/mono_gd/gd_mono_cache.h +++ b/modules/mono/mono_gd/gd_mono_cache.h @@ -58,6 +58,7 @@ struct CachedData { GDMonoClass *class_IntPtr; // System.IntPtr GDMonoClass *class_System_Collections_IEnumerable; + GDMonoClass *class_System_Collections_ICollection; GDMonoClass *class_System_Collections_IDictionary; #ifdef DEBUG_ENABLED @@ -141,22 +142,18 @@ struct CachedData { GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericArray; GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericDictionary; + GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsSystemGenericList; + GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsSystemGenericDictionary; + GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericIEnumerable; + GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericICollection; + GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericIDictionary; GDMonoMethodThunk<MonoReflectionType *, MonoReflectionType **> methodthunk_MarshalUtils_ArrayGetElementType; GDMonoMethodThunk<MonoReflectionType *, MonoReflectionType **, MonoReflectionType **> methodthunk_MarshalUtils_DictionaryGetKeyValueTypes; - GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_GenericIEnumerableIsAssignableFromType; - GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_GenericIDictionaryIsAssignableFromType; - GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *, MonoReflectionType **> methodthunk_MarshalUtils_GenericIEnumerableIsAssignableFromType_with_info; - GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *, MonoReflectionType **, MonoReflectionType **> methodthunk_MarshalUtils_GenericIDictionaryIsAssignableFromType_with_info; - GDMonoMethodThunkR<MonoReflectionType *, MonoReflectionType *> methodthunk_MarshalUtils_MakeGenericArrayType; GDMonoMethodThunkR<MonoReflectionType *, MonoReflectionType *, MonoReflectionType *> methodthunk_MarshalUtils_MakeGenericDictionaryType; - GDMonoMethodThunk<MonoObject *, Array *> methodthunk_MarshalUtils_EnumerableToArray; - GDMonoMethodThunk<MonoObject *, Dictionary *> methodthunk_MarshalUtils_IDictionaryToDictionary; - GDMonoMethodThunk<MonoObject *, Dictionary *> methodthunk_MarshalUtils_GenericIDictionaryToDictionary; - // End of MarshalUtils methods Ref<MonoGCHandleRef> task_scheduler_handle; @@ -186,14 +183,6 @@ inline void clear_godot_api_cache() { cached_data.clear_godot_api_cache(); } -_FORCE_INLINE_ bool tools_godot_api_check() { -#ifdef TOOLS_ENABLED - return cached_data.godot_api_cache_updated; -#else - return true; // Assume it's updated if this was called, otherwise it's a bug -#endif -} - } // namespace GDMonoCache #define CACHED_CLASS(m_class) (GDMonoCache::cached_data.class_##m_class) diff --git a/modules/mono/mono_gd/gd_mono_class.cpp b/modules/mono/mono_gd/gd_mono_class.cpp index ede4203e35..2c65f7e3a0 100644 --- a/modules/mono/mono_gd/gd_mono_class.cpp +++ b/modules/mono/mono_gd/gd_mono_class.cpp @@ -31,6 +31,7 @@ #include "gd_mono_class.h" #include <mono/metadata/attrdefs.h> +#include <mono/metadata/debug-helpers.h> #include "gd_mono_assembly.h" #include "gd_mono_cache.h" @@ -55,7 +56,11 @@ String GDMonoClass::get_full_name() const { return get_full_name(mono_class); } -MonoType *GDMonoClass::get_mono_type() { +String GDMonoClass::get_type_desc() const { + return GDMonoUtils::get_type_desc(get_mono_type()); +} + +MonoType *GDMonoClass::get_mono_type() const { // Careful, you cannot compare two MonoType*. // There is mono_metadata_type_equal, how is this different from comparing two MonoClass*? return get_mono_type(mono_class); @@ -264,6 +269,12 @@ bool GDMonoClass::implements_interface(GDMonoClass *p_interface) { return mono_class_implements_interface(mono_class, p_interface->get_mono_ptr()); } +bool GDMonoClass::has_public_parameterless_ctor() { + + GDMonoMethod *ctor = get_method(".ctor", 0); + return ctor && ctor->get_visibility() == IMonoClassMember::PUBLIC; +} + GDMonoMethod *GDMonoClass::get_method(const StringName &p_name, int p_params_count) { MethodKey key = MethodKey(p_name, p_params_count); @@ -328,6 +339,9 @@ GDMonoMethod *GDMonoClass::get_method_with_desc(const String &p_description, boo MonoMethod *method = mono_method_desc_search_in_class(desc, mono_class); mono_method_desc_free(desc); + if (!method) + return nullptr; + ERR_FAIL_COND_V(mono_method_get_class(method) != mono_class, nullptr); return get_method(method); diff --git a/modules/mono/mono_gd/gd_mono_class.h b/modules/mono/mono_gd/gd_mono_class.h index 0c9a8cdafe..9237aae057 100644 --- a/modules/mono/mono_gd/gd_mono_class.h +++ b/modules/mono/mono_gd/gd_mono_class.h @@ -31,8 +31,6 @@ #ifndef GD_MONO_CLASS_H #define GD_MONO_CLASS_H -#include <mono/metadata/debug-helpers.h> - #include "core/map.h" #include "core/ustring.h" @@ -107,7 +105,8 @@ public: static MonoType *get_mono_type(MonoClass *p_mono_class); String get_full_name() const; - MonoType *get_mono_type(); + String get_type_desc() const; + MonoType *get_mono_type() const; uint32_t get_flags() const; bool is_static() const; @@ -137,6 +136,7 @@ public: void fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base); bool implements_interface(GDMonoClass *p_interface); + bool has_public_parameterless_ctor(); GDMonoMethod *get_method(const StringName &p_name, int p_params_count = 0); GDMonoMethod *get_method(MonoMethod *p_raw_method); diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp index 3f4e5fe5ac..e76cb84d43 100644 --- a/modules/mono/mono_gd/gd_mono_field.cpp +++ b/modules/mono/mono_gd/gd_mono_field.cpp @@ -322,6 +322,13 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ break; } + GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass); + if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) { + MonoArray *managed = GDMonoMarshal::Array_to_mono_array(p_value.operator ::Array(), array_type_class); + mono_field_set_value(p_object, mono_field, managed); + break; + } + ERR_FAIL_MSG("Attempted to convert Variant to a managed array of unmarshallable element type."); } break; @@ -353,56 +360,22 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ break; } - if (CACHED_CLASS(Dictionary) == type_class) { + // Godot.Collections.Dictionary or IDictionary + if (CACHED_CLASS(Dictionary) == type_class || type_class == CACHED_CLASS(System_Collections_IDictionary)) { MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), CACHED_CLASS(Dictionary)); mono_field_set_value(p_object, mono_field, managed); break; } - if (CACHED_CLASS(Array) == type_class) { + // Godot.Collections.Array or ICollection or IEnumerable + if (CACHED_CLASS(Array) == type_class || + type_class == CACHED_CLASS(System_Collections_ICollection) || + type_class == CACHED_CLASS(System_Collections_IEnumerable)) { MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), CACHED_CLASS(Array)); mono_field_set_value(p_object, mono_field, managed); break; } - // The order in which we check the following interfaces is very important (dictionaries and generics first) - - MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type_class->get_mono_type()); - - MonoReflectionType *key_reftype, *value_reftype; - if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype, &key_reftype, &value_reftype)) { - MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), - GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype)); - mono_field_set_value(p_object, mono_field, managed); - break; - } - - if (type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) { - MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), CACHED_CLASS(Dictionary)); - mono_field_set_value(p_object, mono_field, managed); - break; - } - - MonoReflectionType *elem_reftype; - if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype, &elem_reftype)) { - MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), - GDMonoUtils::Marshal::make_generic_array_type(elem_reftype)); - mono_field_set_value(p_object, mono_field, managed); - break; - } - - if (type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) { - if (GDMonoCache::tools_godot_api_check()) { - MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), CACHED_CLASS(Array)); - mono_field_set_value(p_object, mono_field, managed); - break; - } else { - MonoObject *managed = (MonoObject *)GDMonoMarshal::Array_to_mono_array(p_value.operator Array()); - mono_field_set_value(p_object, mono_field, managed); - break; - } - } - ERR_FAIL_MSG("Attempted to set the value of a field of unmarshallable type: '" + type_class->get_name() + "'."); } break; @@ -535,52 +508,62 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ case MONO_TYPE_GENERICINST: { MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type.type_class->get_mono_type()); + // Godot.Collections.Dictionary<TKey, TValue> if (GDMonoUtils::Marshal::type_is_generic_dictionary(reftype)) { MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), type.type_class); mono_field_set_value(p_object, mono_field, managed); break; } + // Godot.Collections.Array<T> if (GDMonoUtils::Marshal::type_is_generic_array(reftype)) { MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), type.type_class); mono_field_set_value(p_object, mono_field, managed); break; } - // The order in which we check the following interfaces is very important (dictionaries and generics first) - - MonoReflectionType *key_reftype, *value_reftype; - if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype, &key_reftype, &value_reftype)) { - MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), - GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype)); + // System.Collections.Generic.Dictionary<TKey, TValue> + if (GDMonoUtils::Marshal::type_is_system_generic_dictionary(reftype)) { + MonoReflectionType *key_reftype = nullptr; + MonoReflectionType *value_reftype = nullptr; + GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype); + MonoObject *managed = GDMonoMarshal::Dictionary_to_system_generic_dict(p_value.operator Dictionary(), + type.type_class, key_reftype, value_reftype); mono_field_set_value(p_object, mono_field, managed); break; } - if (type.type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) { - MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), CACHED_CLASS(Dictionary)); + // System.Collections.Generic.List<T> + if (GDMonoUtils::Marshal::type_is_system_generic_list(reftype)) { + MonoReflectionType *elem_reftype = nullptr; + GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype); + MonoObject *managed = GDMonoMarshal::Array_to_system_generic_list(p_value.operator Array(), + type.type_class, elem_reftype); mono_field_set_value(p_object, mono_field, managed); break; } - MonoReflectionType *elem_reftype; - if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype, &elem_reftype)) { - MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), - GDMonoUtils::Marshal::make_generic_array_type(elem_reftype)); + // IDictionary<TKey, TValue> + if (GDMonoUtils::Marshal::type_is_generic_idictionary(reftype)) { + MonoReflectionType *key_reftype; + MonoReflectionType *value_reftype; + GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype); + GDMonoClass *godot_dict_class = GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype); + + MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), godot_dict_class); mono_field_set_value(p_object, mono_field, managed); break; } - if (type.type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) { - if (GDMonoCache::tools_godot_api_check()) { - MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), CACHED_CLASS(Array)); - mono_field_set_value(p_object, mono_field, managed); - break; - } else { - MonoObject *managed = (MonoObject *)GDMonoMarshal::Array_to_mono_array(p_value.operator Array()); - mono_field_set_value(p_object, mono_field, managed); - break; - } + // ICollection<T> or IEnumerable<T> + if (GDMonoUtils::Marshal::type_is_generic_icollection(reftype) || GDMonoUtils::Marshal::type_is_generic_ienumerable(reftype)) { + MonoReflectionType *elem_reftype; + GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype); + GDMonoClass *godot_array_class = GDMonoUtils::Marshal::make_generic_array_type(elem_reftype); + + MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), godot_array_class); + mono_field_set_value(p_object, mono_field, managed); + break; } } break; diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp index 1878038f44..91ee07388b 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.cpp +++ b/modules/mono/mono_gd/gd_mono_marshal.cpp @@ -154,6 +154,10 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_ if (array_type->eklass == CACHED_CLASS_RAW(Color)) return Variant::PACKED_COLOR_ARRAY; + + GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass); + if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) + return Variant::ARRAY; } break; case MONO_TYPE_CLASS: { @@ -184,23 +188,14 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_ return Variant::ARRAY; } - // The order in which we check the following interfaces is very important (dictionaries and generics first) - - MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type_class->get_mono_type()); - - if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype)) { - return Variant::DICTIONARY; - } - - if (type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) { + // IDictionary + if (p_type.type_class == CACHED_CLASS(System_Collections_IDictionary)) { return Variant::DICTIONARY; } - if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype)) { - return Variant::ARRAY; - } - - if (type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) { + // ICollection or IEnumerable + if (p_type.type_class == CACHED_CLASS(System_Collections_ICollection) || + p_type.type_class == CACHED_CLASS(System_Collections_IEnumerable)) { return Variant::ARRAY; } } break; @@ -214,27 +209,33 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_ case MONO_TYPE_GENERICINST: { MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), p_type.type_class->get_mono_type()); + // Godot.Collections.Dictionary<TKey, TValue> if (GDMonoUtils::Marshal::type_is_generic_dictionary(reftype)) { return Variant::DICTIONARY; } + // Godot.Collections.Array<T> if (GDMonoUtils::Marshal::type_is_generic_array(reftype)) { return Variant::ARRAY; } - // The order in which we check the following interfaces is very important (dictionaries and generics first) - - if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype)) - return Variant::DICTIONARY; - - if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) { + // System.Collections.Generic.Dictionary<TKey, TValue> + if (GDMonoUtils::Marshal::type_is_system_generic_dictionary(reftype)) { return Variant::DICTIONARY; } - if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype)) + // System.Collections.Generic.List<T> + if (GDMonoUtils::Marshal::type_is_system_generic_list(reftype)) { return Variant::ARRAY; + } - if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) { + // IDictionary<TKey, TValue> + if (GDMonoUtils::Marshal::type_is_generic_idictionary(reftype)) { + return Variant::DICTIONARY; + } + + // ICollection<T> or IEnumerable<T> + if (GDMonoUtils::Marshal::type_is_generic_icollection(reftype) || GDMonoUtils::Marshal::type_is_generic_ienumerable(reftype)) { return Variant::ARRAY; } } break; @@ -252,10 +253,20 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_ bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_elem_type) { switch (p_array_type.type_encoding) { + case MONO_TYPE_ARRAY: + case MONO_TYPE_SZARRAY: { + MonoArrayType *array_type = mono_type_get_array_type(p_array_type.type_class->get_mono_type()); + GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass); + r_elem_type = ManagedType::from_class(array_type_class); + return true; + } break; case MONO_TYPE_GENERICINST: { MonoReflectionType *array_reftype = mono_type_get_object(mono_domain_get(), p_array_type.type_class->get_mono_type()); - if (GDMonoUtils::Marshal::type_is_generic_array(array_reftype)) { + if (GDMonoUtils::Marshal::type_is_generic_array(array_reftype) || + GDMonoUtils::Marshal::type_is_system_generic_list(array_reftype) || + GDMonoUtils::Marshal::type_is_generic_icollection(array_reftype) || + GDMonoUtils::Marshal::type_is_generic_ienumerable(array_reftype)) { MonoReflectionType *elem_reftype; GDMonoUtils::Marshal::array_get_element_type(array_reftype, &elem_reftype); @@ -263,12 +274,6 @@ bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_ r_elem_type = ManagedType::from_reftype(elem_reftype); return true; } - - MonoReflectionType *elem_reftype; - if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(array_reftype, &elem_reftype)) { - r_elem_type = ManagedType::from_reftype(elem_reftype); - return true; - } } break; default: { } break; @@ -282,7 +287,9 @@ bool try_get_dictionary_key_value_types(const ManagedType &p_dictionary_type, Ma case MONO_TYPE_GENERICINST: { MonoReflectionType *dict_reftype = mono_type_get_object(mono_domain_get(), p_dictionary_type.type_class->get_mono_type()); - if (GDMonoUtils::Marshal::type_is_generic_dictionary(dict_reftype)) { + if (GDMonoUtils::Marshal::type_is_generic_dictionary(dict_reftype) || + GDMonoUtils::Marshal::type_is_system_generic_dictionary(dict_reftype) || + GDMonoUtils::Marshal::type_is_generic_idictionary(dict_reftype)) { MonoReflectionType *key_reftype; MonoReflectionType *value_reftype; @@ -292,13 +299,6 @@ bool try_get_dictionary_key_value_types(const ManagedType &p_dictionary_type, Ma r_value_type = ManagedType::from_reftype(value_reftype); return true; } - - MonoReflectionType *key_reftype, *value_reftype; - if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(dict_reftype, &key_reftype, &value_reftype)) { - r_key_type = ManagedType::from_reftype(key_reftype); - r_value_type = ManagedType::from_reftype(value_reftype); - return true; - } } break; default: { } break; @@ -577,6 +577,10 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty if (array_type->eklass == CACHED_CLASS_RAW(Color)) return (MonoObject *)PackedColorArray_to_mono_array(p_var->operator PackedColorArray()); + GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass); + if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) + return (MonoObject *)Array_to_mono_array(p_var->operator Array(), array_type_class); + ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to a managed array of unmarshallable element type."); } break; @@ -600,41 +604,17 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty return GDMonoUtils::create_managed_from(p_var->operator RID()); } - if (CACHED_CLASS(Dictionary) == type_class) { + // Godot.Collections.Dictionary or IDictionary + if (CACHED_CLASS(Dictionary) == type_class || CACHED_CLASS(System_Collections_IDictionary) == type_class) { return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), CACHED_CLASS(Dictionary)); } - if (CACHED_CLASS(Array) == type_class) { + // Godot.Collections.Array or ICollection or IEnumerable + if (CACHED_CLASS(Array) == type_class || + CACHED_CLASS(System_Collections_ICollection) == type_class || + CACHED_CLASS(System_Collections_IEnumerable) == type_class) { return GDMonoUtils::create_managed_from(p_var->operator Array(), CACHED_CLASS(Array)); } - - // The order in which we check the following interfaces is very important (dictionaries and generics first) - - MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type_class->get_mono_type()); - - MonoReflectionType *key_reftype, *value_reftype; - if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype, &key_reftype, &value_reftype)) { - return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), - GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype)); - } - - if (type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) { - return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), CACHED_CLASS(Dictionary)); - } - - MonoReflectionType *elem_reftype; - if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype, &elem_reftype)) { - return GDMonoUtils::create_managed_from(p_var->operator Array(), - GDMonoUtils::Marshal::make_generic_array_type(elem_reftype)); - } - - if (type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) { - if (GDMonoCache::tools_godot_api_check()) { - return GDMonoUtils::create_managed_from(p_var->operator Array(), CACHED_CLASS(Array)); - } else { - return (MonoObject *)GDMonoMarshal::Array_to_mono_array(p_var->operator Array()); - } - } } break; case MONO_TYPE_OBJECT: { // Variant @@ -755,38 +735,48 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty case MONO_TYPE_GENERICINST: { MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), p_type.type_class->get_mono_type()); + // Godot.Collections.Dictionary<TKey, TValue> if (GDMonoUtils::Marshal::type_is_generic_dictionary(reftype)) { return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), p_type.type_class); } + // Godot.Collections.Array<T> if (GDMonoUtils::Marshal::type_is_generic_array(reftype)) { return GDMonoUtils::create_managed_from(p_var->operator Array(), p_type.type_class); } - // The order in which we check the following interfaces is very important (dictionaries and generics first) - - MonoReflectionType *key_reftype, *value_reftype; - if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype, &key_reftype, &value_reftype)) { - return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), - GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype)); + // System.Collections.Generic.Dictionary<TKey, TValue> + if (GDMonoUtils::Marshal::type_is_system_generic_dictionary(reftype)) { + MonoReflectionType *key_reftype = nullptr; + MonoReflectionType *value_reftype = nullptr; + GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype); + return Dictionary_to_system_generic_dict(p_var->operator Dictionary(), p_type.type_class, key_reftype, value_reftype); } - if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) { - return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), CACHED_CLASS(Dictionary)); + // System.Collections.Generic.List<T> + if (GDMonoUtils::Marshal::type_is_system_generic_list(reftype)) { + MonoReflectionType *elem_reftype = nullptr; + GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype); + return Array_to_system_generic_list(p_var->operator Array(), p_type.type_class, elem_reftype); } - MonoReflectionType *elem_reftype; - if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype, &elem_reftype)) { - return GDMonoUtils::create_managed_from(p_var->operator Array(), - GDMonoUtils::Marshal::make_generic_array_type(elem_reftype)); + // IDictionary<TKey, TValue> + if (GDMonoUtils::Marshal::type_is_generic_idictionary(reftype)) { + MonoReflectionType *key_reftype; + MonoReflectionType *value_reftype; + GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype); + GDMonoClass *godot_dict_class = GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype); + + return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), godot_dict_class); } - if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) { - if (GDMonoCache::tools_godot_api_check()) { - return GDMonoUtils::create_managed_from(p_var->operator Array(), CACHED_CLASS(Array)); - } else { - return (MonoObject *)GDMonoMarshal::Array_to_mono_array(p_var->operator Array()); - } + // ICollection<T> or IEnumerable<T> + if (GDMonoUtils::Marshal::type_is_generic_icollection(reftype) || GDMonoUtils::Marshal::type_is_generic_ienumerable(reftype)) { + MonoReflectionType *elem_reftype; + GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype); + GDMonoClass *godot_array_class = GDMonoUtils::Marshal::make_generic_array_type(elem_reftype); + + return GDMonoUtils::create_managed_from(p_var->operator Array(), godot_array_class); } } break; } break; @@ -922,6 +912,10 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type if (array_type->eklass == CACHED_CLASS_RAW(Color)) return mono_array_to_PackedColorArray((MonoArray *)p_obj); + GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass); + if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) + return mono_array_to_Array((MonoArray *)p_obj); + if (p_fail_with_err) { ERR_FAIL_V_MSG(Variant(), "Attempted to convert a managed array of unmarshallable element type to Variant."); } else { @@ -957,44 +951,27 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type return ptr ? Variant(*ptr) : Variant(); } - if (CACHED_CLASS(Array) == type_class) { + // Godot.Collections.Dictionary + if (CACHED_CLASS(Dictionary) == type_class) { MonoException *exc = nullptr; - Array *ptr = CACHED_METHOD_THUNK(Array, GetPtr).invoke(p_obj, &exc); + Dictionary *ptr = CACHED_METHOD_THUNK(Dictionary, GetPtr).invoke(p_obj, &exc); UNHANDLED_EXCEPTION(exc); return ptr ? Variant(*ptr) : Variant(); } - if (CACHED_CLASS(Dictionary) == type_class) { + // Godot.Collections.Array + if (CACHED_CLASS(Array) == type_class) { MonoException *exc = nullptr; - Dictionary *ptr = CACHED_METHOD_THUNK(Dictionary, GetPtr).invoke(p_obj, &exc); + Array *ptr = CACHED_METHOD_THUNK(Array, GetPtr).invoke(p_obj, &exc); UNHANDLED_EXCEPTION(exc); return ptr ? Variant(*ptr) : Variant(); } - - // The order in which we check the following interfaces is very important (dictionaries and generics first) - - MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type_class->get_mono_type()); - - if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype)) { - return GDMonoUtils::Marshal::generic_idictionary_to_dictionary(p_obj); - } - - if (type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) { - return GDMonoUtils::Marshal::idictionary_to_dictionary(p_obj); - } - - if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype)) { - return GDMonoUtils::Marshal::enumerable_to_array(p_obj); - } - - if (type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) { - return GDMonoUtils::Marshal::enumerable_to_array(p_obj); - } } break; case MONO_TYPE_GENERICINST: { MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), p_type.type_class->get_mono_type()); + // Godot.Collections.Dictionary<TKey, TValue> if (GDMonoUtils::Marshal::type_is_generic_dictionary(reftype)) { MonoException *exc = nullptr; MonoObject *ret = p_type.type_class->get_method("GetPtr")->invoke(p_obj, &exc); @@ -1002,6 +979,7 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type return *unbox<Dictionary *>(ret); } + // Godot.Collections.Array<T> if (GDMonoUtils::Marshal::type_is_generic_array(reftype)) { MonoException *exc = nullptr; MonoObject *ret = p_type.type_class->get_method("GetPtr")->invoke(p_obj, &exc); @@ -1009,22 +987,19 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type return *unbox<Array *>(ret); } - // The order in which we check the following interfaces is very important (dictionaries and generics first) - - if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype)) { - return GDMonoUtils::Marshal::generic_idictionary_to_dictionary(p_obj); - } - - if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) { - return GDMonoUtils::Marshal::idictionary_to_dictionary(p_obj); + // System.Collections.Generic.Dictionary<TKey, TValue> + if (GDMonoUtils::Marshal::type_is_system_generic_dictionary(reftype)) { + MonoReflectionType *key_reftype = nullptr; + MonoReflectionType *value_reftype = nullptr; + GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype); + return system_generic_dict_to_Dictionary(p_obj, p_type.type_class, key_reftype, value_reftype); } - if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype)) { - return GDMonoUtils::Marshal::enumerable_to_array(p_obj); - } - - if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) { - return GDMonoUtils::Marshal::enumerable_to_array(p_obj); + // System.Collections.Generic.List<T> + if (GDMonoUtils::Marshal::type_is_system_generic_list(reftype)) { + MonoReflectionType *elem_reftype = nullptr; + GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype); + return system_generic_list_to_Array(p_obj, p_type.type_class, elem_reftype); } } break; } @@ -1081,6 +1056,80 @@ String mono_object_to_variant_string(MonoObject *p_obj, MonoException **r_exc) { } } +MonoObject *Dictionary_to_system_generic_dict(const Dictionary &p_dict, GDMonoClass *p_class, MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype) { + String ctor_desc = ":.ctor(System.Collections.Generic.IDictionary`2<" + GDMonoUtils::get_type_desc(p_key_reftype) + + ", " + GDMonoUtils::get_type_desc(p_value_reftype) + ">)"; + GDMonoMethod *ctor = p_class->get_method_with_desc(ctor_desc, true); + CRASH_COND(ctor == nullptr); + + MonoObject *mono_object = mono_object_new(mono_domain_get(), p_class->get_mono_ptr()); + ERR_FAIL_NULL_V(mono_object, nullptr); + + GDMonoClass *godot_dict_class = GDMonoUtils::Marshal::make_generic_dictionary_type(p_key_reftype, p_value_reftype); + MonoObject *godot_dict = GDMonoUtils::create_managed_from(p_dict, godot_dict_class); + + void *ctor_args[1] = { godot_dict }; + + MonoException *exc = nullptr; + ctor->invoke_raw(mono_object, ctor_args, &exc); + UNHANDLED_EXCEPTION(exc); + + return mono_object; +} + +Dictionary system_generic_dict_to_Dictionary(MonoObject *p_obj, [[maybe_unused]] GDMonoClass *p_class, MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype) { + GDMonoClass *godot_dict_class = GDMonoUtils::Marshal::make_generic_dictionary_type(p_key_reftype, p_value_reftype); + String ctor_desc = ":.ctor(System.Collections.Generic.IDictionary`2<" + GDMonoUtils::get_type_desc(p_key_reftype) + + ", " + GDMonoUtils::get_type_desc(p_value_reftype) + ">)"; + GDMonoMethod *godot_dict_ctor = godot_dict_class->get_method_with_desc(ctor_desc, true); + CRASH_COND(godot_dict_ctor == nullptr); + + MonoObject *godot_dict = mono_object_new(mono_domain_get(), godot_dict_class->get_mono_ptr()); + ERR_FAIL_NULL_V(godot_dict, Dictionary()); + + void *ctor_args[1] = { p_obj }; + + MonoException *exc = nullptr; + godot_dict_ctor->invoke_raw(godot_dict, ctor_args, &exc); + UNHANDLED_EXCEPTION(exc); + + exc = nullptr; + MonoObject *ret = godot_dict_class->get_method("GetPtr")->invoke(godot_dict, &exc); + UNHANDLED_EXCEPTION(exc); + + return *unbox<Dictionary *>(ret); +} + +MonoObject *Array_to_system_generic_list(const Array &p_array, GDMonoClass *p_class, MonoReflectionType *p_elem_reftype) { + GDMonoClass *elem_class = ManagedType::from_reftype(p_elem_reftype).type_class; + + String ctor_desc = ":.ctor(System.Collections.Generic.IEnumerable`1<" + elem_class->get_type_desc() + ">)"; + GDMonoMethod *ctor = p_class->get_method_with_desc(ctor_desc, true); + CRASH_COND(ctor == nullptr); + + MonoObject *mono_object = mono_object_new(mono_domain_get(), p_class->get_mono_ptr()); + ERR_FAIL_NULL_V(mono_object, nullptr); + + void *ctor_args[1] = { Array_to_mono_array(p_array, elem_class) }; + + MonoException *exc = nullptr; + ctor->invoke_raw(mono_object, ctor_args, &exc); + UNHANDLED_EXCEPTION(exc); + + return mono_object; +} + +Array system_generic_list_to_Array(MonoObject *p_obj, GDMonoClass *p_class, [[maybe_unused]] MonoReflectionType *p_elem_reftype) { + GDMonoMethod *to_array = p_class->get_method("ToArray", 0); + CRASH_COND(to_array == nullptr); + + MonoException *exc = nullptr; + MonoArray *mono_array = (MonoArray *)to_array->invoke_raw(p_obj, nullptr, &exc); + UNHANDLED_EXCEPTION(exc); + + return mono_array_to_Array(mono_array); +} + MonoArray *Array_to_mono_array(const Array &p_array) { int length = p_array.size(); MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), length); @@ -1093,6 +1142,18 @@ MonoArray *Array_to_mono_array(const Array &p_array) { return ret; } +MonoArray *Array_to_mono_array(const Array &p_array, GDMonoClass *p_array_type_class) { + int length = p_array.size(); + MonoArray *ret = mono_array_new(mono_domain_get(), p_array_type_class->get_mono_ptr(), length); + + for (int i = 0; i < length; i++) { + MonoObject *boxed = variant_to_mono_object(p_array[i]); + mono_array_setref(ret, i, boxed); + } + + return ret; +} + Array mono_array_to_Array(MonoArray *p_array) { Array ret; if (!p_array) diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h index 8b405291a7..f2d887e6d6 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.h +++ b/modules/mono/mono_gd/gd_mono_marshal.h @@ -123,9 +123,18 @@ Variant mono_object_to_variant_no_err(MonoObject *p_obj, const ManagedType &p_ty /// If the MonoObject* cannot be converted to Variant, then 'ToString()' is called instead. String mono_object_to_variant_string(MonoObject *p_obj, MonoException **r_exc); +// System.Collections.Generic + +MonoObject *Dictionary_to_system_generic_dict(const Dictionary &p_dict, GDMonoClass *p_class, MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype); +Dictionary system_generic_dict_to_Dictionary(MonoObject *p_obj, GDMonoClass *p_class, MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype); + +MonoObject *Array_to_system_generic_list(const Array &p_array, GDMonoClass *p_class, MonoReflectionType *p_elem_reftype); +Array system_generic_list_to_Array(MonoObject *p_obj, GDMonoClass *p_class, MonoReflectionType *p_elem_reftype); + // Array MonoArray *Array_to_mono_array(const Array &p_array); +MonoArray *Array_to_mono_array(const Array &p_array, GDMonoClass *p_array_type_class); Array mono_array_to_Array(MonoArray *p_array); // PackedInt32Array diff --git a/modules/mono/mono_gd/gd_mono_method.cpp b/modules/mono/mono_gd/gd_mono_method.cpp index c8cc5247c6..432aa74a6f 100644 --- a/modules/mono/mono_gd/gd_mono_method.cpp +++ b/modules/mono/mono_gd/gd_mono_method.cpp @@ -30,13 +30,14 @@ #include "gd_mono_method.h" +#include <mono/metadata/attrdefs.h> +#include <mono/metadata/debug-helpers.h> + #include "gd_mono_cache.h" #include "gd_mono_class.h" #include "gd_mono_marshal.h" #include "gd_mono_utils.h" -#include <mono/metadata/attrdefs.h> - void GDMonoMethod::_update_signature() { // Apparently MonoMethodSignature needs not to be freed. // mono_method_signature caches the result, we don't need to cache it ourselves. diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp index 00119ced88..f9d492dabb 100644 --- a/modules/mono/mono_gd/gd_mono_utils.cpp +++ b/modules/mono/mono_gd/gd_mono_utils.cpp @@ -30,6 +30,7 @@ #include "gd_mono_utils.h" +#include <mono/metadata/debug-helpers.h> #include <mono/metadata/exception.h> #include "core/debugger/engine_debugger.h" @@ -358,6 +359,14 @@ MonoDomain *create_domain(const String &p_friendly_name) { return domain; } +String get_type_desc(MonoType *p_type) { + return mono_type_full_name(p_type); +} + +String get_type_desc(MonoReflectionType *p_reftype) { + return get_type_desc(mono_reflection_type_get_type(p_reftype)); +} + String get_exception_name_and_message(MonoException *p_exc) { String res; @@ -584,75 +593,56 @@ bool type_is_generic_dictionary(MonoReflectionType *p_reftype) { return (bool)res; } -void array_get_element_type(MonoReflectionType *p_array_reftype, MonoReflectionType **r_elem_reftype) { - MonoException *exc = nullptr; - CACHED_METHOD_THUNK(MarshalUtils, ArrayGetElementType).invoke(p_array_reftype, r_elem_reftype, &exc); - UNHANDLED_EXCEPTION(exc); -} - -void dictionary_get_key_value_types(MonoReflectionType *p_dict_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype) { - MonoException *exc = nullptr; - CACHED_METHOD_THUNK(MarshalUtils, DictionaryGetKeyValueTypes).invoke(p_dict_reftype, r_key_reftype, r_value_reftype, &exc); - UNHANDLED_EXCEPTION(exc); -} - -bool generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype) { +bool type_is_system_generic_list(MonoReflectionType *p_reftype) { NO_GLUE_RET(false); MonoException *exc = nullptr; - MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, GenericIEnumerableIsAssignableFromType).invoke(p_reftype, &exc); + MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, TypeIsSystemGenericList).invoke(p_reftype, &exc); UNHANDLED_EXCEPTION(exc); return (bool)res; } -bool generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype) { +bool type_is_system_generic_dictionary(MonoReflectionType *p_reftype) { NO_GLUE_RET(false); MonoException *exc = nullptr; - MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, GenericIDictionaryIsAssignableFromType).invoke(p_reftype, &exc); + MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, TypeIsSystemGenericDictionary).invoke(p_reftype, &exc); UNHANDLED_EXCEPTION(exc); return (bool)res; } -bool generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_elem_reftype) { +bool type_is_generic_ienumerable(MonoReflectionType *p_reftype) { NO_GLUE_RET(false); MonoException *exc = nullptr; - MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, GenericIEnumerableIsAssignableFromType_with_info).invoke(p_reftype, r_elem_reftype, &exc); + MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, TypeIsGenericIEnumerable).invoke(p_reftype, &exc); UNHANDLED_EXCEPTION(exc); return (bool)res; } -bool generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype) { +bool type_is_generic_icollection(MonoReflectionType *p_reftype) { NO_GLUE_RET(false); MonoException *exc = nullptr; - MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, GenericIDictionaryIsAssignableFromType_with_info).invoke(p_reftype, r_key_reftype, r_value_reftype, &exc); + MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, TypeIsGenericICollection).invoke(p_reftype, &exc); UNHANDLED_EXCEPTION(exc); return (bool)res; } -Array enumerable_to_array(MonoObject *p_enumerable) { - NO_GLUE_RET(Array()); - Array result; +bool type_is_generic_idictionary(MonoReflectionType *p_reftype) { + NO_GLUE_RET(false); MonoException *exc = nullptr; - CACHED_METHOD_THUNK(MarshalUtils, EnumerableToArray).invoke(p_enumerable, &result, &exc); + MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, TypeIsGenericIDictionary).invoke(p_reftype, &exc); UNHANDLED_EXCEPTION(exc); - return result; + return (bool)res; } -Dictionary idictionary_to_dictionary(MonoObject *p_idictionary) { - NO_GLUE_RET(Dictionary()); - Dictionary result; +void array_get_element_type(MonoReflectionType *p_array_reftype, MonoReflectionType **r_elem_reftype) { MonoException *exc = nullptr; - CACHED_METHOD_THUNK(MarshalUtils, IDictionaryToDictionary).invoke(p_idictionary, &result, &exc); + CACHED_METHOD_THUNK(MarshalUtils, ArrayGetElementType).invoke(p_array_reftype, r_elem_reftype, &exc); UNHANDLED_EXCEPTION(exc); - return result; } -Dictionary generic_idictionary_to_dictionary(MonoObject *p_generic_idictionary) { - NO_GLUE_RET(Dictionary()); - Dictionary result; +void dictionary_get_key_value_types(MonoReflectionType *p_dict_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype) { MonoException *exc = nullptr; - CACHED_METHOD_THUNK(MarshalUtils, GenericIDictionaryToDictionary).invoke(p_generic_idictionary, &result, &exc); + CACHED_METHOD_THUNK(MarshalUtils, DictionaryGetKeyValueTypes).invoke(p_dict_reftype, r_key_reftype, r_value_reftype, &exc); UNHANDLED_EXCEPTION(exc); - return result; } GDMonoClass *make_generic_array_type(MonoReflectionType *p_elem_reftype) { diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h index b850e1be9b..e3011ade5d 100644 --- a/modules/mono/mono_gd/gd_mono_utils.h +++ b/modules/mono/mono_gd/gd_mono_utils.h @@ -52,22 +52,18 @@ namespace Marshal { bool type_is_generic_array(MonoReflectionType *p_reftype); bool type_is_generic_dictionary(MonoReflectionType *p_reftype); +bool type_is_system_generic_list(MonoReflectionType *p_reftype); +bool type_is_system_generic_dictionary(MonoReflectionType *p_reftype); +bool type_is_generic_ienumerable(MonoReflectionType *p_reftype); +bool type_is_generic_icollection(MonoReflectionType *p_reftype); +bool type_is_generic_idictionary(MonoReflectionType *p_reftype); void array_get_element_type(MonoReflectionType *p_array_reftype, MonoReflectionType **r_elem_reftype); void dictionary_get_key_value_types(MonoReflectionType *p_dict_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype); -bool generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype); -bool generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype); -bool generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_elem_reftype); -bool generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype); - GDMonoClass *make_generic_array_type(MonoReflectionType *p_elem_reftype); GDMonoClass *make_generic_dictionary_type(MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype); -Array enumerable_to_array(MonoObject *p_enumerable); -Dictionary idictionary_to_dictionary(MonoObject *p_idictionary); -Dictionary generic_idictionary_to_dictionary(MonoObject *p_generic_idictionary); - } // namespace Marshal _FORCE_INLINE_ void hash_combine(uint32_t &p_hash, const uint32_t &p_with_hash) { @@ -115,6 +111,9 @@ MonoObject *create_managed_from(const Dictionary &p_from, GDMonoClass *p_class); MonoDomain *create_domain(const String &p_friendly_name); +String get_type_desc(MonoType *p_type); +String get_type_desc(MonoReflectionType *p_reftype); + String get_exception_name_and_message(MonoException *p_exc); void set_exception_message(MonoException *p_exc, String message); diff --git a/modules/opensimplex/noise_texture.cpp b/modules/opensimplex/noise_texture.cpp index ec67030a65..2018f90e9f 100644 --- a/modules/opensimplex/noise_texture.cpp +++ b/modules/opensimplex/noise_texture.cpp @@ -137,14 +137,19 @@ void NoiseTexture::_queue_update() { Ref<Image> NoiseTexture::_generate_texture() { - if (noise.is_null()) return Ref<Image>(); + // Prevent memdelete due to unref() on other thread. + Ref<OpenSimplexNoise> ref_noise = noise; + + if (ref_noise.is_null()) { + return Ref<Image>(); + } Ref<Image> image; if (seamless) { - image = noise->get_seamless_image(size.x); + image = ref_noise->get_seamless_image(size.x); } else { - image = noise->get_image(size.x, size.y); + image = ref_noise->get_image(size.x, size.y); } if (as_normalmap) { diff --git a/modules/pvr/texture_loader_pvr.cpp b/modules/pvr/texture_loader_pvr.cpp index 10d4d71f5e..a8e8a9a2f1 100644 --- a/modules/pvr/texture_loader_pvr.cpp +++ b/modules/pvr/texture_loader_pvr.cpp @@ -51,7 +51,7 @@ enum PVRFLags { }; -RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) *r_error = ERR_CANT_OPEN; diff --git a/modules/pvr/texture_loader_pvr.h b/modules/pvr/texture_loader_pvr.h index 642323db35..07ef129689 100644 --- a/modules/pvr/texture_loader_pvr.h +++ b/modules/pvr/texture_loader_pvr.h @@ -36,7 +36,7 @@ class ResourceFormatPVR : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path, Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path, Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp index e5fb6f996d..b9f276fb12 100644 --- a/modules/theora/video_stream_theora.cpp +++ b/modules/theora/video_stream_theora.cpp @@ -725,7 +725,7 @@ void VideoStreamTheora::_bind_methods() { //////////// -RES ResourceFormatLoaderTheora::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderTheora::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ); if (!f) { diff --git a/modules/theora/video_stream_theora.h b/modules/theora/video_stream_theora.h index cd7bff7adb..f98368ed8b 100644 --- a/modules/theora/video_stream_theora.h +++ b/modules/theora/video_stream_theora.h @@ -187,7 +187,7 @@ public: class ResourceFormatLoaderTheora : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/upnp/upnp.cpp b/modules/upnp/upnp.cpp index 856f4188aa..988bf3017d 100644 --- a/modules/upnp/upnp.cpp +++ b/modules/upnp/upnp.cpp @@ -44,9 +44,8 @@ bool UPNP::is_common_device(const String &dev) const { } int UPNP::discover(int timeout, int ttl, const String &device_filter) { - ERR_FAIL_COND_V(timeout < 0, UPNP_RESULT_INVALID_PARAM); - ERR_FAIL_COND_V(ttl < 0, UPNP_RESULT_INVALID_PARAM); - ERR_FAIL_COND_V(ttl > 255, UPNP_RESULT_INVALID_PARAM); + ERR_FAIL_COND_V_MSG(timeout < 0, UPNP_RESULT_INVALID_PARAM, "The response's wait time can't be negative."); + ERR_FAIL_COND_V_MSG(ttl < 0 || ttl > 255, UPNP_RESULT_INVALID_PARAM, "The time-to-live must be set between 0 and 255 (inclusive)."); devices.clear(); @@ -264,7 +263,7 @@ void UPNP::clear_devices() { } Ref<UPNPDevice> UPNP::get_gateway() const { - ERR_FAIL_COND_V(devices.size() < 1, nullptr); + ERR_FAIL_COND_V_MSG(devices.size() < 1, nullptr, "Couldn't find any UPNPDevices."); for (int i = 0; i < devices.size(); i++) { Ref<UPNPDevice> dev = get_device(i); diff --git a/modules/upnp/upnp_device.cpp b/modules/upnp/upnp_device.cpp index c21826d14d..40eb6106a0 100644 --- a/modules/upnp/upnp_device.cpp +++ b/modules/upnp/upnp_device.cpp @@ -35,7 +35,7 @@ #include <miniupnpc/upnpcommands.h> String UPNPDevice::query_external_address() const { - ERR_FAIL_COND_V(!is_valid_gateway(), ""); + ERR_FAIL_COND_V_MSG(!is_valid_gateway(), "", "The Internet Gateway Device must be valid."); char addr[16]; int i = UPNP_GetExternalIPAddress( @@ -43,17 +43,17 @@ String UPNPDevice::query_external_address() const { igd_service_type.utf8().get_data(), (char *)&addr); - ERR_FAIL_COND_V(i != UPNPCOMMAND_SUCCESS, ""); + ERR_FAIL_COND_V_MSG(i != UPNPCOMMAND_SUCCESS, "", "Couldn't get external IP address."); return String(addr); } int UPNPDevice::add_port_mapping(int port, int port_internal, String desc, String proto, int duration) const { - ERR_FAIL_COND_V(!is_valid_gateway(), UPNP::UPNP_RESULT_INVALID_GATEWAY); - ERR_FAIL_COND_V(port < 1 || port > 65535, UPNP::UPNP_RESULT_INVALID_PORT); - ERR_FAIL_COND_V(port_internal < 0 || port_internal > 65535, UPNP::UPNP_RESULT_INVALID_PORT); // Needs to allow 0 because 0 signifies "use external port as internal port" - ERR_FAIL_COND_V(proto != "UDP" && proto != "TCP", UPNP::UPNP_RESULT_INVALID_PROTOCOL); - ERR_FAIL_COND_V(duration < 0, UPNP::UPNP_RESULT_INVALID_DURATION); + ERR_FAIL_COND_V_MSG(!is_valid_gateway(), UPNP::UPNP_RESULT_INVALID_GATEWAY, "The Internet Gateway Device must be valid."); + ERR_FAIL_COND_V_MSG(port < 1 || port > 65535, UPNP::UPNP_RESULT_INVALID_PORT, "The port number must be set between 1 and 65535 (inclusive)."); + ERR_FAIL_COND_V_MSG(port_internal < 0 || port_internal > 65535, UPNP::UPNP_RESULT_INVALID_PORT, "The port number must be set between 0 and 65535 (inclusive)."); // Needs to allow 0 because 0 signifies "use external port as internal port" + ERR_FAIL_COND_V_MSG(proto != "UDP" && proto != "TCP", UPNP::UPNP_RESULT_INVALID_PROTOCOL, "The protocol must be either TCP or UDP."); + ERR_FAIL_COND_V_MSG(duration < 0, UPNP::UPNP_RESULT_INVALID_DURATION, "The port mapping's lease duration can't be negative."); if (port_internal < 1) { port_internal = port; @@ -70,14 +70,14 @@ int UPNPDevice::add_port_mapping(int port, int port_internal, String desc, Strin nullptr, // Remote host, always nullptr as IGDs don't support it duration > 0 ? itos(duration).utf8().get_data() : nullptr); - ERR_FAIL_COND_V(i != UPNPCOMMAND_SUCCESS, UPNP::upnp_result(i)); + ERR_FAIL_COND_V_MSG(i != UPNPCOMMAND_SUCCESS, UPNP::upnp_result(i), "Couldn't add port mapping."); return UPNP::UPNP_RESULT_SUCCESS; } int UPNPDevice::delete_port_mapping(int port, String proto) const { - ERR_FAIL_COND_V(port < 1 || port > 65535, UPNP::UPNP_RESULT_INVALID_PORT); - ERR_FAIL_COND_V(proto != "UDP" && proto != "TCP", UPNP::UPNP_RESULT_INVALID_PROTOCOL); + ERR_FAIL_COND_V_MSG(port < 1 || port > 65535, UPNP::UPNP_RESULT_INVALID_PORT, "The port number must be set between 1 and 65535 (inclusive)."); + ERR_FAIL_COND_V_MSG(proto != "UDP" && proto != "TCP", UPNP::UPNP_RESULT_INVALID_PROTOCOL, "The protocol must be either TCP or UDP."); int i = UPNP_DeletePortMapping( igd_control_url.utf8().get_data(), @@ -87,7 +87,7 @@ int UPNPDevice::delete_port_mapping(int port, String proto) const { nullptr // Remote host, always nullptr as IGDs don't support it ); - ERR_FAIL_COND_V(i != UPNPCOMMAND_SUCCESS, UPNP::upnp_result(i)); + ERR_FAIL_COND_V_MSG(i != UPNPCOMMAND_SUCCESS, UPNP::upnp_result(i), "Couldn't delete port mapping."); return UPNP::UPNP_RESULT_SUCCESS; } diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index b52dfe1733..fe1d82f977 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -727,6 +727,26 @@ void VisualScript::rename_variable(const StringName &p_name, const StringName &p variables[p_new_name] = variables[p_name]; variables.erase(p_name); + + List<StringName> funcs; + get_function_list(&funcs); + for (List<StringName>::Element *F = funcs.front(); F; F = F->next()) { // loop through all the functions + List<int> ids; + get_node_list(F->get(), &ids); + for (List<int>::Element *E = ids.front(); E; E = E->next()) { + Ref<VisualScriptVariableGet> nodeget = get_node(F->get(), E->get()); + if (nodeget.is_valid()) { + if (nodeget->get_variable() == p_name) + nodeget->set_variable(p_new_name); + } else { + Ref<VisualScriptVariableSet> nodeset = get_node(F->get(), E->get()); + if (nodeset.is_valid()) { + if (nodeset->get_variable() == p_name) + nodeset->set_variable(p_new_name); + } + } + } + } } void VisualScript::add_custom_signal(const StringName &p_name) { @@ -1440,6 +1460,10 @@ VisualScript::VisualScript() { is_tool_script = false; } +bool VisualScript::inherits_script(const Ref<Script> &p_script) const { + return this == p_script.ptr(); //there is no inheritance in visual scripts, so this is enough +} + StringName VisualScript::get_default_func() const { return StringName("f_312843592"); } diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h index 29309aa156..c154e56703 100644 --- a/modules/visual_script/visual_script.h +++ b/modules/visual_script/visual_script.h @@ -272,6 +272,8 @@ protected: static void _bind_methods(); public: + bool inherits_script(const Ref<Script> &p_script) const; + // TODO: Remove it in future when breaking changes are acceptable StringName get_default_func() const; void add_function(const StringName &p_name); diff --git a/modules/visual_script/visual_script_builtin_funcs.cpp b/modules/visual_script/visual_script_builtin_funcs.cpp index 39d8f7c082..bb291b1cb6 100644 --- a/modules/visual_script/visual_script_builtin_funcs.cpp +++ b/modules/visual_script/visual_script_builtin_funcs.cpp @@ -506,10 +506,12 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons case MATH_CEIL: { t = Variant::FLOAT; } break; - case MATH_POSMOD: - case MATH_ROUND: { + case MATH_POSMOD: { t = Variant::INT; } break; + case MATH_ROUND: { + t = Variant::FLOAT; + } break; case MATH_ABS: { t = Variant::NIL; } break; diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index ab528fac30..59b1bcdd96 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -350,8 +350,11 @@ static Color _color_from_type(Variant::Type p_type, bool dark_theme = true) { case Variant::STRING: color = Color(0.42, 0.65, 0.93); break; case Variant::VECTOR2: color = Color(0.74, 0.57, 0.95); break; + case Variant::VECTOR2I: color = Color(0.74, 0.57, 0.95); break; case Variant::RECT2: color = Color(0.95, 0.57, 0.65); break; + case Variant::RECT2I: color = Color(0.95, 0.57, 0.65); break; case Variant::VECTOR3: color = Color(0.84, 0.49, 0.93); break; + case Variant::VECTOR3I: color = Color(0.84, 0.49, 0.93); break; case Variant::TRANSFORM2D: color = Color(0.77, 0.93, 0.41); break; case Variant::PLANE: color = Color(0.97, 0.44, 0.44); break; case Variant::QUAT: color = Color(0.93, 0.41, 0.64); break; @@ -389,8 +392,11 @@ static Color _color_from_type(Variant::Type p_type, bool dark_theme = true) { case Variant::STRING: color = Color(0.27, 0.56, 0.91); break; case Variant::VECTOR2: color = Color(0.68, 0.46, 0.93); break; + case Variant::VECTOR2I: color = Color(0.68, 0.46, 0.93); break; case Variant::RECT2: color = Color(0.93, 0.46, 0.56); break; + case Variant::RECT2I: color = Color(0.93, 0.46, 0.56); break; case Variant::VECTOR3: color = Color(0.86, 0.42, 0.93); break; + case Variant::VECTOR3I: color = Color(0.86, 0.42, 0.93); break; case Variant::TRANSFORM2D: color = Color(0.59, 0.81, 0.1); break; case Variant::PLANE: color = Color(0.97, 0.44, 0.44); break; case Variant::QUAT: color = Color(0.93, 0.41, 0.64); break; @@ -510,8 +516,11 @@ void VisualScriptEditor::_update_graph(int p_only_id) { Control::get_theme_icon("float", "EditorIcons"), Control::get_theme_icon("String", "EditorIcons"), Control::get_theme_icon("Vector2", "EditorIcons"), + Control::get_theme_icon("Vector2i", "EditorIcons"), Control::get_theme_icon("Rect2", "EditorIcons"), + Control::get_theme_icon("Rect2i", "EditorIcons"), Control::get_theme_icon("Vector3", "EditorIcons"), + Control::get_theme_icon("Vector3i", "EditorIcons"), Control::get_theme_icon("Transform2D", "EditorIcons"), Control::get_theme_icon("Plane", "EditorIcons"), Control::get_theme_icon("Quat", "EditorIcons"), @@ -522,6 +531,8 @@ void VisualScriptEditor::_update_graph(int p_only_id) { Control::get_theme_icon("NodePath", "EditorIcons"), Control::get_theme_icon("RID", "EditorIcons"), Control::get_theme_icon("MiniObject", "EditorIcons"), + Control::get_theme_icon("Callable", "EditorIcons"), + Control::get_theme_icon("Signal", "EditorIcons"), Control::get_theme_icon("Dictionary", "EditorIcons"), Control::get_theme_icon("Array", "EditorIcons"), Control::get_theme_icon("PackedByteArray", "EditorIcons"), @@ -974,8 +985,11 @@ void VisualScriptEditor::_update_members() { Control::get_theme_icon("float", "EditorIcons"), Control::get_theme_icon("String", "EditorIcons"), Control::get_theme_icon("Vector2", "EditorIcons"), + Control::get_theme_icon("Vector2i", "EditorIcons"), Control::get_theme_icon("Rect2", "EditorIcons"), + Control::get_theme_icon("Rect2i", "EditorIcons"), Control::get_theme_icon("Vector3", "EditorIcons"), + Control::get_theme_icon("Vector3i", "EditorIcons"), Control::get_theme_icon("Transform2D", "EditorIcons"), Control::get_theme_icon("Plane", "EditorIcons"), Control::get_theme_icon("Quat", "EditorIcons"), @@ -986,6 +1000,8 @@ void VisualScriptEditor::_update_members() { Control::get_theme_icon("NodePath", "EditorIcons"), Control::get_theme_icon("RID", "EditorIcons"), Control::get_theme_icon("MiniObject", "EditorIcons"), + Control::get_theme_icon("Callable", "EditorIcons"), + Control::get_theme_icon("Signal", "EditorIcons"), Control::get_theme_icon("Dictionary", "EditorIcons"), Control::get_theme_icon("Array", "EditorIcons"), Control::get_theme_icon("PackedByteArray", "EditorIcons"), @@ -1155,6 +1171,8 @@ void VisualScriptEditor::_member_edited() { undo_redo->add_undo_method(script.ptr(), "rename_variable", new_name, name); undo_redo->add_do_method(this, "_update_members"); undo_redo->add_undo_method(this, "_update_members"); + undo_redo->add_do_method(this, "_update_graph"); + undo_redo->add_undo_method(this, "_update_graph"); undo_redo->add_do_method(this, "emit_signal", "edited_script_changed"); undo_redo->add_undo_method(this, "emit_signal", "edited_script_changed"); undo_redo->commit_action(); @@ -3917,7 +3935,9 @@ void VisualScriptEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_READY: { variable_editor->connect("changed", callable_mp(this, &VisualScriptEditor::_update_members)); + variable_editor->connect("changed", callable_mp(this, &VisualScriptEditor::_update_graph), varray(-1), CONNECT_DEFERRED); signal_editor->connect("changed", callable_mp(this, &VisualScriptEditor::_update_members)); + signal_editor->connect("changed", callable_mp(this, &VisualScriptEditor::_update_graph), varray(-1), CONNECT_DEFERRED); [[fallthrough]]; } case NOTIFICATION_THEME_CHANGED: { @@ -4629,6 +4649,7 @@ void VisualScriptEditor::_bind_methods() { ClassDB::bind_method("_input", &VisualScriptEditor::_input); ClassDB::bind_method("_update_graph_connections", &VisualScriptEditor::_update_graph_connections); + ClassDB::bind_method("_update_members", &VisualScriptEditor::_update_members); ClassDB::bind_method("_generic_search", &VisualScriptEditor::_generic_search); } diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index 97c2686cd5..c860e08943 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -4184,9 +4184,12 @@ void register_visual_script_nodes() { VisualScriptLanguage::singleton->add_register_func("operators/logic/select", create_node_generic<VisualScriptSelect>); VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR2), create_node_deconst_typed<Variant::Type::VECTOR2>); + VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR2I), create_node_deconst_typed<Variant::Type::VECTOR2I>); VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR3), create_node_deconst_typed<Variant::Type::VECTOR3>); + VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR3I), create_node_deconst_typed<Variant::Type::VECTOR3I>); VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::COLOR), create_node_deconst_typed<Variant::Type::COLOR>); VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::RECT2), create_node_deconst_typed<Variant::Type::RECT2>); + VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::RECT2I), create_node_deconst_typed<Variant::Type::RECT2I>); VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::TRANSFORM2D), create_node_deconst_typed<Variant::Type::TRANSFORM2D>); VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::PLANE), create_node_deconst_typed<Variant::Type::PLANE>); VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::QUAT), create_node_deconst_typed<Variant::Type::QUAT>); diff --git a/modules/webm/video_stream_webm.cpp b/modules/webm/video_stream_webm.cpp index ca78d664f7..a2d0f78f5f 100644 --- a/modules/webm/video_stream_webm.cpp +++ b/modules/webm/video_stream_webm.cpp @@ -474,7 +474,7 @@ void VideoStreamWebm::set_audio_track(int p_track) { //////////// -RES ResourceFormatLoaderWebm::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderWebm::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ); if (!f) { diff --git a/modules/webm/video_stream_webm.h b/modules/webm/video_stream_webm.h index bc209e0057..6677fb85aa 100644 --- a/modules/webm/video_stream_webm.h +++ b/modules/webm/video_stream_webm.h @@ -128,7 +128,7 @@ public: class ResourceFormatLoaderWebm : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/platform/android/SCsub b/platform/android/SCsub index f39eb8b889..ec42bc42b5 100644 --- a/platform/android/SCsub +++ b/platform/android/SCsub @@ -17,8 +17,8 @@ android_files = [ "java_godot_io_wrapper.cpp", "jni_utils.cpp", "android_keys_utils.cpp", - "vulkan/vk_renderer_jni.cpp", - "plugin/godot_plugin_jni.cpp", + "display_server_android.cpp", + "vulkan/vulkan_context_android.cpp", ] env_android = env.Clone() diff --git a/platform/android/api/api.cpp b/platform/android/api/api.cpp index ef11b12971..4fe868d4f0 100644 --- a/platform/android/api/api.cpp +++ b/platform/android/api/api.cpp @@ -32,6 +32,7 @@ #include "core/engine.h" #include "java_class_wrapper.h" +#include "jni_singleton.h" #if !defined(ANDROID_ENABLED) static JavaClassWrapper *java_class_wrapper = nullptr; @@ -40,7 +41,11 @@ static JavaClassWrapper *java_class_wrapper = nullptr; void register_android_api() { #if !defined(ANDROID_ENABLED) + // On Android platforms, the `java_class_wrapper` instantiation and the + // `JNISingleton` registration occurs in + // `platform/android/java_godot_lib_jni.cpp#Java_org_godotengine_godot_GodotLib_setup` java_class_wrapper = memnew(JavaClassWrapper); // Dummy + ClassDB::register_class<JNISingleton>(); #endif ClassDB::register_class<JavaClass>(); diff --git a/platform/android/api/jni_singleton.h b/platform/android/api/jni_singleton.h new file mode 100644 index 0000000000..917c3f5029 --- /dev/null +++ b/platform/android/api/jni_singleton.h @@ -0,0 +1,242 @@ +/*************************************************************************/ +/* jni_singleton.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef JNI_SINGLETON_H +#define JNI_SINGLETON_H + +#include <core/engine.h> +#include <core/variant.h> +#ifdef ANDROID_ENABLED +#include <platform/android/jni_utils.h> +#endif + +class JNISingleton : public Object { + + GDCLASS(JNISingleton, Object); + +#ifdef ANDROID_ENABLED + struct MethodData { + + jmethodID method; + Variant::Type ret_type; + Vector<Variant::Type> argtypes; + }; + + jobject instance; + Map<StringName, MethodData> method_map; +#endif + +public: + virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { +#ifdef ANDROID_ENABLED + Map<StringName, MethodData>::Element *E = method_map.find(p_method); + + // Check the method we're looking for is in the JNISingleton map and that + // the arguments match. + bool call_error = !E || E->get().argtypes.size() != p_argcount; + if (!call_error) { + for (int i = 0; i < p_argcount; i++) { + + if (!Variant::can_convert(p_args[i]->get_type(), E->get().argtypes[i])) { + call_error = true; + break; + } + } + } + + if (call_error) { + // The method is not in this map, defaulting to the regular instance calls. + return Object::call(p_method, p_args, p_argcount, r_error); + } + + ERR_FAIL_COND_V(!instance, Variant()); + + r_error.error = Callable::CallError::CALL_OK; + + jvalue *v = nullptr; + + if (p_argcount) { + + v = (jvalue *)alloca(sizeof(jvalue) * p_argcount); + } + + JNIEnv *env = ThreadAndroid::get_env(); + + int res = env->PushLocalFrame(16); + + ERR_FAIL_COND_V(res != 0, Variant()); + + List<jobject> to_erase; + for (int i = 0; i < p_argcount; i++) { + + jvalret vr = _variant_to_jvalue(env, E->get().argtypes[i], p_args[i]); + v[i] = vr.val; + if (vr.obj) + to_erase.push_back(vr.obj); + } + + Variant ret; + + switch (E->get().ret_type) { + + case Variant::NIL: { + + env->CallVoidMethodA(instance, E->get().method, v); + } break; + case Variant::BOOL: { + + ret = env->CallBooleanMethodA(instance, E->get().method, v) == JNI_TRUE; + } break; + case Variant::INT: { + + ret = env->CallIntMethodA(instance, E->get().method, v); + } break; + case Variant::FLOAT: { + + ret = env->CallFloatMethodA(instance, E->get().method, v); + } break; + case Variant::STRING: { + + jobject o = env->CallObjectMethodA(instance, E->get().method, v); + ret = jstring_to_string((jstring)o, env); + env->DeleteLocalRef(o); + } break; + case Variant::PACKED_STRING_ARRAY: { + + jobjectArray arr = (jobjectArray)env->CallObjectMethodA(instance, E->get().method, v); + + ret = _jobject_to_variant(env, arr); + + env->DeleteLocalRef(arr); + } break; + case Variant::PACKED_INT32_ARRAY: { + + jintArray arr = (jintArray)env->CallObjectMethodA(instance, E->get().method, v); + + int fCount = env->GetArrayLength(arr); + Vector<int> sarr; + sarr.resize(fCount); + + int *w = sarr.ptrw(); + env->GetIntArrayRegion(arr, 0, fCount, w); + ret = sarr; + env->DeleteLocalRef(arr); + } break; + case Variant::PACKED_FLOAT32_ARRAY: { + + jfloatArray arr = (jfloatArray)env->CallObjectMethodA(instance, E->get().method, v); + + int fCount = env->GetArrayLength(arr); + Vector<float> sarr; + sarr.resize(fCount); + + float *w = sarr.ptrw(); + env->GetFloatArrayRegion(arr, 0, fCount, w); + ret = sarr; + env->DeleteLocalRef(arr); + } break; + +#ifndef _MSC_VER +#warning This is missing 64 bits arrays, I have no idea how to do it in JNI +#endif + case Variant::DICTIONARY: { + + jobject obj = env->CallObjectMethodA(instance, E->get().method, v); + ret = _jobject_to_variant(env, obj); + env->DeleteLocalRef(obj); + + } break; + default: { + + env->PopLocalFrame(nullptr); + ERR_FAIL_V(Variant()); + } break; + } + + while (to_erase.size()) { + env->DeleteLocalRef(to_erase.front()->get()); + to_erase.pop_front(); + } + + env->PopLocalFrame(nullptr); + + return ret; +#else // ANDROID_ENABLED + + // Defaulting to the regular instance calls. + return Object::call(p_method, p_args, p_argcount, r_error); +#endif + } + +#ifdef ANDROID_ENABLED + jobject get_instance() const { + + return instance; + } + + void set_instance(jobject p_instance) { + + instance = p_instance; + } + + void add_method(const StringName &p_name, jmethodID p_method, const Vector<Variant::Type> &p_args, Variant::Type p_ret_type) { + + MethodData md; + md.method = p_method; + md.argtypes = p_args; + md.ret_type = p_ret_type; + method_map[p_name] = md; + } + + void add_signal(const StringName &p_name, const Vector<Variant::Type> &p_args) { + if (p_args.size() == 0) + ADD_SIGNAL(MethodInfo(p_name)); + else if (p_args.size() == 1) + ADD_SIGNAL(MethodInfo(p_name, PropertyInfo(p_args[0], "arg1"))); + else if (p_args.size() == 2) + ADD_SIGNAL(MethodInfo(p_name, PropertyInfo(p_args[0], "arg1"), PropertyInfo(p_args[1], "arg2"))); + else if (p_args.size() == 3) + ADD_SIGNAL(MethodInfo(p_name, PropertyInfo(p_args[0], "arg1"), PropertyInfo(p_args[1], "arg2"), PropertyInfo(p_args[2], "arg3"))); + else if (p_args.size() == 4) + ADD_SIGNAL(MethodInfo(p_name, PropertyInfo(p_args[0], "arg1"), PropertyInfo(p_args[1], "arg2"), PropertyInfo(p_args[2], "arg3"), PropertyInfo(p_args[3], "arg4"))); + else if (p_args.size() == 5) + ADD_SIGNAL(MethodInfo(p_name, PropertyInfo(p_args[0], "arg1"), PropertyInfo(p_args[1], "arg2"), PropertyInfo(p_args[2], "arg3"), PropertyInfo(p_args[3], "arg4"), PropertyInfo(p_args[4], "arg5"))); + } + +#endif + + JNISingleton() { +#ifdef ANDROID_ENABLED + instance = nullptr; +#endif + } +}; + +#endif // JNI_SINGLETON_H diff --git a/platform/android/detect.py b/platform/android/detect.py index ed0643e3b3..6da1e5f3d6 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -25,7 +25,7 @@ def get_opts(): return [ ("ANDROID_NDK_ROOT", "Path to the Android NDK", os.environ.get("ANDROID_NDK_ROOT", 0)), - ("ndk_platform", 'Target platform (android-<api>, e.g. "android-18")', "android-18"), + ("ndk_platform", 'Target platform (android-<api>, e.g. "android-24")', "android-24"), EnumVariable("android_arch", "Target architecture", "armv7", ("armv7", "arm64v8", "x86", "x86_64")), BoolVariable("android_neon", "Enable NEON support (armv7 only)", True), ] @@ -102,7 +102,7 @@ def configure(env): neon_text = "" if env["android_arch"] == "armv7" and env["android_neon"]: neon_text = " (with NEON)" - print("Building for Android (" + env["android_arch"] + ")" + neon_text) + print("Building for Android, platform " + env["ndk_platform"] + " (" + env["android_arch"] + ")" + neon_text) can_vectorize = True if env["android_arch"] == "x86": @@ -314,8 +314,8 @@ def configure(env): ) env.Prepend(CPPPATH=["#platform/android"]) - env.Append(CPPDEFINES=["ANDROID_ENABLED", "UNIX_ENABLED", "NO_FCNTL"]) - env.Append(LIBS=["OpenSLES", "EGL", "GLESv3", "GLESv2", "android", "log", "z", "dl"]) + env.Append(CPPDEFINES=["ANDROID_ENABLED", "UNIX_ENABLED", "VULKAN_ENABLED", "NO_FCNTL"]) + env.Append(LIBS=["OpenSLES", "EGL", "GLESv2", "vulkan", "android", "log", "z", "dl"]) # Return NDK version string in source.properties (adapted from the Chromium project). diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp new file mode 100644 index 0000000000..9534387d35 --- /dev/null +++ b/platform/android/display_server_android.cpp @@ -0,0 +1,655 @@ +/*************************************************************************/ +/* display_server_android.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "display_server_android.h" + +#include "android_keys_utils.h" +#include "core/project_settings.h" +#include "java_godot_io_wrapper.h" +#include "java_godot_wrapper.h" +#include "os_android.h" + +#if defined(OPENGL_ENABLED) +#include "drivers/gles2/rasterizer_gles2.h" +#endif +#if defined(VULKAN_ENABLED) +#include "drivers/vulkan/rendering_device_vulkan.h" +#include "platform/android/vulkan/vulkan_context_android.h" +#include "servers/rendering/rasterizer_rd/rasterizer_rd.h" +#endif + +DisplayServerAndroid *DisplayServerAndroid::get_singleton() { + return (DisplayServerAndroid *)DisplayServer::get_singleton(); +} + +bool DisplayServerAndroid::has_feature(Feature p_feature) const { + switch (p_feature) { + //case FEATURE_CONSOLE_WINDOW: + //case FEATURE_CURSOR_SHAPE: + //case FEATURE_CUSTOM_CURSOR_SHAPE: + //case FEATURE_GLOBAL_MENU: + //case FEATURE_HIDPI: + //case FEATURE_ICON: + //case FEATURE_IME: + //case FEATURE_MOUSE: + //case FEATURE_MOUSE_WARP: + //case FEATURE_NATIVE_DIALOG: + //case FEATURE_NATIVE_ICON: + //case FEATURE_NATIVE_VIDEO: + //case FEATURE_WINDOW_TRANSPARENCY: + case FEATURE_CLIPBOARD: + case FEATURE_KEEP_SCREEN_ON: + case FEATURE_ORIENTATION: + case FEATURE_TOUCHSCREEN: + case FEATURE_VIRTUAL_KEYBOARD: + return true; + default: + return false; + } +} + +String DisplayServerAndroid::get_name() const { + return "Android"; +} + +void DisplayServerAndroid::clipboard_set(const String &p_text) { + GodotJavaWrapper *godot_java = OS_Android::get_singleton()->get_godot_java(); + ERR_FAIL_COND(!godot_java); + + if (godot_java->has_set_clipboard()) { + godot_java->set_clipboard(p_text); + } else { + DisplayServer::clipboard_set(p_text); + } +} + +String DisplayServerAndroid::clipboard_get() const { + GodotJavaWrapper *godot_java = OS_Android::get_singleton()->get_godot_java(); + ERR_FAIL_COND_V(!godot_java, String()); + + if (godot_java->has_get_clipboard()) { + return godot_java->get_clipboard(); + } else { + return DisplayServer::clipboard_get(); + } +} + +void DisplayServerAndroid::screen_set_keep_on(bool p_enable) { + GodotJavaWrapper *godot_java = OS_Android::get_singleton()->get_godot_java(); + ERR_FAIL_COND(!godot_java); + + godot_java->set_keep_screen_on(p_enable); + keep_screen_on = p_enable; +} + +bool DisplayServerAndroid::screen_is_kept_on() const { + return keep_screen_on; +} + +void DisplayServerAndroid::screen_set_orientation(DisplayServer::ScreenOrientation p_orientation, int p_screen) { + GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java(); + ERR_FAIL_COND(!godot_io_java); + + godot_io_java->set_screen_orientation(p_orientation); +} + +DisplayServer::ScreenOrientation DisplayServerAndroid::screen_get_orientation(int p_screen) const { + GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java(); + ERR_FAIL_COND_V(!godot_io_java, SCREEN_LANDSCAPE); + + return (ScreenOrientation)godot_io_java->get_screen_orientation(); +} + +int DisplayServerAndroid::get_screen_count() const { + return 1; +} + +Point2i DisplayServerAndroid::screen_get_position(int p_screen) const { + return Point2i(0, 0); +} + +Size2i DisplayServerAndroid::screen_get_size(int p_screen) const { + return OS_Android::get_singleton()->get_display_size(); +} + +Rect2i DisplayServerAndroid::screen_get_usable_rect(int p_screen) const { + Size2i display_size = OS_Android::get_singleton()->get_display_size(); + return Rect2i(0, 0, display_size.width, display_size.height); +} + +int DisplayServerAndroid::screen_get_dpi(int p_screen) const { + GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java(); + ERR_FAIL_COND_V(!godot_io_java, 0); + + return godot_io_java->get_screen_dpi(); +} + +bool DisplayServerAndroid::screen_is_touchscreen(int p_screen) const { + return true; +} + +void DisplayServerAndroid::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_length) { + GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java(); + ERR_FAIL_COND(!godot_io_java); + + if (godot_io_java->has_vk()) { + godot_io_java->show_vk(p_existing_text, p_max_length); + } else { + ERR_PRINT("Virtual keyboard not available"); + } +} + +void DisplayServerAndroid::virtual_keyboard_hide() { + GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java(); + ERR_FAIL_COND(!godot_io_java); + + if (godot_io_java->has_vk()) { + godot_io_java->hide_vk(); + } else { + ERR_PRINT("Virtual keyboard not available"); + } +} + +int DisplayServerAndroid::virtual_keyboard_get_height() const { + GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java(); + ERR_FAIL_COND_V(!godot_io_java, 0); + + return godot_io_java->get_vk_height(); +} + +void DisplayServerAndroid::window_set_window_event_callback(const Callable &p_callable, DisplayServer::WindowID p_window) { + window_event_callback = p_callable; +} + +void DisplayServerAndroid::window_set_input_event_callback(const Callable &p_callable, DisplayServer::WindowID p_window) { + input_event_callback = p_callable; +} + +void DisplayServerAndroid::window_set_input_text_callback(const Callable &p_callable, DisplayServer::WindowID p_window) { + input_text_callback = p_callable; +} + +void DisplayServerAndroid::window_set_rect_changed_callback(const Callable &p_callable, DisplayServer::WindowID p_window) { + // Not supported on Android. +} + +void DisplayServerAndroid::window_set_drop_files_callback(const Callable &p_callable, DisplayServer::WindowID p_window) { + // Not supported on Android. +} + +void DisplayServerAndroid::_window_callback(const Callable &p_callable, const Variant &p_arg) const { + if (!p_callable.is_null()) { + const Variant *argp = &p_arg; + Variant ret; + Callable::CallError ce; + p_callable.call((const Variant **)&argp, 1, ret, ce); + } +} + +void DisplayServerAndroid::send_window_event(DisplayServer::WindowEvent p_event) const { + _window_callback(window_event_callback, int(p_event)); +} + +void DisplayServerAndroid::send_input_event(const Ref<InputEvent> &p_event) const { + _window_callback(input_event_callback, p_event); +} + +void DisplayServerAndroid::send_input_text(const String &p_text) const { + _window_callback(input_text_callback, p_text); +} + +void DisplayServerAndroid::_dispatch_input_events(const Ref<InputEvent> &p_event) { + DisplayServerAndroid::get_singleton()->send_input_event(p_event); +} + +Vector<DisplayServer::WindowID> DisplayServerAndroid::get_window_list() const { + Vector<WindowID> ret; + ret.push_back(MAIN_WINDOW_ID); + return ret; +} + +DisplayServer::WindowID DisplayServerAndroid::get_window_at_screen_position(const Point2i &p_position) const { + return MAIN_WINDOW_ID; +} + +void DisplayServerAndroid::window_attach_instance_id(ObjectID p_instance, DisplayServer::WindowID p_window) { + window_attached_instance_id = p_instance; +} + +ObjectID DisplayServerAndroid::window_get_attached_instance_id(DisplayServer::WindowID p_window) const { + return window_attached_instance_id; +} + +void DisplayServerAndroid::window_set_title(const String &p_title, DisplayServer::WindowID p_window) { + // Not supported on Android. +} + +int DisplayServerAndroid::window_get_current_screen(DisplayServer::WindowID p_window) const { + return SCREEN_OF_MAIN_WINDOW; +} + +void DisplayServerAndroid::window_set_current_screen(int p_screen, DisplayServer::WindowID p_window) { + // Not supported on Android. +} + +Point2i DisplayServerAndroid::window_get_position(DisplayServer::WindowID p_window) const { + return Point2i(); +} + +void DisplayServerAndroid::window_set_position(const Point2i &p_position, DisplayServer::WindowID p_window) { + // Not supported on Android. +} + +void DisplayServerAndroid::window_set_transient(DisplayServer::WindowID p_window, DisplayServer::WindowID p_parent) { + // Not supported on Android. +} + +void DisplayServerAndroid::window_set_max_size(const Size2i p_size, DisplayServer::WindowID p_window) { + // Not supported on Android. +} + +Size2i DisplayServerAndroid::window_get_max_size(DisplayServer::WindowID p_window) const { + return Size2i(); +} + +void DisplayServerAndroid::window_set_min_size(const Size2i p_size, DisplayServer::WindowID p_window) { + // Not supported on Android. +} + +Size2i DisplayServerAndroid::window_get_min_size(DisplayServer::WindowID p_window) const { + return Size2i(); +} + +void DisplayServerAndroid::window_set_size(const Size2i p_size, DisplayServer::WindowID p_window) { + // Not supported on Android. +} + +Size2i DisplayServerAndroid::window_get_size(DisplayServer::WindowID p_window) const { + return OS_Android::get_singleton()->get_display_size(); +} + +Size2i DisplayServerAndroid::window_get_real_size(DisplayServer::WindowID p_window) const { + return OS_Android::get_singleton()->get_display_size(); +} + +void DisplayServerAndroid::window_set_mode(DisplayServer::WindowMode p_mode, DisplayServer::WindowID p_window) { + // Not supported on Android. +} + +DisplayServer::WindowMode DisplayServerAndroid::window_get_mode(DisplayServer::WindowID p_window) const { + return WINDOW_MODE_FULLSCREEN; +} + +bool DisplayServerAndroid::window_is_maximize_allowed(DisplayServer::WindowID p_window) const { + return false; +} + +void DisplayServerAndroid::window_set_flag(DisplayServer::WindowFlags p_flag, bool p_enabled, DisplayServer::WindowID p_window) { + // Not supported on Android. +} + +bool DisplayServerAndroid::window_get_flag(DisplayServer::WindowFlags p_flag, DisplayServer::WindowID p_window) const { + return false; +} + +void DisplayServerAndroid::window_request_attention(DisplayServer::WindowID p_window) { + // Not supported on Android. +} + +void DisplayServerAndroid::window_move_to_foreground(DisplayServer::WindowID p_window) { + // Not supported on Android. +} + +bool DisplayServerAndroid::window_can_draw(DisplayServer::WindowID p_window) const { + return true; +} + +bool DisplayServerAndroid::can_any_window_draw() const { + return true; +} + +void DisplayServerAndroid::alert(const String &p_alert, const String &p_title) { + GodotJavaWrapper *godot_java = OS_Android::get_singleton()->get_godot_java(); + ERR_FAIL_COND(!godot_java); + + godot_java->alert(p_alert, p_title); +} + +void DisplayServerAndroid::process_events() { + // Nothing to do +} + +Vector<String> DisplayServerAndroid::get_rendering_drivers_func() { + Vector<String> drivers; + +#ifdef OPENGL_ENABLED + drivers.push_back("opengl"); +#endif +#ifdef VULKAN_ENABLED + drivers.push_back("vulkan"); +#endif + + return drivers; +} + +DisplayServer *DisplayServerAndroid::create_func(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { + return memnew(DisplayServerAndroid(p_rendering_driver, p_mode, p_flags, p_resolution, r_error)); +} + +void DisplayServerAndroid::register_android_driver() { + register_create_function("android", create_func, get_rendering_drivers_func); +} + +DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { + rendering_driver = p_rendering_driver; + + // TODO: rendering_driver is broken, change when different drivers are supported again + rendering_driver = "vulkan"; + + keep_screen_on = GLOBAL_GET("display/window/energy_saving/keep_screen_on"); + +#if defined(OPENGL_ENABLED) + if (rendering_driver == "opengl") { + bool gl_initialization_error = false; + + if (RasterizerGLES2::is_viable() == OK) { + RasterizerGLES2::register_config(); + RasterizerGLES2::make_current(); + } else { + gl_initialization_error = true; + } + + if (gl_initialization_error) { + OS::get_singleton()->alert("Your device does not support any of the supported OpenGL versions.\n" + "Please try updating your Android version.", + "Unable to initialize video driver"); + return; + } + } +#endif + +#if defined(VULKAN_ENABLED) + context_vulkan = nullptr; + rendering_device_vulkan = nullptr; + + if (rendering_driver == "vulkan") { + ANativeWindow *native_window = OS_Android::get_singleton()->get_native_window(); + ERR_FAIL_COND(!native_window); + + context_vulkan = memnew(VulkanContextAndroid); + if (context_vulkan->initialize() != OK) { + memdelete(context_vulkan); + context_vulkan = nullptr; + ERR_FAIL_MSG("Failed to initialize Vulkan context"); + } + + Size2i display_size = OS_Android::get_singleton()->get_display_size(); + if (context_vulkan->window_create(native_window, display_size.width, display_size.height) == -1) { + memdelete(context_vulkan); + context_vulkan = nullptr; + ERR_FAIL_MSG("Failed to create Vulkan window."); + } + + rendering_device_vulkan = memnew(RenderingDeviceVulkan); + rendering_device_vulkan->initialize(context_vulkan); + + RasterizerRD::make_current(); + } +#endif + + InputFilter::get_singleton()->set_event_dispatch_function(_dispatch_input_events); +} + +DisplayServerAndroid::~DisplayServerAndroid() { +#if defined(VULKAN_ENABLED) + if (rendering_driver == "vulkan") { + if (rendering_device_vulkan) { + rendering_device_vulkan->finalize(); + memdelete(rendering_device_vulkan); + } + + if (context_vulkan) { + memdelete(context_vulkan); + } + } +#endif +} + +void DisplayServerAndroid::process_joy_event(DisplayServerAndroid::JoypadEvent p_event) { + switch (p_event.type) { + case JOY_EVENT_BUTTON: + InputFilter::get_singleton()->joy_button(p_event.device, p_event.index, p_event.pressed); + break; + case JOY_EVENT_AXIS: + InputFilter::JoyAxis value; + value.min = -1; + value.value = p_event.value; + InputFilter::get_singleton()->joy_axis(p_event.device, p_event.index, value); + break; + case JOY_EVENT_HAT: + InputFilter::get_singleton()->joy_hat(p_event.device, p_event.hat); + break; + default: + return; + } +} + +void DisplayServerAndroid::process_key_event(int p_keycode, int p_scancode, int p_unicode_char, bool p_pressed) { + Ref<InputEventKey> ev; + ev.instance(); + int val = p_unicode_char; + int keycode = android_get_keysym(p_keycode); + int phy_keycode = android_get_keysym(p_scancode); + ev->set_keycode(keycode); + ev->set_physical_keycode(phy_keycode); + ev->set_unicode(val); + ev->set_pressed(p_pressed); + + if (val == '\n') { + ev->set_keycode(KEY_ENTER); + } else if (val == 61448) { + ev->set_keycode(KEY_BACKSPACE); + ev->set_unicode(KEY_BACKSPACE); + } else if (val == 61453) { + ev->set_keycode(KEY_ENTER); + ev->set_unicode(KEY_ENTER); + } else if (p_keycode == 4) { + OS_Android::get_singleton()->main_loop_request_go_back(); + } + + InputFilter::get_singleton()->parse_input_event(ev); +} + +void DisplayServerAndroid::process_touch(int p_what, int p_pointer, const Vector<DisplayServerAndroid::TouchPos> &p_points) { + switch (p_what) { + case 0: { //gesture begin + if (touch.size()) { + //end all if exist + for (int i = 0; i < touch.size(); i++) { + + Ref<InputEventScreenTouch> ev; + ev.instance(); + ev->set_index(touch[i].id); + ev->set_pressed(false); + ev->set_position(touch[i].pos); + InputFilter::get_singleton()->parse_input_event(ev); + } + } + + touch.resize(p_points.size()); + for (int i = 0; i < p_points.size(); i++) { + touch.write[i].id = p_points[i].id; + touch.write[i].pos = p_points[i].pos; + } + + //send touch + for (int i = 0; i < touch.size(); i++) { + + Ref<InputEventScreenTouch> ev; + ev.instance(); + ev->set_index(touch[i].id); + ev->set_pressed(true); + ev->set_position(touch[i].pos); + InputFilter::get_singleton()->parse_input_event(ev); + } + + } break; + case 1: { //motion + ERR_FAIL_COND(touch.size() != p_points.size()); + + for (int i = 0; i < touch.size(); i++) { + + int idx = -1; + for (int j = 0; j < p_points.size(); j++) { + + if (touch[i].id == p_points[j].id) { + idx = j; + break; + } + } + + ERR_CONTINUE(idx == -1); + + if (touch[i].pos == p_points[idx].pos) + continue; //no move unncesearily + + Ref<InputEventScreenDrag> ev; + ev.instance(); + ev->set_index(touch[i].id); + ev->set_position(p_points[idx].pos); + ev->set_relative(p_points[idx].pos - touch[i].pos); + InputFilter::get_singleton()->parse_input_event(ev); + touch.write[i].pos = p_points[idx].pos; + } + + } break; + case 2: { //release + if (touch.size()) { + //end all if exist + for (int i = 0; i < touch.size(); i++) { + + Ref<InputEventScreenTouch> ev; + ev.instance(); + ev->set_index(touch[i].id); + ev->set_pressed(false); + ev->set_position(touch[i].pos); + InputFilter::get_singleton()->parse_input_event(ev); + } + touch.clear(); + } + } break; + case 3: { // add touch + for (int i = 0; i < p_points.size(); i++) { + if (p_points[i].id == p_pointer) { + TouchPos tp = p_points[i]; + touch.push_back(tp); + + Ref<InputEventScreenTouch> ev; + ev.instance(); + + ev->set_index(tp.id); + ev->set_pressed(true); + ev->set_position(tp.pos); + InputFilter::get_singleton()->parse_input_event(ev); + + break; + } + } + } break; + case 4: { // remove touch + for (int i = 0; i < touch.size(); i++) { + if (touch[i].id == p_pointer) { + + Ref<InputEventScreenTouch> ev; + ev.instance(); + ev->set_index(touch[i].id); + ev->set_pressed(false); + ev->set_position(touch[i].pos); + InputFilter::get_singleton()->parse_input_event(ev); + touch.remove(i); + + break; + } + } + } break; + } +} + +void DisplayServerAndroid::process_hover(int p_type, Point2 p_pos) { + // https://developer.android.com/reference/android/view/MotionEvent.html#ACTION_HOVER_ENTER + switch (p_type) { + case 7: // hover move + case 9: // hover enter + case 10: { // hover exit + Ref<InputEventMouseMotion> ev; + ev.instance(); + ev->set_position(p_pos); + ev->set_global_position(p_pos); + ev->set_relative(p_pos - hover_prev_pos); + InputFilter::get_singleton()->parse_input_event(ev); + hover_prev_pos = p_pos; + } break; + } +} + +void DisplayServerAndroid::process_double_tap(Point2 p_pos) { + Ref<InputEventMouseButton> ev; + ev.instance(); + ev->set_position(p_pos); + ev->set_global_position(p_pos); + ev->set_pressed(false); + ev->set_doubleclick(true); + InputFilter::get_singleton()->parse_input_event(ev); +} + +void DisplayServerAndroid::process_scroll(Point2 p_pos) { + Ref<InputEventPanGesture> ev; + ev.instance(); + ev->set_position(p_pos); + ev->set_delta(p_pos - scroll_prev_pos); + InputFilter::get_singleton()->parse_input_event(ev); + scroll_prev_pos = p_pos; +} + +void DisplayServerAndroid::process_accelerometer(const Vector3 &p_accelerometer) { + InputFilter::get_singleton()->set_accelerometer(p_accelerometer); +} + +void DisplayServerAndroid::process_gravity(const Vector3 &p_gravity) { + InputFilter::get_singleton()->set_gravity(p_gravity); +} + +void DisplayServerAndroid::process_magnetometer(const Vector3 &p_magnetometer) { + InputFilter::get_singleton()->set_magnetometer(p_magnetometer); +} + +void DisplayServerAndroid::process_gyroscope(const Vector3 &p_gyroscope) { + InputFilter::get_singleton()->set_gyroscope(p_gyroscope); +} diff --git a/platform/android/display_server_android.h b/platform/android/display_server_android.h new file mode 100644 index 0000000000..2096ba68f1 --- /dev/null +++ b/platform/android/display_server_android.h @@ -0,0 +1,174 @@ +/*************************************************************************/ +/* display_server_android.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef DISPLAY_SERVER_ANDROID_H +#define DISPLAY_SERVER_ANDROID_H + +#include "servers/display_server.h" + +#if defined(VULKAN_ENABLED) +class VulkanContextAndroid; +class RenderingDeviceVulkan; +#endif + +class DisplayServerAndroid : public DisplayServer { +public: + struct TouchPos { + int id; + Point2 pos; + }; + + enum { + JOY_EVENT_BUTTON = 0, + JOY_EVENT_AXIS = 1, + JOY_EVENT_HAT = 2 + }; + + struct JoypadEvent { + + int device; + int type; + int index; + bool pressed; + float value; + int hat; + }; + +private: + String rendering_driver; + + bool keep_screen_on; + + Vector<TouchPos> touch; + Point2 hover_prev_pos; // needed to calculate the relative position on hover events + Point2 scroll_prev_pos; // needed to calculate the relative position on scroll events + +#if defined(VULKAN_ENABLED) + VulkanContextAndroid *context_vulkan; + RenderingDeviceVulkan *rendering_device_vulkan; +#endif + + ObjectID window_attached_instance_id; + + Callable window_event_callback; + Callable input_event_callback; + Callable input_text_callback; + + void _window_callback(const Callable &p_callable, const Variant &p_arg) const; + + static void _dispatch_input_events(const Ref<InputEvent> &p_event); + +public: + static DisplayServerAndroid *get_singleton(); + + virtual bool has_feature(Feature p_feature) const; + virtual String get_name() const; + + virtual void clipboard_set(const String &p_text); + virtual String clipboard_get() const; + + virtual void screen_set_keep_on(bool p_enable); + virtual bool screen_is_kept_on() const; + + virtual void screen_set_orientation(ScreenOrientation p_orientation, int p_screen = SCREEN_OF_MAIN_WINDOW); + virtual ScreenOrientation screen_get_orientation(int p_screen = SCREEN_OF_MAIN_WINDOW) const; + + virtual int get_screen_count() const; + virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const; + virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const; + virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const; + virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const; + virtual bool screen_is_touchscreen(int p_screen = SCREEN_OF_MAIN_WINDOW) const; + + virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_length = -1); + virtual void virtual_keyboard_hide(); + virtual int virtual_keyboard_get_height() const; + + virtual void window_set_window_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID); + virtual void window_set_input_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID); + virtual void window_set_input_text_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID); + virtual void window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID); + virtual void window_set_drop_files_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID); + + void send_window_event(WindowEvent p_event) const; + void send_input_event(const Ref<InputEvent> &p_event) const; + void send_input_text(const String &p_text) const; + + virtual Vector<WindowID> get_window_list() const; + virtual WindowID get_window_at_screen_position(const Point2i &p_position) const; + virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID); + virtual ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const; + virtual void window_set_title(const String &p_title, WindowID p_window = MAIN_WINDOW_ID); + virtual int window_get_current_screen(WindowID p_window = MAIN_WINDOW_ID) const; + virtual void window_set_current_screen(int p_screen, WindowID p_window = MAIN_WINDOW_ID); + virtual Point2i window_get_position(WindowID p_window = MAIN_WINDOW_ID) const; + virtual void window_set_position(const Point2i &p_position, WindowID p_window = MAIN_WINDOW_ID); + virtual void window_set_transient(WindowID p_window, WindowID p_parent); + virtual void window_set_max_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID); + virtual Size2i window_get_max_size(WindowID p_window = MAIN_WINDOW_ID) const; + virtual void window_set_min_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID); + virtual Size2i window_get_min_size(WindowID p_window = MAIN_WINDOW_ID) const; + virtual void window_set_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID); + virtual Size2i window_get_size(WindowID p_window = MAIN_WINDOW_ID) const; + virtual Size2i window_get_real_size(WindowID p_window = MAIN_WINDOW_ID) const; + virtual void window_set_mode(WindowMode p_mode, WindowID p_window = MAIN_WINDOW_ID); + virtual WindowMode window_get_mode(WindowID p_window = MAIN_WINDOW_ID) const; + virtual bool window_is_maximize_allowed(WindowID p_window = MAIN_WINDOW_ID) const; + virtual void window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window = MAIN_WINDOW_ID); + virtual bool window_get_flag(WindowFlags p_flag, WindowID p_window = MAIN_WINDOW_ID) const; + virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID); + virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID); + virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const; + virtual bool can_any_window_draw() const; + + virtual void alert(const String &p_alert, const String &p_title); + + virtual void process_events(); + + void process_accelerometer(const Vector3 &p_accelerometer); + void process_gravity(const Vector3 &p_gravity); + void process_magnetometer(const Vector3 &p_magnetometer); + void process_gyroscope(const Vector3 &p_gyroscope); + void process_touch(int p_what, int p_pointer, const Vector<TouchPos> &p_points); + void process_hover(int p_type, Point2 p_pos); + void process_double_tap(Point2 p_pos); + void process_scroll(Point2 p_pos); + void process_joy_event(JoypadEvent p_event); + void process_key_event(int p_keycode, int p_scancode, int p_unicode_char, bool p_pressed); + + static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error); + static Vector<String> get_rendering_drivers_func(); + static void register_android_driver(); + + DisplayServerAndroid(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error); + ~DisplayServerAndroid(); +}; + +#endif // DISPLAY_SERVER_ANDROID_H diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index b6c30d120c..1eb1ee0d29 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -1932,6 +1932,7 @@ public: ImageLoader::load_image(path, launcher_adaptive_icon_background_image); } + Vector<String> invalid_abis(enabled_abis); while (ret == UNZ_OK) { //get filename @@ -1977,6 +1978,7 @@ public: bool enabled = false; for (int i = 0; i < enabled_abis.size(); ++i) { if (file.begins_with("lib/" + enabled_abis[i] + "/")) { + invalid_abis.erase(enabled_abis[i]); enabled = true; break; } @@ -2016,6 +2018,13 @@ public: ret = unzGoToNextFile(pkg); } + if (!invalid_abis.empty()) { + String unsupported_arch = String(", ").join(invalid_abis); + EditorNode::add_io_error("Missing libraries in the export template for the selected architectures: " + unsupported_arch + ".\n" + + "Please build a template with all required libraries, or uncheck the missing architectures in the export preset."); + CLEANUP_AND_RETURN(ERR_FILE_NOT_FOUND); + } + if (ep.step("Adding files...", 1)) { CLEANUP_AND_RETURN(ERR_SKIP); } diff --git a/platform/android/java/app/build.gradle b/platform/android/java/app/build.gradle index 1a3bb77670..9ae47d6174 100644 --- a/platform/android/java/app/build.gradle +++ b/platform/android/java/app/build.gradle @@ -56,6 +56,11 @@ android { compileSdkVersion versions.compileSdk buildToolsVersion versions.buildTools + compileOptions { + sourceCompatibility 1.8 + targetCompatibility 1.8 + } + defaultConfig { // Feel free to modify the application id to your own. applicationId getExportPackageName() @@ -71,7 +76,9 @@ android { packagingOptions { exclude 'META-INF/LICENSE' exclude 'META-INF/NOTICE' - doNotStrip '**/*.so' + + // Should be uncommented for development purpose within Android Studio + // doNotStrip '**/*.so' } // Both signing and zip-aligning will be done at export time diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle index 96cfd272f2..aa98194a10 100644 --- a/platform/android/java/app/config.gradle +++ b/platform/android/java/app/config.gradle @@ -3,7 +3,7 @@ ext.versions = [ compileSdk : 29, minSdk : 18, targetSdk : 29, - buildTools : '29.0.1', + buildTools : '29.0.3', supportCoreUtils : '28.0.0', kotlinVersion : '1.3.61', v4Support : '28.0.0' diff --git a/platform/android/java/app/settings.gradle b/platform/android/java/app/settings.gradle new file mode 100644 index 0000000000..33b863c7bf --- /dev/null +++ b/platform/android/java/app/settings.gradle @@ -0,0 +1,2 @@ +// Empty settings.gradle file to denote this directory as being the root project +// of the Godot custom build. diff --git a/platform/android/java/lib/AndroidManifest.xml b/platform/android/java/lib/AndroidManifest.xml index b133585f99..fa39bc0f1d 100644 --- a/platform/android/java/lib/AndroidManifest.xml +++ b/platform/android/java/lib/AndroidManifest.xml @@ -13,7 +13,7 @@ <instrumentation android:icon="@mipmap/icon" android:label="@string/godot_project_name_string" - android:name=".GodotInstrumentation" + android:name="org.godotengine.godot.GodotInstrumentation" android:targetPackage="org.godotengine.godot" /> </manifest> diff --git a/platform/android/java/lib/build.gradle b/platform/android/java/lib/build.gradle index 062f91e08e..19eee5a315 100644 --- a/platform/android/java/lib/build.gradle +++ b/platform/android/java/lib/build.gradle @@ -1,4 +1,5 @@ apply plugin: 'com.android.library' +apply plugin: 'kotlin-android' dependencies { implementation libraries.supportCoreUtils @@ -11,7 +12,6 @@ def pathToRootDir = "../../../../" android { compileSdkVersion versions.compileSdk buildToolsVersion versions.buildTools - useLibrary 'org.apache.http.legacy' defaultConfig { minSdkVersion versions.minSdk @@ -26,7 +26,9 @@ android { packagingOptions { exclude 'META-INF/LICENSE' exclude 'META-INF/NOTICE' - doNotStrip '**/*.so' + + // Should be uncommented for development purpose within Android Studio + // doNotStrip '**/*.so' } sourceSets { diff --git a/platform/android/java/lib/res/drawable-hdpi/notify_panel_notification_icon_bg.png b/platform/android/java/lib/res/drawable-hdpi/notify_panel_notification_icon_bg.png Binary files differdeleted file mode 100644 index f849d8e90d..0000000000 --- a/platform/android/java/lib/res/drawable-hdpi/notify_panel_notification_icon_bg.png +++ /dev/null diff --git a/platform/android/java/lib/res/drawable-mdpi/notify_panel_notification_icon_bg.png b/platform/android/java/lib/res/drawable-mdpi/notify_panel_notification_icon_bg.png Binary files differdeleted file mode 100644 index 1dfb28b33a..0000000000 --- a/platform/android/java/lib/res/drawable-mdpi/notify_panel_notification_icon_bg.png +++ /dev/null diff --git a/platform/android/java/lib/res/drawable-xhdpi/notify_panel_notification_icon_bg.png b/platform/android/java/lib/res/drawable-xhdpi/notify_panel_notification_icon_bg.png Binary files differdeleted file mode 100644 index 372b763ec5..0000000000 --- a/platform/android/java/lib/res/drawable-xhdpi/notify_panel_notification_icon_bg.png +++ /dev/null diff --git a/platform/android/java/lib/res/drawable-xxhdpi/notify_panel_notification_icon_bg.png b/platform/android/java/lib/res/drawable-xxhdpi/notify_panel_notification_icon_bg.png Binary files differdeleted file mode 100644 index 302a972049..0000000000 --- a/platform/android/java/lib/res/drawable-xxhdpi/notify_panel_notification_icon_bg.png +++ /dev/null diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.java b/platform/android/java/lib/src/org/godotengine/godot/Godot.java index 1798a1df3a..bf0d1c6273 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java +++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java @@ -153,7 +153,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe private String[] command_line; private boolean use_apk_expansion; - public GodotView mView; + public GodotRenderView mRenderView; private boolean godot_initialized = false; private SensorManager mSensorManager; @@ -213,34 +213,41 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe setContentView(layout); // GodotEditText layout - GodotEditText edittext = new GodotEditText(this); - edittext.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); + GodotEditText editText = new GodotEditText(this); + editText.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); // ...add to FrameLayout - layout.addView(edittext); + layout.addView(editText); - mView = new GodotView(this, xrMode, use_32_bits, use_debug_opengl); - layout.addView(mView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); - edittext.setView(mView); - io.setEdit(edittext); + GodotLib.setup(command_line); - mView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { + final String videoDriver = GodotLib.getGlobal("rendering/quality/driver/driver_name"); + if (videoDriver.equals("Vulkan")) { + mRenderView = new GodotVulkanRenderView(this); + } else { + mRenderView = new GodotGLRenderView(this, xrMode, use_32_bits, use_debug_opengl); + } + + View view = mRenderView.getView(); + layout.addView(view, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); + editText.setView(mRenderView); + io.setEdit(editText); + + view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { Point fullSize = new Point(); getWindowManager().getDefaultDisplay().getSize(fullSize); Rect gameSize = new Rect(); - mView.getWindowVisibleDisplayFrame(gameSize); + mRenderView.getView().getWindowVisibleDisplayFrame(gameSize); final int keyboardHeight = fullSize.y - gameSize.bottom; GodotLib.setVirtualKeyboardHeight(keyboardHeight); } }); - final String[] current_command_line = command_line; - mView.queueEvent(new Runnable() { + mRenderView.queueOnRenderThread(new Runnable() { @Override public void run() { - GodotLib.setup(current_command_line); // Must occur after GodotLib.setup has completed. for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) { @@ -384,7 +391,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe */ @Keep private Surface getSurface() { - return mView.getHolder().getSurface(); + return mRenderView.getView().getHolder().getSurface(); } /** @@ -617,7 +624,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe } return; } - mView.onPause(); + mRenderView.onActivityPaused(); mSensorManager.unregisterListener(this); @@ -655,7 +662,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe return; } - mView.onResume(); + mRenderView.onActivityResumed(); mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME); mSensorManager.registerListener(this, mGravity, SensorManager.SENSOR_DELAY_GAME); @@ -721,8 +728,8 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe final float z = adjustedValues[2]; final int typeOfSensor = event.sensor.getType(); - if (mView != null) { - mView.queueEvent(new Runnable() { + if (mRenderView != null) { + mRenderView.queueOnRenderThread(new Runnable() { @Override public void run() { if (typeOfSensor == Sensor.TYPE_ACCELEROMETER) { @@ -773,8 +780,8 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe } } - if (shouldQuit && mView != null) { - mView.queueEvent(new Runnable() { + if (shouldQuit && mRenderView != null) { + mRenderView.queueOnRenderThread(new Runnable() { @Override public void run() { GodotLib.back(); @@ -789,8 +796,8 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe * This must be called after the render thread has started. */ public final void runOnRenderThread(@NonNull Runnable action) { - if (mView != null) { - mView.queueEvent(action); + if (mRenderView != null) { + mRenderView.queueOnRenderThread(action); } } @@ -847,7 +854,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe if (evcount == 0) return true; - if (mView != null) { + if (mRenderView != null) { final int[] arr = new int[event.getPointerCount() * 3]; for (int i = 0; i < event.getPointerCount(); i++) { @@ -860,7 +867,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe //System.out.printf("gaction: %d\n",event.getAction()); final int action = event.getAction() & MotionEvent.ACTION_MASK; - mView.queueEvent(new Runnable() { + mRenderView.queueOnRenderThread(new Runnable() { @Override public void run() { switch (action) { @@ -911,7 +918,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe for (int i = cc.length; --i >= 0; cnt += cc[i] != 0 ? 1 : 0) ; if (cnt == 0) return super.onKeyMultiple(inKeyCode, repeatCount, event); - mView.queueEvent(new Runnable() { + mRenderView.queueOnRenderThread(new Runnable() { // This method will be called on the rendering thread: public void run() { for (int i = 0, n = cc.length; i < n; i++) { @@ -1033,6 +1040,6 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe progress.mOverallTotal)); } public void initInputDevices() { - mView.initInputDevices(); + mRenderView.initInputDevices(); } } diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java index 8d3c2ae319..9be93243b8 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotView.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java @@ -1,5 +1,5 @@ /*************************************************************************/ -/* GodotView.java */ +/* GodotGLRenderView.java */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -35,6 +35,7 @@ import android.opengl.GLSurfaceView; import android.view.GestureDetector; import android.view.KeyEvent; import android.view.MotionEvent; +import android.view.SurfaceView; import org.godotengine.godot.input.GodotGestureHandler; import org.godotengine.godot.input.GodotInputHandler; import org.godotengine.godot.utils.GLUtils; @@ -64,16 +65,14 @@ import org.godotengine.godot.xr.regular.RegularFallbackConfigChooser; * that matches it exactly (with regards to red/green/blue/alpha channels * bit depths). Failure to do so would result in an EGL_BAD_MATCH error. */ -public class GodotView extends GLSurfaceView { - - private static String TAG = GodotView.class.getSimpleName(); +public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView { private final Godot activity; private final GodotInputHandler inputHandler; private final GestureDetector detector; private final GodotRenderer godotRenderer; - public GodotView(Godot activity, XRMode xrMode, boolean p_use_32_bits, boolean p_use_debug_opengl) { + public GodotGLRenderView(Godot activity, XRMode xrMode, boolean p_use_32_bits, boolean p_use_debug_opengl) { super(activity); GLUtils.use_32 = p_use_32_bits; GLUtils.use_debug_opengl = p_use_debug_opengl; @@ -85,10 +84,36 @@ public class GodotView extends GLSurfaceView { init(xrMode, false, 16, 0); } + @Override + public SurfaceView getView() { + return this; + } + + @Override public void initInputDevices() { this.inputHandler.initInputDevices(); } + @Override + public void queueOnRenderThread(Runnable event) { + queueEvent(event); + } + + @Override + public void onActivityPaused() { + onPause(); + } + + @Override + public void onActivityResumed() { + onResume(); + } + + @Override + public void onBackPressed() { + activity.onBackPressed(); + } + @SuppressLint("ClickableViewAccessibility") @Override public boolean onTouchEvent(MotionEvent event) { @@ -170,10 +195,6 @@ public class GodotView extends GLSurfaceView { setRenderer(godotRenderer); } - public void onBackPressed() { - activity.onBackPressed(); - } - @Override public void onResume() { super.onResume(); diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java index 68ce40ba10..016a3a8d18 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java @@ -53,8 +53,6 @@ public class GodotIO { Godot activity; GodotEditText edit; - MediaPlayer mediaPlayer; - final int SCREEN_LANDSCAPE = 0; final int SCREEN_PORTRAIT = 1; final int SCREEN_REVERSE_LANDSCAPE = 2; @@ -530,44 +528,14 @@ public class GodotIO { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR); } break; } - }; - - public void setEdit(GodotEditText _edit) { - edit = _edit; - } - - public void playVideo(String p_path) { - Uri filePath = Uri.parse(p_path); - mediaPlayer = new MediaPlayer(); - - try { - mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); - mediaPlayer.setDataSource(activity.getApplicationContext(), filePath); - mediaPlayer.prepare(); - mediaPlayer.start(); - } catch (IOException e) { - System.out.println("IOError while playing video"); - } } - public boolean isVideoPlaying() { - if (mediaPlayer != null) { - return mediaPlayer.isPlaying(); - } - return false; + public int getScreenOrientation() { + return activity.getRequestedOrientation(); } - public void pauseVideo() { - if (mediaPlayer != null) { - mediaPlayer.pause(); - } - } - - public void stopVideo() { - if (mediaPlayer != null) { - mediaPlayer.release(); - mediaPlayer = null; - } + public void setEdit(GodotEditText _edit) { + edit = _edit; } public static final int SYSTEM_DIR_DESKTOP = 0; diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java index 89a65aea24..71fe822233 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java @@ -32,6 +32,7 @@ package org.godotengine.godot; import android.app.Activity; import android.hardware.SensorEvent; +import android.view.Surface; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; @@ -72,11 +73,11 @@ public class GodotLib { public static native void resize(int width, int height); /** - * Invoked on the GL thread when the underlying Android surface is created or recreated. + * Invoked on the render thread when the underlying Android surface is created or recreated. + * @param p_surface * @param p_32_bits - * @see android.opengl.GLSurfaceView.Renderer#onSurfaceCreated(GL10, EGLConfig) */ - public static native void newcontext(boolean p_32_bits); + public static native void newcontext(Surface p_surface, boolean p_32_bits); /** * Forward {@link Activity#onBackPressed()} event from the main thread to the GL thread. diff --git a/platform/android/vulkan/vk_renderer_jni.h b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java index 017766fea2..170c433c9c 100644 --- a/platform/android/vulkan/vk_renderer_jni.h +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java @@ -1,5 +1,5 @@ /*************************************************************************/ -/* vk_renderer_jni.h */ +/* GodotRenderView.java */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,19 +28,20 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef VK_RENDERER_JNI_H -#define VK_RENDERER_JNI_H +package org.godotengine.godot; -#include <android/log.h> -#include <jni.h> +import android.view.SurfaceView; -extern "C" { -JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkSurfaceCreated(JNIEnv *env, jobject obj, jobject j_surface); -JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkSurfaceChanged(JNIEnv *env, jobject object, jobject j_surface, jint width, jint height); -JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkResume(JNIEnv *env, jobject obj); -JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkDrawFrame(JNIEnv *env, jobject obj); -JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkPause(JNIEnv *env, jobject obj); -JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkDestroy(JNIEnv *env, jobject obj); -} +public interface GodotRenderView { + + abstract public SurfaceView getView(); + + abstract public void initInputDevices(); -#endif // VK_RENDERER_JNI_H + abstract public void queueOnRenderThread(Runnable event); + + abstract public void onActivityPaused(); + abstract public void onActivityResumed(); + + abstract public void onBackPressed(); +} diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java index ee9a2aee4f..3e5bb4a4c9 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java @@ -70,7 +70,7 @@ class GodotRenderer implements GLSurfaceView.Renderer { } public void onSurfaceCreated(GL10 gl, EGLConfig config) { - GodotLib.newcontext(GLUtils.use_32); + GodotLib.newcontext(null, GLUtils.use_32); for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) { plugin.onGLSurfaceCreated(gl, config); } diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java new file mode 100644 index 0000000000..30197d5729 --- /dev/null +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java @@ -0,0 +1,142 @@ +/*************************************************************************/ +/* GodotVulkanRenderView.java */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +package org.godotengine.godot; + +import android.annotation.SuppressLint; +import android.view.GestureDetector; +import android.view.KeyEvent; +import android.view.MotionEvent; +import android.view.SurfaceView; +import org.godotengine.godot.input.GodotGestureHandler; +import org.godotengine.godot.input.GodotInputHandler; +import org.godotengine.godot.vulkan.VkRenderer; +import org.godotengine.godot.vulkan.VkSurfaceView; + +public class GodotVulkanRenderView extends VkSurfaceView implements GodotRenderView { + + private final Godot mActivity; + private final GodotInputHandler mInputHandler; + private final GestureDetector mGestureDetector; + private final VkRenderer mRenderer; + + public GodotVulkanRenderView(Godot activity) { + super(activity); + + mActivity = activity; + mInputHandler = new GodotInputHandler(this); + mGestureDetector = new GestureDetector(mActivity, new GodotGestureHandler(this)); + mRenderer = new VkRenderer(); + + setFocusableInTouchMode(true); + startRenderer(mRenderer); + } + + @Override + public SurfaceView getView() { + return this; + } + + @Override + public void initInputDevices() { + mInputHandler.initInputDevices(); + } + + @Override + public void queueOnRenderThread(Runnable event) { + queueOnVkThread(event); + } + + @Override + public void onActivityPaused() { + onPause(); + } + + @Override + public void onActivityResumed() { + onResume(); + } + + @Override + public void onBackPressed() { + mActivity.onBackPressed(); + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouchEvent(MotionEvent event) { + super.onTouchEvent(event); + mGestureDetector.onTouchEvent(event); + return mActivity.gotTouchEvent(event); + } + + @Override + public boolean onKeyUp(final int keyCode, KeyEvent event) { + return mInputHandler.onKeyUp(keyCode, event) || super.onKeyUp(keyCode, event); + } + + @Override + public boolean onKeyDown(final int keyCode, KeyEvent event) { + return mInputHandler.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event); + } + + @Override + public boolean onGenericMotionEvent(MotionEvent event) { + return mInputHandler.onGenericMotionEvent(event) || super.onGenericMotionEvent(event); + } + + @Override + public void onResume() { + super.onResume(); + + queueOnVkThread(new Runnable() { + @Override + public void run() { + // Resume the renderer + mRenderer.onVkResume(); + GodotLib.focusin(); + } + }); + } + + @Override + public void onPause() { + super.onPause(); + + queueOnVkThread(new Runnable() { + @Override + public void run() { + GodotLib.focusout(); + // Pause the renderer + mRenderer.onVkPause(); + } + }); + } +} diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java index e901b4b36d..92bb118e44 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java @@ -51,7 +51,7 @@ public class GodotEditText extends EditText { // =========================================================== // Fields // =========================================================== - private GodotView mView; + private GodotRenderView mRenderView; private GodotTextInputWrapper mInputWrapper; private EditHandler sHandler = new EditHandler(this); private String mOriginText; @@ -76,22 +76,22 @@ public class GodotEditText extends EditText { // =========================================================== public GodotEditText(final Context context) { super(context); - this.initView(); + initView(); } public GodotEditText(final Context context, final AttributeSet attrs) { super(context, attrs); - this.initView(); + initView(); } public GodotEditText(final Context context, final AttributeSet attrs, final int defStyle) { super(context, attrs, defStyle); - this.initView(); + initView(); } protected void initView() { - this.setPadding(0, 0, 0, 0); - this.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI); + setPadding(0, 0, 0, 0); + setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI); } private void handleMessage(final Message msg) { @@ -106,7 +106,7 @@ public class GodotEditText extends EditText { edit.mInputWrapper.setOriginText(text); edit.addTextChangedListener(edit.mInputWrapper); setMaxInputLength(edit, msg.arg1); - final InputMethodManager imm = (InputMethodManager)mView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + final InputMethodManager imm = (InputMethodManager)mRenderView.getView().getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(edit, 0); } } break; @@ -115,9 +115,9 @@ public class GodotEditText extends EditText { GodotEditText edit = (GodotEditText)msg.obj; edit.removeTextChangedListener(mInputWrapper); - final InputMethodManager imm = (InputMethodManager)mView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + final InputMethodManager imm = (InputMethodManager)mRenderView.getView().getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(edit.getWindowToken(), 0); - edit.mView.requestFocus(); + edit.mRenderView.getView().requestFocus(); } break; } } @@ -135,12 +135,12 @@ public class GodotEditText extends EditText { // =========================================================== // Getter & Setter // =========================================================== - public void setView(final GodotView view) { - this.mView = view; + public void setView(final GodotRenderView view) { + mRenderView = view; if (mInputWrapper == null) - mInputWrapper = new GodotTextInputWrapper(mView, this); - this.setOnEditorActionListener(mInputWrapper); - view.requestFocus(); + mInputWrapper = new GodotTextInputWrapper(mRenderView, this); + setOnEditorActionListener(mInputWrapper); + view.getView().requestFocus(); } // =========================================================== @@ -152,7 +152,7 @@ public class GodotEditText extends EditText { /* Let GlSurfaceView get focus if back key is input. */ if (keyCode == KeyEvent.KEYCODE_BACK) { - this.mView.requestFocus(); + mRenderView.getView().requestFocus(); } return true; @@ -162,7 +162,7 @@ public class GodotEditText extends EditText { // Methods // =========================================================== public void showKeyboard(String p_existing_text, int p_max_input_length) { - this.mOriginText = p_existing_text; + mOriginText = p_existing_text; final Message msg = new Message(); msg.what = HANDLER_OPEN_IME_KEYBOARD; diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java index 1a38a9c3d2..b1e0f66373 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java @@ -34,22 +34,22 @@ import android.util.Log; import android.view.GestureDetector; import android.view.MotionEvent; import org.godotengine.godot.GodotLib; -import org.godotengine.godot.GodotView; +import org.godotengine.godot.GodotRenderView; /** - * Handles gesture input related events for the {@link GodotView} view. + * Handles gesture input related events for the {@link GodotRenderView} view. * https://developer.android.com/reference/android/view/GestureDetector.SimpleOnGestureListener */ public class GodotGestureHandler extends GestureDetector.SimpleOnGestureListener { - private final GodotView godotView; + private final GodotRenderView mRenderView; - public GodotGestureHandler(GodotView godotView) { - this.godotView = godotView; + public GodotGestureHandler(GodotRenderView godotView) { + mRenderView = godotView; } private void queueEvent(Runnable task) { - godotView.queueEvent(task); + mRenderView.queueOnRenderThread(task); } @Override diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java index e00ca86c41..0e4fc65119 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java @@ -42,27 +42,27 @@ import java.util.Collections; import java.util.Comparator; import java.util.List; import org.godotengine.godot.GodotLib; -import org.godotengine.godot.GodotView; +import org.godotengine.godot.GodotRenderView; import org.godotengine.godot.input.InputManagerCompat.InputDeviceListener; /** - * Handles input related events for the {@link GodotView} view. + * Handles input related events for the {@link GodotRenderView} view. */ public class GodotInputHandler implements InputDeviceListener { - private final ArrayList<Joystick> joysticksDevices = new ArrayList<Joystick>(); + private final ArrayList<Joystick> mJoysticksDevices = new ArrayList<Joystick>(); - private final GodotView godotView; - private final InputManagerCompat inputManager; + private final GodotRenderView mRenderView; + private final InputManagerCompat mInputManager; - public GodotInputHandler(GodotView godotView) { - this.godotView = godotView; - this.inputManager = InputManagerCompat.Factory.getInputManager(godotView.getContext()); - this.inputManager.registerInputDeviceListener(this, null); + public GodotInputHandler(GodotRenderView godotView) { + mRenderView = godotView; + mInputManager = InputManagerCompat.Factory.getInputManager(mRenderView.getView().getContext()); + mInputManager.registerInputDeviceListener(this, null); } private void queueEvent(Runnable task) { - godotView.queueEvent(task); + mRenderView.queueOnRenderThread(task); } private boolean isKeyEvent_GameDevice(int source) { @@ -113,7 +113,7 @@ public class GodotInputHandler implements InputDeviceListener { public boolean onKeyDown(final int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { - godotView.onBackPressed(); + mRenderView.onBackPressed(); // press 'back' button should not terminate program //normal handle 'back' event in game logic return true; @@ -164,7 +164,7 @@ public class GodotInputHandler implements InputDeviceListener { // Check if the device exists if (device_id > -1) { - Joystick joy = joysticksDevices.get(device_id); + Joystick joy = mJoysticksDevices.get(device_id); for (int i = 0; i < joy.axes.size(); i++) { InputDevice.MotionRange range = joy.axes.get(i); @@ -208,11 +208,11 @@ public class GodotInputHandler implements InputDeviceListener { public void initInputDevices() { /* initially add input devices*/ - int[] deviceIds = inputManager.getInputDeviceIds(); + int[] deviceIds = mInputManager.getInputDeviceIds(); for (int deviceId : deviceIds) { - InputDevice device = inputManager.getInputDevice(deviceId); + InputDevice device = mInputManager.getInputDevice(deviceId); if (DEBUG) { - Log.v("GodotView", String.format("init() deviceId:%d, Name:%s\n", deviceId, device.getName())); + Log.v("GodotInputHandler", String.format("init() deviceId:%d, Name:%s\n", deviceId, device.getName())); } onInputDeviceAdded(deviceId); } @@ -224,13 +224,13 @@ public class GodotInputHandler implements InputDeviceListener { // Check if the device has not been already added if (id < 0) { - InputDevice device = inputManager.getInputDevice(deviceId); + InputDevice device = mInputManager.getInputDevice(deviceId); //device can be null if deviceId is not found if (device != null) { int sources = device.getSources(); if (((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) || ((sources & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK)) { - id = joysticksDevices.size(); + id = mJoysticksDevices.size(); Joystick joy = new Joystick(); joy.device_id = deviceId; @@ -249,7 +249,7 @@ public class GodotInputHandler implements InputDeviceListener { } } - joysticksDevices.add(joy); + mJoysticksDevices.add(joy); final int device_id = id; final String name = joy.name; @@ -270,7 +270,7 @@ public class GodotInputHandler implements InputDeviceListener { // Check if the evice has not been already removed if (device_id > -1) { - joysticksDevices.remove(device_id); + mJoysticksDevices.remove(device_id); queueEvent(new Runnable() { @Override @@ -360,8 +360,8 @@ public class GodotInputHandler implements InputDeviceListener { } private int findJoystickDevice(int device_id) { - for (int i = 0; i < joysticksDevices.size(); i++) { - if (joysticksDevices.get(i).device_id == device_id) { + for (int i = 0; i < mJoysticksDevices.size(); i++) { + if (mJoysticksDevices.get(i).device_id == device_id) { return i; } } diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java index 18f2d57661..e12ff266bf 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java @@ -48,7 +48,7 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene // =========================================================== // Fields // =========================================================== - private final GodotView mView; + private final GodotRenderView mRenderView; private final GodotEditText mEdit; private String mOriginText; @@ -56,9 +56,9 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene // Constructors // =========================================================== - public GodotTextInputWrapper(final GodotView view, final GodotEditText edit) { - this.mView = view; - this.mEdit = edit; + public GodotTextInputWrapper(final GodotRenderView view, final GodotEditText edit) { + mRenderView = view; + mEdit = edit; } // =========================================================== @@ -66,13 +66,13 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene // =========================================================== private boolean isFullScreenEdit() { - final TextView textField = this.mEdit; + final TextView textField = mEdit; final InputMethodManager imm = (InputMethodManager)textField.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); return imm.isFullscreenMode(); } public void setOriginText(final String originText) { - this.mOriginText = originText; + mOriginText = originText; } // =========================================================== @@ -87,7 +87,7 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene public void beforeTextChanged(final CharSequence pCharSequence, final int start, final int count, final int after) { //Log.d(TAG, "beforeTextChanged(" + pCharSequence + ")start: " + start + ",count: " + count + ",after: " + after); - mView.queueEvent(new Runnable() { + mRenderView.queueOnRenderThread(new Runnable() { @Override public void run() { for (int i = 0; i < count; ++i) { @@ -106,7 +106,7 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene for (int i = start; i < start + count; ++i) { newChars[i - start] = pCharSequence.charAt(i); } - mView.queueEvent(new Runnable() { + mRenderView.queueOnRenderThread(new Runnable() { @Override public void run() { for (int i = 0; i < count; ++i) { @@ -124,10 +124,10 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene @Override public boolean onEditorAction(final TextView pTextView, final int pActionID, final KeyEvent pKeyEvent) { - if (this.mEdit == pTextView && this.isFullScreenEdit()) { + if (mEdit == pTextView && isFullScreenEdit()) { final String characters = pKeyEvent.getCharacters(); - mView.queueEvent(new Runnable() { + mRenderView.queueOnRenderThread(new Runnable() { @Override public void run() { for (int i = 0; i < characters.length(); i++) { @@ -144,7 +144,7 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene GodotLib.key(KeyEvent.KEYCODE_ENTER, KeyEvent.KEYCODE_ENTER, 0, true); GodotLib.key(KeyEvent.KEYCODE_ENTER, KeyEvent.KEYCODE_ENTER, 0, false); - this.mView.requestFocus(); + mRenderView.getView().requestFocus(); return true; } return false; diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java index e3683704e1..a051164d15 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java +++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java @@ -34,6 +34,8 @@ import android.app.Activity; import android.content.Intent; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.text.TextUtils; +import android.util.Log; import android.view.Surface; import android.view.View; import java.lang.reflect.Method; @@ -41,8 +43,10 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; +import org.godotengine.godot.BuildConfig; import org.godotengine.godot.Godot; /** @@ -70,7 +74,10 @@ import org.godotengine.godot.Godot; */ public abstract class GodotPlugin { + private static final String TAG = GodotPlugin.class.getSimpleName(); + private final Godot godot; + private final ConcurrentHashMap<String, SignalInfo> registeredSignals = new ConcurrentHashMap<>(); public GodotPlugin(Godot godot) { this.godot = godot; @@ -118,6 +125,13 @@ public abstract class GodotPlugin { nativeRegisterMethod(getPluginName(), method.getName(), method.getReturnType().getName(), pt); } + // Register the signals for this plugin. + for (SignalInfo signalInfo : getPluginSignals()) { + String signalName = signalInfo.getName(); + nativeRegisterSignal(getPluginName(), signalName, signalInfo.getParamTypesNames()); + registeredSignals.put(signalName, signalInfo); + } + // Get the list of gdnative libraries to register. Set<String> gdnativeLibrariesPaths = getPluginGDNativeLibrariesPaths(); if (!gdnativeLibrariesPaths.isEmpty()) { @@ -220,7 +234,17 @@ public abstract class GodotPlugin { * Returns the list of methods to be exposed to Godot. */ @NonNull - public abstract List<String> getPluginMethods(); + public List<String> getPluginMethods() { + return Collections.emptyList(); + } + + /** + * Returns the list of signals to be exposed to Godot. + */ + @NonNull + public Set<SignalInfo> getPluginSignals() { + return Collections.emptySet(); + } /** * Returns the paths for the plugin's gdnative libraries. @@ -253,6 +277,49 @@ public abstract class GodotPlugin { } /** + * Emit a registered Godot signal. + * @param signalName + * @param signalArgs + */ + protected void emitSignal(final String signalName, final Object... signalArgs) { + try { + // Check that the given signal is among the registered set. + SignalInfo signalInfo = registeredSignals.get(signalName); + if (signalInfo == null) { + throw new IllegalArgumentException( + "Signal " + signalName + " is not registered for this plugin."); + } + + // Validate the arguments count. + Class<?>[] signalParamTypes = signalInfo.getParamTypes(); + if (signalArgs.length != signalParamTypes.length) { + throw new IllegalArgumentException( + "Invalid arguments count. Should be " + signalParamTypes.length + " but is " + signalArgs.length); + } + + // Validate the argument's types. + for (int i = 0; i < signalParamTypes.length; i++) { + if (!signalParamTypes[i].isInstance(signalArgs[i])) { + throw new IllegalArgumentException( + "Invalid type for argument #" + i + ". Should be of type " + signalParamTypes[i].getName()); + } + } + + runOnRenderThread(new Runnable() { + @Override + public void run() { + nativeEmitSignal(getPluginName(), signalName, signalArgs); + } + }); + } catch (IllegalArgumentException exception) { + Log.w(TAG, exception.getMessage()); + if (BuildConfig.DEBUG) { + throw exception; + } + } + } + + /** * Used to setup a {@link GodotPlugin} instance. * @param p_name Name of the instance. */ @@ -272,4 +339,20 @@ public abstract class GodotPlugin { * @param gdnlibPaths Paths to the libraries relative to the 'assets' directory. */ private native void nativeRegisterGDNativeLibraries(String[] gdnlibPaths); + + /** + * Used to complete registration of the {@link GodotPlugin} instance's methods. + * @param pluginName Name of the plugin + * @param signalName Name of the signal to register + * @param signalParamTypes Signal parameters types + */ + private native void nativeRegisterSignal(String pluginName, String signalName, String[] signalParamTypes); + + /** + * Used to emit signal by {@link GodotPlugin} instance. + * @param pluginName Name of the plugin + * @param signalName Name of the signal to emit + * @param signalParams Signal parameters + */ + private native void nativeEmitSignal(String pluginName, String signalName, Object[] signalParams); } diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java new file mode 100644 index 0000000000..f907706889 --- /dev/null +++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java @@ -0,0 +1,98 @@ +/*************************************************************************/ +/* SignalInfo.java */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +package org.godotengine.godot.plugin; + +import android.support.annotation.NonNull; +import android.text.TextUtils; +import java.util.Arrays; + +/** + * Store information about a {@link GodotPlugin}'s signal. + */ +public final class SignalInfo { + + private final String name; + private final Class<?>[] paramTypes; + private final String[] paramTypesNames; + + public SignalInfo(@NonNull String signalName, Class<?>... paramTypes) { + if (TextUtils.isEmpty(signalName)) { + throw new IllegalArgumentException("Invalid signal name: " + signalName); + } + + this.name = signalName; + this.paramTypes = paramTypes == null ? new Class<?>[ 0 ] : paramTypes; + this.paramTypesNames = new String[this.paramTypes.length]; + for (int i = 0; i < this.paramTypes.length; i++) { + this.paramTypesNames[i] = this.paramTypes[i].getName(); + } + } + + public String getName() { + return name; + } + + Class<?>[] getParamTypes() { + return paramTypes; + } + + String[] getParamTypesNames() { + return paramTypesNames; + } + + @Override + public String toString() { + return "SignalInfo{" + + + "name='" + name + '\'' + + ", paramsTypes=" + Arrays.toString(paramTypes) + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof SignalInfo)) { + return false; + } + + SignalInfo that = (SignalInfo)o; + + return name.equals(that.name); + } + + @Override + public int hashCode() { + return name.hashCode(); + } +} diff --git a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt index 67faad8ddd..608ad48df9 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt @@ -33,6 +33,11 @@ package org.godotengine.godot.vulkan import android.view.Surface +import org.godotengine.godot.Godot +import org.godotengine.godot.GodotLib +import org.godotengine.godot.plugin.GodotPlugin +import org.godotengine.godot.plugin.GodotPluginRegistry + /** * Responsible to setting up and driving the Vulkan rendering logic. * @@ -48,52 +53,64 @@ import android.view.Surface */ internal class VkRenderer { + private val pluginRegistry: GodotPluginRegistry = GodotPluginRegistry.getPluginRegistry() + /** * Called when the surface is created and signals the beginning of rendering. */ fun onVkSurfaceCreated(surface: Surface) { - nativeOnVkSurfaceCreated(surface) + // TODO: properly implement surface re-creation: + // GodotLib.newcontext should be called here once it's done. + //GodotLib.newcontext(surface, false) + + for (plugin in pluginRegistry.getAllPlugins()) { + plugin.onVkSurfaceCreated(surface) + } } /** * Called after the surface is created and whenever its size changes. */ fun onVkSurfaceChanged(surface: Surface, width: Int, height: Int) { - nativeOnVkSurfaceChanged(surface, width, height) + GodotLib.resize(width, height) + + // TODO: properly implement surface re-creation: + // Update the native renderer instead of restarting the app. + // GodotLib.newcontext should not be called here once it's done. + GodotLib.newcontext(surface, false) + + for (plugin in pluginRegistry.getAllPlugins()) { + plugin.onVkSurfaceChanged(surface, width, height) + } } /** * Called to draw the current frame. */ fun onVkDrawFrame() { - nativeOnVkDrawFrame() + GodotLib.step() + for (plugin in pluginRegistry.getAllPlugins()) { + plugin.onVkDrawFrame() + } } /** * Called when the rendering thread is resumed. */ fun onVkResume() { - nativeOnVkResume() + GodotLib.onRendererResumed() } /** * Called when the rendering thread is paused. */ fun onVkPause() { - nativeOnVkPause() + GodotLib.onRendererPaused() } /** * Called when the rendering thread is destroyed and used as signal to tear down the Vulkan logic. */ fun onVkDestroy() { - nativeOnVkDestroy() } - - private external fun nativeOnVkSurfaceCreated(surface: Surface) - private external fun nativeOnVkSurfaceChanged(surface: Surface, width: Int, height: Int) - private external fun nativeOnVkResume() - private external fun nativeOnVkDrawFrame() - private external fun nativeOnVkPause() - private external fun nativeOnVkDestroy() } diff --git a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt index 1c594f3201..6b0e12b21a 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt @@ -49,7 +49,7 @@ import android.view.SurfaceView * UI thread. * </ul> */ -internal class VkSurfaceView(context: Context) : SurfaceView(context), SurfaceHolder.Callback { +open internal class VkSurfaceView(context: Context) : SurfaceView(context), SurfaceHolder.Callback { companion object { fun checkState(expression: Boolean, errorMessage: Any) { @@ -100,7 +100,7 @@ internal class VkSurfaceView(context: Context) : SurfaceView(context), SurfaceHo * * Must not be called before a [VkRenderer] has been set. */ - fun onResume() { + open fun onResume() { vkThread.onResume() } @@ -109,7 +109,7 @@ internal class VkSurfaceView(context: Context) : SurfaceView(context), SurfaceHo * * Must not be called before a [VkRenderer] has been set. */ - fun onPause() { + open fun onPause() { vkThread.onPause() } diff --git a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt index 2e332840bf..7557c8aa22 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt @@ -219,9 +219,9 @@ internal class VkThread(private val vkSurfaceView: VkSurfaceView, private val vk vkRenderer.onVkDrawFrame() } } catch (ex: InterruptedException) { - Log.i(TAG, ex.message) + Log.i(TAG, "InterruptedException", ex) } catch (ex: IllegalStateException) { - Log.i(TAG, ex.message) + Log.i(TAG, "IllegalStateException", ex) } finally { threadExiting() } diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java index f2b4c95a2c..31cf696195 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java +++ b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java @@ -51,7 +51,6 @@ public class RegularContextFactory implements GLSurfaceView.EGLContextFactory { private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098; public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) { - String driver_name = GodotLib.getGlobal("rendering/quality/driver/driver_name"); // FIXME: Add support for Vulkan. Log.w(TAG, "creating OpenGL ES 2.0 context :"); diff --git a/platform/android/java/plugins/godotpayment/build.gradle b/platform/android/java/plugins/godotpayment/build.gradle index 4f376c4587..ffab86e26e 100644 --- a/platform/android/java/plugins/godotpayment/build.gradle +++ b/platform/android/java/plugins/godotpayment/build.gradle @@ -3,6 +3,7 @@ apply plugin: 'com.android.library' android { compileSdkVersion versions.compileSdk buildToolsVersion versions.buildTools + useLibrary 'org.apache.http.legacy' defaultConfig { minSdkVersion versions.minSdk diff --git a/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/ValidateTask.java b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/ValidateTask.java index 179cc08ed1..d42ded0c9b 100644 --- a/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/ValidateTask.java +++ b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/ValidateTask.java @@ -34,8 +34,8 @@ import android.app.Activity; import android.app.ProgressDialog; import android.os.AsyncTask; import java.lang.ref.WeakReference; -import org.godotengine.godot.utils.HttpRequester; -import org.godotengine.godot.utils.RequestParams; +import org.godotengine.godot.plugin.payment.utils.HttpRequester; +import org.godotengine.godot.plugin.payment.utils.RequestParams; import org.json.JSONException; import org.json.JSONObject; diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/utils/CustomSSLSocketFactory.java index c78e8c1c66..9571769cd3 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java +++ b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/utils/CustomSSLSocketFactory.java @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -package org.godotengine.godot.utils; +package org.godotengine.godot.plugin.payment.utils; + import java.io.IOException; import java.net.Socket; import java.net.UnknownHostException; diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/HttpRequester.java b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/utils/HttpRequester.java index 68f9a83597..dcb983201e 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/utils/HttpRequester.java +++ b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/utils/HttpRequester.java @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -package org.godotengine.godot.utils; +package org.godotengine.godot.plugin.payment.utils; import android.content.Context; import android.content.SharedPreferences; @@ -61,6 +61,7 @@ import org.apache.http.params.HttpParams; import org.apache.http.params.HttpProtocolParams; import org.apache.http.protocol.HTTP; import org.apache.http.util.EntityUtils; +import org.godotengine.godot.utils.Crypt; /** * diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/RequestParams.java b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/utils/RequestParams.java index 25fa10647d..4be8b37473 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/utils/RequestParams.java +++ b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/utils/RequestParams.java @@ -28,10 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -package org.godotengine.godot.utils; +package org.godotengine.godot.plugin.payment.utils; import java.util.ArrayList; -import java.util.Date; import java.util.HashMap; import java.util.List; import org.apache.http.NameValuePair; diff --git a/platform/android/java_godot_io_wrapper.cpp b/platform/android/java_godot_io_wrapper.cpp index 8d075f8e97..0da0bd6387 100644 --- a/platform/android/java_godot_io_wrapper.cpp +++ b/platform/android/java_godot_io_wrapper.cpp @@ -56,11 +56,8 @@ GodotIOJavaWrapper::GodotIOJavaWrapper(JNIEnv *p_env, jobject p_godot_io_instanc _show_keyboard = p_env->GetMethodID(cls, "showKeyboard", "(Ljava/lang/String;I)V"); _hide_keyboard = p_env->GetMethodID(cls, "hideKeyboard", "()V"); _set_screen_orientation = p_env->GetMethodID(cls, "setScreenOrientation", "(I)V"); + _get_screen_orientation = p_env->GetMethodID(cls, "getScreenOrientation", "()I"); _get_system_dir = p_env->GetMethodID(cls, "getSystemDir", "(I)Ljava/lang/String;"); - _play_video = p_env->GetMethodID(cls, "playVideo", "(Ljava/lang/String;)V"); - _is_video_playing = p_env->GetMethodID(cls, "isVideoPlaying", "()Z"); - _pause_video = p_env->GetMethodID(cls, "pauseVideo", "()V"); - _stop_video = p_env->GetMethodID(cls, "stopVideo", "()V"); } } @@ -157,40 +154,22 @@ void GodotIOJavaWrapper::set_screen_orientation(int p_orient) { } } -String GodotIOJavaWrapper::get_system_dir(int p_dir) { - if (_get_system_dir) { +int GodotIOJavaWrapper::get_screen_orientation() { + if (_get_screen_orientation) { JNIEnv *env = ThreadAndroid::get_env(); - jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_system_dir, p_dir); - return jstring_to_string(s, env); + return env->CallIntMethod(godot_io_instance, _get_screen_orientation); } else { - return String("."); + return 0; } } -void GodotIOJavaWrapper::play_video(const String &p_path) { - // Why is this not here?!?! -} - -bool GodotIOJavaWrapper::is_video_playing() { - if (_is_video_playing) { +String GodotIOJavaWrapper::get_system_dir(int p_dir) { + if (_get_system_dir) { JNIEnv *env = ThreadAndroid::get_env(); - return env->CallBooleanMethod(godot_io_instance, _is_video_playing); + jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_system_dir, p_dir); + return jstring_to_string(s, env); } else { - return false; - } -} - -void GodotIOJavaWrapper::pause_video() { - if (_pause_video) { - JNIEnv *env = ThreadAndroid::get_env(); - env->CallVoidMethod(godot_io_instance, _pause_video); - } -} - -void GodotIOJavaWrapper::stop_video() { - if (_stop_video) { - JNIEnv *env = ThreadAndroid::get_env(); - env->CallVoidMethod(godot_io_instance, _stop_video); + return String("."); } } diff --git a/platform/android/java_godot_io_wrapper.h b/platform/android/java_godot_io_wrapper.h index 7dfed52187..dbb3b564f6 100644 --- a/platform/android/java_godot_io_wrapper.h +++ b/platform/android/java_godot_io_wrapper.h @@ -54,11 +54,8 @@ private: jmethodID _show_keyboard = 0; jmethodID _hide_keyboard = 0; jmethodID _set_screen_orientation = 0; + jmethodID _get_screen_orientation = 0; jmethodID _get_system_dir = 0; - jmethodID _play_video = 0; - jmethodID _is_video_playing = 0; - jmethodID _pause_video = 0; - jmethodID _stop_video = 0; public: GodotIOJavaWrapper(JNIEnv *p_env, jobject p_godot_io_instance); @@ -78,11 +75,8 @@ public: int get_vk_height(); void set_vk_height(int p_height); void set_screen_orientation(int p_orient); + int get_screen_orientation(); String get_system_dir(int p_dir); - void play_video(const String &p_path); - bool is_video_playing(); - void pause_video(); - void stop_video(); }; #endif /* !JAVA_GODOT_IO_WRAPPER_H */ diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp index 9d44ab4619..8b38113e09 100644 --- a/platform/android/java_godot_lib_jni.cpp +++ b/platform/android/java_godot_lib_jni.cpp @@ -34,13 +34,14 @@ #include "java_godot_wrapper.h" #include "android/asset_manager_jni.h" -#include "android_keys_utils.h" #include "api/java_class_wrapper.h" +#include "api/jni_singleton.h" #include "audio_driver_jandroid.h" #include "core/engine.h" #include "core/input/input_filter.h" #include "core/project_settings.h" #include "dir_access_jandroid.h" +#include "display_server_android.h" #include "file_access_android.h" #include "file_access_jandroid.h" #include "jni_utils.h" @@ -52,6 +53,8 @@ #include <unistd.h> +#include <android/native_window_jni.h> + static JavaClassWrapper *java_class_wrapper = nullptr; static OS_Android *os_android = nullptr; static GodotJavaWrapper *godot_java = nullptr; @@ -160,22 +163,26 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jc } java_class_wrapper = memnew(JavaClassWrapper(godot_java->get_activity())); + ClassDB::register_class<JNISingleton>(); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jclass clazz, jint width, jint height) { if (os_android) - os_android->set_display_size(Size2(width, height)); + os_android->set_display_size(Size2i(width, height)); } -JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz, jboolean p_32_bits) { - +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz, jobject p_surface, jboolean p_32_bits) { if (os_android) { if (step == 0) { // During startup os_android->set_context_is_16_bits(!p_32_bits); + if (p_surface) { + ANativeWindow *native_window = ANativeWindow_fromSurface(env, p_surface); + os_android->set_native_window(native_window); + } } else { - // GL context recreated because it was lost; restart app to let it reload everything + // Rendering context recreated because it was lost; restart app to let it reload everything os_android->main_loop_end(); godot_java->restart(env); step = -1; // Ensure no further steps are attempted @@ -195,7 +202,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jcl return; if (step == 0) { - // Since Godot is initialized on the UI thread, _main_thread_id was set to that thread's id, // but for Godot purposes, the main thread is the one running the game loop Main::setup2(Thread::get_caller_id()); @@ -213,10 +219,10 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jcl ++step; } - os_android->process_accelerometer(accelerometer); - os_android->process_gravity(gravity); - os_android->process_magnetometer(magnetometer); - os_android->process_gyroscope(gyroscope); + DisplayServerAndroid::get_singleton()->process_accelerometer(accelerometer); + DisplayServerAndroid::get_singleton()->process_gravity(gravity); + DisplayServerAndroid::get_singleton()->process_magnetometer(magnetometer); + DisplayServerAndroid::get_singleton()->process_gyroscope(gyroscope); if (os_android->main_loop_iterate()) { @@ -229,18 +235,18 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch(JNIEnv *env, jc if (step == 0) return; - Vector<OS_Android::TouchPos> points; + Vector<DisplayServerAndroid::TouchPos> points; for (int i = 0; i < count; i++) { jint p[3]; env->GetIntArrayRegion(positions, i * 3, 3, p); - OS_Android::TouchPos tp; + DisplayServerAndroid::TouchPos tp; tp.pos = Point2(p[1], p[2]); tp.id = p[0]; points.push_back(tp); } - os_android->process_touch(ev, pointer, points); + DisplayServerAndroid::get_singleton()->process_touch(ev, pointer, points); /* if (os_android) @@ -252,78 +258,78 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_hover(JNIEnv *env, jc if (step == 0) return; - os_android->process_hover(p_type, Point2(p_x, p_y)); + DisplayServerAndroid::get_singleton()->process_hover(p_type, Point2(p_x, p_y)); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_doubletap(JNIEnv *env, jclass clazz, jint p_x, jint p_y) { if (step == 0) return; - os_android->process_double_tap(Point2(p_x, p_y)); + DisplayServerAndroid::get_singleton()->process_double_tap(Point2(p_x, p_y)); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_scroll(JNIEnv *env, jclass clazz, jint p_x, jint p_y) { if (step == 0) return; - os_android->process_scroll(Point2(p_x, p_y)); + DisplayServerAndroid::get_singleton()->process_scroll(Point2(p_x, p_y)); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env, jclass clazz, jint p_device, jint p_button, jboolean p_pressed) { if (step == 0) return; - OS_Android::JoypadEvent jevent; + DisplayServerAndroid::JoypadEvent jevent; jevent.device = p_device; - jevent.type = OS_Android::JOY_EVENT_BUTTON; + jevent.type = DisplayServerAndroid::JOY_EVENT_BUTTON; jevent.index = p_button; jevent.pressed = p_pressed; - os_android->process_joy_event(jevent); + DisplayServerAndroid::get_singleton()->process_joy_event(jevent); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env, jclass clazz, jint p_device, jint p_axis, jfloat p_value) { if (step == 0) return; - OS_Android::JoypadEvent jevent; + DisplayServerAndroid::JoypadEvent jevent; jevent.device = p_device; - jevent.type = OS_Android::JOY_EVENT_AXIS; + jevent.type = DisplayServerAndroid::JOY_EVENT_AXIS; jevent.index = p_axis; jevent.value = p_value; - os_android->process_joy_event(jevent); + DisplayServerAndroid::get_singleton()->process_joy_event(jevent); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, jclass clazz, jint p_device, jint p_hat_x, jint p_hat_y) { if (step == 0) return; - OS_Android::JoypadEvent jevent; + DisplayServerAndroid::JoypadEvent jevent; jevent.device = p_device; - jevent.type = OS_Android::JOY_EVENT_HAT; + jevent.type = DisplayServerAndroid::JOY_EVENT_HAT; int hat = 0; if (p_hat_x != 0) { if (p_hat_x < 0) - hat |= InputDefault::HAT_MASK_LEFT; + hat |= InputFilter::HAT_MASK_LEFT; else - hat |= InputDefault::HAT_MASK_RIGHT; + hat |= InputFilter::HAT_MASK_RIGHT; } if (p_hat_y != 0) { if (p_hat_y < 0) - hat |= InputDefault::HAT_MASK_UP; + hat |= InputFilter::HAT_MASK_UP; else - hat |= InputDefault::HAT_MASK_DOWN; + hat |= InputFilter::HAT_MASK_DOWN; } jevent.hat = hat; - os_android->process_joy_event(jevent); + DisplayServerAndroid::get_singleton()->process_joy_event(jevent); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged(JNIEnv *env, jclass clazz, jint p_device, jboolean p_connected, jstring p_name) { if (os_android) { String name = jstring_to_string(p_name, env); - os_android->joy_connection_changed(p_device, p_connected, name); + InputFilter::get_singleton()->joy_connection_changed(p_device, p_connected, name); } } @@ -331,29 +337,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jcla if (step == 0) return; - Ref<InputEventKey> ievent; - ievent.instance(); - int val = p_unicode_char; - int keycode = android_get_keysym(p_keycode); - int phy_keycode = android_get_keysym(p_scancode); - ievent->set_keycode(keycode); - ievent->set_physical_keycode(phy_keycode); - ievent->set_unicode(val); - ievent->set_pressed(p_pressed); - - if (val == '\n') { - ievent->set_keycode(KEY_ENTER); - } else if (val == 61448) { - ievent->set_keycode(KEY_BACKSPACE); - ievent->set_unicode(KEY_BACKSPACE); - } else if (val == 61453) { - ievent->set_keycode(KEY_ENTER); - ievent->set_unicode(KEY_ENTER); - } else if (p_keycode == 4) { - os_android->main_loop_request_go_back(); - } - - os_android->process_event(ievent); + DisplayServerAndroid::get_singleton()->process_key_event(p_keycode, p_scancode, p_unicode_char, p_pressed); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_accelerometer(JNIEnv *env, jclass clazz, jfloat x, jfloat y, jfloat z) { diff --git a/platform/android/java_godot_lib_jni.h b/platform/android/java_godot_lib_jni.h index a7a5970440..221d701e2b 100644 --- a/platform/android/java_godot_lib_jni.h +++ b/platform/android/java_godot_lib_jni.h @@ -41,7 +41,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jclass clazz, jobject activity); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jclass clazz, jobjectArray p_cmdline); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jclass clazz, jint width, jint height); -JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz, jboolean p_32_bits); +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz, jobject p_surface, jboolean p_32_bits); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jclass clazz); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_back(JNIEnv *env, jclass clazz); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch(JNIEnv *env, jclass clazz, jint ev, jint pointer, jint count, jintArray positions); diff --git a/platform/android/jni_utils.h b/platform/android/jni_utils.h index b9ee243308..c2baa51b4a 100644 --- a/platform/android/jni_utils.h +++ b/platform/android/jni_utils.h @@ -53,190 +53,4 @@ Variant::Type get_jni_type(const String &p_type); const char *get_jni_sig(const String &p_type); -class JNISingleton : public Object { - - GDCLASS(JNISingleton, Object); - - struct MethodData { - - jmethodID method; - Variant::Type ret_type; - Vector<Variant::Type> argtypes; - }; - - jobject instance; - Map<StringName, MethodData> method_map; - -public: - virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { - - ERR_FAIL_COND_V(!instance, Variant()); - - r_error.error = Callable::CallError::CALL_OK; - - Map<StringName, MethodData>::Element *E = method_map.find(p_method); - if (!E) { - - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - return Variant(); - } - - int ac = E->get().argtypes.size(); - if (ac < p_argcount) { - - r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; - r_error.argument = ac; - return Variant(); - } - - if (ac > p_argcount) { - - r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; - r_error.argument = ac; - return Variant(); - } - - for (int i = 0; i < p_argcount; i++) { - - if (!Variant::can_convert(p_args[i]->get_type(), E->get().argtypes[i])) { - - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = i; - r_error.expected = E->get().argtypes[i]; - } - } - - jvalue *v = nullptr; - - if (p_argcount) { - - v = (jvalue *)alloca(sizeof(jvalue) * p_argcount); - } - - JNIEnv *env = ThreadAndroid::get_env(); - - int res = env->PushLocalFrame(16); - - ERR_FAIL_COND_V(res != 0, Variant()); - - List<jobject> to_erase; - for (int i = 0; i < p_argcount; i++) { - - jvalret vr = _variant_to_jvalue(env, E->get().argtypes[i], p_args[i]); - v[i] = vr.val; - if (vr.obj) - to_erase.push_back(vr.obj); - } - - Variant ret; - - switch (E->get().ret_type) { - - case Variant::NIL: { - - env->CallVoidMethodA(instance, E->get().method, v); - } break; - case Variant::BOOL: { - - ret = env->CallBooleanMethodA(instance, E->get().method, v) == JNI_TRUE; - } break; - case Variant::INT: { - - ret = env->CallIntMethodA(instance, E->get().method, v); - } break; - case Variant::FLOAT: { - - ret = env->CallFloatMethodA(instance, E->get().method, v); - } break; - case Variant::STRING: { - - jobject o = env->CallObjectMethodA(instance, E->get().method, v); - ret = jstring_to_string((jstring)o, env); - env->DeleteLocalRef(o); - } break; - case Variant::PACKED_STRING_ARRAY: { - - jobjectArray arr = (jobjectArray)env->CallObjectMethodA(instance, E->get().method, v); - - ret = _jobject_to_variant(env, arr); - - env->DeleteLocalRef(arr); - } break; - case Variant::PACKED_INT32_ARRAY: { - - jintArray arr = (jintArray)env->CallObjectMethodA(instance, E->get().method, v); - - int fCount = env->GetArrayLength(arr); - Vector<int> sarr; - sarr.resize(fCount); - - int *w = sarr.ptrw(); - env->GetIntArrayRegion(arr, 0, fCount, w); - ret = sarr; - env->DeleteLocalRef(arr); - } break; - case Variant::PACKED_FLOAT32_ARRAY: { - - jfloatArray arr = (jfloatArray)env->CallObjectMethodA(instance, E->get().method, v); - - int fCount = env->GetArrayLength(arr); - Vector<float> sarr; - sarr.resize(fCount); - - float *w = sarr.ptrw(); - env->GetFloatArrayRegion(arr, 0, fCount, w); - ret = sarr; - env->DeleteLocalRef(arr); - } break; - -#ifndef _MSC_VER -#warning This is missing 64 bits arrays, I have no idea how to do it in JNI -#endif - case Variant::DICTIONARY: { - - jobject obj = env->CallObjectMethodA(instance, E->get().method, v); - ret = _jobject_to_variant(env, obj); - env->DeleteLocalRef(obj); - - } break; - default: { - - env->PopLocalFrame(nullptr); - ERR_FAIL_V(Variant()); - } break; - } - - while (to_erase.size()) { - env->DeleteLocalRef(to_erase.front()->get()); - to_erase.pop_front(); - } - - env->PopLocalFrame(nullptr); - - return ret; - } - - jobject get_instance() const { - - return instance; - } - void set_instance(jobject p_instance) { - - instance = p_instance; - } - - void add_method(const StringName &p_name, jmethodID p_method, const Vector<Variant::Type> &p_args, Variant::Type p_ret_type) { - - MethodData md; - md.method = p_method; - md.argtypes = p_args; - md.ret_type = p_ret_type; - method_map[p_name] = md; - } - - JNISingleton() { - instance = nullptr; - } -}; - #endif // JNI_UTILS_H diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index 344377d673..760157595c 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -32,15 +32,11 @@ #include "core/io/file_access_buffered_fa.h" #include "core/project_settings.h" -#if defined(OPENGL_ENABLED) -#include "drivers/gles2/rasterizer_gles2.h" -#endif #include "drivers/unix/dir_access_unix.h" #include "drivers/unix/file_access_unix.h" #include "file_access_android.h" #include "main/main.h" -#include "servers/rendering/rendering_server_raster.h" -#include "servers/rendering/rendering_server_wrap_mt.h" +#include "platform/android/display_server_android.h" #include "dir_access_jandroid.h" #include "file_access_jandroid.h" @@ -60,29 +56,6 @@ public: virtual ~AndroidLogger() {} }; -int OS_Android::get_video_driver_count() const { - - return 2; -} - -const char *OS_Android::get_video_driver_name(int p_driver) const { - - switch (p_driver) { - case VIDEO_DRIVER_GLES2: - return "GLES2"; - } - ERR_FAIL_V_MSG(nullptr, "Invalid video driver index: " + itos(p_driver) + "."); -} -int OS_Android::get_audio_driver_count() const { - - return 1; -} - -const char *OS_Android::get_audio_driver_name(int p_driver) const { - - return "Android"; -} - void OS_Android::initialize_core() { OS_Unix::initialize_core(); @@ -110,71 +83,33 @@ void OS_Android::initialize_core() { NetSocketAndroid::make_default(); } -void OS_Android::set_opengl_extensions(const char *p_gl_extensions) { - - ERR_FAIL_COND(!p_gl_extensions); - gl_extensions = p_gl_extensions; -} - -int OS_Android::get_current_video_driver() const { - return video_driver_index; +void OS_Android::initialize() { + initialize_core(); } -Error OS_Android::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { +void OS_Android::initialize_joypads() { + InputFilter::get_singleton()->set_fallback_mapping(godot_java->get_input_fallback_mapping()); - // FIXME: Add Vulkan support. Readd fallback code from Vulkan to GLES2? - -#if defined(OPENGL_ENABLED) - if (video_driver_index == VIDEO_DRIVER_GLES2) { - bool gl_initialization_error = false; - - if (RasterizerGLES2::is_viable() == OK) { - RasterizerGLES2::register_config(); - RasterizerGLES2::make_current(); - } else { - gl_initialization_error = true; - } - - if (gl_initialization_error) { - OS::get_singleton()->alert("Your device does not support any of the supported OpenGL versions.\n" - "Please try updating your Android version.", - "Unable to initialize video driver"); - return ERR_UNAVAILABLE; - } - } -#endif - - video_driver_index = p_video_driver; - - rendering_server = memnew(RenderingServerRaster); - if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { - rendering_server = memnew(RenderingServerWrapMT(rendering_server, false)); - } - - rendering_server->init(); - - AudioDriverManager::initialize(p_audio_driver); - - input = memnew(InputDefault); - input->set_fallback_mapping(godot_java->get_input_fallback_mapping()); - - return OK; + // This queries/updates the currently connected devices/joypads. + godot_java->init_input_devices(); } void OS_Android::set_main_loop(MainLoop *p_main_loop) { - main_loop = p_main_loop; - input->set_main_loop(p_main_loop); } void OS_Android::delete_main_loop() { - - memdelete(main_loop); + if (main_loop) { + memdelete(main_loop); + main_loop = nullptr; + } } void OS_Android::finalize() { +} - memdelete(input); +OS_Android *OS_Android::get_singleton() { + return (OS_Android *)OS::get_singleton(); } GodotJavaWrapper *OS_Android::get_godot_java() { @@ -185,12 +120,6 @@ GodotIOJavaWrapper *OS_Android::get_godot_io_java() { return godot_io_java; } -void OS_Android::alert(const String &p_alert, const String &p_title) { - - //print("ALERT: %s\n", p_alert.utf8().get_data()); - godot_java->alert(p_alert, p_title); -} - bool OS_Android::request_permission(const String &p_name) { return godot_java->request_permission(p_name); @@ -212,63 +141,6 @@ Error OS_Android::open_dynamic_library(const String p_path, void *&p_library_han return OK; } -void OS_Android::set_mouse_show(bool p_show) { - - //android has no mouse... -} - -void OS_Android::set_mouse_grab(bool p_grab) { - - //it really has no mouse...! -} - -bool OS_Android::is_mouse_grab_enabled() const { - - //*sigh* technology has evolved so much since i was a kid.. - return false; -} - -Point2 OS_Android::get_mouse_position() const { - - return Point2(); -} - -int OS_Android::get_mouse_button_state() const { - - return 0; -} - -void OS_Android::set_window_title(const String &p_title) { - //This queries/updates the currently connected devices/joypads - //Set_window_title is called when initializing the main loop (main.cpp) - //therefore this place is found to be suitable (I found no better). - godot_java->init_input_devices(); -} - -void OS_Android::set_video_mode(const VideoMode &p_video_mode, int p_screen) { -} - -OS::VideoMode OS_Android::get_video_mode(int p_screen) const { - - return default_videomode; -} - -void OS_Android::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) const { - - p_list->push_back(default_videomode); -} - -void OS_Android::set_keep_screen_on(bool p_enabled) { - OS::set_keep_screen_on(p_enabled); - - godot_java->set_keep_screen_on(p_enabled); -} - -Size2 OS_Android::get_window_size() const { - - return Vector2(default_videomode.width, default_videomode.height); -} - String OS_Android::get_name() const { return "Android"; @@ -279,11 +151,6 @@ MainLoop *OS_Android::get_main_loop() const { return main_loop; } -bool OS_Android::can_draw() const { - - return true; //always? -} - void OS_Android::main_loop_begin() { if (main_loop) @@ -304,277 +171,17 @@ void OS_Android::main_loop_end() { } void OS_Android::main_loop_focusout() { - - if (main_loop) - main_loop->notification(NOTIFICATION_WM_FOCUS_OUT); + DisplayServerAndroid::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_OUT); audio_driver_android.set_pause(true); } void OS_Android::main_loop_focusin() { - - if (main_loop) - main_loop->notification(NOTIFICATION_WM_FOCUS_IN); + DisplayServerAndroid::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_IN); audio_driver_android.set_pause(false); } -void OS_Android::process_joy_event(OS_Android::JoypadEvent p_event) { - - switch (p_event.type) { - case JOY_EVENT_BUTTON: - input->joy_button(p_event.device, p_event.index, p_event.pressed); - break; - case JOY_EVENT_AXIS: - InputDefault::JoyAxis value; - value.min = -1; - value.value = p_event.value; - input->joy_axis(p_event.device, p_event.index, value); - break; - case JOY_EVENT_HAT: - input->joy_hat(p_event.device, p_event.hat); - break; - default: - return; - } -} - -void OS_Android::process_event(Ref<InputEvent> p_event) { - - input->parse_input_event(p_event); -} - -void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos> &p_points) { - - switch (p_what) { - case 0: { //gesture begin - - if (touch.size()) { - //end all if exist - for (int i = 0; i < touch.size(); i++) { - - Ref<InputEventScreenTouch> ev; - ev.instance(); - ev->set_index(touch[i].id); - ev->set_pressed(false); - ev->set_position(touch[i].pos); - input->parse_input_event(ev); - } - } - - touch.resize(p_points.size()); - for (int i = 0; i < p_points.size(); i++) { - touch.write[i].id = p_points[i].id; - touch.write[i].pos = p_points[i].pos; - } - - //send touch - for (int i = 0; i < touch.size(); i++) { - - Ref<InputEventScreenTouch> ev; - ev.instance(); - ev->set_index(touch[i].id); - ev->set_pressed(true); - ev->set_position(touch[i].pos); - input->parse_input_event(ev); - } - - } break; - case 1: { //motion - - ERR_FAIL_COND(touch.size() != p_points.size()); - - for (int i = 0; i < touch.size(); i++) { - - int idx = -1; - for (int j = 0; j < p_points.size(); j++) { - - if (touch[i].id == p_points[j].id) { - idx = j; - break; - } - } - - ERR_CONTINUE(idx == -1); - - if (touch[i].pos == p_points[idx].pos) - continue; //no move unncesearily - - Ref<InputEventScreenDrag> ev; - ev.instance(); - ev->set_index(touch[i].id); - ev->set_position(p_points[idx].pos); - ev->set_relative(p_points[idx].pos - touch[i].pos); - input->parse_input_event(ev); - touch.write[i].pos = p_points[idx].pos; - } - - } break; - case 2: { //release - - if (touch.size()) { - //end all if exist - for (int i = 0; i < touch.size(); i++) { - - Ref<InputEventScreenTouch> ev; - ev.instance(); - ev->set_index(touch[i].id); - ev->set_pressed(false); - ev->set_position(touch[i].pos); - input->parse_input_event(ev); - } - touch.clear(); - } - } break; - case 3: { // add touch - - for (int i = 0; i < p_points.size(); i++) { - if (p_points[i].id == p_pointer) { - TouchPos tp = p_points[i]; - touch.push_back(tp); - - Ref<InputEventScreenTouch> ev; - ev.instance(); - - ev->set_index(tp.id); - ev->set_pressed(true); - ev->set_position(tp.pos); - input->parse_input_event(ev); - - break; - } - } - } break; - case 4: { // remove touch - - for (int i = 0; i < touch.size(); i++) { - if (touch[i].id == p_pointer) { - - Ref<InputEventScreenTouch> ev; - ev.instance(); - ev->set_index(touch[i].id); - ev->set_pressed(false); - ev->set_position(touch[i].pos); - input->parse_input_event(ev); - touch.remove(i); - - break; - } - } - } break; - } -} - -void OS_Android::process_hover(int p_type, Point2 p_pos) { - // https://developer.android.com/reference/android/view/MotionEvent.html#ACTION_HOVER_ENTER - switch (p_type) { - case 7: // hover move - case 9: // hover enter - case 10: { // hover exit - Ref<InputEventMouseMotion> ev; - ev.instance(); - ev->set_position(p_pos); - ev->set_global_position(p_pos); - ev->set_relative(p_pos - hover_prev_pos); - input->parse_input_event(ev); - hover_prev_pos = p_pos; - } break; - } -} - -void OS_Android::process_double_tap(Point2 p_pos) { - Ref<InputEventMouseButton> ev; - ev.instance(); - ev->set_position(p_pos); - ev->set_global_position(p_pos); - ev->set_pressed(false); - ev->set_doubleclick(true); - input->parse_input_event(ev); -} - -void OS_Android::process_scroll(Point2 p_pos) { - Ref<InputEventPanGesture> ev; - ev.instance(); - ev->set_position(p_pos); - ev->set_delta(p_pos - scroll_prev_pos); - input->parse_input_event(ev); - scroll_prev_pos = p_pos; -} - -void OS_Android::process_accelerometer(const Vector3 &p_accelerometer) { - - input->set_accelerometer(p_accelerometer); -} - -void OS_Android::process_gravity(const Vector3 &p_gravity) { - - input->set_gravity(p_gravity); -} - -void OS_Android::process_magnetometer(const Vector3 &p_magnetometer) { - - input->set_magnetometer(p_magnetometer); -} - -void OS_Android::process_gyroscope(const Vector3 &p_gyroscope) { - - input->set_gyroscope(p_gyroscope); -} - -bool OS_Android::has_touchscreen_ui_hint() const { - - return true; -} - -bool OS_Android::has_virtual_keyboard() const { - - return true; -} - -int OS_Android::get_virtual_keyboard_height() const { - return godot_io_java->get_vk_height(); - - // ERR_PRINT("Cannot obtain virtual keyboard height."); - // return 0; -} - -void OS_Android::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_input_length) { - - if (godot_io_java->has_vk()) { - godot_io_java->show_vk(p_existing_text, p_max_input_length); - } else { - - ERR_PRINT("Virtual keyboard not available"); - }; -} - -void OS_Android::hide_virtual_keyboard() { - - if (godot_io_java->has_vk()) { - - godot_io_java->hide_vk(); - } else { - - ERR_PRINT("Virtual keyboard not available"); - }; -} - -void OS_Android::init_video_mode(int p_video_width, int p_video_height) { - - default_videomode.width = p_video_width; - default_videomode.height = p_video_height; - default_videomode.fullscreen = true; - default_videomode.resizable = false; -} - void OS_Android::main_loop_request_go_back() { - - if (main_loop) - main_loop->notification(NOTIFICATION_WM_GO_BACK_REQUEST); -} - -void OS_Android::set_display_size(Size2 p_size) { - - default_videomode.width = p_size.x; - default_videomode.height = p_size.y; + DisplayServerAndroid::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_GO_BACK_REQUEST); } Error OS_Android::shell_open(String p_uri) { @@ -597,26 +204,6 @@ String OS_Android::get_locale() const { return OS_Unix::get_locale(); } -void OS_Android::set_clipboard(const String &p_text) { - - // DO we really need the fallback to OS_Unix here?! - if (godot_java->has_set_clipboard()) { - godot_java->set_clipboard(p_text); - } else { - OS_Unix::set_clipboard(p_text); - } -} - -String OS_Android::get_clipboard() const { - - // DO we really need the fallback to OS_Unix here?! - if (godot_java->has_get_clipboard()) { - return godot_java->get_clipboard(); - } - - return OS_Unix::get_clipboard(); -} - String OS_Android::get_model_name() const { String model = godot_io_java->get_model(); @@ -626,11 +213,6 @@ String OS_Android::get_model_name() const { return OS_Unix::get_model_name(); } -int OS_Android::get_screen_dpi(int p_screen) const { - - return godot_io_java->get_screen_dpi(); -} - String OS_Android::get_user_data_dir() const { if (data_dir_cache != String()) @@ -662,11 +244,6 @@ String OS_Android::get_user_data_dir() const { return "."; } -void OS_Android::set_screen_orientation(ScreenOrientation p_orientation) { - - godot_io_java->set_screen_orientation(p_orientation); -} - String OS_Android::get_unique_id() const { String unique_id = godot_io_java->get_unique_id(); @@ -676,50 +253,46 @@ String OS_Android::get_unique_id() const { return OS::get_unique_id(); } -Error OS_Android::native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track) { - // FIXME: Add support for volume, audio and subtitle tracks - - godot_io_java->play_video(p_path); - return OK; -} - -bool OS_Android::native_video_is_playing() const { - - return godot_io_java->is_video_playing(); -} - -void OS_Android::native_video_pause() { - - godot_io_java->pause_video(); -} - String OS_Android::get_system_dir(SystemDir p_dir) const { return godot_io_java->get_system_dir(p_dir); } -void OS_Android::native_video_stop() { +void OS_Android::set_display_size(const Size2i &p_size) { + display_size = p_size; +} - godot_io_java->stop_video(); +Size2i OS_Android::get_display_size() const { + return display_size; } void OS_Android::set_context_is_16_bits(bool p_is_16) { - +#if defined(OPENGL_ENABLED) //use_16bits_fbo = p_is_16; //if (rasterizer) // rasterizer->set_force_16_bits_fbo(p_is_16); +#endif } -void OS_Android::joy_connection_changed(int p_device, bool p_connected, String p_name) { - return input->joy_connection_changed(p_device, p_connected, p_name, ""); +void OS_Android::set_opengl_extensions(const char *p_gl_extensions) { +#if defined(OPENGL_ENABLED) + ERR_FAIL_COND(!p_gl_extensions); + gl_extensions = p_gl_extensions; +#endif } -bool OS_Android::is_joy_known(int p_device) { - return input->is_joy_mapped(p_device); +void OS_Android::set_native_window(ANativeWindow *p_native_window) { +#if defined(VULKAN_ENABLED) + native_window = p_native_window; +#endif } -String OS_Android::get_joy_guid(int p_device) const { - return input->get_joy_guid_remapped(p_device); +ANativeWindow *OS_Android::get_native_window() const { +#if defined(VULKAN_ENABLED) + return native_window; +#else + return nullptr; +#endif } void OS_Android::vibrate_handheld(int p_duration_ms) { @@ -747,19 +320,21 @@ bool OS_Android::_check_internal_feature_support(const String &p_feature) { } OS_Android::OS_Android(GodotJavaWrapper *p_godot_java, GodotIOJavaWrapper *p_godot_io_java, bool p_use_apk_expansion) { + display_size.width = 800; + display_size.height = 600; use_apk_expansion = p_use_apk_expansion; - default_videomode.width = 800; - default_videomode.height = 600; - default_videomode.fullscreen = true; - default_videomode.resizable = false; main_loop = nullptr; + +#if defined(OPENGL_ENABLED) gl_extensions = nullptr; - //rasterizer = nullptr; use_gl2 = false; +#endif - rendering_server = nullptr; +#if defined(VULKAN_ENABLED) + native_window = nullptr; +#endif godot_java = p_godot_java; godot_io_java = p_godot_io_java; @@ -769,6 +344,8 @@ OS_Android::OS_Android(GodotJavaWrapper *p_godot_java, GodotIOJavaWrapper *p_god _set_logger(memnew(CompositeLogger(loggers))); AudioDriverManager::add_driver(&audio_driver_android); + + DisplayServerAndroid::register_android_driver(); } OS_Android::~OS_Android() { diff --git a/platform/android/os_android.h b/platform/android/os_android.h index 8a91412ef6..cac7efaa88 100644 --- a/platform/android/os_android.h +++ b/platform/android/os_android.h @@ -33,78 +33,45 @@ #include "audio_driver_jandroid.h" #include "audio_driver_opensl.h" -#include "core/input/input_filter.h" #include "core/os/main_loop.h" #include "drivers/unix/os_unix.h" #include "servers/audio_server.h" -#include "servers/rendering/rasterizer.h" class GodotJavaWrapper; class GodotIOJavaWrapper; -class OS_Android : public OS_Unix { -public: - struct TouchPos { - int id; - Point2 pos; - }; - - enum { - JOY_EVENT_BUTTON = 0, - JOY_EVENT_AXIS = 1, - JOY_EVENT_HAT = 2 - }; - - struct JoypadEvent { - - int device; - int type; - int index; - bool pressed; - float value; - int hat; - }; +struct ANativeWindow; +class OS_Android : public OS_Unix { private: - Vector<TouchPos> touch; - Point2 hover_prev_pos; // needed to calculate the relative position on hover events - Point2 scroll_prev_pos; // needed to calculate the relative position on scroll events + Size2i display_size; - bool use_gl2; bool use_apk_expansion; +#if defined(OPENGL_ENABLED) bool use_16bits_fbo; + const char *gl_extensions; +#endif - RenderingServer *rendering_server; +#if defined(VULKAN_ENABLED) + ANativeWindow *native_window; +#endif mutable String data_dir_cache; //AudioDriverAndroid audio_driver_android; AudioDriverOpenSL audio_driver_android; - const char *gl_extensions; - - InputDefault *input; - VideoMode default_videomode; MainLoop *main_loop; GodotJavaWrapper *godot_java; GodotIOJavaWrapper *godot_io_java; - int video_driver_index; - public: - // functions used by main to initialize/deinitialize the OS - virtual int get_video_driver_count() const; - virtual const char *get_video_driver_name(int p_driver) const; - - virtual int get_audio_driver_count() const; - virtual const char *get_audio_driver_name(int p_driver) const; - - virtual int get_current_video_driver() const; - virtual void initialize_core(); - virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver); + virtual void initialize(); + + virtual void initialize_joypads(); virtual void set_main_loop(MainLoop *p_main_loop); virtual void delete_main_loop(); @@ -113,37 +80,19 @@ public: typedef int64_t ProcessID; - static OS *get_singleton(); + static OS_Android *get_singleton(); GodotJavaWrapper *get_godot_java(); GodotIOJavaWrapper *get_godot_io_java(); - virtual void alert(const String &p_alert, const String &p_title = "ALERT!"); virtual bool request_permission(const String &p_name); virtual bool request_permissions(); virtual Vector<String> get_granted_permissions() const; virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false); - virtual void set_mouse_show(bool p_show); - virtual void set_mouse_grab(bool p_grab); - virtual bool is_mouse_grab_enabled() const; - virtual Point2 get_mouse_position() const; - virtual int get_mouse_button_state() const; - virtual void set_window_title(const String &p_title); - - virtual void set_video_mode(const VideoMode &p_video_mode, int p_screen = 0); - virtual VideoMode get_video_mode(int p_screen = 0) const; - virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const; - - virtual void set_keep_screen_on(bool p_enabled); - - virtual Size2 get_window_size() const; - virtual String get_name() const; virtual MainLoop *get_main_loop() const; - virtual bool can_draw() const; - void main_loop_begin(); bool main_loop_iterate(); void main_loop_request_go_back(); @@ -151,53 +100,25 @@ public: void main_loop_focusout(); void main_loop_focusin(); - virtual bool has_touchscreen_ui_hint() const; - - virtual bool has_virtual_keyboard() const; - virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_input_length = -1); - virtual void hide_virtual_keyboard(); - virtual int get_virtual_keyboard_height() const; - - void set_opengl_extensions(const char *p_gl_extensions); - void set_display_size(Size2 p_size); + void set_display_size(const Size2i &p_size); + Size2i get_display_size() const; void set_context_is_16_bits(bool p_is_16); + void set_opengl_extensions(const char *p_gl_extensions); - virtual void set_screen_orientation(ScreenOrientation p_orientation); + void set_native_window(ANativeWindow *p_native_window); + ANativeWindow *get_native_window() const; virtual Error shell_open(String p_uri); virtual String get_user_data_dir() const; virtual String get_resource_dir() const; virtual String get_locale() const; - virtual void set_clipboard(const String &p_text); - virtual String get_clipboard() const; virtual String get_model_name() const; - virtual int get_screen_dpi(int p_screen = 0) const; virtual String get_unique_id() const; virtual String get_system_dir(SystemDir p_dir) const; - void process_accelerometer(const Vector3 &p_accelerometer); - void process_gravity(const Vector3 &p_gravity); - void process_magnetometer(const Vector3 &p_magnetometer); - void process_gyroscope(const Vector3 &p_gyroscope); - void process_touch(int p_what, int p_pointer, const Vector<TouchPos> &p_points); - void process_hover(int p_type, Point2 p_pos); - void process_double_tap(Point2 p_pos); - void process_scroll(Point2 p_pos); - void process_joy_event(JoypadEvent p_event); - void process_event(Ref<InputEvent> p_event); - void init_video_mode(int p_video_width, int p_video_height); - - virtual Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track); - virtual bool native_video_is_playing() const; - virtual void native_video_pause(); - virtual void native_video_stop(); - - virtual bool is_joy_known(int p_device); - virtual String get_joy_guid(int p_device) const; - void joy_connection_changed(int p_device, bool p_connected, String p_name); void vibrate_handheld(int p_duration_ms); virtual bool _check_internal_feature_support(const String &p_feature); diff --git a/platform/android/plugin/godot_plugin_jni.cpp b/platform/android/plugin/godot_plugin_jni.cpp index 7413236e5d..c3bfb2f2ed 100644 --- a/platform/android/plugin/godot_plugin_jni.cpp +++ b/platform/android/plugin/godot_plugin_jni.cpp @@ -33,6 +33,7 @@ #include <core/engine.h> #include <core/error_macros.h> #include <core/project_settings.h> +#include <platform/android/api/jni_singleton.h> #include <platform/android/jni_utils.h> #include <platform/android/string_android.h> @@ -43,7 +44,7 @@ extern "C" { JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSingleton(JNIEnv *env, jobject obj, jstring name) { String singname = jstring_to_string(name, env); - JNISingleton *s = memnew(JNISingleton); + JNISingleton *s = (JNISingleton *)ClassDB::instance("JNISingleton"); s->set_instance(env->NewGlobalRef(obj)); jni_singletons[singname] = s; @@ -86,6 +87,51 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegis s->add_method(mname, mid, types, get_jni_type(retval)); } +JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSignal(JNIEnv *env, jobject obj, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_param_types) { + String singleton_name = jstring_to_string(j_plugin_name, env); + + ERR_FAIL_COND(!jni_singletons.has(singleton_name)); + + JNISingleton *singleton = jni_singletons.get(singleton_name); + + String signal_name = jstring_to_string(j_signal_name, env); + Vector<Variant::Type> types; + + int stringCount = env->GetArrayLength(j_signal_param_types); + + for (int i = 0; i < stringCount; i++) { + + jstring j_signal_param_type = (jstring)env->GetObjectArrayElement(j_signal_param_types, i); + const String signal_param_type = jstring_to_string(j_signal_param_type, env); + types.push_back(get_jni_type(signal_param_type)); + } + + singleton->add_signal(signal_name, types); +} + +JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitSignal(JNIEnv *env, jobject obj, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_params) { + String singleton_name = jstring_to_string(j_plugin_name, env); + + ERR_FAIL_COND(!jni_singletons.has(singleton_name)); + + JNISingleton *singleton = jni_singletons.get(singleton_name); + + String signal_name = jstring_to_string(j_signal_name, env); + + int count = env->GetArrayLength(j_signal_params); + const Variant *args[count]; + + for (int i = 0; i < count; i++) { + + jobject j_param = env->GetObjectArrayElement(j_signal_params, i); + Variant variant = _jobject_to_variant(env, j_param); + args[i] = &variant; + env->DeleteLocalRef(j_param); + }; + + singleton->emit_signal(signal_name, args, count); +} + JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterGDNativeLibraries(JNIEnv *env, jobject obj, jobjectArray gdnlib_paths) { int gdnlib_count = env->GetArrayLength(gdnlib_paths); if (gdnlib_count == 0) { diff --git a/platform/android/plugin/godot_plugin_jni.h b/platform/android/plugin/godot_plugin_jni.h index 0d613d3bfe..80ce332e7c 100644 --- a/platform/android/plugin/godot_plugin_jni.h +++ b/platform/android/plugin/godot_plugin_jni.h @@ -37,6 +37,8 @@ extern "C" { JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSingleton(JNIEnv *env, jobject obj, jstring name); JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterMethod(JNIEnv *env, jobject obj, jstring sname, jstring name, jstring ret, jobjectArray args); +JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSignal(JNIEnv *env, jobject obj, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_param_types); +JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitSignal(JNIEnv *env, jobject obj, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_params); JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterGDNativeLibraries(JNIEnv *env, jobject obj, jobjectArray gdnlib_paths); } diff --git a/platform/android/vulkan/vulkan_context_android.cpp b/platform/android/vulkan/vulkan_context_android.cpp new file mode 100644 index 0000000000..5fb7a83da4 --- /dev/null +++ b/platform/android/vulkan/vulkan_context_android.cpp @@ -0,0 +1,60 @@ +/*************************************************************************/ +/* vulkan_context_android.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "vulkan_context_android.h" +#include <vulkan/vulkan_android.h> + +const char *VulkanContextAndroid::_get_platform_surface_extension() const { + return VK_KHR_ANDROID_SURFACE_EXTENSION_NAME; +} + +int VulkanContextAndroid::window_create(ANativeWindow *p_window, int p_width, int p_height) { + VkAndroidSurfaceCreateInfoKHR createInfo; + createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR; + createInfo.pNext = nullptr; + createInfo.flags = 0; + createInfo.window = p_window; + + VkSurfaceKHR surface; + VkResult err = vkCreateAndroidSurfaceKHR(_get_instance(), &createInfo, nullptr, &surface); + if (err != VK_SUCCESS) { + ERR_FAIL_V_MSG(-1, "vkCreateAndroidSurfaceKHR failed with error " + itos(err)); + } + + return _window_create(DisplayServer::MAIN_WINDOW_ID, surface, p_width, p_height); +} + +VulkanContextAndroid::VulkanContextAndroid() { + // TODO: fix validation layers + use_validation_layers = false; +} + +VulkanContextAndroid::~VulkanContextAndroid() { +} diff --git a/platform/android/vulkan/vk_renderer_jni.cpp b/platform/android/vulkan/vulkan_context_android.h index 3026e7daad..7e698ada4f 100644 --- a/platform/android/vulkan/vk_renderer_jni.cpp +++ b/platform/android/vulkan/vulkan_context_android.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* vk_renderer_jni.cpp */ +/* vulkan_context_android.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,31 +28,22 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "vk_renderer_jni.h" +#ifndef VULKAN_CONTEXT_ANDROID_H +#define VULKAN_CONTEXT_ANDROID_H -extern "C" { +#include "drivers/vulkan/vulkan_context.h" -JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkSurfaceCreated(JNIEnv *env, jobject obj, jobject j_surface) { - // TODO: complete -} +struct ANativeWindow; -JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkSurfaceChanged(JNIEnv *env, jobject object, jobject j_surface, jint width, jint height) { - // TODO: complete -} +class VulkanContextAndroid : public VulkanContext { -JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkResume(JNIEnv *env, jobject obj) { - // TODO: complete -} + virtual const char *_get_platform_surface_extension() const; -JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkDrawFrame(JNIEnv *env, jobject obj) { - // TODO: complete -} +public: + int window_create(ANativeWindow *p_window, int p_width, int p_height); -JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkPause(JNIEnv *env, jobject obj) { - // TODO: complete -} + VulkanContextAndroid(); + ~VulkanContextAndroid(); +}; -JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkDestroy(JNIEnv *env, jobject obj) { - // TODO: complete -} -} +#endif // VULKAN_CONTEXT_ANDROID_H diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index 47497eb95f..78ddef5ff6 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -254,10 +254,10 @@ bool DisplayServerX11::_refresh_device_info() { bool absolute_mode = false; int resolution_x = 0; int resolution_y = 0; - int range_min_x = 0; - int range_min_y = 0; - int range_max_x = 0; - int range_max_y = 0; + double range_min_x = 0; + double range_min_y = 0; + double range_max_x = 0; + double range_max_y = 0; int pressure_resolution = 0; int tilt_resolution_x = 0; int tilt_resolution_y = 0; @@ -1471,8 +1471,11 @@ DisplayServer::WindowMode DisplayServerX11::window_get_mode(WindowID p_window) c if (result == Success && data) { long *state = (long *)data; - if (state[0] == WM_IconicState) + if (state[0] == WM_IconicState) { + XFree(data); return WINDOW_MODE_MINIMIZED; + } + XFree(data); } } diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index c46b6eeb5c..8ba334bc67 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -435,10 +435,10 @@ bool Area2D::is_monitorable() const { return monitorable; } -Array Area2D::get_overlapping_bodies() const { +TypedArray<Node2D> Area2D::get_overlapping_bodies() const { ERR_FAIL_COND_V_MSG(!monitoring, Array(), "Can't find overlapping bodies when monitoring is off."); - Array ret; + TypedArray<Node2D> ret; ret.resize(body_map.size()); int idx = 0; for (const Map<ObjectID, BodyState>::Element *E = body_map.front(); E; E = E->next()) { @@ -453,10 +453,10 @@ Array Area2D::get_overlapping_bodies() const { return ret; } -Array Area2D::get_overlapping_areas() const { +TypedArray<Area2D> Area2D::get_overlapping_areas() const { ERR_FAIL_COND_V_MSG(!monitoring, Array(), "Can't find overlapping bodies when monitoring is off."); - Array ret; + TypedArray<Area2D> ret; ret.resize(area_map.size()); int idx = 0; for (const Map<ObjectID, AreaState>::Element *E = area_map.front(); E; E = E->next()) { diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h index c5e6635412..0e2c0ac672 100644 --- a/scene/2d/area_2d.h +++ b/scene/2d/area_2d.h @@ -178,8 +178,8 @@ public: void set_collision_layer_bit(int p_bit, bool p_value); bool get_collision_layer_bit(int p_bit) const; - Array get_overlapping_bodies() const; //function for script - Array get_overlapping_areas() const; //function for script + TypedArray<Node2D> get_overlapping_bodies() const; //function for script + TypedArray<Area2D> get_overlapping_areas() const; //function for script bool overlaps_area(Node *p_area) const; bool overlaps_body(Node *p_body) const; diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp index d77fd5b097..19484442b1 100644 --- a/scene/2d/navigation_region_2d.cpp +++ b/scene/2d/navigation_region_2d.cpp @@ -95,7 +95,7 @@ Vector<Vector2> NavigationPolygon::get_vertices() const { return vertices; } -void NavigationPolygon::_set_polygons(const Array &p_array) { +void NavigationPolygon::_set_polygons(const TypedArray<Vector<int32_t>> &p_array) { { MutexLock lock(navmesh_generation); @@ -118,7 +118,7 @@ Array NavigationPolygon::_get_polygons() const { return ret; } -void NavigationPolygon::_set_outlines(const Array &p_array) { +void NavigationPolygon::_set_outlines(const TypedArray<Vector<int32_t>> &p_array) { outlines.resize(p_array.size()); for (int i = 0; i < p_array.size(); i++) { diff --git a/scene/2d/navigation_region_2d.h b/scene/2d/navigation_region_2d.h index 73e056a353..cbfe4299fb 100644 --- a/scene/2d/navigation_region_2d.h +++ b/scene/2d/navigation_region_2d.h @@ -55,10 +55,10 @@ class NavigationPolygon : public Resource { protected: static void _bind_methods(); - void _set_polygons(const Array &p_array); + void _set_polygons(const TypedArray<Vector<int32_t>> &p_array); Array _get_polygons() const; - void _set_outlines(const Array &p_array); + void _set_outlines(const TypedArray<Vector<int32_t>> &p_array); Array _get_outlines() const; public: diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp index d55b21bc24..ed8481db4a 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -321,16 +321,14 @@ void PathFollow2D::set_offset(float p_offset) { offset = p_offset; if (path) { - if (path->get_curve().is_valid() && path->get_curve()->get_baked_length()) { + if (path->get_curve().is_valid()) { float path_length = path->get_curve()->get_baked_length(); if (loop) { - while (offset > path_length) - offset -= path_length; - - while (offset < 0) - offset += path_length; - + offset = Math::fposmod(offset, path_length); + if (!Math::is_zero_approx(p_offset) && Math::is_zero_approx(offset)) { + offset = path_length; + } } else { offset = CLAMP(offset, 0, path_length); } diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 21dc9537ec..de15f0efc2 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -139,7 +139,7 @@ PhysicsBody2D::PhysicsBody2D(PhysicsServer2D::BodyMode p_mode) : set_pickable(false); } -Array PhysicsBody2D::get_collision_exceptions() { +TypedArray<PhysicsBody2D> PhysicsBody2D::get_collision_exceptions() { List<RID> exceptions; PhysicsServer2D::get_singleton()->body_get_collision_exceptions(get_rid(), &exceptions); Array ret; @@ -739,11 +739,11 @@ RigidBody2D::CCDMode RigidBody2D::get_continuous_collision_detection_mode() cons return ccd_mode; } -Array RigidBody2D::get_colliding_bodies() const { +TypedArray<Node2D> RigidBody2D::get_colliding_bodies() const { ERR_FAIL_COND_V(!contact_monitor, Array()); - Array ret; + TypedArray<Node2D> ret; ret.resize(contact_monitor->body_map.size()); int idx = 0; for (const Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) { diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index 0d92a820e3..75f4f778bf 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -67,7 +67,7 @@ public: void set_collision_layer_bit(int p_bit, bool p_value); bool get_collision_layer_bit(int p_bit) const; - Array get_collision_exceptions(); + TypedArray<PhysicsBody2D> get_collision_exceptions(); void add_collision_exception_with(Node *p_node); //must be physicsbody void remove_collision_exception_with(Node *p_node); @@ -256,7 +256,7 @@ public: void add_force(const Vector2 &p_offset, const Vector2 &p_force); void add_torque(float p_torque); - Array get_colliding_bodies() const; //function for script + TypedArray<Node2D> get_colliding_bodies() const; //function for script virtual String get_configuration_warning() const; diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 1cf12e4421..9628c01718 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -1691,27 +1691,27 @@ bool TileMap::is_centered_textures_enabled() const { return centered_textures; } -Array TileMap::get_used_cells() const { +TypedArray<Vector2i> TileMap::get_used_cells() const { - Array a; + TypedArray<Vector2i> a; a.resize(tile_map.size()); int i = 0; for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) { - Vector2 p(E->key().x, E->key().y); + Vector2i p(E->key().x, E->key().y); a[i++] = p; } return a; } -Array TileMap::get_used_cells_by_id(int p_id) const { +TypedArray<Vector2i> TileMap::get_used_cells_by_id(int p_id) const { - Array a; + TypedArray<Vector2i> a; for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) { if (E->value().id == p_id) { - Vector2 p(E->key().x, E->key().y); + Vector2i p(E->key().x, E->key().y); a.push_back(p); } } diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index d9490aae13..cc1537f583 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -328,8 +328,8 @@ public: void set_centered_textures(bool p_enable); bool is_centered_textures_enabled() const; - Array get_used_cells() const; - Array get_used_cells_by_id(int p_id) const; + TypedArray<Vector2i> get_used_cells() const; + TypedArray<Vector2i> get_used_cells_by_id(int p_id) const; Rect2 get_used_rect(); // Not const because of cache void set_occluder_light_mask(int p_mask); diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp index 17ae553e5e..b72483d71b 100644 --- a/scene/3d/area_3d.cpp +++ b/scene/3d/area_3d.cpp @@ -416,7 +416,7 @@ bool Area3D::is_monitoring() const { return monitoring; } -Array Area3D::get_overlapping_bodies() const { +TypedArray<Node3D> Area3D::get_overlapping_bodies() const { ERR_FAIL_COND_V(!monitoring, Array()); Array ret; @@ -451,7 +451,7 @@ bool Area3D::is_monitorable() const { return monitorable; } -Array Area3D::get_overlapping_areas() const { +TypedArray<Area3D> Area3D::get_overlapping_areas() const { ERR_FAIL_COND_V(!monitoring, Array()); Array ret; diff --git a/scene/3d/area_3d.h b/scene/3d/area_3d.h index ff6c0b6b08..f6503c6d2d 100644 --- a/scene/3d/area_3d.h +++ b/scene/3d/area_3d.h @@ -184,8 +184,8 @@ public: void set_collision_layer_bit(int p_bit, bool p_value); bool get_collision_layer_bit(int p_bit) const; - Array get_overlapping_bodies() const; - Array get_overlapping_areas() const; //function for script + TypedArray<Node3D> get_overlapping_bodies() const; + TypedArray<Area3D> get_overlapping_areas() const; //function for script bool overlaps_area(Node *p_area) const; bool overlaps_body(Node *p_body) const; diff --git a/scene/3d/decal.cpp b/scene/3d/decal.cpp new file mode 100644 index 0000000000..4c824aedc4 --- /dev/null +++ b/scene/3d/decal.cpp @@ -0,0 +1,235 @@ +/*************************************************************************/ +/* decal.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "decal.h" + +void Decal::set_extents(const Vector3 &p_extents) { + extents = p_extents; + RS::get_singleton()->decal_set_extents(decal, p_extents); + update_gizmo(); + _change_notify("extents"); +} + +Vector3 Decal::get_extents() const { + return extents; +} + +void Decal::set_texture(DecalTexture p_type, const Ref<Texture2D> &p_texture) { + ERR_FAIL_INDEX(p_type, TEXTURE_MAX); + textures[p_type] = p_texture; + RID texture_rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); + RS::get_singleton()->decal_set_texture(decal, RS::DecalTexture(p_type), texture_rid); +} +Ref<Texture2D> Decal::get_texture(DecalTexture p_type) const { + ERR_FAIL_INDEX_V(p_type, TEXTURE_MAX, Ref<Texture2D>()); + return textures[p_type]; +} + +void Decal::set_emission_energy(float p_energy) { + emission_energy = p_energy; + RS::get_singleton()->decal_set_emission_energy(decal, emission_energy); +} +float Decal::get_emission_energy() const { + return emission_energy; +} + +void Decal::set_albedo_mix(float p_mix) { + albedo_mix = p_mix; + RS::get_singleton()->decal_set_albedo_mix(decal, albedo_mix); +} +float Decal::get_albedo_mix() const { + return albedo_mix; +} + +void Decal::set_upper_fade(float p_fade) { + upper_fade = p_fade; + RS::get_singleton()->decal_set_fade(decal, upper_fade, lower_fade); +} +float Decal::get_upper_fade() const { + return upper_fade; +} + +void Decal::set_lower_fade(float p_fade) { + lower_fade = p_fade; + RS::get_singleton()->decal_set_fade(decal, upper_fade, lower_fade); +} +float Decal::get_lower_fade() const { + return lower_fade; +} + +void Decal::set_normal_fade(float p_fade) { + normal_fade = p_fade; + RS::get_singleton()->decal_set_normal_fade(decal, normal_fade); +} +float Decal::get_normal_fade() const { + return normal_fade; +} + +void Decal::set_modulate(Color p_modulate) { + modulate = p_modulate; + RS::get_singleton()->decal_set_modulate(decal, p_modulate); +} + +Color Decal::get_modulate() const { + return modulate; +} + +void Decal::set_enable_distance_fade(bool p_enable) { + distance_fade_enabled = p_enable; + RS::get_singleton()->decal_set_distance_fade(decal, distance_fade_enabled, distance_fade_begin, distance_fade_length); +} +bool Decal::is_distance_fade_enabled() const { + return distance_fade_enabled; +} + +void Decal::set_distance_fade_begin(float p_distance) { + distance_fade_begin = p_distance; + RS::get_singleton()->decal_set_distance_fade(decal, distance_fade_enabled, distance_fade_begin, distance_fade_length); +} +float Decal::get_distance_fade_begin() const { + return distance_fade_begin; +} + +void Decal::set_distance_fade_length(float p_length) { + distance_fade_length = p_length; + RS::get_singleton()->decal_set_distance_fade(decal, distance_fade_enabled, distance_fade_begin, distance_fade_length); +} +float Decal::get_distance_fade_length() const { + return distance_fade_length; +} + +void Decal::set_cull_mask(uint32_t p_layers) { + cull_mask = p_layers; + RS::get_singleton()->decal_set_cull_mask(decal, cull_mask); +} +uint32_t Decal::get_cull_mask() const { + return cull_mask; +} + +AABB Decal::get_aabb() const { + + AABB aabb; + aabb.position = -extents; + aabb.size = extents * 2.0; + return aabb; +} +Vector<Face3> Decal::get_faces(uint32_t p_usage_flags) const { + + return Vector<Face3>(); +} + +void Decal::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_extents", "extents"), &Decal::set_extents); + ClassDB::bind_method(D_METHOD("get_extents"), &Decal::get_extents); + + ClassDB::bind_method(D_METHOD("set_texture", "type", "texture"), &Decal::set_texture); + ClassDB::bind_method(D_METHOD("get_texture", "type"), &Decal::get_texture); + + ClassDB::bind_method(D_METHOD("set_emission_energy", "energy"), &Decal::set_emission_energy); + ClassDB::bind_method(D_METHOD("get_emission_energy"), &Decal::get_emission_energy); + + ClassDB::bind_method(D_METHOD("set_albedo_mix", "energy"), &Decal::set_albedo_mix); + ClassDB::bind_method(D_METHOD("get_albedo_mix"), &Decal::get_albedo_mix); + + ClassDB::bind_method(D_METHOD("set_modulate", "color"), &Decal::set_modulate); + ClassDB::bind_method(D_METHOD("get_modulate"), &Decal::get_modulate); + + ClassDB::bind_method(D_METHOD("set_upper_fade", "fade"), &Decal::set_upper_fade); + ClassDB::bind_method(D_METHOD("get_upper_fade"), &Decal::get_upper_fade); + + ClassDB::bind_method(D_METHOD("set_lower_fade", "fade"), &Decal::set_lower_fade); + ClassDB::bind_method(D_METHOD("get_lower_fade"), &Decal::get_lower_fade); + + ClassDB::bind_method(D_METHOD("set_normal_fade", "fade"), &Decal::set_normal_fade); + ClassDB::bind_method(D_METHOD("get_normal_fade"), &Decal::get_normal_fade); + + ClassDB::bind_method(D_METHOD("set_enable_distance_fade", "enable"), &Decal::set_enable_distance_fade); + ClassDB::bind_method(D_METHOD("is_distance_fade_enabled"), &Decal::is_distance_fade_enabled); + + ClassDB::bind_method(D_METHOD("set_distance_fade_begin", "distance"), &Decal::set_distance_fade_begin); + ClassDB::bind_method(D_METHOD("get_distance_fade_begin"), &Decal::get_distance_fade_begin); + + ClassDB::bind_method(D_METHOD("set_distance_fade_length", "distance"), &Decal::set_distance_fade_length); + ClassDB::bind_method(D_METHOD("get_distance_fade_length"), &Decal::get_distance_fade_length); + + ClassDB::bind_method(D_METHOD("set_cull_mask", "mask"), &Decal::set_cull_mask); + ClassDB::bind_method(D_METHOD("get_cull_mask"), &Decal::get_cull_mask); + + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0,1024,0.001,or_greater"), "set_extents", "get_extents"); + ADD_GROUP("Textures", "texture_"); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_albedo", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ALBEDO); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_NORMAL); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_orm", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ORM); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_emission", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_EMISSION); + ADD_GROUP("Parameters", ""); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_energy", PROPERTY_HINT_RANGE, "0,128,0.01"), "set_emission_energy", "get_emission_energy"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "modulate"), "set_modulate", "get_modulate"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "albedo_mix", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_albedo_mix", "get_albedo_mix"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "normal_fade", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_normal_fade", "get_normal_fade"); + ADD_GROUP("Vertical Fade", ""); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "upper_fade", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_upper_fade", "get_upper_fade"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lower_fade", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_lower_fade", "get_lower_fade"); + ADD_GROUP("Distance Fade", "distance_fade_"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "distance_fade_enabled"), "set_enable_distance_fade", "is_distance_fade_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_begin"), "set_distance_fade_begin", "get_distance_fade_begin"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_length"), "set_distance_fade_length", "get_distance_fade_length"); + ADD_GROUP("Cull Mask", ""); + ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_cull_mask", "get_cull_mask"); + + BIND_ENUM_CONSTANT(TEXTURE_ALBEDO); + BIND_ENUM_CONSTANT(TEXTURE_NORMAL); + BIND_ENUM_CONSTANT(TEXTURE_ORM); + BIND_ENUM_CONSTANT(TEXTURE_EMISSION); + BIND_ENUM_CONSTANT(TEXTURE_MAX); +} + +Decal::Decal() { + + extents = Vector3(1, 1, 1); + emission_energy = 1.0; + modulate = Color(1, 1, 1, 1); + albedo_mix = 1.0; + cull_mask = (1 << 20) - 1; + upper_fade = 0.3; + lower_fade = 0.3; + normal_fade = 0; + distance_fade_enabled = false; + distance_fade_begin = 10; + distance_fade_length = 1; + + decal = RenderingServer::get_singleton()->decal_create(); + RS::get_singleton()->instance_set_base(get_instance(), decal); +} + +Decal::~Decal() { + + RS::get_singleton()->free(decal); +} diff --git a/scene/3d/decal.h b/scene/3d/decal.h new file mode 100644 index 0000000000..665444829d --- /dev/null +++ b/scene/3d/decal.h @@ -0,0 +1,114 @@ +/*************************************************************************/ +/* decal.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef DECAL_H +#define DECAL_H + +#include "scene/3d/visual_instance_3d.h" +#include "scene/resources/texture.h" +#include "servers/rendering_server.h" + +class Decal : public VisualInstance3D { + GDCLASS(Decal, VisualInstance3D); + +public: + enum DecalTexture { + TEXTURE_ALBEDO, + TEXTURE_NORMAL, + TEXTURE_ORM, + TEXTURE_EMISSION, + TEXTURE_MAX + }; + +private: + RID decal; + Vector3 extents; + Ref<Texture2D> textures[TEXTURE_MAX]; + float emission_energy; + float albedo_mix; + Color modulate; + uint32_t cull_mask; + float normal_fade; + float upper_fade; + float lower_fade; + bool distance_fade_enabled; + float distance_fade_begin; + float distance_fade_length; + +protected: + static void _bind_methods(); + +public: + void set_extents(const Vector3 &p_extents); + Vector3 get_extents() const; + + void set_texture(DecalTexture p_type, const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_texture(DecalTexture p_type) const; + + void set_emission_energy(float p_energy); + float get_emission_energy() const; + + void set_albedo_mix(float p_mix); + float get_albedo_mix() const; + + void set_modulate(Color p_modulate); + Color get_modulate() const; + + void set_upper_fade(float p_energy); + float get_upper_fade() const; + + void set_lower_fade(float p_fade); + float get_lower_fade() const; + + void set_normal_fade(float p_fade); + float get_normal_fade() const; + + void set_enable_distance_fade(bool p_enable); + bool is_distance_fade_enabled() const; + + void set_distance_fade_begin(float p_distance); + float get_distance_fade_begin() const; + + void set_distance_fade_length(float p_length); + float get_distance_fade_length() const; + + void set_cull_mask(uint32_t p_layers); + uint32_t get_cull_mask() const; + + virtual AABB get_aabb() const; + virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const; + + Decal(); + ~Decal(); +}; + +VARIANT_ENUM_CAST(Decal::DecalTexture); + +#endif // DECAL_H diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp index be3b369724..c048f60ebd 100644 --- a/scene/3d/light_3d.cpp +++ b/scene/3d/light_3d.cpp @@ -70,7 +70,7 @@ void Light3D::set_shadow(bool p_enable) { shadow = p_enable; RS::get_singleton()->light_set_shadow(light, p_enable); - if (type == RenderingServer::LIGHT_SPOT) { + if (type == RenderingServer::LIGHT_SPOT || type == RenderingServer::LIGHT_OMNI) { update_configuration_warning(); } } @@ -166,6 +166,18 @@ Light3D::BakeMode Light3D::get_bake_mode() const { return bake_mode; } +void Light3D::set_projector(const Ref<Texture2D> &p_texture) { + + projector = p_texture; + RID tex_id = projector.is_valid() ? projector->get_rid() : RID(); + RS::get_singleton()->light_set_projector(light, tex_id); + update_configuration_warning(); +} + +Ref<Texture2D> Light3D::get_projector() const { + return projector; +} + void Light3D::_update_visibility() { if (!is_inside_tree()) @@ -217,8 +229,16 @@ bool Light3D::is_editor_only() const { void Light3D::_validate_property(PropertyInfo &property) const { - if (RenderingServer::get_singleton()->is_low_end() && property.name == "shadow_contact") { - property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; + if (get_light_type() == RS::LIGHT_DIRECTIONAL && property.name == "light_size") { + property.usage = 0; + } + + if (get_light_type() == RS::LIGHT_DIRECTIONAL && property.name == "light_projector") { + property.usage = 0; + } + + if (get_light_type() != RS::LIGHT_DIRECTIONAL && property.name == "light_angular_distance") { + property.usage = 0; } } @@ -251,10 +271,16 @@ void Light3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_bake_mode", "bake_mode"), &Light3D::set_bake_mode); ClassDB::bind_method(D_METHOD("get_bake_mode"), &Light3D::get_bake_mode); + ClassDB::bind_method(D_METHOD("set_projector", "projector"), &Light3D::set_projector); + ClassDB::bind_method(D_METHOD("get_projector"), &Light3D::get_projector); + ADD_GROUP("Light", "light_"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "light_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_color", "get_color"); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_param", "get_param", PARAM_ENERGY); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_indirect_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_param", "get_param", PARAM_INDIRECT_ENERGY); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "light_projector", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_projector", "get_projector"); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_size", PROPERTY_HINT_RANGE, "0,64,0.01,or_greater"), "set_param", "get_param", PARAM_SIZE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_angular_distance", PROPERTY_HINT_RANGE, "0,90,0.01"), "set_param", "get_param", PARAM_SIZE); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "light_negative"), "set_negative", "is_negative"); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_specular", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SPECULAR); ADD_PROPERTY(PropertyInfo(Variant::INT, "light_bake_mode", PROPERTY_HINT_ENUM, "Disable,Indirect,All"), "set_bake_mode", "get_bake_mode"); @@ -262,9 +288,11 @@ void Light3D::_bind_methods() { ADD_GROUP("Shadow", "shadow_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_enabled"), "set_shadow", "has_shadow"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "shadow_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_shadow_color", "get_shadow_color"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_bias", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_param", "get_param", PARAM_SHADOW_BIAS); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_contact", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_param", "get_param", PARAM_CONTACT_SHADOW_SIZE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_bias", PROPERTY_HINT_RANGE, "0,10,0.001"), "set_param", "get_param", PARAM_SHADOW_BIAS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_normal_bias", PROPERTY_HINT_RANGE, "0,10,0.001"), "set_param", "get_param", PARAM_SHADOW_NORMAL_BIAS); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_reverse_cull_face"), "set_shadow_reverse_cull_face", "get_shadow_reverse_cull_face"); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_transmittance_bias", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_param", "get_param", PARAM_TRANSMITTANCE_BIAS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_blur", PROPERTY_HINT_RANGE, "0.1,8,0.01"), "set_param", "get_param", PARAM_SHADOW_BLUR); ADD_GROUP("Editor", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_only"), "set_editor_only", "is_editor_only"); ADD_GROUP("", ""); @@ -273,10 +301,10 @@ void Light3D::_bind_methods() { BIND_ENUM_CONSTANT(PARAM_INDIRECT_ENERGY); BIND_ENUM_CONSTANT(PARAM_SPECULAR); BIND_ENUM_CONSTANT(PARAM_RANGE); + BIND_ENUM_CONSTANT(PARAM_SIZE); BIND_ENUM_CONSTANT(PARAM_ATTENUATION); BIND_ENUM_CONSTANT(PARAM_SPOT_ANGLE); BIND_ENUM_CONSTANT(PARAM_SPOT_ATTENUATION); - BIND_ENUM_CONSTANT(PARAM_CONTACT_SHADOW_SIZE); BIND_ENUM_CONSTANT(PARAM_SHADOW_MAX_DISTANCE); BIND_ENUM_CONSTANT(PARAM_SHADOW_SPLIT_1_OFFSET); BIND_ENUM_CONSTANT(PARAM_SHADOW_SPLIT_2_OFFSET); @@ -284,7 +312,9 @@ void Light3D::_bind_methods() { BIND_ENUM_CONSTANT(PARAM_SHADOW_FADE_START); BIND_ENUM_CONSTANT(PARAM_SHADOW_NORMAL_BIAS); BIND_ENUM_CONSTANT(PARAM_SHADOW_BIAS); - BIND_ENUM_CONSTANT(PARAM_SHADOW_BIAS_SPLIT_SCALE); + BIND_ENUM_CONSTANT(PARAM_SHADOW_PANCAKE_SIZE); + BIND_ENUM_CONSTANT(PARAM_SHADOW_BLUR); + BIND_ENUM_CONSTANT(PARAM_TRANSMITTANCE_BIAS); BIND_ENUM_CONSTANT(PARAM_MAX); BIND_ENUM_CONSTANT(BAKE_DISABLED); @@ -318,17 +348,20 @@ Light3D::Light3D(RenderingServer::LightType p_type) { set_param(PARAM_INDIRECT_ENERGY, 1); set_param(PARAM_SPECULAR, 0.5); set_param(PARAM_RANGE, 5); + set_param(PARAM_SIZE, 0); set_param(PARAM_ATTENUATION, 1); set_param(PARAM_SPOT_ANGLE, 45); set_param(PARAM_SPOT_ATTENUATION, 1); - set_param(PARAM_CONTACT_SHADOW_SIZE, 0); set_param(PARAM_SHADOW_MAX_DISTANCE, 0); set_param(PARAM_SHADOW_SPLIT_1_OFFSET, 0.1); set_param(PARAM_SHADOW_SPLIT_2_OFFSET, 0.2); set_param(PARAM_SHADOW_SPLIT_3_OFFSET, 0.5); set_param(PARAM_SHADOW_FADE_START, 0.8); - set_param(PARAM_SHADOW_NORMAL_BIAS, 0.0); - set_param(PARAM_SHADOW_BIAS, 0.15); + set_param(PARAM_SHADOW_PANCAKE_SIZE, 20.0); + set_param(PARAM_SHADOW_BLUR, 1.0); + set_param(PARAM_SHADOW_BIAS, 0.02); + set_param(PARAM_SHADOW_NORMAL_BIAS, 1.0); + set_param(PARAM_TRANSMITTANCE_BIAS, 0.05); set_param(PARAM_SHADOW_FADE_START, 1); set_disable_scale(true); } @@ -398,10 +431,9 @@ void DirectionalLight3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_split_3", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param", "get_param", PARAM_SHADOW_SPLIT_3_OFFSET); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_fade_start", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SHADOW_FADE_START); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "directional_shadow_blend_splits"), "set_blend_splits", "is_blend_splits_enabled"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_normal_bias", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_param", "get_param", PARAM_SHADOW_NORMAL_BIAS); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_bias_split_scale", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SHADOW_BIAS_SPLIT_SCALE); ADD_PROPERTY(PropertyInfo(Variant::INT, "directional_shadow_depth_range", PROPERTY_HINT_ENUM, "Stable,Optimized"), "set_shadow_depth_range", "get_shadow_depth_range"); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_max_distance", PROPERTY_HINT_EXP_RANGE, "0,8192,0.1,or_greater"), "set_param", "get_param", PARAM_SHADOW_MAX_DISTANCE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_pancake_size", PROPERTY_HINT_EXP_RANGE, "0,1024,0.1,or_greater"), "set_param", "get_param", PARAM_SHADOW_PANCAKE_SIZE); BIND_ENUM_CONSTANT(SHADOW_ORTHOGONAL); BIND_ENUM_CONSTANT(SHADOW_PARALLEL_2_SPLITS); @@ -414,11 +446,8 @@ void DirectionalLight3D::_bind_methods() { DirectionalLight3D::DirectionalLight3D() : Light3D(RenderingServer::LIGHT_DIRECTIONAL) { - set_param(PARAM_SHADOW_NORMAL_BIAS, 0.8); - set_param(PARAM_SHADOW_BIAS, 0.1); set_param(PARAM_SHADOW_MAX_DISTANCE, 100); set_param(PARAM_SHADOW_FADE_START, 0.8); - set_param(PARAM_SHADOW_BIAS_SPLIT_SCALE, 0.25); set_shadow_mode(SHADOW_PARALLEL_4_SPLITS); set_shadow_depth_range(SHADOW_DEPTH_RANGE_STABLE); @@ -436,6 +465,19 @@ OmniLight3D::ShadowMode OmniLight3D::get_shadow_mode() const { return shadow_mode; } +String OmniLight3D::get_configuration_warning() const { + String warning = Light3D::get_configuration_warning(); + + if (!has_shadow() && get_projector().is_valid()) { + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("Projector texture only works with shadows active."); + } + + return warning; +} + void OmniLight3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_shadow_mode", "mode"), &OmniLight3D::set_shadow_mode); @@ -467,6 +509,13 @@ String SpotLight3D::get_configuration_warning() const { warning += TTR("A SpotLight3D with an angle wider than 90 degrees cannot cast shadows."); } + if (!has_shadow() && get_projector().is_valid()) { + if (warning != String()) { + warning += "\n\n"; + } + warning += TTR("Projector texture only works with shadows active."); + } + return warning; } diff --git a/scene/3d/light_3d.h b/scene/3d/light_3d.h index 197e5854ec..6e78217342 100644 --- a/scene/3d/light_3d.h +++ b/scene/3d/light_3d.h @@ -46,10 +46,10 @@ public: PARAM_INDIRECT_ENERGY = RS::LIGHT_PARAM_INDIRECT_ENERGY, PARAM_SPECULAR = RS::LIGHT_PARAM_SPECULAR, PARAM_RANGE = RS::LIGHT_PARAM_RANGE, + PARAM_SIZE = RS::LIGHT_PARAM_SIZE, PARAM_ATTENUATION = RS::LIGHT_PARAM_ATTENUATION, PARAM_SPOT_ANGLE = RS::LIGHT_PARAM_SPOT_ANGLE, PARAM_SPOT_ATTENUATION = RS::LIGHT_PARAM_SPOT_ATTENUATION, - PARAM_CONTACT_SHADOW_SIZE = RS::LIGHT_PARAM_CONTACT_SHADOW_SIZE, PARAM_SHADOW_MAX_DISTANCE = RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE, PARAM_SHADOW_SPLIT_1_OFFSET = RS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET, PARAM_SHADOW_SPLIT_2_OFFSET = RS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET, @@ -57,7 +57,9 @@ public: PARAM_SHADOW_FADE_START = RS::LIGHT_PARAM_SHADOW_FADE_START, PARAM_SHADOW_NORMAL_BIAS = RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS, PARAM_SHADOW_BIAS = RS::LIGHT_PARAM_SHADOW_BIAS, - PARAM_SHADOW_BIAS_SPLIT_SCALE = RS::LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE, + PARAM_SHADOW_PANCAKE_SIZE = RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE, + PARAM_SHADOW_BLUR = RS::LIGHT_PARAM_SHADOW_BLUR, + PARAM_TRANSMITTANCE_BIAS = RS::LIGHT_PARAM_TRANSMITTANCE_BIAS, PARAM_MAX = RS::LIGHT_PARAM_MAX }; @@ -79,6 +81,7 @@ private: bool editor_only; void _update_visibility(); BakeMode bake_mode; + Ref<Texture2D> projector; // bind helpers @@ -123,6 +126,9 @@ public: void set_bake_mode(BakeMode p_mode); BakeMode get_bake_mode() const; + void set_projector(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_projector() const; + virtual AABB get_aabb() const; virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const; @@ -194,6 +200,8 @@ public: void set_shadow_mode(ShadowMode p_mode); ShadowMode get_shadow_mode() const; + virtual String get_configuration_warning() const; + OmniLight3D(); }; diff --git a/scene/3d/path_3d.cpp b/scene/3d/path_3d.cpp index f06135f53d..4a425d1e0e 100644 --- a/scene/3d/path_3d.cpp +++ b/scene/3d/path_3d.cpp @@ -316,16 +316,14 @@ void PathFollow3D::set_offset(float p_offset) { offset = p_offset; if (path) { - if (path->get_curve().is_valid() && path->get_curve()->get_baked_length()) { + if (path->get_curve().is_valid()) { float path_length = path->get_curve()->get_baked_length(); if (loop) { - while (offset > path_length) - offset -= path_length; - - while (offset < 0) - offset += path_length; - + offset = Math::fposmod(offset, path_length); + if (!Math::is_zero_approx(p_offset) && Math::is_zero_approx(offset)) { + offset = path_length; + } } else { offset = CLAMP(offset, 0, path_length); } diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index 2b6eb8ac8a..3991efc7c0 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -110,7 +110,7 @@ bool PhysicsBody3D::get_collision_layer_bit(int p_bit) const { return get_collision_layer() & (1 << p_bit); } -Array PhysicsBody3D::get_collision_exceptions() { +TypedArray<PhysicsBody3D> PhysicsBody3D::get_collision_exceptions() { List<RID> exceptions; PhysicsServer3D::get_singleton()->body_get_collision_exceptions(get_rid(), &exceptions); Array ret; @@ -2134,6 +2134,10 @@ void PhysicalBone3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_joint_offset", "offset"), &PhysicalBone3D::set_joint_offset); ClassDB::bind_method(D_METHOD("get_joint_offset"), &PhysicalBone3D::get_joint_offset); + ClassDB::bind_method(D_METHOD("set_joint_rotation", "euler"), &PhysicalBone3D::set_joint_rotation); + ClassDB::bind_method(D_METHOD("get_joint_rotation"), &PhysicalBone3D::get_joint_rotation); + ClassDB::bind_method(D_METHOD("set_joint_rotation_degrees", "euler_degrees"), &PhysicalBone3D::set_joint_rotation_degrees); + ClassDB::bind_method(D_METHOD("get_joint_rotation_degrees"), &PhysicalBone3D::get_joint_rotation_degrees); ClassDB::bind_method(D_METHOD("set_body_offset", "offset"), &PhysicalBone3D::set_body_offset); ClassDB::bind_method(D_METHOD("get_body_offset"), &PhysicalBone3D::get_body_offset); @@ -2159,9 +2163,23 @@ void PhysicalBone3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_gravity_scale", "gravity_scale"), &PhysicalBone3D::set_gravity_scale); ClassDB::bind_method(D_METHOD("get_gravity_scale"), &PhysicalBone3D::get_gravity_scale); + ClassDB::bind_method(D_METHOD("set_linear_damp", "linear_damp"), &PhysicalBone3D::set_linear_damp); + ClassDB::bind_method(D_METHOD("get_linear_damp"), &PhysicalBone3D::get_linear_damp); + + ClassDB::bind_method(D_METHOD("set_angular_damp", "angular_damp"), &PhysicalBone3D::set_angular_damp); + ClassDB::bind_method(D_METHOD("get_angular_damp"), &PhysicalBone3D::get_angular_damp); + + ClassDB::bind_method(D_METHOD("set_can_sleep", "able_to_sleep"), &PhysicalBone3D::set_can_sleep); + ClassDB::bind_method(D_METHOD("is_able_to_sleep"), &PhysicalBone3D::is_able_to_sleep); + + ClassDB::bind_method(D_METHOD("set_axis_lock", "axis", "lock"), &PhysicalBone3D::set_axis_lock); + ClassDB::bind_method(D_METHOD("get_axis_lock", "axis"), &PhysicalBone3D::get_axis_lock); + ADD_GROUP("Joint", "joint_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "joint_type", PROPERTY_HINT_ENUM, "None,PinJoint,ConeJoint,HingeJoint,SliderJoint,6DOFJoint"), "set_joint_type", "get_joint_type"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "joint_offset"), "set_joint_offset", "get_joint_offset"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "joint_rotation_degrees", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_joint_rotation_degrees", "get_joint_rotation_degrees"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "joint_rotation", PROPERTY_HINT_NONE, "", 0), "set_joint_rotation", "get_joint_rotation"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "body_offset"), "set_body_offset", "get_body_offset"); @@ -2170,6 +2188,17 @@ void PhysicalBone3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_friction", "get_friction"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_bounce", "get_bounce"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_scale", PROPERTY_HINT_RANGE, "-10,10,0.01"), "set_gravity_scale", "get_gravity_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "can_sleep"), "set_can_sleep", "is_able_to_sleep"); + + ADD_GROUP("Axis Lock", "axis_lock_"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_X); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Y); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Z); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_X); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_Y); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_Z); BIND_ENUM_CONSTANT(JOINT_TYPE_NONE); BIND_ENUM_CONSTANT(JOINT_TYPE_PIN); @@ -2187,6 +2216,19 @@ Skeleton3D *PhysicalBone3D::find_skeleton_parent(Node *p_parent) { return s ? s : find_skeleton_parent(p_parent->get_parent()); } +void PhysicalBone3D::_update_joint_offset() { + _fix_joint_offset(); + + set_ignore_transform_notification(true); + reset_to_rest_position(); + set_ignore_transform_notification(false); + +#ifdef TOOLS_ENABLED + if (get_gizmo().is_valid()) + get_gizmo()->redraw(); +#endif +} + void PhysicalBone3D::_fix_joint_offset() { // Clamp joint origin to bone origin if (parent_skeleton) { @@ -2370,16 +2412,31 @@ PhysicalBone3D::JointType PhysicalBone3D::get_joint_type() const { void PhysicalBone3D::set_joint_offset(const Transform &p_offset) { joint_offset = p_offset; - _fix_joint_offset(); + _update_joint_offset(); + _change_notify("joint_rotation_degrees"); +} - set_ignore_transform_notification(true); - reset_to_rest_position(); - set_ignore_transform_notification(false); +const Transform &PhysicalBone3D::get_joint_offset() const { + return joint_offset; +} -#ifdef TOOLS_ENABLED - if (get_gizmo().is_valid()) - get_gizmo()->redraw(); -#endif +void PhysicalBone3D::set_joint_rotation(const Vector3 &p_euler_rad) { + joint_offset.basis.set_euler_scale(p_euler_rad, joint_offset.basis.get_scale()); + + _update_joint_offset(); + _change_notify("joint_offset"); +} + +Vector3 PhysicalBone3D::get_joint_rotation() const { + return joint_offset.basis.get_rotation(); +} + +void PhysicalBone3D::set_joint_rotation_degrees(const Vector3 &p_euler_deg) { + set_joint_rotation(p_euler_deg * Math_PI / 180.0); +} + +Vector3 PhysicalBone3D::get_joint_rotation_degrees() const { + return get_joint_rotation() * 180.0 / Math_PI; } const Transform &PhysicalBone3D::get_body_offset() const { @@ -2390,20 +2447,7 @@ void PhysicalBone3D::set_body_offset(const Transform &p_offset) { body_offset = p_offset; body_offset_inverse = body_offset.affine_inverse(); - _fix_joint_offset(); - - set_ignore_transform_notification(true); - reset_to_rest_position(); - set_ignore_transform_notification(false); - -#ifdef TOOLS_ENABLED - if (get_gizmo().is_valid()) - get_gizmo()->redraw(); -#endif -} - -const Transform &PhysicalBone3D::get_joint_offset() const { - return joint_offset; + _update_joint_offset(); } void PhysicalBone3D::set_simulate_physics(bool p_simulate) { @@ -2496,6 +2540,43 @@ real_t PhysicalBone3D::get_gravity_scale() const { return gravity_scale; } +void PhysicalBone3D::set_linear_damp(real_t p_linear_damp) { + ERR_FAIL_COND(p_linear_damp < -1); + linear_damp = p_linear_damp; + PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_LINEAR_DAMP, linear_damp); +} + +real_t PhysicalBone3D::get_linear_damp() const { + return linear_damp; +} + +void PhysicalBone3D::set_angular_damp(real_t p_angular_damp) { + ERR_FAIL_COND(p_angular_damp < -1); + angular_damp = p_angular_damp; + PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP, angular_damp); +} + +real_t PhysicalBone3D::get_angular_damp() const { + return angular_damp; +} + +void PhysicalBone3D::set_can_sleep(bool p_active) { + can_sleep = p_active; + PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_CAN_SLEEP, p_active); +} + +bool PhysicalBone3D::is_able_to_sleep() const { + return can_sleep; +} + +void PhysicalBone3D::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock) { + PhysicsServer3D::get_singleton()->body_set_axis_lock(get_rid(), p_axis, p_lock); +} + +bool PhysicalBone3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const { + return PhysicsServer3D::get_singleton()->body_is_axis_locked(get_rid(), p_axis); +} + PhysicalBone3D::PhysicalBone3D() : PhysicsBody3D(PhysicsServer3D::BODY_MODE_STATIC), #ifdef TOOLS_ENABLED @@ -2510,7 +2591,10 @@ PhysicalBone3D::PhysicalBone3D() : bounce(0), mass(1), friction(1), - gravity_scale(1) { + gravity_scale(1), + linear_damp(-1), + angular_damp(-1), + can_sleep(true) { reset_physics_simulation_state(); } diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h index bf7854b68d..0e719f5108 100644 --- a/scene/3d/physics_body_3d.h +++ b/scene/3d/physics_body_3d.h @@ -68,7 +68,7 @@ public: void set_collision_mask_bit(int p_bit, bool p_value); bool get_collision_mask_bit(int p_bit) const; - Array get_collision_exceptions(); + TypedArray<PhysicsBody3D> get_collision_exceptions(); void add_collision_exception_with(Node *p_node); //must be physicsbody void remove_collision_exception_with(Node *p_node); @@ -562,6 +562,9 @@ private: real_t mass; real_t friction; real_t gravity_scale; + real_t linear_damp; + real_t angular_damp; + bool can_sleep; protected: bool _set(const StringName &p_name, const Variant &p_value); @@ -575,6 +578,7 @@ protected: private: static Skeleton3D *find_skeleton_parent(Node *p_parent); + void _update_joint_offset(); void _fix_joint_offset(); void _reload_joint(); @@ -599,6 +603,12 @@ public: void set_joint_offset(const Transform &p_offset); const Transform &get_joint_offset() const; + void set_joint_rotation(const Vector3 &p_euler_rad); + Vector3 get_joint_rotation() const; + + void set_joint_rotation_degrees(const Vector3 &p_euler_deg); + Vector3 get_joint_rotation_degrees() const; + void set_body_offset(const Transform &p_offset); const Transform &get_body_offset() const; @@ -624,6 +634,18 @@ public: void set_gravity_scale(real_t p_gravity_scale); real_t get_gravity_scale() const; + void set_linear_damp(real_t p_linear_damp); + real_t get_linear_damp() const; + + void set_angular_damp(real_t p_angular_damp); + real_t get_angular_damp() const; + + void set_can_sleep(bool p_active); + bool is_able_to_sleep() const; + + void set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock); + bool get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const; + void apply_central_impulse(const Vector3 &p_impulse); void apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse); diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index 59a6e23005..973822653a 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -33,6 +33,7 @@ #include "core/engine.h" #include "core/message_queue.h" #include "core/project_settings.h" +#include "core/type_info.h" #include "scene/3d/physics_body_3d.h" #include "scene/resources/surface_tool.h" @@ -770,7 +771,7 @@ void _pb_start_simulation(const Skeleton3D *p_skeleton, Node *p_node, const Vect } } -void Skeleton3D::physical_bones_start_simulation_on(const Array &p_bones) { +void Skeleton3D::physical_bones_start_simulation_on(const TypedArray<StringName> &p_bones) { set_physics_process_internal(false); Vector<int> sim_bones; @@ -780,12 +781,9 @@ void Skeleton3D::physical_bones_start_simulation_on(const Array &p_bones) { sim_bones.resize(p_bones.size()); int c = 0; for (int i = sim_bones.size() - 1; 0 <= i; --i) { - Variant::Type type = p_bones.get(i).get_type(); - if (Variant::STRING == type || Variant::STRING_NAME == type) { - int bone_id = find_bone(p_bones.get(i)); - if (bone_id != -1) - sim_bones.write[c++] = bone_id; - } + int bone_id = find_bone(p_bones[i]); + if (bone_id != -1) + sim_bones.write[c++] = bone_id; } sim_bones.resize(c); } diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h index 08b8691658..0bccd3f8fc 100644 --- a/scene/3d/skeleton_3d.h +++ b/scene/3d/skeleton_3d.h @@ -222,7 +222,7 @@ private: public: void physical_bones_stop_simulation(); - void physical_bones_start_simulation_on(const Array &p_bones); + void physical_bones_start_simulation_on(const TypedArray<StringName> &p_bones); void physical_bones_add_collision_exception(RID p_exception); void physical_bones_remove_collision_exception(RID p_exception); #endif // _3D_DISABLED diff --git a/scene/3d/spring_arm_3d.cpp b/scene/3d/spring_arm_3d.cpp index 281be3f7d3..0ffde7aa8f 100644 --- a/scene/3d/spring_arm_3d.cpp +++ b/scene/3d/spring_arm_3d.cpp @@ -45,15 +45,15 @@ void SpringArm3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: if (!Engine::get_singleton()->is_editor_hint()) { - set_process_internal(true); + set_physics_process_internal(true); } break; case NOTIFICATION_EXIT_TREE: if (!Engine::get_singleton()->is_editor_hint()) { - set_process_internal(false); + set_physics_process_internal(false); } break; - case NOTIFICATION_INTERNAL_PROCESS: + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: process_spring(); break; } diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp index 775a9b76e2..604bc53422 100644 --- a/scene/3d/visual_instance_3d.cpp +++ b/scene/3d/visual_instance_3d.cpp @@ -217,6 +217,62 @@ float GeometryInstance3D::get_lod_max_hysteresis() const { void GeometryInstance3D::_notification(int p_what) { } +const StringName *GeometryInstance3D::_instance_uniform_get_remap(const StringName p_name) const { + StringName *r = instance_uniform_property_remap.getptr(p_name); + if (!r) { + String s = p_name; + if (s.begins_with("shader_params/")) { + StringName name = s.replace("shader_params/", ""); + instance_uniform_property_remap[p_name] = name; + return instance_uniform_property_remap.getptr(p_name); + } + + return nullptr; + } + + return r; +} + +bool GeometryInstance3D::_set(const StringName &p_name, const Variant &p_value) { + const StringName *r = _instance_uniform_get_remap(p_name); + if (r) { + set_shader_instance_uniform(*r, p_value); + return true; + } + + return false; +} + +bool GeometryInstance3D::_get(const StringName &p_name, Variant &r_ret) const { + const StringName *r = _instance_uniform_get_remap(p_name); + if (r) { + r_ret = get_shader_instance_uniform(*r); + return true; + } + + return false; +} +void GeometryInstance3D::_get_property_list(List<PropertyInfo> *p_list) const { + List<PropertyInfo> pinfo; + RS::get_singleton()->instance_geometry_get_shader_parameter_list(get_instance(), &pinfo); + for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { + PropertyInfo pi = E->get(); + bool has_def_value = false; + Variant def_value = RS::get_singleton()->instance_geometry_get_shader_parameter_default_value(get_instance(), pi.name); + if (def_value.get_type() != Variant::NIL) { + has_def_value = true; + } + if (instance_uniforms.has(pi.name)) { + pi.usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE | (has_def_value ? (PROPERTY_USAGE_CHECKABLE | PROPERTY_USAGE_CHECKED) : 0); + } else { + pi.usage = PROPERTY_USAGE_EDITOR | (has_def_value ? PROPERTY_USAGE_CHECKABLE : 0); //do not save if not changed + } + + pi.name = "shader_params/" + pi.name; + p_list->push_back(pi); + } +} + void GeometryInstance3D::set_flag(Flags p_flag, bool p_value) { ERR_FAIL_INDEX(p_flag, FLAG_MAX); @@ -258,6 +314,22 @@ float GeometryInstance3D::get_extra_cull_margin() const { return extra_cull_margin; } +void GeometryInstance3D::set_shader_instance_uniform(const StringName &p_uniform, const Variant &p_value) { + + if (p_value.get_type() == Variant::NIL) { + Variant def_value = RS::get_singleton()->instance_geometry_get_shader_parameter_default_value(get_instance(), p_uniform); + RS::get_singleton()->instance_geometry_set_shader_parameter(get_instance(), p_uniform, def_value); + instance_uniforms.erase(p_value); + } else { + instance_uniforms[p_uniform] = p_value; + RS::get_singleton()->instance_geometry_set_shader_parameter(get_instance(), p_uniform, p_value); + } +} + +Variant GeometryInstance3D::get_shader_instance_uniform(const StringName &p_uniform) const { + + return RS::get_singleton()->instance_geometry_get_shader_parameter(get_instance(), p_uniform); +} void GeometryInstance3D::set_custom_aabb(AABB aabb) { RS::get_singleton()->instance_set_custom_aabb(get_instance(), aabb); @@ -280,6 +352,9 @@ void GeometryInstance3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_lod_max_distance", "mode"), &GeometryInstance3D::set_lod_max_distance); ClassDB::bind_method(D_METHOD("get_lod_max_distance"), &GeometryInstance3D::get_lod_max_distance); + ClassDB::bind_method(D_METHOD("set_shader_instance_uniform", "uniform", "value"), &GeometryInstance3D::set_shader_instance_uniform); + ClassDB::bind_method(D_METHOD("get_shader_instance_uniform", "uniform"), &GeometryInstance3D::get_shader_instance_uniform); + ClassDB::bind_method(D_METHOD("set_lod_min_hysteresis", "mode"), &GeometryInstance3D::set_lod_min_hysteresis); ClassDB::bind_method(D_METHOD("get_lod_min_hysteresis"), &GeometryInstance3D::get_lod_min_hysteresis); diff --git a/scene/3d/visual_instance_3d.h b/scene/3d/visual_instance_3d.h index 9476c28848..cc5f92066f 100644 --- a/scene/3d/visual_instance_3d.h +++ b/scene/3d/visual_instance_3d.h @@ -108,9 +108,18 @@ private: float lod_min_hysteresis; float lod_max_hysteresis; + mutable HashMap<StringName, Variant> instance_uniforms; + mutable HashMap<StringName, StringName> instance_uniform_property_remap; + float extra_cull_margin; + const StringName *_instance_uniform_get_remap(const StringName p_name) const; + protected: + bool _set(const StringName &p_name, const Variant &p_value); + bool _get(const StringName &p_name, Variant &r_ret) const; + void _get_property_list(List<PropertyInfo> *p_list) const; + void _notification(int p_what); static void _bind_methods(); @@ -139,6 +148,9 @@ public: void set_extra_cull_margin(float p_margin); float get_extra_cull_margin() const; + void set_shader_instance_uniform(const StringName &p_uniform, const Variant &p_value); + Variant get_shader_instance_uniform(const StringName &p_uniform) const; + void set_custom_aabb(AABB aabb); GeometryInstance3D(); diff --git a/scene/3d/voxelizer.cpp b/scene/3d/voxelizer.cpp index 203c3cd812..f30c58be55 100644 --- a/scene/3d/voxelizer.cpp +++ b/scene/3d/voxelizer.cpp @@ -592,22 +592,16 @@ void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vec Vector<Vector3> vertices = a[Mesh::ARRAY_VERTEX]; const Vector3 *vr = vertices.ptr(); Vector<Vector2> uv = a[Mesh::ARRAY_TEX_UV]; - const Vector2 *uvr; + const Vector2 *uvr = nullptr; Vector<Vector3> normals = a[Mesh::ARRAY_NORMAL]; - const Vector3 *nr; + const Vector3 *nr = nullptr; Vector<int> index = a[Mesh::ARRAY_INDEX]; - bool read_uv = false; - bool read_normals = false; - if (uv.size()) { - uvr = uv.ptr(); - read_uv = true; } if (normals.size()) { - read_normals = true; nr = normals.ptr(); } @@ -626,13 +620,13 @@ void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vec vtxs[k] = p_xform.xform(vr[ir[j * 3 + k]]); } - if (read_uv) { + if (uvr) { for (int k = 0; k < 3; k++) { uvs[k] = uvr[ir[j * 3 + k]]; } } - if (read_normals) { + if (nr) { for (int k = 0; k < 3; k++) { normal[k] = nr[ir[j * 3 + k]]; } @@ -659,13 +653,13 @@ void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vec vtxs[k] = p_xform.xform(vr[j * 3 + k]); } - if (read_uv) { + if (uvr) { for (int k = 0; k < 3; k++) { uvs[k] = uvr[j * 3 + k]; } } - if (read_normals) { + if (nr) { for (int k = 0; k < 3; k++) { normal[k] = nr[j * 3 + k]; } diff --git a/scene/3d/arvr_nodes.cpp b/scene/3d/xr_nodes.cpp index 537c094ceb..0373114e7d 100644 --- a/scene/3d/arvr_nodes.cpp +++ b/scene/3d/xr_nodes.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* arvr_nodes.cpp */ +/* xr_nodes.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,25 +28,25 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "arvr_nodes.h" +#include "xr_nodes.h" #include "core/input/input_filter.h" -#include "servers/arvr/arvr_interface.h" -#include "servers/arvr_server.h" +#include "servers/xr/xr_interface.h" +#include "servers/xr_server.h" //////////////////////////////////////////////////////////////////////////////////////////////////// -void ARVRCamera::_notification(int p_what) { +void XRCamera3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { - // need to find our ARVROrigin parent and let it know we're its camera! - ARVROrigin *origin = Object::cast_to<ARVROrigin>(get_parent()); + // need to find our XROrigin3D parent and let it know we're its camera! + XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent()); if (origin != nullptr) { origin->set_tracked_camera(this); } }; break; case NOTIFICATION_EXIT_TREE: { - // need to find our ARVROrigin parent and let it know we're no longer its camera! - ARVROrigin *origin = Object::cast_to<ARVROrigin>(get_parent()); + // need to find our XROrigin3D parent and let it know we're no longer its camera! + XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent()); if (origin != nullptr) { origin->clear_tracked_camera_if(this); } @@ -54,26 +54,26 @@ void ARVRCamera::_notification(int p_what) { }; }; -String ARVRCamera::get_configuration_warning() const { +String XRCamera3D::get_configuration_warning() const { if (!is_visible() || !is_inside_tree()) return String(); - // must be child node of ARVROrigin! - ARVROrigin *origin = Object::cast_to<ARVROrigin>(get_parent()); + // must be child node of XROrigin3D! + XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent()); if (origin == nullptr) { - return TTR("ARVRCamera must have an ARVROrigin node as its parent."); + return TTR("XRCamera3D must have an XROrigin3D node as its parent."); }; return String(); }; -Vector3 ARVRCamera::project_local_ray_normal(const Point2 &p_pos) const { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, Vector3()); +Vector3 XRCamera3D::project_local_ray_normal(const Point2 &p_pos) const { + // get our XRServer + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, Vector3()); - Ref<ARVRInterface> arvr_interface = arvr_server->get_primary_interface(); - if (arvr_interface.is_null()) { + Ref<XRInterface> xr_interface = xr_server->get_primary_interface(); + if (xr_interface.is_null()) { // we might be in the editor or have VR turned off, just call superclass return Camera3D::project_local_ray_normal(p_pos); } @@ -84,20 +84,20 @@ Vector3 ARVRCamera::project_local_ray_normal(const Point2 &p_pos) const { Vector2 cpos = get_viewport()->get_camera_coords(p_pos); Vector3 ray; - CameraMatrix cm = arvr_interface->get_projection_for_eye(ARVRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar()); + CameraMatrix cm = xr_interface->get_projection_for_eye(XRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar()); Vector2 screen_he = cm.get_viewport_half_extents(); ray = Vector3(((cpos.x / viewport_size.width) * 2.0 - 1.0) * screen_he.x, ((1.0 - (cpos.y / viewport_size.height)) * 2.0 - 1.0) * screen_he.y, -get_znear()).normalized(); return ray; }; -Point2 ARVRCamera::unproject_position(const Vector3 &p_pos) const { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, Vector2()); +Point2 XRCamera3D::unproject_position(const Vector3 &p_pos) const { + // get our XRServer + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, Vector2()); - Ref<ARVRInterface> arvr_interface = arvr_server->get_primary_interface(); - if (arvr_interface.is_null()) { + Ref<XRInterface> xr_interface = xr_server->get_primary_interface(); + if (xr_interface.is_null()) { // we might be in the editor or have VR turned off, just call superclass return Camera3D::unproject_position(p_pos); } @@ -106,7 +106,7 @@ Point2 ARVRCamera::unproject_position(const Vector3 &p_pos) const { Size2 viewport_size = get_viewport()->get_visible_rect().size; - CameraMatrix cm = arvr_interface->get_projection_for_eye(ARVRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar()); + CameraMatrix cm = xr_interface->get_projection_for_eye(XRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar()); Plane p(get_camera_transform().xform_inv(p_pos), 1.0); @@ -120,13 +120,13 @@ Point2 ARVRCamera::unproject_position(const Vector3 &p_pos) const { return res; }; -Vector3 ARVRCamera::project_position(const Point2 &p_point, float p_z_depth) const { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, Vector3()); +Vector3 XRCamera3D::project_position(const Point2 &p_point, float p_z_depth) const { + // get our XRServer + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, Vector3()); - Ref<ARVRInterface> arvr_interface = arvr_server->get_primary_interface(); - if (arvr_interface.is_null()) { + Ref<XRInterface> xr_interface = xr_server->get_primary_interface(); + if (xr_interface.is_null()) { // we might be in the editor or have VR turned off, just call superclass return Camera3D::project_position(p_point, p_z_depth); } @@ -135,7 +135,7 @@ Vector3 ARVRCamera::project_position(const Point2 &p_point, float p_z_depth) con Size2 viewport_size = get_viewport()->get_visible_rect().size; - CameraMatrix cm = arvr_interface->get_projection_for_eye(ARVRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar()); + CameraMatrix cm = xr_interface->get_projection_for_eye(XRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar()); Vector2 vp_he = cm.get_viewport_half_extents(); @@ -149,13 +149,13 @@ Vector3 ARVRCamera::project_position(const Point2 &p_point, float p_z_depth) con return get_camera_transform().xform(p); }; -Vector<Plane> ARVRCamera::get_frustum() const { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, Vector<Plane>()); +Vector<Plane> XRCamera3D::get_frustum() const { + // get our XRServer + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, Vector<Plane>()); - Ref<ARVRInterface> arvr_interface = arvr_server->get_primary_interface(); - if (arvr_interface.is_null()) { + Ref<XRInterface> xr_interface = xr_server->get_primary_interface(); + if (xr_interface.is_null()) { // we might be in the editor or have VR turned off, just call superclass return Camera3D::get_frustum(); } @@ -163,21 +163,21 @@ Vector<Plane> ARVRCamera::get_frustum() const { ERR_FAIL_COND_V(!is_inside_world(), Vector<Plane>()); Size2 viewport_size = get_viewport()->get_visible_rect().size; - CameraMatrix cm = arvr_interface->get_projection_for_eye(ARVRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar()); + CameraMatrix cm = xr_interface->get_projection_for_eye(XRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar()); return cm.get_projection_planes(get_camera_transform()); }; -ARVRCamera::ARVRCamera(){ +XRCamera3D::XRCamera3D(){ // nothing to do here yet for now.. }; -ARVRCamera::~ARVRCamera(){ +XRCamera3D::~XRCamera3D(){ // nothing to do here yet for now.. }; //////////////////////////////////////////////////////////////////////////////////////////////////// -void ARVRController::_notification(int p_what) { +void XRController3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { set_process_internal(true); @@ -186,12 +186,12 @@ void ARVRController::_notification(int p_what) { set_process_internal(false); }; break; case NOTIFICATION_INTERNAL_PROCESS: { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL(arvr_server); + // get our XRServer + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); // find the tracker for our controller - ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, controller_id); + XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); if (tracker == nullptr) { // this controller is currently turned off is_active = false; @@ -236,49 +236,49 @@ void ARVRController::_notification(int p_what) { }; }; -void ARVRController::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_controller_id", "controller_id"), &ARVRController::set_controller_id); - ClassDB::bind_method(D_METHOD("get_controller_id"), &ARVRController::get_controller_id); +void XRController3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_controller_id", "controller_id"), &XRController3D::set_controller_id); + ClassDB::bind_method(D_METHOD("get_controller_id"), &XRController3D::get_controller_id); ADD_PROPERTY(PropertyInfo(Variant::INT, "controller_id", PROPERTY_HINT_RANGE, "0,32,1"), "set_controller_id", "get_controller_id"); - ClassDB::bind_method(D_METHOD("get_controller_name"), &ARVRController::get_controller_name); + ClassDB::bind_method(D_METHOD("get_controller_name"), &XRController3D::get_controller_name); // passthroughs to information about our related joystick - ClassDB::bind_method(D_METHOD("get_joystick_id"), &ARVRController::get_joystick_id); - ClassDB::bind_method(D_METHOD("is_button_pressed", "button"), &ARVRController::is_button_pressed); - ClassDB::bind_method(D_METHOD("get_joystick_axis", "axis"), &ARVRController::get_joystick_axis); + ClassDB::bind_method(D_METHOD("get_joystick_id"), &XRController3D::get_joystick_id); + ClassDB::bind_method(D_METHOD("is_button_pressed", "button"), &XRController3D::is_button_pressed); + ClassDB::bind_method(D_METHOD("get_joystick_axis", "axis"), &XRController3D::get_joystick_axis); - ClassDB::bind_method(D_METHOD("get_is_active"), &ARVRController::get_is_active); - ClassDB::bind_method(D_METHOD("get_hand"), &ARVRController::get_hand); + ClassDB::bind_method(D_METHOD("get_is_active"), &XRController3D::get_is_active); + ClassDB::bind_method(D_METHOD("get_hand"), &XRController3D::get_hand); - ClassDB::bind_method(D_METHOD("get_rumble"), &ARVRController::get_rumble); - ClassDB::bind_method(D_METHOD("set_rumble", "rumble"), &ARVRController::set_rumble); + ClassDB::bind_method(D_METHOD("get_rumble"), &XRController3D::get_rumble); + ClassDB::bind_method(D_METHOD("set_rumble", "rumble"), &XRController3D::set_rumble); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rumble", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_rumble", "get_rumble"); ADD_PROPERTY_DEFAULT("rumble", 0.0); - ClassDB::bind_method(D_METHOD("get_mesh"), &ARVRController::get_mesh); + ClassDB::bind_method(D_METHOD("get_mesh"), &XRController3D::get_mesh); ADD_SIGNAL(MethodInfo("button_pressed", PropertyInfo(Variant::INT, "button"))); ADD_SIGNAL(MethodInfo("button_release", PropertyInfo(Variant::INT, "button"))); ADD_SIGNAL(MethodInfo("mesh_updated", PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"))); }; -void ARVRController::set_controller_id(int p_controller_id) { +void XRController3D::set_controller_id(int p_controller_id) { // We don't check any bounds here, this controller may not yet be active and just be a place holder until it is. // Note that setting this to 0 means this node is not bound to a controller yet. controller_id = p_controller_id; update_configuration_warning(); }; -int ARVRController::get_controller_id(void) const { +int XRController3D::get_controller_id(void) const { return controller_id; }; -String ARVRController::get_controller_name(void) const { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, String()); +String XRController3D::get_controller_name(void) const { + // get our XRServer + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, String()); - ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, controller_id); + XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); if (tracker == nullptr) { return String("Not connected"); }; @@ -286,12 +286,12 @@ String ARVRController::get_controller_name(void) const { return tracker->get_name(); }; -int ARVRController::get_joystick_id() const { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, 0); +int XRController3D::get_joystick_id() const { + // get our XRServer + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, 0); - ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, controller_id); + XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); if (tracker == nullptr) { // No tracker? no joystick id... (0 is our first joystick) return -1; @@ -300,7 +300,7 @@ int ARVRController::get_joystick_id() const { return tracker->get_joy_id(); }; -bool ARVRController::is_button_pressed(int p_button) const { +bool XRController3D::is_button_pressed(int p_button) const { int joy_id = get_joystick_id(); if (joy_id == -1) { return false; @@ -309,7 +309,7 @@ bool ARVRController::is_button_pressed(int p_button) const { return InputFilter::get_singleton()->is_joy_button_pressed(joy_id, p_button); }; -float ARVRController::get_joystick_axis(int p_axis) const { +float XRController3D::get_joystick_axis(int p_axis) const { int joy_id = get_joystick_id(); if (joy_id == -1) { return 0.0; @@ -318,12 +318,12 @@ float ARVRController::get_joystick_axis(int p_axis) const { return InputFilter::get_singleton()->get_joy_axis(joy_id, p_axis); }; -real_t ARVRController::get_rumble() const { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, 0.0); +real_t XRController3D::get_rumble() const { + // get our XRServer + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, 0.0); - ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, controller_id); + XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); if (tracker == nullptr) { return 0.0; }; @@ -331,46 +331,46 @@ real_t ARVRController::get_rumble() const { return tracker->get_rumble(); }; -void ARVRController::set_rumble(real_t p_rumble) { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL(arvr_server); +void XRController3D::set_rumble(real_t p_rumble) { + // get our XRServer + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); - ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, controller_id); + XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); if (tracker != nullptr) { tracker->set_rumble(p_rumble); }; }; -Ref<Mesh> ARVRController::get_mesh() const { +Ref<Mesh> XRController3D::get_mesh() const { return mesh; } -bool ARVRController::get_is_active() const { +bool XRController3D::get_is_active() const { return is_active; }; -ARVRPositionalTracker::TrackerHand ARVRController::get_hand() const { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, ARVRPositionalTracker::TRACKER_HAND_UNKNOWN); +XRPositionalTracker::TrackerHand XRController3D::get_hand() const { + // get our XRServer + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, XRPositionalTracker::TRACKER_HAND_UNKNOWN); - ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, controller_id); + XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); if (tracker == nullptr) { - return ARVRPositionalTracker::TRACKER_HAND_UNKNOWN; + return XRPositionalTracker::TRACKER_HAND_UNKNOWN; }; return tracker->get_hand(); }; -String ARVRController::get_configuration_warning() const { +String XRController3D::get_configuration_warning() const { if (!is_visible() || !is_inside_tree()) return String(); - // must be child node of ARVROrigin! - ARVROrigin *origin = Object::cast_to<ARVROrigin>(get_parent()); + // must be child node of XROrigin! + XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent()); if (origin == nullptr) { - return TTR("ARVRController must have an ARVROrigin node as its parent."); + return TTR("XRController3D must have an XROrigin3D node as its parent."); }; if (controller_id == 0) { @@ -380,19 +380,19 @@ String ARVRController::get_configuration_warning() const { return String(); }; -ARVRController::ARVRController() { +XRController3D::XRController3D() { controller_id = 1; is_active = true; button_states = 0; }; -ARVRController::~ARVRController(){ +XRController3D::~XRController3D(){ // nothing to do here yet for now.. }; //////////////////////////////////////////////////////////////////////////////////////////////////// -void ARVRAnchor::_notification(int p_what) { +void XRAnchor3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { set_process_internal(true); @@ -401,12 +401,12 @@ void ARVRAnchor::_notification(int p_what) { set_process_internal(false); }; break; case NOTIFICATION_INTERNAL_PROCESS: { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL(arvr_server); + // get our XRServer + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); // find the tracker for our anchor - ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_ANCHOR, anchor_id); + XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_ANCHOR, anchor_id); if (tracker == nullptr) { // this anchor is currently not available is_active = false; @@ -415,7 +415,7 @@ void ARVRAnchor::_notification(int p_what) { Transform transform; // we'll need our world_scale - real_t world_scale = arvr_server->get_world_scale(); + real_t world_scale = xr_server->get_world_scale(); // get our info from our tracker transform.basis = tracker->get_orientation(); @@ -427,7 +427,7 @@ void ARVRAnchor::_notification(int p_what) { transform.basis.orthonormalize(); // apply our reference frame and set our transform - set_transform(arvr_server->get_reference_frame() * transform); + set_transform(xr_server->get_reference_frame() * transform); // check for an updated mesh Ref<Mesh> trackerMesh = tracker->get_mesh(); @@ -442,43 +442,43 @@ void ARVRAnchor::_notification(int p_what) { }; }; -void ARVRAnchor::_bind_methods() { +void XRAnchor3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_anchor_id", "anchor_id"), &ARVRAnchor::set_anchor_id); - ClassDB::bind_method(D_METHOD("get_anchor_id"), &ARVRAnchor::get_anchor_id); + ClassDB::bind_method(D_METHOD("set_anchor_id", "anchor_id"), &XRAnchor3D::set_anchor_id); + ClassDB::bind_method(D_METHOD("get_anchor_id"), &XRAnchor3D::get_anchor_id); ADD_PROPERTY(PropertyInfo(Variant::INT, "anchor_id", PROPERTY_HINT_RANGE, "0,32,1"), "set_anchor_id", "get_anchor_id"); - ClassDB::bind_method(D_METHOD("get_anchor_name"), &ARVRAnchor::get_anchor_name); + ClassDB::bind_method(D_METHOD("get_anchor_name"), &XRAnchor3D::get_anchor_name); - ClassDB::bind_method(D_METHOD("get_is_active"), &ARVRAnchor::get_is_active); - ClassDB::bind_method(D_METHOD("get_size"), &ARVRAnchor::get_size); + ClassDB::bind_method(D_METHOD("get_is_active"), &XRAnchor3D::get_is_active); + ClassDB::bind_method(D_METHOD("get_size"), &XRAnchor3D::get_size); - ClassDB::bind_method(D_METHOD("get_plane"), &ARVRAnchor::get_plane); + ClassDB::bind_method(D_METHOD("get_plane"), &XRAnchor3D::get_plane); - ClassDB::bind_method(D_METHOD("get_mesh"), &ARVRAnchor::get_mesh); + ClassDB::bind_method(D_METHOD("get_mesh"), &XRAnchor3D::get_mesh); ADD_SIGNAL(MethodInfo("mesh_updated", PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"))); }; -void ARVRAnchor::set_anchor_id(int p_anchor_id) { +void XRAnchor3D::set_anchor_id(int p_anchor_id) { // We don't check any bounds here, this anchor may not yet be active and just be a place holder until it is. // Note that setting this to 0 means this node is not bound to an anchor yet. anchor_id = p_anchor_id; update_configuration_warning(); }; -int ARVRAnchor::get_anchor_id(void) const { +int XRAnchor3D::get_anchor_id(void) const { return anchor_id; }; -Vector3 ARVRAnchor::get_size() const { +Vector3 XRAnchor3D::get_size() const { return size; }; -String ARVRAnchor::get_anchor_name(void) const { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, String()); +String XRAnchor3D::get_anchor_name(void) const { + // get our XRServer + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, String()); - ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_ANCHOR, anchor_id); + XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_ANCHOR, anchor_id); if (tracker == nullptr) { return String("Not connected"); }; @@ -486,18 +486,18 @@ String ARVRAnchor::get_anchor_name(void) const { return tracker->get_name(); }; -bool ARVRAnchor::get_is_active() const { +bool XRAnchor3D::get_is_active() const { return is_active; }; -String ARVRAnchor::get_configuration_warning() const { +String XRAnchor3D::get_configuration_warning() const { if (!is_visible() || !is_inside_tree()) return String(); - // must be child node of ARVROrigin! - ARVROrigin *origin = Object::cast_to<ARVROrigin>(get_parent()); + // must be child node of XROrigin3D! + XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent()); if (origin == nullptr) { - return TTR("ARVRAnchor must have an ARVROrigin node as its parent."); + return TTR("XRAnchor3D must have an XROrigin3D node as its parent."); }; if (anchor_id == 0) { @@ -507,7 +507,7 @@ String ARVRAnchor::get_configuration_warning() const { return String(); }; -Plane ARVRAnchor::get_plane() const { +Plane XRAnchor3D::get_plane() const { Vector3 location = get_translation(); Basis orientation = get_transform().basis; @@ -516,67 +516,67 @@ Plane ARVRAnchor::get_plane() const { return plane; }; -Ref<Mesh> ARVRAnchor::get_mesh() const { +Ref<Mesh> XRAnchor3D::get_mesh() const { return mesh; } -ARVRAnchor::ARVRAnchor() { +XRAnchor3D::XRAnchor3D() { anchor_id = 1; is_active = true; }; -ARVRAnchor::~ARVRAnchor(){ +XRAnchor3D::~XRAnchor3D(){ // nothing to do here yet for now.. }; //////////////////////////////////////////////////////////////////////////////////////////////////// -String ARVROrigin::get_configuration_warning() const { +String XROrigin3D::get_configuration_warning() const { if (!is_visible() || !is_inside_tree()) return String(); if (tracked_camera == nullptr) - return TTR("ARVROrigin requires an ARVRCamera child node."); + return TTR("XROrigin3D requires an XRCamera3D child node."); return String(); }; -void ARVROrigin::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_world_scale", "world_scale"), &ARVROrigin::set_world_scale); - ClassDB::bind_method(D_METHOD("get_world_scale"), &ARVROrigin::get_world_scale); +void XROrigin3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_world_scale", "world_scale"), &XROrigin3D::set_world_scale); + ClassDB::bind_method(D_METHOD("get_world_scale"), &XROrigin3D::get_world_scale); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "world_scale"), "set_world_scale", "get_world_scale"); }; -void ARVROrigin::set_tracked_camera(ARVRCamera *p_tracked_camera) { +void XROrigin3D::set_tracked_camera(XRCamera3D *p_tracked_camera) { tracked_camera = p_tracked_camera; }; -void ARVROrigin::clear_tracked_camera_if(ARVRCamera *p_tracked_camera) { +void XROrigin3D::clear_tracked_camera_if(XRCamera3D *p_tracked_camera) { if (tracked_camera == p_tracked_camera) { tracked_camera = nullptr; }; }; -float ARVROrigin::get_world_scale() const { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, 1.0); +float XROrigin3D::get_world_scale() const { + // get our XRServer + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, 1.0); - return arvr_server->get_world_scale(); + return xr_server->get_world_scale(); }; -void ARVROrigin::set_world_scale(float p_world_scale) { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL(arvr_server); +void XROrigin3D::set_world_scale(float p_world_scale) { + // get our XRServer + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); - arvr_server->set_world_scale(p_world_scale); + xr_server->set_world_scale(p_world_scale); }; -void ARVROrigin::_notification(int p_what) { - // get our ARVRServer - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL(arvr_server); +void XROrigin3D::_notification(int p_what) { + // get our XRServer + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); switch (p_what) { case NOTIFICATION_ENTER_TREE: { @@ -587,13 +587,13 @@ void ARVROrigin::_notification(int p_what) { }; break; case NOTIFICATION_INTERNAL_PROCESS: { // set our world origin to our node transform - arvr_server->set_world_origin(get_global_transform()); + xr_server->set_world_origin(get_global_transform()); // check if we have a primary interface - Ref<ARVRInterface> arvr_interface = arvr_server->get_primary_interface(); - if (arvr_interface.is_valid() && tracked_camera != nullptr) { + Ref<XRInterface> xr_interface = xr_server->get_primary_interface(); + if (xr_interface.is_valid() && tracked_camera != nullptr) { // get our positioning transform for our headset - Transform t = arvr_interface->get_transform_for_eye(ARVRInterface::EYE_MONO, Transform()); + Transform t = xr_interface->get_transform_for_eye(XRInterface::EYE_MONO, Transform()); // now apply this to our camera tracked_camera->set_transform(t); @@ -603,19 +603,19 @@ void ARVROrigin::_notification(int p_what) { break; }; - // send our notification to all active ARVR interfaces, they may need to react to it also - for (int i = 0; i < arvr_server->get_interface_count(); i++) { - Ref<ARVRInterface> interface = arvr_server->get_interface(i); + // send our notification to all active XE interfaces, they may need to react to it also + for (int i = 0; i < xr_server->get_interface_count(); i++) { + Ref<XRInterface> interface = xr_server->get_interface(i); if (interface.is_valid() && interface->is_initialized()) { interface->notification(p_what); } } }; -ARVROrigin::ARVROrigin() { +XROrigin3D::XROrigin3D() { tracked_camera = nullptr; }; -ARVROrigin::~ARVROrigin(){ +XROrigin3D::~XROrigin3D(){ // nothing to do here yet for now.. }; diff --git a/scene/3d/arvr_nodes.h b/scene/3d/xr_nodes.h index bc5df2e174..a2f16545d1 100644 --- a/scene/3d/arvr_nodes.h +++ b/scene/3d/xr_nodes.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* arvr_nodes.h */ +/* xr_nodes.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,24 +28,24 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef ARVR_NODES_H -#define ARVR_NODES_H +#ifndef XR_NODES_H +#define XR_NODES_H #include "scene/3d/camera_3d.h" #include "scene/3d/node_3d.h" #include "scene/resources/mesh.h" -#include "servers/arvr/arvr_positional_tracker.h" +#include "servers/xr/xr_positional_tracker.h" /** @author Bastiaan Olij <mux213@gmail.com> **/ /* - ARVRCamera is a subclass of camera which will register itself with its parent ARVROrigin and as a result is automatically positioned + XRCamera is a subclass of camera which will register itself with its parent XROrigin and as a result is automatically positioned */ -class ARVRCamera : public Camera3D { +class XRCamera3D : public Camera3D { - GDCLASS(ARVRCamera, Camera3D); + GDCLASS(XRCamera3D, Camera3D); protected: void _notification(int p_what); @@ -58,19 +58,19 @@ public: virtual Vector3 project_position(const Point2 &p_point, float p_z_depth) const; virtual Vector<Plane> get_frustum() const; - ARVRCamera(); - ~ARVRCamera(); + XRCamera3D(); + ~XRCamera3D(); }; /* - ARVRController is a helper node that automatically updates its position based on tracker data. + XRController3D is a helper node that automatically updates its position based on tracker data. - It must be a child node of our ARVROrigin node + It must be a child node of our XROrigin node */ -class ARVRController : public Node3D { +class XRController3D : public Node3D { - GDCLASS(ARVRController, Node3D); + GDCLASS(XRController3D, Node3D); private: int controller_id; @@ -95,23 +95,23 @@ public: void set_rumble(real_t p_rumble); bool get_is_active() const; - ARVRPositionalTracker::TrackerHand get_hand() const; + XRPositionalTracker::TrackerHand get_hand() const; Ref<Mesh> get_mesh(void) const; String get_configuration_warning() const; - ARVRController(); - ~ARVRController(); + XRController3D(); + ~XRController3D(); }; /* - ARVRAnchor is a helper node that automatically updates its position based on anchor data, it represents a real world location. - It must be a child node of our ARVROrigin node + XRAnchor3D is a helper node that automatically updates its position based on anchor data, it represents a real world location. + It must be a child node of our XROrigin3D node */ -class ARVRAnchor : public Node3D { - GDCLASS(ARVRAnchor, Node3D); +class XRAnchor3D : public Node3D { + GDCLASS(XRAnchor3D, Node3D); private: int anchor_id; @@ -137,24 +137,24 @@ public: String get_configuration_warning() const; - ARVRAnchor(); - ~ARVRAnchor(); + XRAnchor3D(); + ~XRAnchor3D(); }; /* - ARVROrigin is special spatial node that acts as our origin point mapping our real world center of our tracking volume into our virtual world. + XROrigin3D is special spatial node that acts as our origin point mapping our real world center of our tracking volume into our virtual world. It is this point that you will move around the world as the player 'moves while standing still', i.e. the player moves through teleporting or controller inputs as opposed to physically moving. Our camera and controllers will always be child nodes and thus place relative to this origin point. - This node will automatically locate any camera child nodes and update its position while our ARVRController node will handle tracked controllers. + This node will automatically locate any camera child nodes and update its position while our XRController3D node will handle tracked controllers. */ -class ARVROrigin : public Node3D { +class XROrigin3D : public Node3D { - GDCLASS(ARVROrigin, Node3D); + GDCLASS(XROrigin3D, Node3D); private: - ARVRCamera *tracked_camera; + XRCamera3D *tracked_camera; protected: void _notification(int p_what); @@ -163,14 +163,14 @@ protected: public: String get_configuration_warning() const; - void set_tracked_camera(ARVRCamera *p_tracked_camera); - void clear_tracked_camera_if(ARVRCamera *p_tracked_camera); + void set_tracked_camera(XRCamera3D *p_tracked_camera); + void clear_tracked_camera_if(XRCamera3D *p_tracked_camera); float get_world_scale() const; void set_world_scale(float p_world_scale); - ARVROrigin(); - ~ARVROrigin(); + XROrigin3D(); + ~XROrigin3D(); }; -#endif /* ARVR_NODES_H */ +#endif /* XR_NODES_H */ diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index b657833a3b..946f759610 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -950,13 +950,13 @@ void AnimationPlayer::_animation_process(float p_delta) { play(queued.front()->get()); String new_name = playback.assigned; queued.pop_front(); - if (end_notify) + if (end_notify || playback.seeked) emit_signal(SceneStringNames::get_singleton()->animation_changed, old, new_name); } else { //stop(); playing = false; _set_process(false); - if (end_notify) + if (end_notify || playback.seeked) emit_signal(SceneStringNames::get_singleton()->animation_finished, playback.assigned); } end_reached = false; diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index e37e93e2a9..0fe65462e4 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -852,7 +852,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { bool in_box = r.intersects(box_selecting_rect); if (in_box) - gn->set_selected(box_selection_mode_aditive); + gn->set_selected(box_selection_mode_additive); else gn->set_selected(previus_selected.find(gn) != nullptr); } @@ -951,8 +951,16 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { if (!gn->is_selected() && !InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL)) { for (int i = 0; i < get_child_count(); i++) { GraphNode *o_gn = Object::cast_to<GraphNode>(get_child(i)); - if (o_gn) - o_gn->set_selected(o_gn == gn); + if (o_gn) { + if (o_gn == gn) { + o_gn->set_selected(true); + } else { + if (o_gn->is_selected()) { + emit_signal("node_unselected", o_gn); + } + o_gn->set_selected(false); + } + } } } @@ -974,7 +982,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { box_selecting = true; box_selecting_from = get_local_mouse_position(); if (b->get_control()) { - box_selection_mode_aditive = true; + box_selection_mode_additive = true; previus_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { @@ -985,7 +993,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { previus_selected.push_back(gn2); } } else if (b->get_shift()) { - box_selection_mode_aditive = false; + box_selection_mode_additive = false; previus_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { @@ -996,14 +1004,16 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { previus_selected.push_back(gn2); } } else { - box_selection_mode_aditive = true; + box_selection_mode_additive = true; previus_selected.clear(); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i)); if (!gn2) continue; - + if (gn2->is_selected()) { + emit_signal("node_unselected", gn2); + } gn2->set_selected(false); } } @@ -1311,6 +1321,7 @@ void GraphEdit::_bind_methods() { ADD_SIGNAL(MethodInfo("copy_nodes_request")); ADD_SIGNAL(MethodInfo("paste_nodes_request")); ADD_SIGNAL(MethodInfo("node_selected", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); + ADD_SIGNAL(MethodInfo("node_unselected", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); ADD_SIGNAL(MethodInfo("connection_to_empty", PropertyInfo(Variant::STRING_NAME, "from"), PropertyInfo(Variant::INT, "from_slot"), PropertyInfo(Variant::VECTOR2, "release_position"))); ADD_SIGNAL(MethodInfo("connection_from_empty", PropertyInfo(Variant::STRING_NAME, "to"), PropertyInfo(Variant::INT, "to_slot"), PropertyInfo(Variant::VECTOR2, "release_position"))); ADD_SIGNAL(MethodInfo("delete_nodes_request")); diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h index 7f1d2699ba..f675f8c7f3 100644 --- a/scene/gui/graph_edit.h +++ b/scene/gui/graph_edit.h @@ -104,7 +104,7 @@ private: float zoom; bool box_selecting; - bool box_selection_mode_aditive; + bool box_selection_mode_additive; Point2 box_selecting_from; Point2 box_selecting_to; Rect2 box_selecting_rect; diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp index 30ecd651b1..a03d6d0cdc 100644 --- a/scene/gui/option_button.cpp +++ b/scene/gui/option_button.cpp @@ -340,8 +340,8 @@ void OptionButton::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "items", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_items", "_get_items"); // "selected" property must come after "items", otherwise GH-10213 occurs. ADD_PROPERTY(PropertyInfo(Variant::INT, "selected"), "_select_int", "get_selected"); - ADD_SIGNAL(MethodInfo("item_selected", PropertyInfo(Variant::INT, "id"))); - ADD_SIGNAL(MethodInfo("item_focused", PropertyInfo(Variant::INT, "id"))); + ADD_SIGNAL(MethodInfo("item_selected", PropertyInfo(Variant::INT, "index"))); + ADD_SIGNAL(MethodInfo("item_focused", PropertyInfo(Variant::INT, "index"))); } OptionButton::OptionButton() { diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 0b314d57c5..9fab9005f9 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -407,7 +407,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & cw = tab_size * font->get_char_size(' ').width; } - if (end > 0 && w + cw + begin > p_width) { + if (end > 0 && fw + cw + begin > p_width) { break; //don't allow lines longer than assigned width } @@ -416,7 +416,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & end++; } CHECK_HEIGHT(fh); - ENSURE_WIDTH(w); + ENSURE_WIDTH(fw); line_ascent = MAX(line_ascent, ascent); line_descent = MAX(line_descent, descent); diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp index e47e2b869d..1f135163d4 100644 --- a/scene/gui/slider.cpp +++ b/scene/gui/slider.cpp @@ -166,8 +166,9 @@ void Slider::_notification(int p_what) { RID ci = get_canvas_item(); Size2i size = get_size(); Ref<StyleBox> style = get_theme_stylebox("slider"); - Ref<StyleBox> grabber_area = get_theme_stylebox("grabber_area"); - Ref<Texture2D> grabber = get_theme_icon(editable ? ((mouse_inside || has_focus()) ? "grabber_highlight" : "grabber") : "grabber_disabled"); + bool highlighted = mouse_inside || has_focus(); + Ref<StyleBox> grabber_area = get_theme_stylebox(highlighted ? "grabber_area_highlight" : "grabber_area"); + Ref<Texture2D> grabber = get_theme_icon(editable ? (highlighted ? "grabber_highlight" : "grabber") : "grabber_disabled"); Ref<Texture2D> tick = get_theme_icon("tick"); double ratio = Math::is_nan(get_as_ratio()) ? 0 : get_as_ratio(); diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp index de80049862..3a128cf8e6 100644 --- a/scene/gui/tab_container.cpp +++ b/scene/gui/tab_container.cpp @@ -990,7 +990,7 @@ void TabContainer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_current_tab"), &TabContainer::get_current_tab); ClassDB::bind_method(D_METHOD("get_previous_tab"), &TabContainer::get_previous_tab); ClassDB::bind_method(D_METHOD("get_current_tab_control"), &TabContainer::get_current_tab_control); - ClassDB::bind_method(D_METHOD("get_tab_control", "idx"), &TabContainer::get_tab_control); + ClassDB::bind_method(D_METHOD("get_tab_control", "tab_idx"), &TabContainer::get_tab_control); ClassDB::bind_method(D_METHOD("set_tab_align", "align"), &TabContainer::set_tab_align); ClassDB::bind_method(D_METHOD("get_tab_align"), &TabContainer::get_tab_align); ClassDB::bind_method(D_METHOD("set_tabs_visible", "visible"), &TabContainer::set_tabs_visible); diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index a7acaae8df..509a52d36a 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -3045,13 +3045,6 @@ void Tree::_notification(int p_what) { draw_item(Point2(), draw_ofs, draw_size, root); } - int ofs = 0; - - for (int i = 0; i < (columns.size() - 1 - 1); i++) { - - ofs += get_column_width(i); - } - if (show_column_titles) { //title buttons diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 50f3bf834f..4c02a15531 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -2693,9 +2693,9 @@ void Node::queue_delete() { } } -Array Node::_get_children() const { +TypedArray<Node> Node::_get_children() const { - Array arr; + TypedArray<Node> arr; int cc = get_child_count(); arr.resize(cc); for (int i = 0; i < cc; i++) diff --git a/scene/main/node.h b/scene/main/node.h index 5de07d506e..1c1b7bbd7a 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -37,6 +37,7 @@ #include "core/object.h" #include "core/project_settings.h" #include "core/script_language.h" +#include "core/typed_array.h" #include "scene/main/scene_tree.h" class Viewport; @@ -182,7 +183,7 @@ private: void _duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p_reown_map) const; Node *_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap = nullptr) const; - Array _get_children() const; + TypedArray<Node> _get_children() const; Array _get_groups() const; Variant _rpc_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 41f31617d2..f30a899d69 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -1421,10 +1421,14 @@ SceneTree::SceneTree() { root->set_as_audio_listener_2d(true); current_scene = nullptr; - int msaa_mode = GLOBAL_DEF("rendering/quality/filters/msaa", 0); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/filters/msaa", PropertyInfo(Variant::INT, "rendering/quality/filters/msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x,AndroidVR 2x,AndroidVR 4x")); + int msaa_mode = GLOBAL_DEF("rendering/quality/screen_filters/msaa", 0); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_filters/msaa", PropertyInfo(Variant::INT, "rendering/quality/screen_filters/msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x")); root->set_msaa(Viewport::MSAA(msaa_mode)); + int ssaa_mode = GLOBAL_DEF("rendering/quality/screen_filters/screen_space_aa", 0); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_filters/screen_space_aa", PropertyInfo(Variant::INT, "rendering/quality/screen_filters/screen_space_aa", PROPERTY_HINT_ENUM, "Disabled,FXAA")); + root->set_screen_space_aa(Viewport::ScreenSpaceAA(ssaa_mode)); + { //load default fallback environment //get possible extensions List<String> exts; diff --git a/scene/main/shader_globals_override.cpp b/scene/main/shader_globals_override.cpp new file mode 100644 index 0000000000..13582cf655 --- /dev/null +++ b/scene/main/shader_globals_override.cpp @@ -0,0 +1,257 @@ +#include "shader_globals_override.h" + +#include "core/core_string_names.h" +#include "scene/main/window.h" +#include "scene/scene_string_names.h" + +StringName *ShaderGlobalsOverride::_remap(const StringName &p_name) const { + + StringName *r = param_remaps.getptr(p_name); + if (!r) { + //not cached, do caching + String p = p_name; + if (p.begins_with("params/")) { + String q = p.replace_first("params/", ""); + param_remaps[p] = q; + r = param_remaps.getptr(q); + } + } + + return r; +} +bool ShaderGlobalsOverride::_set(const StringName &p_name, const Variant &p_value) { + + StringName *r = _remap(p_name); + + if (r) { + Override *o = overrides.getptr(*r); + if (!o) { + Override ov; + ov.in_use = false; + overrides[*r] = ov; + o = overrides.getptr(*r); + } + if (o) { + o->override = p_value; + if (active) { + RS::get_singleton()->global_variable_set_override(*r, p_value); + } + o->in_use = p_value.get_type() != Variant::NIL; + return true; + } + } + + return false; +} + +bool ShaderGlobalsOverride::_get(const StringName &p_name, Variant &r_ret) const { + + StringName *r = _remap(p_name); + + if (r) { + const Override *o = overrides.getptr(*r); + if (o) { + r_ret = o->override; + return true; + } + } + + return false; +} + +void ShaderGlobalsOverride::_get_property_list(List<PropertyInfo> *p_list) const { + + Vector<StringName> variables; + variables = RS::get_singleton()->global_variable_get_list(); + for (int i = 0; i < variables.size(); i++) { + PropertyInfo pinfo; + pinfo.name = "params/" + variables[i]; + pinfo.usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; + + switch (RS::get_singleton()->global_variable_get_type(variables[i])) { + case RS::GLOBAL_VAR_TYPE_BOOL: { + pinfo.type = Variant::BOOL; + } break; + case RS::GLOBAL_VAR_TYPE_BVEC2: { + pinfo.type = Variant::INT; + pinfo.hint = PROPERTY_HINT_FLAGS; + pinfo.hint_string = "x,y"; + } break; + case RS::GLOBAL_VAR_TYPE_BVEC3: { + pinfo.type = Variant::INT; + pinfo.hint = PROPERTY_HINT_FLAGS; + pinfo.hint_string = "x,y,z"; + } break; + case RS::GLOBAL_VAR_TYPE_BVEC4: { + pinfo.type = Variant::INT; + pinfo.hint = PROPERTY_HINT_FLAGS; + pinfo.hint_string = "x,y,z,w"; + } break; + case RS::GLOBAL_VAR_TYPE_INT: { + pinfo.type = Variant::INT; + } break; + case RS::GLOBAL_VAR_TYPE_IVEC2: { + pinfo.type = Variant::VECTOR2I; + } break; + case RS::GLOBAL_VAR_TYPE_IVEC3: { + pinfo.type = Variant::VECTOR3I; + } break; + case RS::GLOBAL_VAR_TYPE_IVEC4: { + pinfo.type = Variant::PACKED_INT32_ARRAY; + } break; + case RS::GLOBAL_VAR_TYPE_RECT2I: { + pinfo.type = Variant::RECT2I; + } break; + case RS::GLOBAL_VAR_TYPE_UINT: { + pinfo.type = Variant::INT; + } break; + case RS::GLOBAL_VAR_TYPE_UVEC2: { + pinfo.type = Variant::VECTOR2I; + } break; + case RS::GLOBAL_VAR_TYPE_UVEC3: { + pinfo.type = Variant::VECTOR3I; + } break; + case RS::GLOBAL_VAR_TYPE_UVEC4: { + pinfo.type = Variant::PACKED_INT32_ARRAY; + } break; + case RS::GLOBAL_VAR_TYPE_FLOAT: { + pinfo.type = Variant::FLOAT; + } break; + case RS::GLOBAL_VAR_TYPE_VEC2: { + pinfo.type = Variant::VECTOR2; + } break; + case RS::GLOBAL_VAR_TYPE_VEC3: { + pinfo.type = Variant::VECTOR3; + } break; + case RS::GLOBAL_VAR_TYPE_VEC4: { + pinfo.type = Variant::PLANE; + } break; + case RS::GLOBAL_VAR_TYPE_RECT2: { + pinfo.type = Variant::RECT2; + } break; + case RS::GLOBAL_VAR_TYPE_COLOR: { + pinfo.type = Variant::COLOR; + } break; + case RS::GLOBAL_VAR_TYPE_MAT2: { + pinfo.type = Variant::PACKED_INT32_ARRAY; + } break; + case RS::GLOBAL_VAR_TYPE_MAT3: { + pinfo.type = Variant::BASIS; + } break; + case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D: { + pinfo.type = Variant::TRANSFORM2D; + } break; + case RS::GLOBAL_VAR_TYPE_TRANSFORM: { + pinfo.type = Variant::TRANSFORM; + } break; + case RS::GLOBAL_VAR_TYPE_MAT4: { + pinfo.type = Variant::PACKED_INT32_ARRAY; + } break; + case RS::GLOBAL_VAR_TYPE_SAMPLER2D: { + pinfo.type = Variant::OBJECT; + pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE; + pinfo.hint_string = "Texture2D"; + } break; + case RS::GLOBAL_VAR_TYPE_SAMPLER2DARRAY: { + pinfo.type = Variant::OBJECT; + pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE; + pinfo.hint_string = "Texture2DArray"; + } break; + case RS::GLOBAL_VAR_TYPE_SAMPLER3D: { + pinfo.type = Variant::OBJECT; + pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE; + pinfo.hint_string = "Texture3D"; + } break; + case RS::GLOBAL_VAR_TYPE_SAMPLERCUBE: { + pinfo.type = Variant::OBJECT; + pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE; + pinfo.hint_string = "Cubemap"; + } break; + default: { + + } break; + } + + if (!overrides.has(variables[i])) { + Override o; + o.in_use = false; + Callable::CallError ce; + o.override = Variant::construct(pinfo.type, NULL, 0, ce); + overrides[variables[i]] = o; + } + + Override *o = overrides.getptr(variables[i]); + if (o->in_use && o->override.get_type() != Variant::NIL) { + pinfo.usage |= PROPERTY_USAGE_CHECKED; + pinfo.usage |= PROPERTY_USAGE_STORAGE; + } + + p_list->push_back(pinfo); + } +} + +void ShaderGlobalsOverride::_activate() { + + List<Node *> nodes; + get_tree()->get_nodes_in_group(SceneStringNames::get_singleton()->shader_overrides_group_active, &nodes); + if (nodes.size() == 0) { + //good we are the only override, enable all + active = true; + add_to_group(SceneStringNames::get_singleton()->shader_overrides_group_active); + + const StringName *K = nullptr; + while ((K = overrides.next(K))) { + Override *o = overrides.getptr(*K); + if (o->in_use && o->override.get_type() != Variant::NIL) { + RS::get_singleton()->global_variable_set_override(*K, o->override); + } + } + + update_configuration_warning(); //may have activated + } +} + +void ShaderGlobalsOverride::_notification(int p_what) { + + if (p_what == Node3D::NOTIFICATION_ENTER_TREE) { + + add_to_group(SceneStringNames::get_singleton()->shader_overrides_group); + _activate(); + + } else if (p_what == Node3D::NOTIFICATION_EXIT_TREE) { + + if (active) { + //remove overrides + const StringName *K = nullptr; + while ((K = overrides.next(K))) { + Override *o = overrides.getptr(*K); + if (o->in_use) { + RS::get_singleton()->global_variable_set_override(*K, Variant()); + } + } + } + + remove_from_group(SceneStringNames::get_singleton()->shader_overrides_group_active); + remove_from_group(SceneStringNames::get_singleton()->shader_overrides_group); + get_tree()->call_group(SceneStringNames::get_singleton()->shader_overrides_group, "_activate"); //another may want to activate when this is removed + active = false; + } +} + +String ShaderGlobalsOverride::get_configuration_warning() const { + + if (!active) { + return TTR("ShaderGlobalsOverride is not active because another node of the same type is in the scene."); + } + + return String(); +} + +void ShaderGlobalsOverride::_bind_methods() { + + ClassDB::bind_method(D_METHOD("_activate"), &ShaderGlobalsOverride::_activate); +} + +ShaderGlobalsOverride::ShaderGlobalsOverride() { + active = false; +} diff --git a/scene/main/shader_globals_override.h b/scene/main/shader_globals_override.h new file mode 100644 index 0000000000..33d0dc948f --- /dev/null +++ b/scene/main/shader_globals_override.h @@ -0,0 +1,37 @@ +#ifndef SHADER_GLOBALS_OVERRIDE_H +#define SHADER_GLOBALS_OVERRIDE_H + +#include "scene/3d/node_3d.h" + +class ShaderGlobalsOverride : public Node { + + GDCLASS(ShaderGlobalsOverride, Node); + + struct Override { + bool in_use = false; + Variant override; + }; + + StringName *_remap(const StringName &p_name) const; + + bool active; + mutable HashMap<StringName, Override> overrides; + mutable HashMap<StringName, StringName> param_remaps; + + void _activate(); + +protected: + bool _set(const StringName &p_name, const Variant &p_value); + bool _get(const StringName &p_name, Variant &r_ret) const; + void _get_property_list(List<PropertyInfo> *p_list) const; + + void _notification(int p_what); + static void _bind_methods(); + +public: + String get_configuration_warning() const; + + ShaderGlobalsOverride(); +}; + +#endif // SHADER_GLOBALS_OVERRIDE_H diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 06d6e81786..51dd22db81 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -3173,7 +3173,7 @@ int Viewport::gui_get_canvas_sort_index() { void Viewport::set_msaa(MSAA p_msaa) { - ERR_FAIL_INDEX(p_msaa, 7); + ERR_FAIL_INDEX(p_msaa, MSAA_MAX); if (msaa == p_msaa) return; msaa = p_msaa; @@ -3185,6 +3185,19 @@ Viewport::MSAA Viewport::get_msaa() const { return msaa; } +void Viewport::set_screen_space_aa(ScreenSpaceAA p_screen_space_aa) { + + ERR_FAIL_INDEX(p_screen_space_aa, SCREEN_SPACE_AA_MAX); + if (screen_space_aa == p_screen_space_aa) + return; + screen_space_aa = p_screen_space_aa; + RS::get_singleton()->viewport_set_screen_space_aa(viewport, RS::ViewportScreenSpaceAA(p_screen_space_aa)); +} + +Viewport::ScreenSpaceAA Viewport::get_screen_space_aa() const { + + return screen_space_aa; +} void Viewport::set_debug_draw(DebugDraw p_debug_draw) { debug_draw = p_debug_draw; @@ -3371,6 +3384,9 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_msaa", "msaa"), &Viewport::set_msaa); ClassDB::bind_method(D_METHOD("get_msaa"), &Viewport::get_msaa); + ClassDB::bind_method(D_METHOD("set_screen_space_aa", "screen_space_aa"), &Viewport::set_screen_space_aa); + ClassDB::bind_method(D_METHOD("get_screen_space_aa"), &Viewport::get_screen_space_aa); + ClassDB::bind_method(D_METHOD("set_debug_draw", "debug_draw"), &Viewport::set_debug_draw); ClassDB::bind_method(D_METHOD("get_debug_draw"), &Viewport::get_debug_draw); @@ -3444,6 +3460,7 @@ void Viewport::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "handle_input_locally"), "set_handle_input_locally", "is_handling_input_locally"); ADD_GROUP("Rendering", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x,AndroidVR 2x,AndroidVR 4x"), "set_msaa", "get_msaa"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "screen_space_aa", PROPERTY_HINT_ENUM, "Disabled,FXAA"), "set_screen_space_aa", "get_screen_space_aa"); ADD_PROPERTY(PropertyInfo(Variant::INT, "debug_draw", PROPERTY_HINT_ENUM, "Disabled,Unshaded,Overdraw,Wireframe"), "set_debug_draw", "get_debug_draw"); ADD_GROUP("Canvas Items", "canvas_item_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "canvas_item_default_texture_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,MipmapLinear,MipmapNearest"), "set_default_canvas_item_texture_filter", "get_default_canvas_item_texture_filter"); @@ -3478,6 +3495,17 @@ void Viewport::_bind_methods() { BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_1024); BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_MAX); + BIND_ENUM_CONSTANT(MSAA_DISABLED); + BIND_ENUM_CONSTANT(MSAA_2X); + BIND_ENUM_CONSTANT(MSAA_4X); + BIND_ENUM_CONSTANT(MSAA_8X); + BIND_ENUM_CONSTANT(MSAA_16X); + BIND_ENUM_CONSTANT(MSAA_MAX); + + BIND_ENUM_CONSTANT(SCREEN_SPACE_AA_DISABLED); + BIND_ENUM_CONSTANT(SCREEN_SPACE_AA_FXAA); + BIND_ENUM_CONSTANT(SCREEN_SPACE_AA_MAX); + BIND_ENUM_CONSTANT(RENDER_INFO_OBJECTS_IN_FRAME); BIND_ENUM_CONSTANT(RENDER_INFO_VERTICES_IN_FRAME); BIND_ENUM_CONSTANT(RENDER_INFO_MATERIAL_CHANGES_IN_FRAME); @@ -3488,9 +3516,10 @@ void Viewport::_bind_methods() { BIND_ENUM_CONSTANT(DEBUG_DRAW_DISABLED); BIND_ENUM_CONSTANT(DEBUG_DRAW_UNSHADED); + BIND_ENUM_CONSTANT(DEBUG_DRAW_LIGHTING); BIND_ENUM_CONSTANT(DEBUG_DRAW_OVERDRAW); BIND_ENUM_CONSTANT(DEBUG_DRAW_WIREFRAME); - + BIND_ENUM_CONSTANT(DEBUG_DRAW_NORMAL_BUFFER); BIND_ENUM_CONSTANT(DEBUG_DRAW_GI_PROBE_ALBEDO); BIND_ENUM_CONSTANT(DEBUG_DRAW_GI_PROBE_LIGHTING); BIND_ENUM_CONSTANT(DEBUG_DRAW_GI_PROBE_EMISSION); @@ -3498,19 +3527,16 @@ void Viewport::_bind_methods() { BIND_ENUM_CONSTANT(DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS); BIND_ENUM_CONSTANT(DEBUG_DRAW_SCENE_LUMINANCE); BIND_ENUM_CONSTANT(DEBUG_DRAW_SSAO); - - BIND_ENUM_CONSTANT(MSAA_DISABLED); - BIND_ENUM_CONSTANT(MSAA_2X); - BIND_ENUM_CONSTANT(MSAA_4X); - BIND_ENUM_CONSTANT(MSAA_8X); - BIND_ENUM_CONSTANT(MSAA_16X); + BIND_ENUM_CONSTANT(DEBUG_DRAW_ROUGHNESS_LIMITER); + BIND_ENUM_CONSTANT(DEBUG_DRAW_PSSM_SPLITS); + BIND_ENUM_CONSTANT(DEBUG_DRAW_DECAL_ATLAS); BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST); BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR); BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS); BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS); - BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_MAX); + BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MIRROR); @@ -3584,7 +3610,7 @@ Viewport::Viewport() { gui.subwindow_drag = SUB_WINDOW_DRAG_DISABLED; msaa = MSAA_DISABLED; - + screen_space_aa = SCREEN_SPACE_AA_DISABLED; debug_draw = DEBUG_DRAW_DISABLED; snap_controls_to_pixels = true; @@ -3613,13 +3639,14 @@ Viewport::~Viewport() { ///////////////////////////////// -void SubViewport::set_use_arvr(bool p_use_arvr) { - arvr = p_use_arvr; +void SubViewport::set_use_xr(bool p_use_xr) { + xr = p_use_xr; - RS::get_singleton()->viewport_set_use_arvr(get_viewport_rid(), arvr); + RS::get_singleton()->viewport_set_use_xr(get_viewport_rid(), xr); } -bool SubViewport::is_using_arvr() { - return arvr; + +bool SubViewport::is_using_xr() { + return xr; } void SubViewport::set_size(const Size2i &p_size) { @@ -3699,8 +3726,8 @@ void SubViewport::_notification(int p_what) { } void SubViewport::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_use_arvr", "use"), &SubViewport::set_use_arvr); - ClassDB::bind_method(D_METHOD("is_using_arvr"), &SubViewport::is_using_arvr); + ClassDB::bind_method(D_METHOD("set_use_xr", "use"), &SubViewport::set_use_xr); + ClassDB::bind_method(D_METHOD("is_using_xr"), &SubViewport::is_using_xr); ClassDB::bind_method(D_METHOD("set_size", "size"), &SubViewport::set_size); ClassDB::bind_method(D_METHOD("get_size"), &SubViewport::get_size); @@ -3717,7 +3744,7 @@ void SubViewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_clear_mode", "mode"), &SubViewport::set_clear_mode); ClassDB::bind_method(D_METHOD("get_clear_mode"), &SubViewport::get_clear_mode); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "arvr"), "set_use_arvr", "is_using_arvr"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "xr"), "set_use_xr", "is_using_xr"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size_2d_override"), "set_size_2d_override", "get_size_2d_override"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "size_2d_override_stretch"), "set_size_2d_override_stretch", "is_size_2d_override_stretch_enabled"); @@ -3725,19 +3752,19 @@ void SubViewport::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "render_target_clear_mode", PROPERTY_HINT_ENUM, "Always,Never,Next Frame"), "set_clear_mode", "get_clear_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "render_target_update_mode", PROPERTY_HINT_ENUM, "Disabled,Once,When Visible,Always"), "set_update_mode", "get_update_mode"); + BIND_ENUM_CONSTANT(CLEAR_MODE_ALWAYS); + BIND_ENUM_CONSTANT(CLEAR_MODE_NEVER); + BIND_ENUM_CONSTANT(CLEAR_MODE_ONLY_NEXT_FRAME); + BIND_ENUM_CONSTANT(UPDATE_DISABLED); BIND_ENUM_CONSTANT(UPDATE_ONCE); BIND_ENUM_CONSTANT(UPDATE_WHEN_VISIBLE); BIND_ENUM_CONSTANT(UPDATE_WHEN_PARENT_VISIBLE); BIND_ENUM_CONSTANT(UPDATE_ALWAYS); - - BIND_ENUM_CONSTANT(CLEAR_MODE_ALWAYS); - BIND_ENUM_CONSTANT(CLEAR_MODE_NEVER); - BIND_ENUM_CONSTANT(CLEAR_MODE_ONLY_NEXT_FRAME); } SubViewport::SubViewport() { - arvr = false; + xr = false; size_2d_override_stretch = false; update_mode = UPDATE_WHEN_VISIBLE; clear_mode = CLEAR_MODE_ALWAYS; diff --git a/scene/main/viewport.h b/scene/main/viewport.h index d603294ed5..7e2df9fe42 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -106,10 +106,16 @@ public: MSAA_4X, MSAA_8X, MSAA_16X, + MSAA_MAX }; - enum RenderInfo { + enum ScreenSpaceAA { + SCREEN_SPACE_AA_DISABLED, + SCREEN_SPACE_AA_FXAA, + SCREEN_SPACE_AA_MAX + }; + enum RenderInfo { RENDER_INFO_OBJECTS_IN_FRAME, RENDER_INFO_VERTICES_IN_FRAME, RENDER_INFO_MATERIAL_CHANGES_IN_FRAME, @@ -133,7 +139,9 @@ public: DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS, DEBUG_DRAW_SCENE_LUMINANCE, DEBUG_DRAW_SSAO, - DEBUG_DRAW_ROUGHNESS_LIMITER + DEBUG_DRAW_ROUGHNESS_LIMITER, + DEBUG_DRAW_PSSM_SPLITS, + DEBUG_DRAW_DECAL_ATLAS }; enum DefaultCanvasItemTextureFilter { @@ -271,6 +279,7 @@ private: ShadowAtlasQuadrantSubdiv shadow_atlas_quadrant_subdiv[4]; MSAA msaa; + ScreenSpaceAA screen_space_aa; Ref<ViewportTexture> default_texture; Set<ViewportTexture *> viewport_textures; @@ -504,6 +513,9 @@ public: void set_msaa(MSAA p_msaa); MSAA get_msaa() const; + void set_screen_space_aa(ScreenSpaceAA p_screen_space_aa); + ScreenSpaceAA get_screen_space_aa() const; + Vector2 get_camera_coords(const Vector2 &p_viewport_coords) const; Vector2 get_camera_rect_size() const; @@ -589,7 +601,7 @@ public: private: UpdateMode update_mode; ClearMode clear_mode; - bool arvr; + bool xr; bool size_2d_override_stretch; protected: @@ -605,8 +617,8 @@ public: void set_size_2d_override(const Size2i &p_size); Size2i get_size_2d_override() const; - void set_use_arvr(bool p_use_arvr); - bool is_using_arvr(); + void set_use_xr(bool p_use_xr); + bool is_using_xr(); void set_size_2d_override_stretch(bool p_enable); bool is_size_2d_override_stretch_enabled() const; @@ -623,6 +635,7 @@ public: VARIANT_ENUM_CAST(SubViewport::UpdateMode); VARIANT_ENUM_CAST(Viewport::ShadowAtlasQuadrantSubdiv); VARIANT_ENUM_CAST(Viewport::MSAA); +VARIANT_ENUM_CAST(Viewport::ScreenSpaceAA); VARIANT_ENUM_CAST(Viewport::DebugDraw); VARIANT_ENUM_CAST(SubViewport::ClearMode); VARIANT_ENUM_CAST(Viewport::RenderInfo); diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 94162cbe4e..dc3ef5b508 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -177,9 +177,10 @@ #include "scene/3d/node_3d.h" #include "scene/3d/skeleton_3d.h" +#include "scene/main/shader_globals_override.h" + #ifndef _3D_DISABLED #include "scene/3d/area_3d.h" -#include "scene/3d/arvr_nodes.h" #include "scene/3d/audio_stream_player_3d.h" #include "scene/3d/baked_lightmap.h" #include "scene/3d/bone_attachment_3d.h" @@ -187,6 +188,7 @@ #include "scene/3d/collision_polygon_3d.h" #include "scene/3d/collision_shape_3d.h" #include "scene/3d/cpu_particles_3d.h" +#include "scene/3d/decal.h" #include "scene/3d/gi_probe.h" #include "scene/3d/gpu_particles_3d.h" #include "scene/3d/immediate_geometry_3d.h" @@ -213,6 +215,7 @@ #include "scene/3d/vehicle_body_3d.h" #include "scene/3d/visibility_notifier_3d.h" #include "scene/3d/world_environment.h" +#include "scene/3d/xr_nodes.h" #include "scene/resources/environment.h" #include "scene/resources/mesh_library.h" #endif @@ -402,6 +405,8 @@ void register_scene_types() { ClassDB::register_class<AnimationNodeTimeSeek>(); ClassDB::register_class<AnimationNodeTransition>(); + ClassDB::register_class<ShaderGlobalsOverride>(); //can be used in any shader + OS::get_singleton()->yield(); //may take time to init #ifndef _3D_DISABLED @@ -410,10 +415,10 @@ void register_scene_types() { ClassDB::register_class<Camera3D>(); ClassDB::register_class<ClippedCamera3D>(); ClassDB::register_class<Listener3D>(); - ClassDB::register_class<ARVRCamera>(); - ClassDB::register_class<ARVRController>(); - ClassDB::register_class<ARVRAnchor>(); - ClassDB::register_class<ARVROrigin>(); + ClassDB::register_class<XRCamera3D>(); + ClassDB::register_class<XRController3D>(); + ClassDB::register_class<XRAnchor3D>(); + ClassDB::register_class<XROrigin3D>(); ClassDB::register_class<MeshInstance3D>(); ClassDB::register_class<ImmediateGeometry3D>(); ClassDB::register_virtual_class<SpriteBase3D>(); @@ -424,6 +429,7 @@ void register_scene_types() { ClassDB::register_class<OmniLight3D>(); ClassDB::register_class<SpotLight3D>(); ClassDB::register_class<ReflectionProbe>(); + ClassDB::register_class<Decal>(); ClassDB::register_class<GIProbe>(); ClassDB::register_class<GIProbeData>(); //ClassDB::register_class<BakedLightmap>(); @@ -751,8 +757,16 @@ void register_scene_types() { ClassDB::add_compatibility_class("AnimationTreePlayer", "AnimationTree"); // Renamed in 4.0. + // Keep alphabetical ordering to easily locate classes and avoid duplicates. ClassDB::add_compatibility_class("AnimatedSprite", "AnimatedSprite2D"); ClassDB::add_compatibility_class("Area", "Area3D"); + ClassDB::add_compatibility_class("ARVRCamera", "XRCamera3D"); + ClassDB::add_compatibility_class("ARVRController", "XRController3D"); + ClassDB::add_compatibility_class("ARVRAnchor", "XRAnchor3D"); + ClassDB::add_compatibility_class("ARVRInterface", "XRInterface"); + ClassDB::add_compatibility_class("ARVROrigin", "XROrigin3D"); + ClassDB::add_compatibility_class("ARVRPositionalTracker", "XRPositionalTracker"); + ClassDB::add_compatibility_class("ARVRServer", "XRServer"); ClassDB::add_compatibility_class("BoneAttachment", "BoneAttachment3D"); ClassDB::add_compatibility_class("BoxShape", "BoxShape3D"); ClassDB::add_compatibility_class("BulletPhysicsDirectBodyState", "BulletPhysicsDirectBodyState3D"); @@ -800,6 +814,7 @@ void register_scene_types() { ClassDB::add_compatibility_class("Navigation2DServer", "NavigationServer2D"); ClassDB::add_compatibility_class("NavigationServer", "NavigationServer3D"); ClassDB::add_compatibility_class("OmniLight", "OmniLight3D"); + ClassDB::add_compatibility_class("PanoramaSky", "Sky"); ClassDB::add_compatibility_class("Particles", "GPUParticles3D"); ClassDB::add_compatibility_class("Particles2D", "GPUParticles2D"); ClassDB::add_compatibility_class("Path", "Path3D"); @@ -821,6 +836,7 @@ void register_scene_types() { ClassDB::add_compatibility_class("PhysicsShapeQueryResult", "PhysicsShapeQueryResult3D"); ClassDB::add_compatibility_class("PinJoint", "PinJoint3D"); ClassDB::add_compatibility_class("PlaneShape", "WorldMarginShape3D"); + ClassDB::add_compatibility_class("ProceduralSky", "Sky"); ClassDB::add_compatibility_class("ProximityGroup", "ProximityGroup3D"); ClassDB::add_compatibility_class("RayCast", "RayCast3D"); ClassDB::add_compatibility_class("RayShape", "RayShape3D"); @@ -851,8 +867,6 @@ void register_scene_types() { ClassDB::add_compatibility_class("VisualShaderNodeScalarOp", "VisualShaderNodeFloatOp"); ClassDB::add_compatibility_class("VisualShaderNodeScalarUniform", "VisualShaderNodeFloatUniform"); ClassDB::add_compatibility_class("World", "World3D"); - ClassDB::add_compatibility_class("ProceduralSky", "Sky"); - ClassDB::add_compatibility_class("PanoramaSky", "Sky"); #endif diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index e6f09eb034..a1e8bf51bd 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -497,6 +497,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_stylebox("slider", "HSlider", make_stylebox(hslider_bg_png, 4, 4, 4, 4)); theme->set_stylebox("grabber_area", "HSlider", make_stylebox(hslider_bg_png, 4, 4, 4, 4)); + theme->set_stylebox("grabber_area_highlight", "HSlider", make_stylebox(hslider_bg_png, 4, 4, 4, 4)); theme->set_icon("grabber", "HSlider", make_icon(hslider_grabber_png)); theme->set_icon("grabber_highlight", "HSlider", make_icon(hslider_grabber_hl_png)); @@ -507,6 +508,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_stylebox("slider", "VSlider", make_stylebox(vslider_bg_png, 4, 4, 4, 4)); theme->set_stylebox("grabber_area", "VSlider", make_stylebox(vslider_bg_png, 4, 4, 4, 4)); + theme->set_stylebox("grabber_area_highlight", "VSlider", make_stylebox(vslider_bg_png, 4, 4, 4, 4)); theme->set_icon("grabber", "VSlider", make_icon(vslider_grabber_png)); theme->set_icon("grabber_highlight", "VSlider", make_icon(vslider_grabber_hl_png)); diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp index a613b01376..eea4d12d0e 100644 --- a/scene/resources/dynamic_font.cpp +++ b/scene/resources/dynamic_font.cpp @@ -1064,7 +1064,7 @@ void DynamicFont::update_oversampling() { ///////////////////////// -RES ResourceFormatLoaderDynamicFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderDynamicFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) *r_error = ERR_FILE_CANT_OPEN; diff --git a/scene/resources/dynamic_font.h b/scene/resources/dynamic_font.h index 9e628fc35a..ef4b9dd9d0 100644 --- a/scene/resources/dynamic_font.h +++ b/scene/resources/dynamic_font.h @@ -302,7 +302,7 @@ VARIANT_ENUM_CAST(DynamicFont::SpacingType); class ResourceFormatLoaderDynamicFont : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index 192eefbf6a..267816f267 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -646,7 +646,7 @@ BitmapFont::~BitmapFont() { //////////// -RES ResourceFormatLoaderBMFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderBMFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) *r_error = ERR_FILE_CANT_OPEN; diff --git a/scene/resources/font.h b/scene/resources/font.h index ce75f27e2a..c233344529 100644 --- a/scene/resources/font.h +++ b/scene/resources/font.h @@ -200,7 +200,7 @@ public: class ResourceFormatLoaderBMFont : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 85adc8c5f1..fd8cff7cd0 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -314,7 +314,7 @@ void BaseMaterial3D::init_shaders() { shader_names->anisotropy = "anisotropy_ratio"; shader_names->heightmap_scale = "heightmap_scale"; shader_names->subsurface_scattering_strength = "subsurface_scattering_strength"; - shader_names->transmission = "transmission"; + shader_names->backlight = "backlight"; shader_names->refraction = "refraction"; shader_names->point_size = "point_size"; shader_names->uv1_scale = "uv1_scale"; @@ -347,6 +347,11 @@ void BaseMaterial3D::init_shaders() { shader_names->refraction_texture_channel = "refraction_texture_channel"; shader_names->alpha_scissor_threshold = "alpha_scissor_threshold"; + shader_names->transmittance_color = "transmittance_color"; + shader_names->transmittance_curve = "transmittance_curve"; + shader_names->transmittance_depth = "transmittance_depth"; + shader_names->transmittance_boost = "transmittance_boost"; + shader_names->texture_names[TEXTURE_ALBEDO] = "texture_albedo"; shader_names->texture_names[TEXTURE_METALLIC] = "texture_metallic"; shader_names->texture_names[TEXTURE_ROUGHNESS] = "texture_roughness"; @@ -358,7 +363,8 @@ void BaseMaterial3D::init_shaders() { shader_names->texture_names[TEXTURE_AMBIENT_OCCLUSION] = "texture_ambient_occlusion"; shader_names->texture_names[TEXTURE_HEIGHTMAP] = "texture_heightmap"; shader_names->texture_names[TEXTURE_SUBSURFACE_SCATTERING] = "texture_subsurface_scattering"; - shader_names->texture_names[TEXTURE_TRANSMISSION] = "texture_transmission"; + shader_names->texture_names[TEXTURE_SUBSURFACE_TRANSMITTANCE] = "texture_subsurface_transmittance"; + shader_names->texture_names[TEXTURE_BACKLIGHT] = "texture_backlight"; shader_names->texture_names[TEXTURE_REFRACTION] = "texture_refraction"; shader_names->texture_names[TEXTURE_DETAIL_MASK] = "texture_detail_mask"; shader_names->texture_names[TEXTURE_DETAIL_ALBEDO] = "texture_detail_albedo"; @@ -385,7 +391,7 @@ void BaseMaterial3D::_update_shader() { dirty_materials->remove(&element); MaterialKey mk = _compute_key(); - if (mk.key == current_key.key) + if (mk == current_key) return; //no update required in the end if (shader_map.has(current_key)) { @@ -444,9 +450,6 @@ void BaseMaterial3D::_update_shader() { case DEPTH_DRAW_DISABLED: code += ",depth_draw_never"; break; } - if (features[FEATURE_SUBSURACE_SCATTERING] && flags[FLAG_SUBSURFACE_MODE_SKIN]) { - code += ",sss_mode_skin"; - } if (transparency == TRANSPARENCY_ALPHA_DEPTH_PRE_PASS) { code += ",depth_prepass_alpha"; } @@ -470,6 +473,9 @@ void BaseMaterial3D::_update_shader() { case SPECULAR_TOON: code += ",specular_toon"; break; case SPECULAR_DISABLED: code += ",specular_disabled"; break; } + if (features[FEATURE_SUBSURFACE_SCATTERING] && flags[FLAG_SUBSURFACE_MODE_SKIN]) { + code += ",sss_mode_skin"; + } if (shading_mode == SHADING_MODE_UNSHADED) { code += ",unshaded"; @@ -589,16 +595,25 @@ void BaseMaterial3D::_update_shader() { code += "uniform sampler2D texture_detail_mask : hint_white," + texfilter_str + ";\n"; } - if (features[FEATURE_SUBSURACE_SCATTERING]) { + if (features[FEATURE_SUBSURFACE_SCATTERING]) { code += "uniform float subsurface_scattering_strength : hint_range(0,1);\n"; code += "uniform sampler2D texture_subsurface_scattering : hint_white," + texfilter_str + ";\n"; } - if (features[FEATURE_TRANSMISSION]) { + if (features[FEATURE_SUBSURFACE_TRANSMITTANCE]) { - code += "uniform vec4 transmission : hint_color;\n"; - code += "uniform sampler2D texture_transmission : hint_black," + texfilter_str + ";\n"; + code += "uniform vec4 transmittance_color : hint_color;\n"; + code += "uniform float transmittance_depth;\n"; + code += "uniform sampler2D texture_subsurface_transmittance : hint_white," + texfilter_str + ";\n"; + code += "uniform float transmittance_curve;\n"; + code += "uniform float transmittance_boost;\n"; + } + + if (features[FEATURE_BACKLIGHT]) { + + code += "uniform vec4 backlight : hint_color;\n"; + code += "uniform sampler2D texture_backlight : hint_black," + texfilter_str + ";\n"; } if (features[FEATURE_HEIGHT_MAPPING]) { @@ -1051,7 +1066,7 @@ void BaseMaterial3D::_update_shader() { code += "\tAO_LIGHT_AFFECT = ao_light_affect;\n"; } - if (features[FEATURE_SUBSURACE_SCATTERING]) { + if (features[FEATURE_SUBSURFACE_SCATTERING]) { if (flags[FLAG_UV1_USE_TRIPLANAR]) { code += "\tfloat sss_tex = triplanar_texture(texture_subsurface_scattering,uv1_power_normal,uv1_triplanar_pos).r;\n"; @@ -1061,13 +1076,27 @@ void BaseMaterial3D::_update_shader() { code += "\tSSS_STRENGTH=subsurface_scattering_strength*sss_tex;\n"; } - if (features[FEATURE_TRANSMISSION]) { + if (features[FEATURE_SUBSURFACE_TRANSMITTANCE]) { + + if (flags[FLAG_UV1_USE_TRIPLANAR]) { + code += "\tvec4 trans_color_tex = triplanar_texture(texture_subsurface_transmittance,uv1_power_normal,uv1_triplanar_pos);\n"; + } else { + code += "\tvec4 trans_color_tex = texture(texture_subsurface_transmittance,base_uv);\n"; + } + code += "\tSSS_TRANSMITTANCE_COLOR=transmittance_color*trans_color_tex;\n"; + + code += "\tSSS_TRANSMITTANCE_DEPTH=transmittance_depth;\n"; + code += "\tSSS_TRANSMITTANCE_CURVE=transmittance_curve;\n"; + code += "\tSSS_TRANSMITTANCE_BOOST=transmittance_boost;\n"; + } + + if (features[FEATURE_BACKLIGHT]) { if (flags[FLAG_UV1_USE_TRIPLANAR]) { - code += "\tvec3 transmission_tex = triplanar_texture(texture_transmission,uv1_power_normal,uv1_triplanar_pos).rgb;\n"; + code += "\tvec3 backlight_tex = triplanar_texture(texture_backlight,uv1_power_normal,uv1_triplanar_pos).rgb;\n"; } else { - code += "\tvec3 transmission_tex = texture(texture_transmission,base_uv).rgb;\n"; + code += "\tvec3 backlight_tex = texture(texture_backlight,base_uv).rgb;\n"; } - code += "\tTRANSMISSION = (transmission.rgb+transmission_tex);\n"; + code += "\tBACKLIGHT = (backlight.rgb+backlight_tex);\n"; } if (features[FEATURE_DETAIL]) { @@ -1309,15 +1338,48 @@ float BaseMaterial3D::get_subsurface_scattering_strength() const { return subsurface_scattering_strength; } -void BaseMaterial3D::set_transmission(const Color &p_transmission) { +void BaseMaterial3D::set_transmittance_color(const Color &p_color) { + transmittance_color = p_color; + RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_color, p_color); +} - transmission = p_transmission; - RS::get_singleton()->material_set_param(_get_material(), shader_names->transmission, transmission); +Color BaseMaterial3D::get_transmittance_color() const { + return transmittance_color; } -Color BaseMaterial3D::get_transmission() const { +void BaseMaterial3D::set_transmittance_depth(float p_depth) { + transmittance_depth = p_depth; + RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_depth, p_depth); +} +float BaseMaterial3D::get_transmittance_depth() const { + return transmittance_depth; +} - return transmission; +void BaseMaterial3D::set_transmittance_curve(float p_curve) { + transmittance_curve = p_curve; + RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_curve, p_curve); +} +float BaseMaterial3D::get_transmittance_curve() const { + return transmittance_curve; +} + +void BaseMaterial3D::set_transmittance_boost(float p_boost) { + transmittance_boost = p_boost; + RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_boost, p_boost); +} +float BaseMaterial3D::get_transmittance_boost() const { + return transmittance_boost; +} + +void BaseMaterial3D::set_backlight(const Color &p_backlight) { + + backlight = p_backlight; + RS::get_singleton()->material_set_param(_get_material(), shader_names->backlight, backlight); +} + +Color BaseMaterial3D::get_backlight() const { + + return backlight; } void BaseMaterial3D::set_refraction(float p_refraction) { @@ -1457,7 +1519,7 @@ void BaseMaterial3D::set_flag(Flags p_flag, bool p_enabled) { return; flags[p_flag] = p_enabled; - if ((p_flag == FLAG_USE_SHADOW_TO_OPACITY) || (p_flag == FLAG_USE_TEXTURE_REPEAT)) { + if (p_flag == FLAG_USE_SHADOW_TO_OPACITY || p_flag == FLAG_USE_TEXTURE_REPEAT || p_flag == FLAG_SUBSURFACE_MODE_SKIN) { _change_notify(); } _queue_shader_change(); @@ -1540,8 +1602,8 @@ void BaseMaterial3D::_validate_property(PropertyInfo &property) const { _validate_feature("anisotropy", FEATURE_ANISOTROPY, property); _validate_feature("ao", FEATURE_AMBIENT_OCCLUSION, property); _validate_feature("heightmap", FEATURE_HEIGHT_MAPPING, property); - _validate_feature("subsurf_scatter", FEATURE_SUBSURACE_SCATTERING, property); - _validate_feature("transmission", FEATURE_TRANSMISSION, property); + _validate_feature("subsurf_scatter", FEATURE_SUBSURFACE_SCATTERING, property); + _validate_feature("backlight", FEATURE_BACKLIGHT, property); _validate_feature("refraction", FEATURE_REFRACTION, property); _validate_feature("detail", FEATURE_DETAIL, property); @@ -1575,6 +1637,10 @@ void BaseMaterial3D::_validate_property(PropertyInfo &property) const { property.usage = 0; } + if (flags[FLAG_SUBSURFACE_MODE_SKIN] && (property.name == "subsurf_scatter_transmittance_color" || property.name == "subsurf_scatter_transmittance_texture" || property.name == "subsurf_scatter_transmittance_curve")) { + property.usage = 0; + } + if (orm) { if (property.name == "shading_mode") { @@ -1631,7 +1697,11 @@ void BaseMaterial3D::_validate_property(PropertyInfo &property) const { property.usage = 0; } - if (property.name.begins_with("transmission")) { + if (property.name.begins_with("backlight")) { + property.usage = 0; + } + + if (property.name.begins_with("transmittance")) { property.usage = 0; } } @@ -2070,8 +2140,20 @@ void BaseMaterial3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_subsurface_scattering_strength", "strength"), &BaseMaterial3D::set_subsurface_scattering_strength); ClassDB::bind_method(D_METHOD("get_subsurface_scattering_strength"), &BaseMaterial3D::get_subsurface_scattering_strength); - ClassDB::bind_method(D_METHOD("set_transmission", "transmission"), &BaseMaterial3D::set_transmission); - ClassDB::bind_method(D_METHOD("get_transmission"), &BaseMaterial3D::get_transmission); + ClassDB::bind_method(D_METHOD("set_transmittance_color", "color"), &BaseMaterial3D::set_transmittance_color); + ClassDB::bind_method(D_METHOD("get_transmittance_color"), &BaseMaterial3D::get_transmittance_color); + + ClassDB::bind_method(D_METHOD("set_transmittance_depth", "depth"), &BaseMaterial3D::set_transmittance_depth); + ClassDB::bind_method(D_METHOD("get_transmittance_depth"), &BaseMaterial3D::get_transmittance_depth); + + ClassDB::bind_method(D_METHOD("set_transmittance_curve", "curve"), &BaseMaterial3D::set_transmittance_curve); + ClassDB::bind_method(D_METHOD("get_transmittance_curve"), &BaseMaterial3D::get_transmittance_curve); + + ClassDB::bind_method(D_METHOD("set_transmittance_boost", "boost"), &BaseMaterial3D::set_transmittance_boost); + ClassDB::bind_method(D_METHOD("get_transmittance_boost"), &BaseMaterial3D::get_transmittance_boost); + + ClassDB::bind_method(D_METHOD("set_backlight", "backlight"), &BaseMaterial3D::set_backlight); + ClassDB::bind_method(D_METHOD("get_backlight"), &BaseMaterial3D::get_backlight); ClassDB::bind_method(D_METHOD("set_refraction", "refraction"), &BaseMaterial3D::set_refraction); ClassDB::bind_method(D_METHOD("get_refraction"), &BaseMaterial3D::get_refraction); @@ -2285,15 +2367,23 @@ void BaseMaterial3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "heightmap_flip_texture"), "set_flag", "get_flag", FLAG_INVERT_HEIGHTMAP); ADD_GROUP("Subsurf Scatter", "subsurf_scatter_"); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "subsurf_scatter_enabled"), "set_feature", "get_feature", FEATURE_SUBSURACE_SCATTERING); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "subsurf_scatter_enabled"), "set_feature", "get_feature", FEATURE_SUBSURFACE_SCATTERING); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "subsurf_scatter_strength", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_subsurface_scattering_strength", "get_subsurface_scattering_strength"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "subsurf_scatter_skin_mode"), "set_flag", "get_flag", FLAG_SUBSURFACE_MODE_SKIN); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "subsurf_scatter_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_SUBSURFACE_SCATTERING); - ADD_GROUP("Transmission", "transmission_"); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "transmission_enabled"), "set_feature", "get_feature", FEATURE_TRANSMISSION); - ADD_PROPERTY(PropertyInfo(Variant::COLOR, "transmission", PROPERTY_HINT_COLOR_NO_ALPHA), "set_transmission", "get_transmission"); - ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "transmission_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_TRANSMISSION); + ADD_SUBGROUP("Transmittance", "subsurf_scatter_transmittance_"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "subsurf_scatter_transmittance_enabled"), "set_feature", "get_feature", FEATURE_SUBSURFACE_TRANSMITTANCE); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "subsurf_scatter_transmittance_color"), "set_transmittance_color", "get_transmittance_color"); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "subsurf_scatter_transmittance_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_SUBSURFACE_TRANSMITTANCE); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "subsurf_scatter_transmittance_depth", PROPERTY_HINT_RANGE, "0.001,8,0.001,or_greater"), "set_transmittance_depth", "get_transmittance_depth"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "subsurf_scatter_transmittance_curve", PROPERTY_HINT_EXP_EASING, "0.01,16,0.01"), "set_transmittance_curve", "get_transmittance_curve"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "subsurf_scatter_transmittance_boost", PROPERTY_HINT_RANGE, "0.00,1.0,0.01"), "set_transmittance_boost", "get_transmittance_boost"); + + ADD_GROUP("Back Lighting", "backlight_"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "backlight_enabled"), "set_feature", "get_feature", FEATURE_BACKLIGHT); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "backlight", PROPERTY_HINT_COLOR_NO_ALPHA), "set_backlight", "get_backlight"); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "backlight_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_BACKLIGHT); ADD_GROUP("Refraction", "refraction_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "refraction_enabled"), "set_feature", "get_feature", FEATURE_REFRACTION); @@ -2366,7 +2456,8 @@ void BaseMaterial3D::_bind_methods() { BIND_ENUM_CONSTANT(TEXTURE_AMBIENT_OCCLUSION); BIND_ENUM_CONSTANT(TEXTURE_HEIGHTMAP); BIND_ENUM_CONSTANT(TEXTURE_SUBSURFACE_SCATTERING); - BIND_ENUM_CONSTANT(TEXTURE_TRANSMISSION); + BIND_ENUM_CONSTANT(TEXTURE_SUBSURFACE_TRANSMITTANCE); + BIND_ENUM_CONSTANT(TEXTURE_BACKLIGHT); BIND_ENUM_CONSTANT(TEXTURE_REFRACTION); BIND_ENUM_CONSTANT(TEXTURE_DETAIL_MASK); BIND_ENUM_CONSTANT(TEXTURE_DETAIL_ALBEDO); @@ -2403,8 +2494,9 @@ void BaseMaterial3D::_bind_methods() { BIND_ENUM_CONSTANT(FEATURE_ANISOTROPY); BIND_ENUM_CONSTANT(FEATURE_AMBIENT_OCCLUSION); BIND_ENUM_CONSTANT(FEATURE_HEIGHT_MAPPING); - BIND_ENUM_CONSTANT(FEATURE_SUBSURACE_SCATTERING); - BIND_ENUM_CONSTANT(FEATURE_TRANSMISSION); + BIND_ENUM_CONSTANT(FEATURE_SUBSURFACE_SCATTERING); + BIND_ENUM_CONSTANT(FEATURE_SUBSURFACE_TRANSMITTANCE); + BIND_ENUM_CONSTANT(FEATURE_BACKLIGHT); BIND_ENUM_CONSTANT(FEATURE_REFRACTION); BIND_ENUM_CONSTANT(FEATURE_DETAIL); BIND_ENUM_CONSTANT(FEATURE_MAX); @@ -2496,7 +2588,11 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) : set_anisotropy(0); set_heightmap_scale(0.05); set_subsurface_scattering_strength(0); - set_transmission(Color(0, 0, 0)); + set_backlight(Color(0, 0, 0)); + set_transmittance_color(Color(1, 1, 1, 1)); + set_transmittance_depth(0.1); + set_transmittance_curve(1.0); + set_transmittance_boost(0.0); set_refraction(0.05); set_point_size(1); set_uv1_offset(Vector3(0, 0, 0)); @@ -2552,7 +2648,8 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) : features[i] = false; } - current_key.key = 0; + current_key.key0 = 0; + current_key.key1 = 0; current_key.invalid_key = 1; texture_filter = TEXTURE_FILTER_LINEAR_WITH_MIPMAPS; _queue_shader_change(); diff --git a/scene/resources/material.h b/scene/resources/material.h index 57f9038bf5..241357ba9b 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -125,7 +125,8 @@ public: TEXTURE_AMBIENT_OCCLUSION, TEXTURE_HEIGHTMAP, TEXTURE_SUBSURFACE_SCATTERING, - TEXTURE_TRANSMISSION, + TEXTURE_SUBSURFACE_TRANSMITTANCE, + TEXTURE_BACKLIGHT, TEXTURE_REFRACTION, TEXTURE_DETAIL_MASK, TEXTURE_DETAIL_ALBEDO, @@ -173,8 +174,9 @@ public: FEATURE_ANISOTROPY, FEATURE_AMBIENT_OCCLUSION, FEATURE_HEIGHT_MAPPING, - FEATURE_SUBSURACE_SCATTERING, - FEATURE_TRANSMISSION, + FEATURE_SUBSURFACE_SCATTERING, + FEATURE_SUBSURFACE_TRANSMITTANCE, + FEATURE_BACKLIGHT, FEATURE_REFRACTION, FEATURE_DETAIL, FEATURE_MAX @@ -291,10 +293,16 @@ private: uint64_t roughness_channel : 3; }; - uint64_t key; + struct { + uint64_t key0; + uint64_t key1; + }; + bool operator==(const MaterialKey &p_key) const { + return (key0 == p_key.key0) && (key1 == p_key.key1); + } bool operator<(const MaterialKey &p_key) const { - return key < p_key.key; + return (key0 == p_key.key0) ? (key1 < p_key.key1) : (key0 < p_key.key0); } }; @@ -310,7 +318,8 @@ private: _FORCE_INLINE_ MaterialKey _compute_key() const { MaterialKey mk; - mk.key = 0; + mk.key0 = 0; + mk.key1 = 0; for (int i = 0; i < FEATURE_MAX; i++) { if (features[i]) { mk.feature_mask |= ((uint64_t)1 << i); @@ -357,7 +366,11 @@ private: StringName anisotropy; StringName heightmap_scale; StringName subsurface_scattering_strength; - StringName transmission; + StringName transmittance_color; + StringName transmittance_curve; + StringName transmittance_depth; + StringName transmittance_boost; + StringName backlight; StringName refraction; StringName point_size; StringName uv1_scale; @@ -415,7 +428,13 @@ private: float anisotropy; float heightmap_scale; float subsurface_scattering_strength; - Color transmission; + float transmittance_amount; + Color transmittance_color; + float transmittance_depth; + float transmittance_curve; + float transmittance_boost; + + Color backlight; float refraction; float point_size; float alpha_scissor_threshold; @@ -546,8 +565,20 @@ public: void set_subsurface_scattering_strength(float p_subsurface_scattering_strength); float get_subsurface_scattering_strength() const; - void set_transmission(const Color &p_transmission); - Color get_transmission() const; + void set_transmittance_color(const Color &p_color); + Color get_transmittance_color() const; + + void set_transmittance_depth(float p_depth); + float get_transmittance_depth() const; + + void set_transmittance_curve(float p_curve); + float get_transmittance_curve() const; + + void set_transmittance_boost(float p_boost); + float get_transmittance_boost() const; + + void set_backlight(const Color &p_backlight); + Color get_backlight() const; void set_refraction(float p_refraction); float get_refraction() const; diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index 5068bb548f..41146036f6 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -120,18 +120,23 @@ Error ResourceLoaderText::_parse_sub_resource(VariantParser::Stream *p_stream, R int index = token.value; - String path = local_path + "::" + itos(index); + if (use_nocache) { + r_res = int_resources[index]; + } else { - if (!ignore_resource_parsing) { + String path = local_path + "::" + itos(index); - if (!ResourceCache::has(path)) { - r_err_str = "Can't load cached sub-resource: " + path; - return ERR_PARSE_ERROR; - } + if (!ignore_resource_parsing) { - r_res = RES(ResourceCache::get(path)); - } else { - r_res = RES(); + if (!ResourceCache::has(path)) { + r_err_str = "Can't load cached sub-resource: " + path; + return ERR_PARSE_ERROR; + } + + r_res = RES(ResourceCache::get(path)); + } else { + r_res = RES(); + } } VariantParser::get_token(p_stream, token, line, r_err_str); @@ -535,7 +540,7 @@ Error ResourceLoaderText::load() { Ref<Resource> res; - if (!ResourceCache::has(path)) { //only if it doesn't exist + if (use_nocache || !ResourceCache::has(path)) { //only if it doesn't exist Object *obj = ClassDB::instance(type); if (!obj) { @@ -556,8 +561,10 @@ Error ResourceLoaderText::load() { } res = Ref<Resource>(r); - resource_cache.push_back(res); - res->set_path(path); + int_resources[id] = res; + if (!use_nocache) { + res->set_path(path); + } } resource_current++; @@ -643,10 +650,12 @@ Error ResourceLoaderText::load() { _printerr(); } else { error = OK; - if (!ResourceCache::has(res_path)) { - resource->set_path(res_path); + if (!use_nocache) { + if (!ResourceCache::has(res_path)) { + resource->set_path(res_path); + } + resource->set_as_translation_remapped(translation_remapped); } - resource->set_as_translation_remapped(translation_remapped); } return error; } @@ -691,7 +700,7 @@ Error ResourceLoaderText::load() { error = OK; //get it here resource = packed_scene; - if (!ResourceCache::has(res_path)) { + if (!use_nocache && !ResourceCache::has(res_path)) { packed_scene->set_path(res_path); } @@ -725,6 +734,9 @@ void ResourceLoaderText::set_translation_remapped(bool p_remapped) { } ResourceLoaderText::ResourceLoaderText() { + + use_nocache = false; + resources_total = 0; resource_current = 0; use_sub_threads = false; @@ -1285,7 +1297,7 @@ String ResourceLoaderText::recognize(FileAccess *p_f) { ///////////////////// -RES ResourceFormatLoaderText::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderText::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) *r_error = ERR_CANT_OPEN; @@ -1298,6 +1310,7 @@ RES ResourceFormatLoaderText::load(const String &p_path, const String &p_origina ResourceLoaderText loader; String path = p_original_path != "" ? p_original_path : p_path; + loader.use_nocache = p_no_cache; loader.use_sub_threads = p_use_sub_threads; loader.local_path = ProjectSettings::get_singleton()->localize_path(path); loader.progress = r_progress; diff --git a/scene/resources/resource_format_text.h b/scene/resources/resource_format_text.h index fbbd2e3346..b9a6db5f36 100644 --- a/scene/resources/resource_format_text.h +++ b/scene/resources/resource_format_text.h @@ -62,6 +62,7 @@ class ResourceLoaderText { //Map<String,String> remaps; Map<int, ExtResource> ext_resources; + Map<int, RES> int_resources; int resources_total; int resource_current; @@ -69,6 +70,8 @@ class ResourceLoaderText { VariantParser::Tag next_tag; + bool use_nocache; + bool use_sub_threads; float *progress; @@ -106,7 +109,6 @@ class ResourceLoaderText { friend class ResourceFormatLoaderText; - List<RES> resource_cache; Error error; RES resource; @@ -134,7 +136,7 @@ public: class ResourceFormatLoaderText : public ResourceFormatLoader { public: static ResourceFormatLoaderText *singleton; - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index a62e7ded16..1ac2f7c3c9 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -176,7 +176,7 @@ Shader::~Shader() { } //////////// -RES ResourceFormatLoaderShader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderShader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) *r_error = ERR_FILE_CANT_OPEN; diff --git a/scene/resources/shader.h b/scene/resources/shader.h index cf0cec362c..75c38bd561 100644 --- a/scene/resources/shader.h +++ b/scene/resources/shader.h @@ -102,7 +102,7 @@ VARIANT_ENUM_CAST(Shader::Mode); class ResourceFormatLoaderShader : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/scene/resources/sky_material.cpp b/scene/resources/sky_material.cpp index 37b88cccea..a0b6ab1e30 100644 --- a/scene/resources/sky_material.cpp +++ b/scene/resources/sky_material.cpp @@ -111,16 +111,6 @@ float ProceduralSkyMaterial::get_ground_energy() const { return ground_energy; } -void ProceduralSkyMaterial::set_sun_angle_min(float p_angle) { - - sun_angle_min = p_angle; - RS::get_singleton()->material_set_param(_get_material(), "sun_angle_min", Math::deg2rad(sun_angle_min)); -} -float ProceduralSkyMaterial::get_sun_angle_min() const { - - return sun_angle_min; -} - void ProceduralSkyMaterial::set_sun_angle_max(float p_angle) { sun_angle_max = p_angle; @@ -181,9 +171,6 @@ void ProceduralSkyMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_ground_energy", "energy"), &ProceduralSkyMaterial::set_ground_energy); ClassDB::bind_method(D_METHOD("get_ground_energy"), &ProceduralSkyMaterial::get_ground_energy); - ClassDB::bind_method(D_METHOD("set_sun_angle_min", "degrees"), &ProceduralSkyMaterial::set_sun_angle_min); - ClassDB::bind_method(D_METHOD("get_sun_angle_min"), &ProceduralSkyMaterial::get_sun_angle_min); - ClassDB::bind_method(D_METHOD("set_sun_angle_max", "degrees"), &ProceduralSkyMaterial::set_sun_angle_max); ClassDB::bind_method(D_METHOD("get_sun_angle_max"), &ProceduralSkyMaterial::get_sun_angle_max); @@ -203,7 +190,6 @@ void ProceduralSkyMaterial::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ground_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_ground_energy", "get_ground_energy"); ADD_GROUP("Sun", "sun_"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_angle_min", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_min", "get_sun_angle_min"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_angle_max", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_max", "get_sun_angle_max"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_curve", PROPERTY_HINT_EXP_EASING), "set_sun_curve", "get_sun_curve"); } @@ -220,8 +206,7 @@ ProceduralSkyMaterial::ProceduralSkyMaterial() { code += "uniform vec4 ground_horizon_color : hint_color = vec4(0.37, 0.33, 0.31, 1.0);\n"; code += "uniform float ground_curve : hint_range(0, 1) = 0.02;\n"; code += "uniform float ground_energy = 1.0;\n\n"; - code += "uniform float sun_angle_min = 0.01;\n"; - code += "uniform float sun_angle_max = 1.0;\n"; + code += "uniform float sun_angle_max = 1.74;\n"; code += "uniform float sun_curve : hint_range(0, 1) = 0.05;\n\n"; code += "const float PI = 3.1415926535897932384626433833;\n\n"; code += "void fragment() {\n"; @@ -231,37 +216,37 @@ ProceduralSkyMaterial::ProceduralSkyMaterial() { code += "\tsky *= sky_energy;\n"; code += "\tif (LIGHT0_ENABLED) {\n"; code += "\t\tfloat sun_angle = acos(dot(LIGHT0_DIRECTION, EYEDIR));\n"; - code += "\t\tif (sun_angle < sun_angle_min) {\n"; + code += "\t\tif (sun_angle < LIGHT0_SIZE) {\n"; code += "\t\t\tsky = LIGHT0_COLOR * LIGHT0_ENERGY;\n"; code += "\t\t} else if (sun_angle < sun_angle_max) {\n"; - code += "\t\t\tfloat c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min);\n"; + code += "\t\t\tfloat c2 = (sun_angle - LIGHT0_SIZE) / (sun_angle_max - LIGHT0_SIZE);\n"; code += "\t\t\tsky = mix(LIGHT0_COLOR * LIGHT0_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n"; code += "\t\t}\n"; code += "\t}\n"; code += "\tif (LIGHT1_ENABLED) {\n"; code += "\t\tfloat sun_angle = acos(dot(LIGHT1_DIRECTION, EYEDIR));\n"; - code += "\t\tif (sun_angle < sun_angle_min) {\n"; + code += "\t\tif (sun_angle < LIGHT1_SIZE) {\n"; code += "\t\t\tsky = LIGHT1_COLOR * LIGHT1_ENERGY;\n"; code += "\t\t} else if (sun_angle < sun_angle_max) {\n"; - code += "\t\t\tfloat c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min);\n"; + code += "\t\t\tfloat c2 = (sun_angle - LIGHT1_SIZE) / (sun_angle_max - LIGHT1_SIZE);\n"; code += "\t\t\tsky = mix(LIGHT1_COLOR * LIGHT1_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n"; code += "\t\t}\n"; code += "\t}\n"; code += "\tif (LIGHT2_ENABLED) {\n"; code += "\t\tfloat sun_angle = acos(dot(LIGHT2_DIRECTION, EYEDIR));\n"; - code += "\t\tif (sun_angle < sun_angle_min) {\n"; + code += "\t\tif (sun_angle < LIGHT2_SIZE) {\n"; code += "\t\t\tsky = LIGHT2_COLOR * LIGHT2_ENERGY;\n"; code += "\t\t} else if (sun_angle < sun_angle_max) {\n"; - code += "\t\t\tfloat c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min);\n"; + code += "\t\t\tfloat c2 = (sun_angle - LIGHT2_SIZE) / (sun_angle_max - LIGHT2_SIZE);\n"; code += "\t\t\tsky = mix(LIGHT2_COLOR * LIGHT2_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n"; code += "\t\t}\n"; code += "\t}\n"; code += "\tif (LIGHT3_ENABLED) {\n"; code += "\t\tfloat sun_angle = acos(dot(LIGHT3_DIRECTION, EYEDIR));\n"; - code += "\t\tif (sun_angle < sun_angle_min) {\n"; + code += "\t\tif (sun_angle < LIGHT3_SIZE) {\n"; code += "\t\t\tsky = LIGHT3_COLOR * LIGHT3_ENERGY;\n"; code += "\t\t} else if (sun_angle < sun_angle_max) {\n"; - code += "\t\t\tfloat c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min);\n"; + code += "\t\t\tfloat c2 = (sun_angle - LIGHT3_SIZE) / (sun_angle_max - LIGHT3_SIZE);\n"; code += "\t\t\tsky = mix(LIGHT3_COLOR * LIGHT3_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n"; code += "\t\t}\n"; code += "\t}\n"; @@ -287,7 +272,6 @@ ProceduralSkyMaterial::ProceduralSkyMaterial() { set_ground_curve(0.02); set_ground_energy(1.0); - set_sun_angle_min(1.0); set_sun_angle_max(100.0); set_sun_curve(0.05); } @@ -535,7 +519,6 @@ PhysicalSkyMaterial::PhysicalSkyMaterial() { code += "const vec3 UP = vec3( 0.0, 1.0, 0.0 );\n\n"; code += "// Sun constants\n"; - code += "const float SOL_SIZE = 0.00872663806;\n"; code += "const float SUN_ENERGY = 1000.0;\n\n"; code += "// optical length at zenith for molecules\n"; @@ -591,8 +574,8 @@ PhysicalSkyMaterial::PhysicalSkyMaterial() { code += "\tLin *= mix(ground_color.rgb, vec3(1.0), smoothstep(-0.1, 0.1, dot(UP, EYEDIR)));\n\n"; code += "\t// Solar disk and out-scattering\n"; - code += "\tfloat sunAngularDiameterCos = cos(SOL_SIZE * sun_disk_scale);\n"; - code += "\tfloat sunAngularDiameterCos2 = cos(SOL_SIZE * sun_disk_scale*0.5);\n"; + code += "\tfloat sunAngularDiameterCos = cos(LIGHT0_SIZE * sun_disk_scale);\n"; + code += "\tfloat sunAngularDiameterCos2 = cos(LIGHT0_SIZE * sun_disk_scale*0.5);\n"; code += "\tfloat sundisk = smoothstep(sunAngularDiameterCos, sunAngularDiameterCos2, cos_theta);\n"; code += "\tvec3 L0 = (sun_energy * 1900.0 * extinction) * sundisk * LIGHT0_COLOR;\n"; code += "\t// Note: Add nightime here: L0 += night_sky * extinction\n\n"; diff --git a/scene/resources/sky_material.h b/scene/resources/sky_material.h index 515706b0c5..9bd9d7ec8b 100644 --- a/scene/resources/sky_material.h +++ b/scene/resources/sky_material.h @@ -49,7 +49,6 @@ private: float ground_curve; float ground_energy; - float sun_angle_min; float sun_angle_max; float sun_curve; @@ -84,9 +83,6 @@ public: void set_ground_energy(float p_energy); float get_ground_energy() const; - void set_sun_angle_min(float p_angle); - float get_sun_angle_min() const; - void set_sun_angle_max(float p_angle); float get_sun_angle_max() const; diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 749dff24f2..f431a2ad48 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -796,7 +796,7 @@ StreamTexture::~StreamTexture() { } } -RES ResourceFormatLoaderStreamTexture::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderStreamTexture::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { Ref<StreamTexture> st; st.instance(); @@ -2024,7 +2024,7 @@ TextureLayered::~TextureLayered() { } } -RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { +RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { if (r_error) { *r_error = ERR_CANT_OPEN; diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 18f70baa07..f4f00c2ca0 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -213,7 +213,7 @@ public: class ResourceFormatLoaderStreamTexture : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; @@ -421,7 +421,7 @@ public: COMPRESSION_UNCOMPRESSED }; - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp index ad996e7d50..5e3f8b803b 100644 --- a/scene/scene_string_names.cpp +++ b/scene/scene_string_names.cpp @@ -202,4 +202,7 @@ SceneStringNames::SceneStringNames() { parameters_base_path = "parameters/"; tracks_changed = "tracks_changed"; + + shader_overrides_group = StaticCString::create("_shader_overrides_group_"); + shader_overrides_group_active = StaticCString::create("_shader_overrides_group_active_"); } diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h index 58e8c28454..c5de10a6f6 100644 --- a/scene/scene_string_names.h +++ b/scene/scene_string_names.h @@ -207,6 +207,8 @@ public: StringName window_input; StringName theme_changed; + StringName shader_overrides_group; + StringName shader_overrides_group_active; enum { MAX_MATERIALS = 32 diff --git a/servers/SCsub b/servers/SCsub index 7080a110da..121990f2e1 100644 --- a/servers/SCsub +++ b/servers/SCsub @@ -5,7 +5,7 @@ Import("env") env.servers_sources = [] env.add_source_files(env.servers_sources, "*.cpp") -SConscript("arvr/SCsub") +SConscript("xr/SCsub") SConscript("camera/SCsub") SConscript("physics_3d/SCsub") SConscript("physics_2d/SCsub") diff --git a/servers/display_server.h b/servers/display_server.h index 1956bcafca..93db7ef844 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -180,7 +180,7 @@ public: }; virtual void screen_set_orientation(ScreenOrientation p_orientation, int p_screen = SCREEN_OF_MAIN_WINDOW); - ScreenOrientation screen_get_orientation(int p_screen = SCREEN_OF_MAIN_WINDOW) const; + virtual ScreenOrientation screen_get_orientation(int p_screen = SCREEN_OF_MAIN_WINDOW) const; virtual void screen_set_keep_on(bool p_enable); //disable screensaver virtual bool screen_is_kept_on() const; diff --git a/servers/physics_2d/shape_2d_sw.h b/servers/physics_2d/shape_2d_sw.h index 48f3bea1e1..ca001e6dd9 100644 --- a/servers/physics_2d/shape_2d_sw.h +++ b/servers/physics_2d/shape_2d_sw.h @@ -465,7 +465,11 @@ public: virtual Variant get_data() const; _FORCE_INLINE_ void project_range(const Vector2 &p_normal, const Transform2D &p_transform, real_t &r_min, real_t &r_max) const { - // no matter the angle, the box is mirrored anyway + + if (!points || point_count <= 0) { + r_min = r_max = 0; + return; + } r_min = r_max = p_normal.dot(p_transform.xform(points[0].pos)); for (int i = 1; i < point_count; i++) { diff --git a/servers/physics_3d/body_3d_sw.h b/servers/physics_3d/body_3d_sw.h index b553cf0670..2bd335e6c0 100644 --- a/servers/physics_3d/body_3d_sw.h +++ b/servers/physics_3d/body_3d_sw.h @@ -257,7 +257,7 @@ public: _FORCE_INLINE_ void add_force(const Vector3 &p_force, const Vector3 &p_pos) { applied_force += p_force; - applied_torque += p_pos.cross(p_force); + applied_torque += (p_pos - center_of_mass).cross(p_force); } _FORCE_INLINE_ void add_torque(const Vector3 &p_torque) { @@ -421,7 +421,7 @@ public: virtual void apply_impulse(const Vector3 &p_pos, const Vector3 &p_j) { body->apply_impulse(p_pos, p_j); } virtual void apply_torque_impulse(const Vector3 &p_j) { body->apply_torque_impulse(p_j); } - virtual void set_sleep_state(bool p_enable) { body->set_active(!p_enable); } + virtual void set_sleep_state(bool p_sleep) { body->set_active(!p_sleep); } virtual bool is_sleeping() const { return !body->is_active(); } virtual int get_contact_count() const { return body->contact_count; } diff --git a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp index 1f433ec6a5..e15aeca842 100644 --- a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp +++ b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp @@ -497,28 +497,28 @@ void Generic6DOFJoint3DSW::set_param(Vector3::Axis p_axis, PhysicsServer3D::G6DO } break; case PhysicsServer3D::G6DOF_JOINT_LINEAR_MOTOR_TARGET_VELOCITY: { - // Not implemented in GodotPhysics backend + // Not implemented in GodotPhysics3D backend } break; case PhysicsServer3D::G6DOF_JOINT_LINEAR_MOTOR_FORCE_LIMIT: { - // Not implemented in GodotPhysics backend + // Not implemented in GodotPhysics3D backend } break; case PhysicsServer3D::G6DOF_JOINT_LINEAR_SPRING_STIFFNESS: { - // Not implemented in GodotPhysics backend + // Not implemented in GodotPhysics3D backend } break; case PhysicsServer3D::G6DOF_JOINT_LINEAR_SPRING_DAMPING: { - // Not implemented in GodotPhysics backend + // Not implemented in GodotPhysics3D backend } break; case PhysicsServer3D::G6DOF_JOINT_LINEAR_SPRING_EQUILIBRIUM_POINT: { - // Not implemented in GodotPhysics backend + // Not implemented in GodotPhysics3D backend } break; case PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_STIFFNESS: { - // Not implemented in GodotPhysics backend + // Not implemented in GodotPhysics3D backend } break; case PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_DAMPING: { - // Not implemented in GodotPhysics backend + // Not implemented in GodotPhysics3D backend } break; case PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT: { - // Not implemented in GodotPhysics backend + // Not implemented in GodotPhysics3D backend } break; case PhysicsServer3D::G6DOF_JOINT_MAX: break; // Can't happen, but silences warning } @@ -597,28 +597,28 @@ real_t Generic6DOFJoint3DSW::get_param(Vector3::Axis p_axis, PhysicsServer3D::G6 } break; case PhysicsServer3D::G6DOF_JOINT_LINEAR_MOTOR_TARGET_VELOCITY: { - // Not implemented in GodotPhysics backend + // Not implemented in GodotPhysics3D backend } break; case PhysicsServer3D::G6DOF_JOINT_LINEAR_MOTOR_FORCE_LIMIT: { - // Not implemented in GodotPhysics backend + // Not implemented in GodotPhysics3D backend } break; case PhysicsServer3D::G6DOF_JOINT_LINEAR_SPRING_STIFFNESS: { - // Not implemented in GodotPhysics backend + // Not implemented in GodotPhysics3D backend } break; case PhysicsServer3D::G6DOF_JOINT_LINEAR_SPRING_DAMPING: { - // Not implemented in GodotPhysics backend + // Not implemented in GodotPhysics3D backend } break; case PhysicsServer3D::G6DOF_JOINT_LINEAR_SPRING_EQUILIBRIUM_POINT: { - // Not implemented in GodotPhysics backend + // Not implemented in GodotPhysics3D backend } break; case PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_STIFFNESS: { - // Not implemented in GodotPhysics backend + // Not implemented in GodotPhysics3D backend } break; case PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_DAMPING: { - // Not implemented in GodotPhysics backend + // Not implemented in GodotPhysics3D backend } break; case PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT: { - // Not implemented in GodotPhysics backend + // Not implemented in GodotPhysics3D backend } break; case PhysicsServer3D::G6DOF_JOINT_MAX: break; // Can't happen, but silences warning } @@ -643,13 +643,13 @@ void Generic6DOFJoint3DSW::set_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOF m_angularLimits[p_axis].m_enableMotor = p_value; } break; case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_MOTOR: { - // Not implemented in GodotPhysics backend + // Not implemented in GodotPhysics3D backend } break; case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_SPRING: { - // Not implemented in GodotPhysics backend + // Not implemented in GodotPhysics3D backend } break; case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_SPRING: { - // Not implemented in GodotPhysics backend + // Not implemented in GodotPhysics3D backend } break; case PhysicsServer3D::G6DOF_JOINT_FLAG_MAX: break; // Can't happen, but silences warning } @@ -671,13 +671,13 @@ bool Generic6DOFJoint3DSW::get_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOF return m_angularLimits[p_axis].m_enableMotor; } break; case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_MOTOR: { - // Not implemented in GodotPhysics backend + // Not implemented in GodotPhysics3D backend } break; case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_SPRING: { - // Not implemented in GodotPhysics backend + // Not implemented in GodotPhysics3D backend } break; case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_SPRING: { - // Not implemented in GodotPhysics backend + // Not implemented in GodotPhysics3D backend } break; case PhysicsServer3D::G6DOF_JOINT_FLAG_MAX: break; // Can't happen, but silences warning } diff --git a/servers/physics_3d/physics_server_3d_sw.cpp b/servers/physics_3d/physics_server_3d_sw.cpp index bc42c2fd9e..b454dc54af 100644 --- a/servers/physics_3d/physics_server_3d_sw.cpp +++ b/servers/physics_3d/physics_server_3d_sw.cpp @@ -70,7 +70,7 @@ RID PhysicsServer3DSW::shape_create(ShapeType p_shape) { } break; case SHAPE_CYLINDER: { - ERR_FAIL_V_MSG(RID(), "CylinderShape3D is not supported in GodotPhysics. Please switch to Bullet in the Project Settings."); + ERR_FAIL_V_MSG(RID(), "CylinderShape3D is not supported in GodotPhysics3D. Please switch to Bullet in the Project Settings."); } break; case SHAPE_CONVEX_POLYGON: { @@ -1499,7 +1499,7 @@ void PhysicsServer3DSW::flush_queries() { values.push_back(USEC_TO_SEC(OS::get_singleton()->get_ticks_usec() - time_beg)); values.push_front("physics"); - EngineDebugger::profiler_add_frame_data("server", values); + EngineDebugger::profiler_add_frame_data("servers", values); } #endif }; diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h index a2f08b3ed8..8ea8b22455 100644 --- a/servers/physics_server_3d.h +++ b/servers/physics_server_3d.h @@ -70,7 +70,7 @@ public: virtual void apply_impulse(const Vector3 &p_pos, const Vector3 &p_j) = 0; virtual void apply_torque_impulse(const Vector3 &p_j) = 0; - virtual void set_sleep_state(bool p_enable) = 0; + virtual void set_sleep_state(bool p_sleep) = 0; virtual bool is_sleeping() const = 0; virtual int get_contact_count() const = 0; diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index 64b48bea50..60217002fb 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -33,9 +33,6 @@ #include "core/engine.h" #include "core/project_settings.h" -#include "arvr/arvr_interface.h" -#include "arvr/arvr_positional_tracker.h" -#include "arvr_server.h" #include "audio/audio_effect.h" #include "audio/audio_stream.h" #include "audio/effects/audio_effect_amplify.h" @@ -65,8 +62,15 @@ #include "physics_3d/physics_server_3d_sw.h" #include "physics_server_2d.h" #include "physics_server_3d.h" +#include "rendering/rasterizer.h" +#include "rendering/rendering_device.h" +#include "rendering/rendering_device_binds.h" + #include "rendering_server.h" #include "servers/rendering/shader_types.h" +#include "xr/xr_interface.h" +#include "xr/xr_positional_tracker.h" +#include "xr_server.h" ShaderTypes *shader_types = nullptr; @@ -100,13 +104,17 @@ void register_server_types() { ClassDB::register_virtual_class<DisplayServer>(); ClassDB::register_virtual_class<RenderingServer>(); ClassDB::register_class<AudioServer>(); - ClassDB::register_virtual_class<PhysicsServer3D>(); ClassDB::register_virtual_class<PhysicsServer2D>(); - ClassDB::register_class<ARVRServer>(); + ClassDB::register_virtual_class<PhysicsServer3D>(); + ClassDB::register_virtual_class<NavigationServer2D>(); + ClassDB::register_virtual_class<NavigationServer3D>(); + ClassDB::register_class<XRServer>(); ClassDB::register_class<CameraServer>(); - ClassDB::register_virtual_class<ARVRInterface>(); - ClassDB::register_class<ARVRPositionalTracker>(); + ClassDB::register_virtual_class<RenderingDevice>(); + + ClassDB::register_virtual_class<XRInterface>(); + ClassDB::register_class<XRPositionalTracker>(); ClassDB::register_virtual_class<AudioStream>(); ClassDB::register_virtual_class<AudioStreamPlayback>(); @@ -157,6 +165,22 @@ void register_server_types() { ClassDB::register_virtual_class<AudioEffectSpectrumAnalyzerInstance>(); } + ClassDB::register_virtual_class<RenderingDevice>(); + ClassDB::register_class<RDTextureFormat>(); + ClassDB::register_class<RDTextureView>(); + ClassDB::register_class<RDAttachmentFormat>(); + ClassDB::register_class<RDSamplerState>(); + ClassDB::register_class<RDVertexAttribute>(); + ClassDB::register_class<RDUniform>(); + ClassDB::register_class<RDPipelineRasterizationState>(); + ClassDB::register_class<RDPipelineMultisampleState>(); + ClassDB::register_class<RDPipelineDepthStencilState>(); + ClassDB::register_class<RDPipelineColorBlendStateAttachment>(); + ClassDB::register_class<RDPipelineColorBlendState>(); + ClassDB::register_class<RDShaderSource>(); + ClassDB::register_class<RDShaderBytecode>(); + ClassDB::register_class<RDShaderFile>(); + ClassDB::register_class<CameraFeed>(); ClassDB::register_virtual_class<PhysicsDirectBodyState2D>(); @@ -174,15 +198,15 @@ void register_server_types() { GLOBAL_DEF(PhysicsServer2DManager::setting_property_name, "DEFAULT"); ProjectSettings::get_singleton()->set_custom_property_info(PhysicsServer2DManager::setting_property_name, PropertyInfo(Variant::STRING, PhysicsServer2DManager::setting_property_name, PROPERTY_HINT_ENUM, "DEFAULT")); - PhysicsServer2DManager::register_server("GodotPhysics", &_createGodotPhysics2DCallback); - PhysicsServer2DManager::set_default_server("GodotPhysics"); + PhysicsServer2DManager::register_server("GodotPhysics2D", &_createGodotPhysics2DCallback); + PhysicsServer2DManager::set_default_server("GodotPhysics2D"); // Physics 3D GLOBAL_DEF(PhysicsServer3DManager::setting_property_name, "DEFAULT"); ProjectSettings::get_singleton()->set_custom_property_info(PhysicsServer3DManager::setting_property_name, PropertyInfo(Variant::STRING, PhysicsServer3DManager::setting_property_name, PROPERTY_HINT_ENUM, "DEFAULT")); - PhysicsServer3DManager::register_server("GodotPhysics", &_createGodotPhysics3DCallback); - PhysicsServer3DManager::set_default_server("GodotPhysics"); + PhysicsServer3DManager::register_server("GodotPhysics3D", &_createGodotPhysics3DCallback); + PhysicsServer3DManager::set_default_server("GodotPhysics3D"); } void unregister_server_types() { @@ -192,12 +216,13 @@ void unregister_server_types() { void register_server_singletons() { + Engine::get_singleton()->add_singleton(Engine::Singleton("DisplayServer", DisplayServer::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("RenderingServer", RenderingServer::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("AudioServer", AudioServer::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("PhysicsServer2D", PhysicsServer2D::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("PhysicsServer3D", PhysicsServer3D::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("NavigationServer2D", NavigationServer2D::get_singleton_mut())); Engine::get_singleton()->add_singleton(Engine::Singleton("NavigationServer3D", NavigationServer3D::get_singleton_mut())); - Engine::get_singleton()->add_singleton(Engine::Singleton("ARVRServer", ARVRServer::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("XRServer", XRServer::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("CameraServer", CameraServer::get_singleton())); } diff --git a/servers/rendering/rasterizer.h b/servers/rendering/rasterizer.h index d77963b3dd..955241e79c 100644 --- a/servers/rendering/rasterizer.h +++ b/servers/rendering/rasterizer.h @@ -106,6 +106,9 @@ public: virtual void camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) = 0; virtual void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) = 0; + virtual void shadows_quality_set(RS::ShadowQuality p_quality) = 0; + virtual void directional_shadow_quality_set(RS::ShadowQuality p_quality) = 0; + struct InstanceBase; struct InstanceDependency { @@ -164,6 +167,17 @@ public: AABB aabb; AABB transformed_aabb; + struct InstanceShaderParameter { + int32_t index = -1; + Variant value; + Variant default_value; + PropertyInfo info; + }; + + Map<StringName, InstanceShaderParameter> instance_shader_parameters; + bool instance_allocated_shader_parameters = false; + int32_t instance_allocated_shader_parameters_offset = -1; + virtual void dependency_deleted(RID p_dependency) = 0; virtual void dependency_changed(bool p_aabb, bool p_dependencies) = 0; @@ -229,7 +243,7 @@ public: virtual RID light_instance_create(RID p_light) = 0; virtual void light_instance_set_transform(RID p_light_instance, const Transform &p_transform) = 0; - virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale = 1.0) = 0; + virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) = 0; virtual void light_instance_mark_visible(RID p_light_instance) = 0; virtual bool light_instances_can_render_shadow_cube() const { return true; @@ -246,12 +260,15 @@ public: virtual bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) = 0; virtual bool reflection_probe_instance_postprocess_step(RID p_instance) = 0; + virtual RID decal_instance_create(RID p_decal) = 0; + virtual void decal_instance_set_transform(RID p_decal, const Transform &p_transform) = 0; + virtual RID gi_probe_instance_create(RID p_gi_probe) = 0; virtual void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) = 0; virtual bool gi_probe_needs_update(RID p_probe) const = 0; virtual void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, int p_dynamic_object_count, InstanceBase **p_dynamic_objects) = 0; - virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) = 0; + virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) = 0; virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) = 0; virtual void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) = 0; @@ -261,7 +278,7 @@ public: virtual void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) = 0; virtual RID render_buffers_create() = 0; - virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa) = 0; + virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa) = 0; virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_curve) = 0; virtual bool screen_space_roughness_limiter_is_active() const = 0; @@ -321,6 +338,9 @@ public: virtual Size2 texture_size_with_proxy(RID p_proxy) = 0; + virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0; + virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0; + /* SHADER API */ virtual RID shader_create() = 0; @@ -348,6 +368,14 @@ public: virtual bool material_is_animated(RID p_material) = 0; virtual bool material_casts_shadows(RID p_material) = 0; + struct InstanceShaderParam { + PropertyInfo info; + int index; + Variant default_value; + }; + + virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) = 0; + virtual void material_update_dependency(RID p_material, RasterizerScene::InstanceBase *p_instance) = 0; /* MESH API */ @@ -501,6 +529,21 @@ public: virtual void base_update_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance) = 0; virtual void skeleton_update_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance) = 0; + /* DECAL API */ + + virtual RID decal_create() = 0; + virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) = 0; + virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) = 0; + virtual void decal_set_emission_energy(RID p_decal, float p_energy) = 0; + virtual void decal_set_albedo_mix(RID p_decal, float p_mix) = 0; + virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) = 0; + virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) = 0; + virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) = 0; + virtual void decal_set_fade(RID p_decal, float p_above, float p_below) = 0; + virtual void decal_set_normal_fade(RID p_decal, float p_fade) = 0; + + virtual AABB decal_get_aabb(RID p_decal) const = 0; + /* GI PROBE API */ virtual RID gi_probe_create() = 0; @@ -611,6 +654,24 @@ public: virtual int particles_get_draw_passes(RID p_particles) const = 0; virtual RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const = 0; + /* GLOBAL VARIABLES */ + + virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) = 0; + virtual void global_variable_remove(const StringName &p_name) = 0; + virtual Vector<StringName> global_variable_get_list() const = 0; + + virtual void global_variable_set(const StringName &p_name, const Variant &p_value) = 0; + virtual void global_variable_set_override(const StringName &p_name, const Variant &p_value) = 0; + virtual Variant global_variable_get(const StringName &p_name) const = 0; + virtual RS::GlobalVariableType global_variable_get_type(const StringName &p_name) const = 0; + + virtual void global_variables_load_settings(bool p_load_textures = true) = 0; + virtual void global_variables_clear() = 0; + + virtual int32_t global_variables_instance_allocate(RID p_instance) = 0; + virtual void global_variables_instance_free(RID p_instance) = 0; + virtual void global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) = 0; + /* RENDER TARGET */ enum RenderTargetFlags { diff --git a/servers/rendering/rasterizer_rd/light_cluster_builder.cpp b/servers/rendering/rasterizer_rd/light_cluster_builder.cpp index 943ef1c7fa..f75308a975 100644 --- a/servers/rendering/rasterizer_rd/light_cluster_builder.cpp +++ b/servers/rendering/rasterizer_rd/light_cluster_builder.cpp @@ -39,6 +39,7 @@ void LightClusterBuilder::begin(const Transform &p_view_transform, const CameraM //reset counts light_count = 0; refprobe_count = 0; + decal_count = 0; item_count = 0; sort_id_count = 0; } diff --git a/servers/rendering/rasterizer_rd/light_cluster_builder.h b/servers/rendering/rasterizer_rd/light_cluster_builder.h index 3411ed07a0..78288dc620 100644 --- a/servers/rendering/rasterizer_rd/light_cluster_builder.h +++ b/servers/rendering/rasterizer_rd/light_cluster_builder.h @@ -170,17 +170,15 @@ public: _add_item(aabb, ITEM_TYPE_OMNI_LIGHT, light_count); } break; case LIGHT_TYPE_SPOT: { - Vector3 v(0, 0, -1); - v.rotated(Vector3(0, 1, 0), Math::deg2rad(ld.spot_aperture)); //rotate in x-z - v.normalize(); - v *= ld.radius; - v.y = v.x; + + float r = ld.radius; + real_t len = Math::tan(Math::deg2rad(ld.spot_aperture)) * r; aabb.position = xform.origin; - aabb.expand_to(xform.xform(v)); - aabb.expand_to(xform.xform(Vector3(-v.x, v.y, v.z))); - aabb.expand_to(xform.xform(Vector3(-v.x, -v.y, v.z))); - aabb.expand_to(xform.xform(Vector3(v.x, -v.y, v.z))); + aabb.expand_to(xform.xform(Vector3(len, len, -r))); + aabb.expand_to(xform.xform(Vector3(-len, len, -r))); + aabb.expand_to(xform.xform(Vector3(-len, -len, -r))); + aabb.expand_to(xform.xform(Vector3(len, -len, -r))); _add_item(aabb, ITEM_TYPE_SPOT_LIGHT, light_count); } break; } @@ -195,23 +193,25 @@ public: refprobes = (OrientedBoxData *)memrealloc(refprobes, sizeof(OrientedBoxData) * refprobe_max); } + Transform xform = view_xform * p_transform; + OrientedBoxData &rp = refprobes[refprobe_count]; - Vector3 origin = p_transform.origin; + Vector3 origin = xform.origin; rp.position[0] = origin.x; rp.position[1] = origin.y; rp.position[2] = origin.z; - Vector3 x_axis = p_transform.basis.get_axis(0) * p_half_extents.x; + Vector3 x_axis = xform.basis.get_axis(0) * p_half_extents.x; rp.x_axis[0] = x_axis.x; rp.x_axis[1] = x_axis.y; rp.x_axis[2] = x_axis.z; - Vector3 y_axis = p_transform.basis.get_axis(1) * p_half_extents.y; + Vector3 y_axis = xform.basis.get_axis(1) * p_half_extents.y; rp.y_axis[0] = y_axis.x; rp.y_axis[1] = y_axis.y; rp.y_axis[2] = y_axis.z; - Vector3 z_axis = p_transform.basis.get_axis(2) * p_half_extents.z; + Vector3 z_axis = xform.basis.get_axis(2) * p_half_extents.z; rp.z_axis[0] = z_axis.x; rp.z_axis[1] = z_axis.y; rp.z_axis[2] = z_axis.z; @@ -232,35 +232,37 @@ public: refprobe_count++; } - _FORCE_INLINE_ void add_decal(const Transform &p_transform, const Vector2 &p_half_extents, float p_depth) { + _FORCE_INLINE_ void add_decal(const Transform &p_transform, const Vector3 &p_half_extents) { if (unlikely(decal_count == decal_max)) { decal_max = nearest_power_of_2_templated(decal_max + 1); decals = (OrientedBoxData *)memrealloc(decals, sizeof(OrientedBoxData) * decal_max); } - OrientedBoxData &dc = decals[decal_count]; + Transform xform = view_xform * p_transform; - Vector3 z_axis = -p_transform.basis.get_axis(2) * p_depth * 0.5; - dc.z_axis[0] = z_axis.x; - dc.z_axis[1] = z_axis.y; - dc.z_axis[2] = z_axis.z; + OrientedBoxData &dc = decals[decal_count]; - Vector3 origin = p_transform.origin - z_axis; + Vector3 origin = xform.origin; dc.position[0] = origin.x; dc.position[1] = origin.y; dc.position[2] = origin.z; - Vector3 x_axis = p_transform.basis.get_axis(0) * p_half_extents.x; + Vector3 x_axis = xform.basis.get_axis(0) * p_half_extents.x; dc.x_axis[0] = x_axis.x; dc.x_axis[1] = x_axis.y; dc.x_axis[2] = x_axis.z; - Vector3 y_axis = p_transform.basis.get_axis(1) * p_half_extents.y; + Vector3 y_axis = xform.basis.get_axis(1) * p_half_extents.y; dc.y_axis[0] = y_axis.x; dc.y_axis[1] = y_axis.y; dc.y_axis[2] = y_axis.z; + Vector3 z_axis = xform.basis.get_axis(2) * p_half_extents.z; + dc.z_axis[0] = z_axis.x; + dc.z_axis[1] = z_axis.y; + dc.z_axis[2] = z_axis.z; + AABB aabb; aabb.position = origin + x_axis + y_axis + z_axis; diff --git a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp index ba4f4c4acb..956bf54d01 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp @@ -273,7 +273,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int Vector<uint8_t> polygon_buffer; polygon_buffer.resize(buffer_size * sizeof(float)); - Vector<RD::VertexDescription> descriptions; + Vector<RD::VertexAttribute> descriptions; descriptions.resize(4); Vector<RID> buffers; buffers.resize(4); @@ -284,7 +284,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int uint32_t *uptr = (uint32_t *)r; uint32_t base_offset = 0; { //vertices - RD::VertexDescription vd; + RD::VertexAttribute vd; vd.format = RD::DATA_FORMAT_R32G32_SFLOAT; vd.offset = base_offset * sizeof(float); vd.location = RS::ARRAY_VERTEX; @@ -304,7 +304,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int //colors if ((uint32_t)p_colors.size() == vertex_count || p_colors.size() == 1) { - RD::VertexDescription vd; + RD::VertexAttribute vd; vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; vd.offset = base_offset * sizeof(float); vd.location = RS::ARRAY_COLOR; @@ -332,7 +332,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int } base_offset += 4; } else { - RD::VertexDescription vd; + RD::VertexAttribute vd; vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; vd.offset = 0; vd.location = RS::ARRAY_COLOR; @@ -344,7 +344,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int //uvs if ((uint32_t)p_uvs.size() == vertex_count) { - RD::VertexDescription vd; + RD::VertexAttribute vd; vd.format = RD::DATA_FORMAT_R32G32_SFLOAT; vd.offset = base_offset * sizeof(float); vd.location = RS::ARRAY_TEX_UV; @@ -360,7 +360,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int } base_offset += 2; } else { - RD::VertexDescription vd; + RD::VertexAttribute vd; vd.format = RD::DATA_FORMAT_R32G32_SFLOAT; vd.offset = 0; vd.location = RS::ARRAY_TEX_UV; @@ -372,7 +372,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int //bones if ((uint32_t)p_indices.size() == vertex_count * 4 && (uint32_t)p_weights.size() == vertex_count * 4) { - RD::VertexDescription vd; + RD::VertexAttribute vd; vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT; vd.offset = base_offset * sizeof(float); vd.location = RS::ARRAY_BONES; @@ -401,7 +401,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int base_offset += 4; } else { - RD::VertexDescription vd; + RD::VertexAttribute vd; vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT; vd.offset = 0; vd.location = RS::ARRAY_BONES; @@ -618,6 +618,14 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ } } + { + RD::Uniform u; + u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.binding = 7; + u.ids.push_back(storage->global_variables_get_storage_buffer()); + uniforms.push_back(u); + } + //validate and update lighs if they are being used if (light_count > 0) { @@ -2012,6 +2020,9 @@ void RasterizerCanvasRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_ for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { + if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) { + continue; + } if (E->get().texture_order >= 0) { order[E->get().texture_order + 100000] = E->key(); } else { @@ -2027,6 +2038,23 @@ void RasterizerCanvasRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_ } } +void RasterizerCanvasRD::ShaderData::get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const { + + for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { + + if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { + continue; + } + + RasterizerStorage::InstanceShaderParam p; + p.info = ShaderLanguage::uniform_to_property_info(E->get()); + p.info.name = E->key(); //supply name + p.index = E->get().instance_index; + p.default_value = ShaderLanguage::constant_value_to_variant(E->get().default_value, E->get().type, E->get().hint); + p_param_list->push_back(p); + } +} + bool RasterizerCanvasRD::ShaderData::is_param_texture(const StringName &p_param) const { if (!uniforms.has(p_param)) { return false; @@ -2366,6 +2394,8 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) { actions.default_repeat = ShaderLanguage::REPEAT_DISABLE; actions.base_varying_index = 4; + actions.global_buffer_array_variable = "global_variables.data"; + shader.compiler.initialize(actions); } @@ -2393,8 +2423,8 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) { } //pipelines - Vector<RD::VertexDescription> vf; - RD::VertexDescription vd; + Vector<RD::VertexAttribute> vf; + RD::VertexAttribute vd; vd.format = RD::DATA_FORMAT_R32G32B32_SFLOAT; vd.location = 0; vd.offset = 0; diff --git a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h index 83b431eaf6..4d47b3e13b 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h @@ -185,6 +185,8 @@ class RasterizerCanvasRD : public RasterizerCanvas { virtual void set_code(const String &p_Code); virtual void set_default_texture_param(const StringName &p_name, RID p_texture); virtual void get_param_list(List<PropertyInfo> *p_param_list) const; + virtual void get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const; + virtual bool is_param_texture(const StringName &p_param) const; virtual bool is_animated() const; virtual bool casts_shadows() const; diff --git a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp index 2d881dbd37..d469dd97ca 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp @@ -99,7 +99,7 @@ RID RasterizerEffectsRD::_get_uniform_set_from_texture(RID p_texture, bool p_use u.ids.push_back(p_texture); uniforms.push_back(u); //any thing with the same configuration (one texture in binding 0 for set 0), is good - RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, blur.shader.version_get_shader(blur.shader_version, 0), 0); + RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, tonemap.shader.version_get_shader(tonemap.shader_version, 0), 0); texture_to_uniform_set_cache[p_texture] = uniform_set; @@ -204,135 +204,224 @@ RID RasterizerEffectsRD::_get_compute_uniform_set_from_image_pair(RID p_texture1 return uniform_set; } -void RasterizerEffectsRD::copy_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_rect, bool p_flip_y, bool p_force_luminance) { +void RasterizerEffectsRD::copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y, bool p_panorama) { + + zeromem(©_to_fb.push_constant, sizeof(CopyToFbPushConstant)); + + copy_to_fb.push_constant.use_section = true; + copy_to_fb.push_constant.section[0] = p_uv_rect.position.x; + copy_to_fb.push_constant.section[1] = p_uv_rect.position.y; + copy_to_fb.push_constant.section[2] = p_uv_rect.size.x; + copy_to_fb.push_constant.section[3] = p_uv_rect.size.y; - zeromem(&blur.push_constant, sizeof(BlurPushConstant)); if (p_flip_y) { - blur.push_constant.flags |= BLUR_FLAG_FLIP_Y; + copy_to_fb.push_constant.flip_y = true; + } + + RD::DrawListID draw_list = p_draw_list; + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_to_fb.pipelines[p_panorama ? COPY_TO_FB_COPY_PANORAMA_TO_DP : COPY_TO_FB_COPY].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0); + RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); + RD::get_singleton()->draw_list_set_push_constant(draw_list, ©_to_fb.push_constant, sizeof(CopyToFbPushConstant)); + RD::get_singleton()->draw_list_draw(draw_list, true); +} + +void RasterizerEffectsRD::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_alpha_to_zero) { + zeromem(©_to_fb.push_constant, sizeof(CopyToFbPushConstant)); + + if (p_flip_y) { + copy_to_fb.push_constant.flip_y = true; } if (p_force_luminance) { - blur.push_constant.flags |= BLUR_COPY_FORCE_LUMINANCE; + copy_to_fb.push_constant.force_luminance = true; + } + if (p_alpha_to_zero) { + copy_to_fb.push_constant.alpha_to_zero = true; } RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, p_rect); - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur.pipelines[BLUR_MODE_SIMPLY_COPY].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_to_fb.pipelines[COPY_TO_FB_COPY].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0); RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); - RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur.push_constant, sizeof(BlurPushConstant)); + RD::get_singleton()->draw_list_set_push_constant(draw_list, ©_to_fb.push_constant, sizeof(CopyToFbPushConstant)); RD::get_singleton()->draw_list_draw(draw_list, true); RD::get_singleton()->draw_list_end(); } -void RasterizerEffectsRD::region_copy(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_region) { +void RasterizerEffectsRD::copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_all_source, bool p_8_bit_dst) { + + zeromem(©.push_constant, sizeof(CopyPushConstant)); + if (p_flip_y) { + copy.push_constant.flags |= COPY_FLAG_FLIP_Y; + } - zeromem(&blur.push_constant, sizeof(BlurPushConstant)); + if (p_force_luminance) { + copy.push_constant.flags |= COPY_FLAG_FORCE_LUMINANCE; + } - if (p_region != Rect2()) { - blur.push_constant.flags = BLUR_FLAG_USE_BLUR_SECTION; - blur.push_constant.section[0] = p_region.position.x; - blur.push_constant.section[1] = p_region.position.y; - blur.push_constant.section[2] = p_region.size.width; - blur.push_constant.section[3] = p_region.size.height; + if (p_all_source) { + copy.push_constant.flags |= COPY_FLAG_ALL_SOURCE; } - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur.pipelines[BLUR_MODE_SIMPLY_COPY].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0); - RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); - RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur.push_constant, sizeof(BlurPushConstant)); - RD::get_singleton()->draw_list_draw(draw_list, true); - RD::get_singleton()->draw_list_end(); + copy.push_constant.section[0] = 0; + copy.push_constant.section[1] = 0; + copy.push_constant.section[2] = p_rect.size.width; + copy.push_constant.section[3] = p_rect.size.height; + copy.push_constant.target[0] = p_rect.position.x; + copy.push_constant.target[1] = p_rect.position.y; + + int32_t x_groups = (p_rect.size.width - 1) / 8 + 1; + int32_t y_groups = (p_rect.size.height - 1) / 8 + 1; + + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[p_8_bit_dst ? COPY_MODE_SIMPLY_COPY_8BIT : COPY_MODE_SIMPLY_COPY]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3); + RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); + RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_end(); } -void RasterizerEffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_framebuffer_half, RID p_rd_texture_half, RID p_dest_framebuffer, const Vector2 &p_pixel_size, const Rect2 &p_region) { +void RasterizerEffectsRD::copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far) { - zeromem(&blur.push_constant, sizeof(BlurPushConstant)); + zeromem(©.push_constant, sizeof(CopyPushConstant)); + if (p_flip_y) { + copy.push_constant.flags |= COPY_FLAG_FLIP_Y; + } - uint32_t base_flags = 0; - if (p_region != Rect2()) { - base_flags = BLUR_FLAG_USE_BLUR_SECTION; - blur.push_constant.section[0] = p_region.position.x; - blur.push_constant.section[1] = p_region.position.y; - blur.push_constant.section[2] = p_region.size.width; - blur.push_constant.section[3] = p_region.size.height; + copy.push_constant.section[0] = 0; + copy.push_constant.section[1] = 0; + copy.push_constant.section[2] = p_rect.size.width; + copy.push_constant.section[3] = p_rect.size.height; + copy.push_constant.target[0] = p_rect.position.x; + copy.push_constant.target[1] = p_rect.position.y; + copy.push_constant.camera_z_far = p_z_far; + copy.push_constant.camera_z_near = p_z_near; + + int32_t x_groups = (p_rect.size.width - 1) / 8 + 1; + int32_t y_groups = (p_rect.size.height - 1) / 8 + 1; + + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[COPY_MODE_LINEARIZE_DEPTH]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3); + RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); + RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_end(); +} + +void RasterizerEffectsRD::copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y) { + + zeromem(©.push_constant, sizeof(CopyPushConstant)); + if (p_flip_y) { + copy.push_constant.flags |= COPY_FLAG_FLIP_Y; } - blur.push_constant.pixel_size[0] = p_pixel_size.x; - blur.push_constant.pixel_size[1] = p_pixel_size.y; + copy.push_constant.section[0] = 0; + copy.push_constant.section[1] = 0; + copy.push_constant.section[2] = p_rect.size.width; + copy.push_constant.section[3] = p_rect.size.height; + copy.push_constant.target[0] = p_rect.position.x; + copy.push_constant.target[1] = p_rect.position.y; + int32_t x_groups = (p_rect.size.width - 1) / 8 + 1; + int32_t y_groups = (p_rect.size.height - 1) / 8 + 1; + + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[COPY_MODE_SIMPLY_COPY_DEPTH]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3); + RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); + RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_end(); +} + +void RasterizerEffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Rect2i &p_region, bool p_8bit_dst) { + + zeromem(©.push_constant, sizeof(CopyPushConstant)); + + uint32_t base_flags = 0; + copy.push_constant.section[0] = p_region.position.x; + copy.push_constant.section[1] = p_region.position.y; + copy.push_constant.section[2] = p_region.size.width; + copy.push_constant.section[3] = p_region.size.height; + + int32_t x_groups = (p_region.size.width - 1) / 8 + 1; + int32_t y_groups = (p_region.size.height - 1) / 8 + 1; //HORIZONTAL - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer_half, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur.pipelines[BLUR_MODE_GAUSSIAN_BLUR].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer_half))); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0); - RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); + RD::DrawListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[p_8bit_dst ? COPY_MODE_GAUSSIAN_COPY_8BIT : COPY_MODE_GAUSSIAN_COPY]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_back_texture), 0); - blur.push_constant.flags = base_flags | BLUR_FLAG_HORIZONTAL; - RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur.push_constant, sizeof(BlurPushConstant)); + copy.push_constant.flags = base_flags | COPY_FLAG_HORIZONTAL; + RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - RD::get_singleton()->draw_list_draw(draw_list, true); - RD::get_singleton()->draw_list_end(); + RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + + RD::get_singleton()->compute_list_add_barrier(compute_list); //VERTICAL - draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur.pipelines[BLUR_MODE_GAUSSIAN_BLUR].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_rd_texture_half), 0); - RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_back_texture), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_texture), 0); - blur.push_constant.flags = base_flags; - RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur.push_constant, sizeof(BlurPushConstant)); + copy.push_constant.flags = base_flags; + RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - RD::get_singleton()->draw_list_draw(draw_list, true); - RD::get_singleton()->draw_list_end(); + RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_end(); } -void RasterizerEffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_framebuffer_half, RID p_rd_texture_half, RID p_dest_framebuffer, const Vector2 &p_pixel_size, float p_strength, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_treshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_grey) { +void RasterizerEffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Size2i &p_size, float p_strength, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_treshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_grey) { - zeromem(&blur.push_constant, sizeof(BlurPushConstant)); + zeromem(©.push_constant, sizeof(CopyPushConstant)); - BlurMode blur_mode = p_first_pass && p_auto_exposure.is_valid() ? BLUR_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE : BLUR_MODE_GAUSSIAN_GLOW; + CopyMode copy_mode = p_first_pass && p_auto_exposure.is_valid() ? COPY_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE : COPY_MODE_GAUSSIAN_GLOW; uint32_t base_flags = 0; - blur.push_constant.pixel_size[0] = p_pixel_size.x; - blur.push_constant.pixel_size[1] = p_pixel_size.y; + int32_t x_groups = (p_size.width - 1) / 8 + 1; + int32_t y_groups = (p_size.height - 1) / 8 + 1; + + copy.push_constant.section[2] = p_size.x; + copy.push_constant.section[3] = p_size.y; - blur.push_constant.glow_strength = p_strength; - blur.push_constant.glow_bloom = p_bloom; - blur.push_constant.glow_hdr_threshold = p_hdr_bleed_treshold; - blur.push_constant.glow_hdr_scale = p_hdr_bleed_scale; - blur.push_constant.glow_exposure = p_exposure; - blur.push_constant.glow_white = 0; //actually unused - blur.push_constant.glow_luminance_cap = p_luminance_cap; + copy.push_constant.glow_strength = p_strength; + copy.push_constant.glow_bloom = p_bloom; + copy.push_constant.glow_hdr_threshold = p_hdr_bleed_treshold; + copy.push_constant.glow_hdr_scale = p_hdr_bleed_scale; + copy.push_constant.glow_exposure = p_exposure; + copy.push_constant.glow_white = 0; //actually unused + copy.push_constant.glow_luminance_cap = p_luminance_cap; - blur.push_constant.glow_auto_exposure_grey = p_auto_exposure_grey; //unused also + copy.push_constant.glow_auto_exposure_grey = p_auto_exposure_grey; //unused also //HORIZONTAL - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer_half, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur.pipelines[blur_mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer_half))); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0); + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[copy_mode]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_back_texture), 3); if (p_auto_exposure.is_valid() && p_first_pass) { - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_auto_exposure), 1); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_auto_exposure), 1); } - RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); - blur.push_constant.flags = base_flags | BLUR_FLAG_HORIZONTAL | (p_first_pass ? BLUR_FLAG_GLOW_FIRST_PASS : 0); - RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur.push_constant, sizeof(BlurPushConstant)); + copy.push_constant.flags = base_flags | COPY_FLAG_HORIZONTAL | (p_first_pass ? COPY_FLAG_GLOW_FIRST_PASS : 0); + RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - RD::get_singleton()->draw_list_draw(draw_list, true); - RD::get_singleton()->draw_list_end(); + RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_add_barrier(compute_list); - blur_mode = BLUR_MODE_GAUSSIAN_GLOW; + copy_mode = COPY_MODE_GAUSSIAN_GLOW; //VERTICAL - draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur.pipelines[blur_mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_rd_texture_half), 0); - RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[copy_mode]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_back_texture), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_texture), 3); - blur.push_constant.flags = base_flags; - RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur.push_constant, sizeof(BlurPushConstant)); + copy.push_constant.flags = base_flags; + RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - RD::get_singleton()->draw_list_draw(draw_list, true); - RD::get_singleton()->draw_list_end(); + RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_end(); } void RasterizerEffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal, RenderingServer::EnvironmentSSRRoughnessQuality p_roughness_quality, RID p_roughness, RID p_blur_radius, RID p_blur_radius2, RID p_metallic, const Color &p_metallic_mask, RID p_depth, RID p_scale_depth, RID p_scale_normal, RID p_output, RID p_output_blur, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const CameraMatrix &p_camera) { @@ -541,37 +630,49 @@ void RasterizerEffectsRD::merge_specular(RID p_dest_framebuffer, RID p_specular, RD::get_singleton()->draw_list_end(); } -void RasterizerEffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_framebuffer, const Vector2 &p_pixel_size) { +void RasterizerEffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size) { - zeromem(&blur.push_constant, sizeof(BlurPushConstant)); + zeromem(©.push_constant, sizeof(CopyPushConstant)); - blur.push_constant.pixel_size[0] = p_pixel_size.x; - blur.push_constant.pixel_size[1] = p_pixel_size.y; + copy.push_constant.section[0] = 0; + copy.push_constant.section[1] = 0; + copy.push_constant.section[2] = p_size.width; + copy.push_constant.section[3] = p_size.height; - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur.pipelines[BLUR_MODE_MIPMAP].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0); - RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); - RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur.push_constant, sizeof(BlurPushConstant)); - RD::get_singleton()->draw_list_draw(draw_list, true); - RD::get_singleton()->draw_list_end(); + int32_t x_groups = (p_size.width - 1) / 8 + 1; + int32_t y_groups = (p_size.height - 1) / 8 + 1; + + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[COPY_MODE_MIPMAP]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3); + RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); + RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_end(); } -void RasterizerEffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip) { +void RasterizerEffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip) { CopyToDPPushConstant push_constant; + push_constant.screen_size[0] = p_rect.size.x; + push_constant.screen_size[1] = p_rect.size.y; + push_constant.dest_offset[0] = p_rect.position.x; + push_constant.dest_offset[1] = p_rect.position.y; push_constant.bias = p_bias; push_constant.z_far = p_z_far; push_constant.z_near = p_z_near; push_constant.z_flip = p_dp_flip; - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, p_rect); - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy.pipelines[COPY_MODE_CUBE_TO_DP].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0); - RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); - RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(CopyToDPPushConstant)); - RD::get_singleton()->draw_list_draw(draw_list, true); - RD::get_singleton()->draw_list_end(); + int32_t x_groups = (p_rect.size.width - 1) / 8 + 1; + int32_t y_groups = (p_rect.size.height - 1) / 8 + 1; + + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, cube_to_dp.pipeline); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 1); + RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(CopyToDPPushConstant)); + RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_end(); } void RasterizerEffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer, const TonemapSettings &p_settings) { @@ -600,7 +701,11 @@ void RasterizerEffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer, tonemap.push_constant.use_color_correction = p_settings.use_color_correction; - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dst_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); + tonemap.push_constant.use_fxaa = p_settings.use_fxaa; + tonemap.push_constant.pixel_size[0] = 1.0 / p_settings.texture_size.x; + tonemap.push_constant.pixel_size[1] = 1.0 / p_settings.texture_size.y; + + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dst_framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD); RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, tonemap.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dst_framebuffer))); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_color), 0); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_settings.exposure_texture), 1); @@ -1110,30 +1215,39 @@ void RasterizerEffectsRD::render_sky(RD::DrawListID p_list, float p_time, RID p_ RasterizerEffectsRD::RasterizerEffectsRD() { - { // Initialize blur - Vector<String> blur_modes; - blur_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n"); - blur_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n"); - blur_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n#define GLOW_USE_AUTO_EXPOSURE\n"); - blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_LOW\n"); - blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_MEDIUM\n"); - blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_HIGH\n"); - blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_LOW\n#define DOF_NEAR_BLUR_MERGE\n"); - blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_MEDIUM\n#define DOF_NEAR_BLUR_MERGE\n"); - blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_HIGH\n#define DOF_NEAR_BLUR_MERGE\n"); - blur_modes.push_back("\n#define MODE_DOF_FAR_BLUR\n#define DOF_QUALITY_LOW\n"); - blur_modes.push_back("\n#define MODE_DOF_FAR_BLUR\n#define DOF_QUALITY_MEDIUM\n"); - blur_modes.push_back("\n#define MODE_DOF_FAR_BLUR\n#define DOF_QUALITY_HIGH\n"); - blur_modes.push_back("\n#define MODE_SSAO_MERGE\n"); - blur_modes.push_back("\n#define MODE_SIMPLE_COPY\n"); - blur_modes.push_back("\n#define MODE_MIPMAP\n"); - - blur.shader.initialize(blur_modes); - zeromem(&blur.push_constant, sizeof(BlurPushConstant)); - blur.shader_version = blur.shader.version_create(); - - for (int i = 0; i < BLUR_MODE_MAX; i++) { - blur.pipelines[i].setup(blur.shader.version_get_shader(blur.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0); + { // Initialize copy + Vector<String> copy_modes; + copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n"); + copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n#define DST_IMAGE_8BIT\n"); + copy_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n"); + copy_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n#define GLOW_USE_AUTO_EXPOSURE\n"); + copy_modes.push_back("\n#define MODE_SIMPLE_COPY\n"); + copy_modes.push_back("\n#define MODE_SIMPLE_COPY\n#define DST_IMAGE_8BIT\n"); + copy_modes.push_back("\n#define MODE_SIMPLE_COPY_DEPTH\n"); + copy_modes.push_back("\n#define MODE_MIPMAP\n"); + copy_modes.push_back("\n#define MODE_LINEARIZE_DEPTH_COPY\n"); + + copy.shader.initialize(copy_modes); + zeromem(©.push_constant, sizeof(CopyPushConstant)); + copy.shader_version = copy.shader.version_create(); + + for (int i = 0; i < COPY_MODE_MAX; i++) { + copy.pipelines[i] = RD::get_singleton()->compute_pipeline_create(copy.shader.version_get_shader(copy.shader_version, i)); + } + } + { + Vector<String> copy_modes; + copy_modes.push_back("\n"); + copy_modes.push_back("\n#define MODE_PANORAMA_TO_DP\n"); + + copy_to_fb.shader.initialize(copy_modes); + + copy_to_fb.shader_version = copy_to_fb.shader.version_create(); + + //use additive + + for (int i = 0; i < COPY_TO_FB_MAX; i++) { + copy_to_fb.pipelines[i].setup(copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0); } } @@ -1182,15 +1296,13 @@ RasterizerEffectsRD::RasterizerEffectsRD() { { // Initialize copier Vector<String> copy_modes; - copy_modes.push_back("\n#define MODE_CUBE_TO_DP\n"); + copy_modes.push_back("\n"); - copy.shader.initialize(copy_modes); + cube_to_dp.shader.initialize(copy_modes); - copy.shader_version = copy.shader.version_create(); + cube_to_dp.shader_version = cube_to_dp.shader.version_create(); - for (int i = 0; i < COPY_MODE_MAX; i++) { - copy.pipelines[i].setup(copy.shader.version_get_shader(copy.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0); - } + cube_to_dp.pipeline = RD::get_singleton()->compute_pipeline_create(cube_to_dp.shader.version_get_shader(cube_to_dp.shader_version, 0)); } { @@ -1462,9 +1574,10 @@ RasterizerEffectsRD::~RasterizerEffectsRD() { RD::get_singleton()->free(index_buffer); //array gets freed as dependency RD::get_singleton()->free(filter.coefficient_buffer); - blur.shader.version_free(blur.shader_version); bokeh.shader.version_free(bokeh.shader_version); copy.shader.version_free(copy.shader_version); + copy_to_fb.shader.version_free(copy_to_fb.shader_version); + cube_to_dp.shader.version_free(cube_to_dp.shader_version); cubemap_downsampler.shader.version_free(cubemap_downsampler.shader_version); filter.shader.version_free(filter.shader_version); luminance_reduce.shader.version_free(luminance_reduce.shader_version); diff --git a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h index 27f051d194..531591442b 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h @@ -33,9 +33,10 @@ #include "core/math/camera_matrix.h" #include "servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h" -#include "servers/rendering/rasterizer_rd/shaders/blur.glsl.gen.h" #include "servers/rendering/rasterizer_rd/shaders/bokeh_dof.glsl.gen.h" #include "servers/rendering/rasterizer_rd/shaders/copy.glsl.gen.h" +#include "servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl.gen.h" +#include "servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl.gen.h" #include "servers/rendering/rasterizer_rd/shaders/cubemap_downsampler.glsl.gen.h" #include "servers/rendering/rasterizer_rd/shaders/cubemap_filter.glsl.gen.h" #include "servers/rendering/rasterizer_rd/shaders/cubemap_roughness.glsl.gen.h" @@ -55,70 +56,87 @@ class RasterizerEffectsRD { - enum BlurMode { - BLUR_MODE_GAUSSIAN_BLUR, - BLUR_MODE_GAUSSIAN_GLOW, - BLUR_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE, - BLUR_MODE_DOF_NEAR_LOW, - BLUR_MODE_DOF_NEAR_MEDIUM, - BLUR_MODE_DOF_NEAR_HIGH, - BLUR_MODE_DOF_NEAR_MERGE_LOW, - BLUR_MODE_DOF_NEAR_MERGE_MEDIUM, - BLUR_MODE_DOF_NEAR_MERGE_HIGH, - BLUR_MODE_DOF_FAR_LOW, - BLUR_MODE_DOF_FAR_MEDIUM, - BLUR_MODE_DOF_FAR_HIGH, - BLUR_MODE_SSAO_MERGE, - BLUR_MODE_SIMPLY_COPY, - BLUR_MODE_MIPMAP, - BLUR_MODE_MAX, + enum CopyMode { + COPY_MODE_GAUSSIAN_COPY, + COPY_MODE_GAUSSIAN_COPY_8BIT, + COPY_MODE_GAUSSIAN_GLOW, + COPY_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE, + COPY_MODE_SIMPLY_COPY, + COPY_MODE_SIMPLY_COPY_8BIT, + COPY_MODE_SIMPLY_COPY_DEPTH, + COPY_MODE_MIPMAP, + COPY_MODE_LINEARIZE_DEPTH, + COPY_MODE_MAX, }; enum { - BLUR_FLAG_HORIZONTAL = (1 << 0), - BLUR_FLAG_USE_BLUR_SECTION = (1 << 1), - BLUR_FLAG_USE_ORTHOGONAL_PROJECTION = (1 << 2), - BLUR_FLAG_DOF_NEAR_FIRST_TAP = (1 << 3), - BLUR_FLAG_GLOW_FIRST_PASS = (1 << 4), - BLUR_FLAG_FLIP_Y = (1 << 5), - BLUR_COPY_FORCE_LUMINANCE = (1 << 6) + COPY_FLAG_HORIZONTAL = (1 << 0), + COPY_FLAG_USE_COPY_SECTION = (1 << 1), + COPY_FLAG_USE_ORTHOGONAL_PROJECTION = (1 << 2), + COPY_FLAG_DOF_NEAR_FIRST_TAP = (1 << 3), + COPY_FLAG_GLOW_FIRST_PASS = (1 << 4), + COPY_FLAG_FLIP_Y = (1 << 5), + COPY_FLAG_FORCE_LUMINANCE = (1 << 6), + COPY_FLAG_ALL_SOURCE = (1 << 7) }; - struct BlurPushConstant { - float section[4]; - float pixel_size[2]; + struct CopyPushConstant { + + int32_t section[4]; + int32_t target[2]; uint32_t flags; uint32_t pad; - //glow + // Glow. float glow_strength; float glow_bloom; float glow_hdr_threshold; float glow_hdr_scale; + float glow_exposure; float glow_white; float glow_luminance_cap; float glow_auto_exposure_grey; - //dof - float dof_begin; - float dof_end; - float dof_radius; - float dof_pad; - - float dof_dir[2]; + // DOF. float camera_z_far; float camera_z_near; + uint32_t pad2[2]; + }; + + struct Copy { + CopyPushConstant push_constant; + CopyShaderRD shader; + RID shader_version; + RID pipelines[COPY_MODE_MAX]; + + } copy; + + enum CopyToFBMode { + COPY_TO_FB_COPY, + COPY_TO_FB_COPY_PANORAMA_TO_DP, + COPY_TO_FB_MAX, + + }; + + struct CopyToFbPushConstant { + + float section[4]; + float pixel_size[2]; + uint32_t flip_y; + uint32_t use_section; - float ssao_color[4]; + uint32_t force_luminance; + uint32_t alpha_to_zero; + uint32_t pad[2]; }; - struct Blur { - BlurPushConstant push_constant; - BlurShaderRD shader; + struct CopyToFb { + CopyToFbPushConstant push_constant; + CopyToFbShaderRD shader; RID shader_version; - RenderPipelineVertexFormatCacheRD pipelines[BLUR_MODE_MAX]; + RenderPipelineVertexFormatCacheRD pipelines[COPY_TO_FB_MAX]; - } blur; + } copy_to_fb; struct CubemapRoughnessPushConstant { uint32_t face_id; @@ -161,10 +179,17 @@ class RasterizerEffectsRD { float exposure; float white; float auto_exposure_grey; + + float pixel_size[2]; + uint32_t use_fxaa; + uint32_t pad; }; + /* tonemap actually writes to a framebuffer, which is + * better to do using the raster pipeline rather than + * comptute, as that framebuffer might be in different formats + */ struct Tonemap { - TonemapPushConstant push_constant; TonemapShaderRD shader; RID shader_version; @@ -195,23 +220,20 @@ class RasterizerEffectsRD { } luminance_reduce; struct CopyToDPPushConstant { + int32_t screen_size[2]; + int32_t dest_offset[2]; float bias; float z_far; float z_near; uint32_t z_flip; }; - enum CopyMode { - COPY_MODE_CUBE_TO_DP, - COPY_MODE_MAX - }; - - struct Copy { + struct CoptToDP { - CopyShaderRD shader; + CubeToDpShaderRD shader; RID shader_version; - RenderPipelineVertexFormatCacheRD pipelines[COPY_MODE_MAX]; - } copy; + RID pipeline; + } cube_to_dp; struct BokehPushConstant { uint32_t size[2]; @@ -391,6 +413,10 @@ class RasterizerEffectsRD { SPECULAR_MERGE_MAX }; + /* Specular merge must be done using raster, rather than compute + * because it must continue the existing color buffer + */ + struct SpecularMerge { SpecularMergeShaderRD shader; @@ -536,16 +562,17 @@ class RasterizerEffectsRD { RID _get_compute_uniform_set_from_image_pair(RID p_texture, RID p_texture2); public: - //TODO must re-do most of the shaders in compute - - void region_copy(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_region); - void copy_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_rect, bool p_flip_y = false, bool p_force_luminance = false); - void gaussian_blur(RID p_source_rd_texture, RID p_framebuffer_half, RID p_rd_texture_half, RID p_dest_framebuffer, const Vector2 &p_pixel_size, const Rect2 &p_region); - void gaussian_glow(RID p_source_rd_texture, RID p_framebuffer_half, RID p_rd_texture_half, RID p_dest_framebuffer, const Vector2 &p_pixel_size, float p_strength = 1.0, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_treshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_grey = 1.0); + void copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_alpha_to_zero = false); + void copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_all_source = false, bool p_8_bit_dst = false); + void copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false); + void copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far); + void copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y = false, bool p_panorama = false); + void gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Rect2i &p_region, bool p_8bit_dst = false); + void gaussian_glow(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Size2i &p_size, float p_strength = 1.0, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_treshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_grey = 1.0); void cubemap_roughness(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size); - void make_mipmap(RID p_source_rd_texture, RID p_framebuffer_half, const Vector2 &p_pixel_size); - void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip); + void make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size); + void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip); void luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set = false); void bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i &p_base_texture_size, RID p_secondary_texture, RID p_bokeh_texture1, RID p_bokeh_texture2, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_bokeh_size, RS::DOFBokehShape p_bokeh_shape, RS::DOFBlurQuality p_quality, bool p_use_jitter, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal); @@ -582,6 +609,9 @@ public: bool use_color_correction = false; RID color_correction_texture; + + bool use_fxaa = false; + Vector2i texture_size; }; void tonemapper(RID p_source_color, RID p_dst_framebuffer, const TonemapSettings &p_settings); diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp index 685c30b5b8..b3cf40f166 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp @@ -52,6 +52,21 @@ static _FORCE_INLINE_ void store_transform(const Transform &p_mtx, float *p_arra p_array[15] = 1; } +static _FORCE_INLINE_ void store_basis_3x4(const Basis &p_mtx, float *p_array) { + p_array[0] = p_mtx.elements[0][0]; + p_array[1] = p_mtx.elements[1][0]; + p_array[2] = p_mtx.elements[2][0]; + p_array[3] = 0; + p_array[4] = p_mtx.elements[0][1]; + p_array[5] = p_mtx.elements[1][1]; + p_array[6] = p_mtx.elements[2][1]; + p_array[7] = 0; + p_array[8] = p_mtx.elements[0][2]; + p_array[9] = p_mtx.elements[1][2]; + p_array[10] = p_mtx.elements[2][2]; + p_array[11] = 0; +} + static _FORCE_INLINE_ void store_transform_3x3(const Transform &p_mtx, float *p_array) { p_array[0] = p_mtx.basis.elements[0][0]; p_array[1] = p_mtx.basis.elements[1][0]; @@ -77,6 +92,13 @@ static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_arra } } +static _FORCE_INLINE_ void store_soft_shadow_kernel(const float *p_kernel, float *p_array) { + + for (int i = 0; i < 128; i++) { + p_array[i] = p_kernel[i]; + } +} + /* SCENE SHADER */ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) { //compile @@ -109,6 +131,7 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) { unshaded = false; uses_vertex = false; uses_sss = false; + uses_transmittance = false; uses_screen_texture = false; uses_depth_texture = false; uses_normal_texture = false; @@ -142,6 +165,7 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) { actions.render_mode_flags["depth_prepass_alpha"] = &uses_depth_pre_pass; actions.usage_flag_pointers["SSS_STRENGTH"] = &uses_sss; + actions.usage_flag_pointers["SSS_TRANSMITTANCE_DEPTH"] = &uses_transmittance; actions.usage_flag_pointers["SCREEN_TEXTURE"] = &uses_screen_texture; actions.usage_flag_pointers["DEPTH_TEXTURE"] = &uses_depth_texture; @@ -354,6 +378,10 @@ void RasterizerSceneHighEndRD::ShaderData::get_param_list(List<PropertyInfo> *p_ for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { + if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) { + continue; + } + if (E->get().texture_order >= 0) { order[E->get().texture_order + 100000] = E->key(); } else { @@ -369,6 +397,23 @@ void RasterizerSceneHighEndRD::ShaderData::get_param_list(List<PropertyInfo> *p_ } } +void RasterizerSceneHighEndRD::ShaderData::get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const { + + for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { + + if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { + continue; + } + + RasterizerStorage::InstanceShaderParam p; + p.info = ShaderLanguage::uniform_to_property_info(E->get()); + p.info.name = E->key(); //supply name + p.index = E->get().instance_index; + p.default_value = ShaderLanguage::constant_value_to_variant(E->get().default_value, E->get().type, E->get().hint); + p_param_list->push_back(p); + } +} + bool RasterizerSceneHighEndRD::ShaderData::is_param_texture(const StringName &p_param) const { if (!uniforms.has(p_param)) { return false; @@ -533,46 +578,100 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::ensure_specular() { tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; tf.width = width; tf.height = height; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; + if (msaa != RS::VIEWPORT_MSAA_DISABLED) { + tf.usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; + } else { + tf.usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; + } specular = RD::get_singleton()->texture_create(tf, RD::TextureView()); - { - Vector<RID> fb; - fb.push_back(color); - fb.push_back(specular); - fb.push_back(depth); + if (msaa == RS::VIEWPORT_MSAA_DISABLED) { - color_specular_fb = RD::get_singleton()->framebuffer_create(fb); - } - { - Vector<RID> fb; - fb.push_back(specular); + { + Vector<RID> fb; + fb.push_back(color); + fb.push_back(specular); + fb.push_back(depth); + + color_specular_fb = RD::get_singleton()->framebuffer_create(fb); + } + { + Vector<RID> fb; + fb.push_back(specular); + + specular_only_fb = RD::get_singleton()->framebuffer_create(fb); + } - specular_only_fb = RD::get_singleton()->framebuffer_create(fb); + } else { + + tf.samples = texture_samples; + tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; + specular_msaa = RD::get_singleton()->texture_create(tf, RD::TextureView()); + + { + Vector<RID> fb; + fb.push_back(color_msaa); + fb.push_back(specular_msaa); + fb.push_back(depth_msaa); + + color_specular_fb = RD::get_singleton()->framebuffer_create(fb); + } + { + Vector<RID> fb; + fb.push_back(specular_msaa); + + specular_only_fb = RD::get_singleton()->framebuffer_create(fb); + } } } } void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::clear() { + if (color_msaa.is_valid()) { + RD::get_singleton()->free(color_msaa); + color_msaa = RID(); + } + + if (depth_msaa.is_valid()) { + RD::get_singleton()->free(depth_msaa); + depth_msaa = RID(); + } + if (specular.is_valid()) { + if (specular_msaa.is_valid()) { + RD::get_singleton()->free(specular_msaa); + specular_msaa = RID(); + } RD::get_singleton()->free(specular); specular = RID(); } + color = RID(); + depth = RID(); color_specular_fb = RID(); specular_only_fb = RID(); color_fb = RID(); + depth_fb = RID(); if (normal_buffer.is_valid()) { RD::get_singleton()->free(normal_buffer); + if (normal_buffer_msaa.is_valid()) { + RD::get_singleton()->free(normal_buffer_msaa); + normal_buffer_msaa = RID(); + } normal_buffer = RID(); depth_normal_fb = RID(); } if (roughness_buffer.is_valid()) { RD::get_singleton()->free(roughness_buffer); + if (roughness_buffer_msaa.is_valid()) { + RD::get_singleton()->free(roughness_buffer_msaa); + roughness_buffer_msaa = RID(); + } roughness_buffer = RID(); depth_normal_roughness_fb = RID(); } @@ -581,24 +680,69 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::clear() { void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa) { clear(); + msaa = p_msaa; + width = p_width; height = p_height; color = p_color_buffer; depth = p_depth_buffer; - { - Vector<RID> fb; - fb.push_back(p_color_buffer); - fb.push_back(depth); + if (p_msaa == RS::VIEWPORT_MSAA_DISABLED) { - color_fb = RD::get_singleton()->framebuffer_create(fb); - } - { - Vector<RID> fb; - fb.push_back(depth); + { + Vector<RID> fb; + fb.push_back(p_color_buffer); + fb.push_back(depth); + + color_fb = RD::get_singleton()->framebuffer_create(fb); + } + { + Vector<RID> fb; + fb.push_back(depth); + + depth_fb = RD::get_singleton()->framebuffer_create(fb); + } + } else { - depth_fb = RD::get_singleton()->framebuffer_create(fb); + RD::TextureFormat tf; + tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; + tf.width = p_width; + tf.height = p_height; + tf.type = RD::TEXTURE_TYPE_2D; + tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; + + RD::TextureSamples ts[RS::VIEWPORT_MSAA_MAX] = { + RD::TEXTURE_SAMPLES_1, + RD::TEXTURE_SAMPLES_2, + RD::TEXTURE_SAMPLES_4, + RD::TEXTURE_SAMPLES_8, + RD::TEXTURE_SAMPLES_16 + }; + + texture_samples = ts[p_msaa]; + tf.samples = texture_samples; + + color_msaa = RD::get_singleton()->texture_create(tf, RD::TextureView()); + + tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D24_UNORM_S8_UINT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D24_UNORM_S8_UINT : RD::DATA_FORMAT_D32_SFLOAT_S8_UINT; + tf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; + + depth_msaa = RD::get_singleton()->texture_create(tf, RD::TextureView()); + + { + Vector<RID> fb; + fb.push_back(color_msaa); + fb.push_back(depth_msaa); + + color_fb = RD::get_singleton()->framebuffer_create(fb); + } + { + Vector<RID> fb; + fb.push_back(depth_msaa); + + depth_fb = RD::get_singleton()->framebuffer_create(fb); + } } } @@ -611,13 +755,31 @@ void RasterizerSceneHighEndRD::_allocate_normal_texture(RenderBufferDataHighEnd tf.format = RD::DATA_FORMAT_A2B10G10R10_UNORM_PACK32; tf.width = rb->width; tf.height = rb->height; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT; + + if (rb->msaa != RS::VIEWPORT_MSAA_DISABLED) { + tf.usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; + } else { + tf.usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; + } rb->normal_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView()); - Vector<RID> fb; - fb.push_back(rb->depth); - fb.push_back(rb->normal_buffer); - rb->depth_normal_fb = RD::get_singleton()->framebuffer_create(fb); + + if (rb->msaa == RS::VIEWPORT_MSAA_DISABLED) { + Vector<RID> fb; + fb.push_back(rb->depth); + fb.push_back(rb->normal_buffer); + rb->depth_normal_fb = RD::get_singleton()->framebuffer_create(fb); + } else { + tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; + tf.samples = rb->texture_samples; + rb->normal_buffer_msaa = RD::get_singleton()->texture_create(tf, RD::TextureView()); + + Vector<RID> fb; + fb.push_back(rb->depth_msaa); + fb.push_back(rb->normal_buffer_msaa); + rb->depth_normal_fb = RD::get_singleton()->framebuffer_create(fb); + } _render_buffers_clear_uniform_set(rb); } @@ -636,12 +798,32 @@ void RasterizerSceneHighEndRD::_allocate_roughness_texture(RenderBufferDataHighE tf.height = rb->height; tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; + if (rb->msaa != RS::VIEWPORT_MSAA_DISABLED) { + tf.usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; + } else { + tf.usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; + } + rb->roughness_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView()); - Vector<RID> fb; - fb.push_back(rb->depth); - fb.push_back(rb->normal_buffer); - fb.push_back(rb->roughness_buffer); - rb->depth_normal_roughness_fb = RD::get_singleton()->framebuffer_create(fb); + + if (rb->msaa == RS::VIEWPORT_MSAA_DISABLED) { + + Vector<RID> fb; + fb.push_back(rb->depth); + fb.push_back(rb->normal_buffer); + fb.push_back(rb->roughness_buffer); + rb->depth_normal_roughness_fb = RD::get_singleton()->framebuffer_create(fb); + } else { + tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; + tf.samples = rb->texture_samples; + rb->roughness_buffer_msaa = RD::get_singleton()->texture_create(tf, RD::TextureView()); + + Vector<RID> fb; + fb.push_back(rb->depth_msaa); + fb.push_back(rb->normal_buffer_msaa); + fb.push_back(rb->roughness_buffer_msaa); + rb->depth_normal_roughness_fb = RD::get_singleton()->framebuffer_create(fb); + } _render_buffers_clear_uniform_set(rb); } @@ -667,6 +849,7 @@ void RasterizerSceneHighEndRD::_fill_instances(RenderList::Element **p_elements, store_transform(Transform(e->instance->transform.basis.inverse().transposed()), id.normal_transform); id.flags = 0; id.mask = e->instance->layer_mask; + id.instance_uniforms_ofs = e->instance->instance_allocated_shader_parameters_offset >= 0 ? e->instance->instance_allocated_shader_parameters_offset : 0; if (e->instance->base_type == RS::INSTANCE_MULTIMESH) { id.flags |= INSTANCE_DATA_FLAG_MULTIMESH; @@ -944,7 +1127,7 @@ void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_l } } -void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers) { +void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers, bool p_pancake_shadows) { //CameraMatrix projection = p_cam_projection; //projection.flip_y(); // Vulkan and modern APIs use Y-Down @@ -961,6 +1144,18 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const Camer scene_state.ubo.z_far = p_zfar; scene_state.ubo.z_near = p_znear; + scene_state.ubo.pancake_shadows = p_pancake_shadows; + + store_soft_shadow_kernel(directional_penumbra_shadow_kernel_get(), scene_state.ubo.directional_penumbra_shadow_kernel); + store_soft_shadow_kernel(directional_soft_shadow_kernel_get(), scene_state.ubo.directional_soft_shadow_kernel); + store_soft_shadow_kernel(penumbra_shadow_kernel_get(), scene_state.ubo.penumbra_shadow_kernel); + store_soft_shadow_kernel(soft_shadow_kernel_get(), scene_state.ubo.soft_shadow_kernel); + + scene_state.ubo.directional_penumbra_shadow_samples = directional_penumbra_shadow_samples_get(); + scene_state.ubo.directional_soft_shadow_samples = directional_soft_shadow_samples_get(); + scene_state.ubo.penumbra_shadow_samples = penumbra_shadow_samples_get(); + scene_state.ubo.soft_shadow_samples = soft_shadow_samples_get(); + scene_state.ubo.screen_pixel_size[0] = p_screen_pixel_size.x; scene_state.ubo.screen_pixel_size[1] = p_screen_pixel_size.y; @@ -991,7 +1186,7 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const Camer } else if (is_environment(p_environment)) { RS::EnvironmentBG env_bg = environment_get_background(p_environment); - RS::EnvironmentAmbientSource ambient_src = environment_get_ambient_light_ambient_source(p_environment); + RS::EnvironmentAmbientSource ambient_src = environment_get_ambient_source(p_environment); float bg_energy = environment_get_bg_energy(p_environment); scene_state.ubo.ambient_light_color_energy[3] = bg_energy; @@ -1011,7 +1206,7 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const Camer scene_state.ubo.use_ambient_cubemap = false; } else { - float energy = environment_get_ambient_light_ambient_energy(p_environment); + float energy = environment_get_ambient_light_energy(p_environment); Color color = environment_get_ambient_light_color(p_environment); color = color.to_linear(); scene_state.ubo.ambient_light_color_energy[0] = color.r * energy; @@ -1353,7 +1548,7 @@ void RasterizerSceneHighEndRD::_setup_reflections(RID *p_reflection_probe_cull_r Color ambient_linear = storage->reflection_probe_get_interior_ambient(base_probe).to_linear(); if (is_environment(p_environment)) { Color env_ambient_color = environment_get_ambient_light_color(p_environment).to_linear(); - float env_ambient_energy = environment_get_ambient_light_ambient_energy(p_environment); + float env_ambient_energy = environment_get_ambient_light_energy(p_environment); ambient_linear = env_ambient_color; ambient_linear.r *= env_ambient_energy; ambient_linear.g *= env_ambient_energy; @@ -1479,11 +1674,49 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig light_data.specular = storage->light_get_param(base, RS::LIGHT_PARAM_SPECULAR); light_data.mask = storage->light_get_cull_mask(base); + float size = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE); + + light_data.size = 1.0 - Math::cos(Math::deg2rad(size)); //angle to cosine offset + Color shadow_col = storage->light_get_shadow_color(base).to_linear(); - light_data.shadow_color[0] = shadow_col.r; - light_data.shadow_color[1] = shadow_col.g; - light_data.shadow_color[2] = shadow_col.b; + if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_PSSM_SPLITS) { + light_data.shadow_color1[0] = 1.0; + light_data.shadow_color1[1] = 0.0; + light_data.shadow_color1[2] = 0.0; + light_data.shadow_color1[3] = 1.0; + light_data.shadow_color2[0] = 0.0; + light_data.shadow_color2[1] = 1.0; + light_data.shadow_color2[2] = 0.0; + light_data.shadow_color2[3] = 1.0; + light_data.shadow_color3[0] = 0.0; + light_data.shadow_color3[1] = 0.0; + light_data.shadow_color3[2] = 1.0; + light_data.shadow_color3[3] = 1.0; + light_data.shadow_color4[0] = 1.0; + light_data.shadow_color4[1] = 1.0; + light_data.shadow_color4[2] = 0.0; + light_data.shadow_color4[3] = 1.0; + + } else { + + light_data.shadow_color1[0] = shadow_col.r; + light_data.shadow_color1[1] = shadow_col.g; + light_data.shadow_color1[2] = shadow_col.b; + light_data.shadow_color1[3] = 1.0; + light_data.shadow_color2[0] = shadow_col.r; + light_data.shadow_color2[1] = shadow_col.g; + light_data.shadow_color2[2] = shadow_col.b; + light_data.shadow_color2[3] = 1.0; + light_data.shadow_color3[0] = shadow_col.r; + light_data.shadow_color3[1] = shadow_col.g; + light_data.shadow_color3[2] = shadow_col.b; + light_data.shadow_color3[3] = 1.0; + light_data.shadow_color4[0] = shadow_col.r; + light_data.shadow_color4[1] = shadow_col.g; + light_data.shadow_color4[2] = shadow_col.b; + light_data.shadow_color4[3] = 1.0; + } light_data.shadow_enabled = p_using_shadows && storage->light_has_shadow(base); @@ -1507,12 +1740,52 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig CameraMatrix shadow_mtx = rectm * bias * matrix * modelview; light_data.shadow_split_offsets[j] = split; + float bias_scale = light_instance_get_shadow_bias_scale(li, j); + light_data.shadow_bias[j] = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) * bias_scale; + light_data.shadow_normal_bias[j] = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * light_instance_get_directional_shadow_texel_size(li, j); + light_data.shadow_transmittance_bias[j] = storage->light_get_transmittance_bias(base) * bias_scale; + light_data.shadow_transmittance_z_scale[j] = light_instance_get_shadow_range(li, j); + light_data.shadow_range_begin[j] = light_instance_get_shadow_range_begin(li, j); store_camera(shadow_mtx, light_data.shadow_matrices[j]); + + Vector2 uv_scale = light_instance_get_shadow_uv_scale(li, j); + uv_scale *= atlas_rect.size; //adapt to atlas size + switch (j) { + case 0: { + light_data.uv_scale1[0] = uv_scale.x; + light_data.uv_scale1[1] = uv_scale.y; + } break; + case 1: { + light_data.uv_scale2[0] = uv_scale.x; + light_data.uv_scale2[1] = uv_scale.y; + } break; + case 2: { + light_data.uv_scale3[0] = uv_scale.x; + light_data.uv_scale3[1] = uv_scale.y; + } break; + case 3: { + light_data.uv_scale4[0] = uv_scale.x; + light_data.uv_scale4[1] = uv_scale.y; + } break; + } } float fade_start = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_FADE_START); light_data.fade_from = -light_data.shadow_split_offsets[3] * MIN(fade_start, 0.999); //using 1.0 would break smoothstep light_data.fade_to = -light_data.shadow_split_offsets[3]; + + light_data.soft_shadow_scale = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BLUR); + + float softshadow_angle = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE); + if (softshadow_angle > 0.0) { + // I know tan(0) is 0, but let's not risk it with numerical precision. + // technically this will keep expanding until reaching the sun, but all we care + // is expand until we reach the radius of the near plane (there can't be more occluders than that) + light_data.softshadow_angle = Math::tan(Math::deg2rad(softshadow_angle)); + } else { + light_data.softshadow_angle = 0; + light_data.soft_shadow_scale *= directional_shadow_quality_radius_get(); // Only use quality radius for PCF + } } // Copy to SkyDirectionalLightData @@ -1533,6 +1806,7 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig sky_light_data.color[2] = light_data.color[2]; sky_light_data.enabled = true; + sky_light_data.size = light_data.softshadow_angle; sky_scene_state.directional_light_count++; } @@ -1575,51 +1849,114 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig light_data.direction[1] = direction.y; light_data.direction[2] = direction.z; + float size = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE); + + light_data.size = size; + light_data.cone_attenuation_angle[0] = Math::make_half_float(storage->light_get_param(base, RS::LIGHT_PARAM_SPOT_ATTENUATION)); float spot_angle = storage->light_get_param(base, RS::LIGHT_PARAM_SPOT_ANGLE); light_data.cone_attenuation_angle[1] = Math::make_half_float(Math::cos(Math::deg2rad(spot_angle))); light_data.mask = storage->light_get_cull_mask(base); - Color shadow_color = storage->light_get_shadow_color(base); - - bool has_shadow = p_using_shadows && storage->light_has_shadow(base); - light_data.shadow_color_enabled[0] = MIN(uint32_t(shadow_color.r * 255), 255); - light_data.shadow_color_enabled[1] = MIN(uint32_t(shadow_color.g * 255), 255); - light_data.shadow_color_enabled[2] = MIN(uint32_t(shadow_color.b * 255), 255); - light_data.shadow_color_enabled[3] = has_shadow ? 255 : 0; - light_data.atlas_rect[0] = 0; light_data.atlas_rect[1] = 0; light_data.atlas_rect[2] = 0; light_data.atlas_rect[3] = 0; + RID projector = storage->light_get_projector(base); + + if (projector.is_valid()) { + Rect2 rect = storage->decal_atlas_get_texture_rect(projector); + + if (type == RS::LIGHT_SPOT) { + + light_data.projector_rect[0] = rect.position.x; + light_data.projector_rect[1] = rect.position.y + rect.size.height; //flip because shadow is flipped + light_data.projector_rect[2] = rect.size.width; + light_data.projector_rect[3] = -rect.size.height; + } else { + light_data.projector_rect[0] = rect.position.x; + light_data.projector_rect[1] = rect.position.y; + light_data.projector_rect[2] = rect.size.width; + light_data.projector_rect[3] = rect.size.height * 0.5; //used by dp, so needs to be half + } + } else { + light_data.projector_rect[0] = 0; + light_data.projector_rect[1] = 0; + light_data.projector_rect[2] = 0; + light_data.projector_rect[3] = 0; + } + if (p_using_shadows && p_shadow_atlas.is_valid() && shadow_atlas_owns_light_instance(p_shadow_atlas, li)) { // fill in the shadow information + Color shadow_color = storage->light_get_shadow_color(base); + + light_data.shadow_color_enabled[0] = MIN(uint32_t(shadow_color.r * 255), 255); + light_data.shadow_color_enabled[1] = MIN(uint32_t(shadow_color.g * 255), 255); + light_data.shadow_color_enabled[2] = MIN(uint32_t(shadow_color.b * 255), 255); + light_data.shadow_color_enabled[3] = 255; + + if (type == RS::LIGHT_SPOT) { + light_data.shadow_bias = (storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) * radius / 10.0); + float shadow_texel_size = Math::tan(Math::deg2rad(spot_angle)) * radius * 2.0; + shadow_texel_size *= light_instance_get_shadow_texel_size(li, p_shadow_atlas); + + light_data.shadow_normal_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size; + + } else { //omni + light_data.shadow_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) * radius / 10.0; + float shadow_texel_size = light_instance_get_shadow_texel_size(li, p_shadow_atlas); + light_data.shadow_normal_bias = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size * 2.0; // applied in -1 .. 1 space + } + + light_data.transmittance_bias = storage->light_get_transmittance_bias(base); + Rect2 rect = light_instance_get_shadow_atlas_rect(li, p_shadow_atlas); - if (type == RS::LIGHT_OMNI) { + light_data.atlas_rect[0] = rect.position.x; + light_data.atlas_rect[1] = rect.position.y; + light_data.atlas_rect[2] = rect.size.width; + light_data.atlas_rect[3] = rect.size.height; + + light_data.soft_shadow_scale = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BLUR); - light_data.atlas_rect[0] = rect.position.x; - light_data.atlas_rect[1] = rect.position.y; - light_data.atlas_rect[2] = rect.size.width; - light_data.atlas_rect[3] = rect.size.height * 0.5; + if (type == RS::LIGHT_OMNI) { + light_data.atlas_rect[3] *= 0.5; //one paraboloid on top of another Transform proj = (p_camera_inverse_transform * light_transform).inverse(); store_transform(proj, light_data.shadow_matrix); + + if (size > 0.0) { + + light_data.soft_shadow_size = size; + } else { + light_data.soft_shadow_size = 0.0; + light_data.soft_shadow_scale *= shadows_quality_radius_get(); // Only use quality radius for PCF + } + } else if (type == RS::LIGHT_SPOT) { Transform modelview = (p_camera_inverse_transform * light_transform).inverse(); CameraMatrix bias; bias.set_light_bias(); - CameraMatrix rectm; - rectm.set_light_atlas_rect(rect); - CameraMatrix shadow_mtx = rectm * bias * light_instance_get_shadow_camera(li, 0) * modelview; + CameraMatrix shadow_mtx = bias * light_instance_get_shadow_camera(li, 0) * modelview; store_camera(shadow_mtx, light_data.shadow_matrix); + + if (size > 0.0) { + CameraMatrix cm = light_instance_get_shadow_camera(li, 0); + float half_np = cm.get_z_near() * Math::tan(Math::deg2rad(spot_angle)); + light_data.soft_shadow_size = (size * 0.5 / radius) / (half_np / cm.get_z_near()) * rect.size.width; + } else { + light_data.soft_shadow_size = 0.0; + light_data.soft_shadow_scale *= shadows_quality_radius_get(); // Only use quality radius for PCF + } } + } else { + light_data.shadow_color_enabled[3] = 0; } light_instance_set_index(li, light_count); @@ -1644,7 +1981,140 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig } } -void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color) { +void RasterizerSceneHighEndRD::_setup_decals(const RID *p_decal_instances, int p_decal_count, const Transform &p_camera_inverse_xform) { + + Transform uv_xform; + uv_xform.basis.scale(Vector3(2.0, 1.0, 2.0)); + uv_xform.origin = Vector3(-1.0, 0.0, -1.0); + + p_decal_count = MIN((uint32_t)p_decal_count, scene_state.max_decals); + int idx = 0; + for (int i = 0; i < p_decal_count; i++) { + + RID di = p_decal_instances[i]; + RID decal = decal_instance_get_base(di); + + Transform xform = decal_instance_get_transform(di); + + float fade = 1.0; + + if (storage->decal_is_distance_fade_enabled(decal)) { + real_t distance = -p_camera_inverse_xform.xform(xform.origin).z; + float fade_begin = storage->decal_get_distance_fade_begin(decal); + float fade_length = storage->decal_get_distance_fade_length(decal); + + if (distance > fade_begin) { + if (distance > fade_begin + fade_length) { + continue; // do not use this decal, its invisible + } + + fade = 1.0 - (distance - fade_begin) / fade_length; + } + } + + DecalData &dd = scene_state.decals[idx]; + + Vector3 decal_extents = storage->decal_get_extents(decal); + + Transform scale_xform; + scale_xform.basis.scale(Vector3(decal_extents.x, decal_extents.y, decal_extents.z)); + Transform to_decal_xform = (p_camera_inverse_xform * decal_instance_get_transform(di) * scale_xform * uv_xform).affine_inverse(); + store_transform(to_decal_xform, dd.xform); + + Vector3 normal = xform.basis.get_axis(Vector3::AXIS_Y).normalized(); + normal = p_camera_inverse_xform.basis.xform(normal); //camera is normalized, so fine + + dd.normal[0] = normal.x; + dd.normal[1] = normal.y; + dd.normal[2] = normal.z; + dd.normal_fade = storage->decal_get_normal_fade(decal); + + RID albedo_tex = storage->decal_get_texture(decal, RS::DECAL_TEXTURE_ALBEDO); + RID emission_tex = storage->decal_get_texture(decal, RS::DECAL_TEXTURE_EMISSION); + if (albedo_tex.is_valid()) { + Rect2 rect = storage->decal_atlas_get_texture_rect(albedo_tex); + dd.albedo_rect[0] = rect.position.x; + dd.albedo_rect[1] = rect.position.y; + dd.albedo_rect[2] = rect.size.x; + dd.albedo_rect[3] = rect.size.y; + } else { + + if (!emission_tex.is_valid()) { + continue; //no albedo, no emission, no decal. + } + dd.albedo_rect[0] = 0; + dd.albedo_rect[1] = 0; + dd.albedo_rect[2] = 0; + dd.albedo_rect[3] = 0; + } + + RID normal_tex = storage->decal_get_texture(decal, RS::DECAL_TEXTURE_NORMAL); + + if (normal_tex.is_valid()) { + Rect2 rect = storage->decal_atlas_get_texture_rect(normal_tex); + dd.normal_rect[0] = rect.position.x; + dd.normal_rect[1] = rect.position.y; + dd.normal_rect[2] = rect.size.x; + dd.normal_rect[3] = rect.size.y; + + Basis normal_xform = p_camera_inverse_xform.basis * xform.basis.orthonormalized(); + store_basis_3x4(normal_xform, dd.normal_xform); + } else { + dd.normal_rect[0] = 0; + dd.normal_rect[1] = 0; + dd.normal_rect[2] = 0; + dd.normal_rect[3] = 0; + } + + RID orm_tex = storage->decal_get_texture(decal, RS::DECAL_TEXTURE_ORM); + if (orm_tex.is_valid()) { + Rect2 rect = storage->decal_atlas_get_texture_rect(orm_tex); + dd.orm_rect[0] = rect.position.x; + dd.orm_rect[1] = rect.position.y; + dd.orm_rect[2] = rect.size.x; + dd.orm_rect[3] = rect.size.y; + } else { + dd.orm_rect[0] = 0; + dd.orm_rect[1] = 0; + dd.orm_rect[2] = 0; + dd.orm_rect[3] = 0; + } + + if (emission_tex.is_valid()) { + Rect2 rect = storage->decal_atlas_get_texture_rect(emission_tex); + dd.emission_rect[0] = rect.position.x; + dd.emission_rect[1] = rect.position.y; + dd.emission_rect[2] = rect.size.x; + dd.emission_rect[3] = rect.size.y; + } else { + dd.emission_rect[0] = 0; + dd.emission_rect[1] = 0; + dd.emission_rect[2] = 0; + dd.emission_rect[3] = 0; + } + + Color modulate = storage->decal_get_modulate(decal); + dd.modulate[0] = modulate.r; + dd.modulate[1] = modulate.g; + dd.modulate[2] = modulate.b; + dd.modulate[3] = modulate.a * fade; + dd.emission_energy = storage->decal_get_emission_energy(decal) * fade; + dd.albedo_mix = storage->decal_get_albedo_mix(decal); + dd.mask = storage->decal_get_cull_mask(decal); + dd.upper_fade = storage->decal_get_upper_fade(decal); + dd.lower_fade = storage->decal_get_lower_fade(decal); + + cluster_builder.add_decal(xform, decal_extents); + + idx++; + } + + if (idx > 0) { + RD::get_singleton()->buffer_update(scene_state.decal_buffer, 0, sizeof(DecalData) * idx, scene_state.decals, true); + } +} + +void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color) { RenderBufferDataHighEnd *render_buffer = nullptr; if (p_render_buffer.is_valid()) { @@ -1655,27 +2125,6 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor render_pass++; //fill up ubo -#if 0 - storage->info.render.object_count += p_cull_count; - - Environment *env = environment_owner.getornull(p_environment); - ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas); - ReflectionAtlas *reflection_atlas = reflection_atlas_owner.getornull(p_reflection_atlas); - - if (shadow_atlas && shadow_atlas->size) { - glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 5); - glBindTexture(GL_TEXTURE_2D, shadow_atlas->depth); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LESS); - scene_state.ubo.shadow_atlas_pixel_size[0] = 1.0 / shadow_atlas->size; - scene_state.ubo.shadow_atlas_pixel_size[1] = 1.0 / shadow_atlas->size; - } - - if (reflection_atlas && reflection_atlas->size) { - glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 3); - glBindTexture(GL_TEXTURE_2D, reflection_atlas->color); - } -#endif RENDER_TIMESTAMP("Setup 3D Scene"); @@ -1698,9 +2147,6 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor //scene_state.ubo.subsurface_scatter_width = subsurface_scatter_size; - scene_state.ubo.shadow_z_offset = 0; - scene_state.ubo.shadow_z_slope_scale = 0; - Vector2 vp_he = p_cam_projection.get_viewport_half_extents(); scene_state.ubo.viewport_size[0] = vp_he.x; scene_state.ubo.viewport_size[1] = vp_he.y; @@ -1718,6 +2164,7 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor bool using_ssr = false; if (render_buffer) { + screen_pixel_size.width = 1.0 / render_buffer->width; screen_pixel_size.height = 1.0 / render_buffer->height; screen_size.x = render_buffer->width; @@ -1784,6 +2231,7 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor cluster_builder.begin(p_cam_transform.affine_inverse(), p_cam_projection); //prepare cluster _setup_lights(p_light_cull_result, p_light_cull_count, p_cam_transform.affine_inverse(), p_shadow_atlas, using_shadows); + _setup_decals(p_decal_cull_result, p_decal_cull_count, p_cam_transform.affine_inverse()); _setup_reflections(p_reflection_probe_cull_result, p_reflection_probe_cull_count, p_cam_transform.affine_inverse(), p_environment); _setup_gi_probes(p_gi_probe_cull_result, p_gi_probe_cull_count, p_cam_transform); _setup_environment(p_environment, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_pixel_size, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), false); @@ -1828,23 +2276,7 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor clear_color.b *= bg_energy; } break; case RS::ENV_BG_SKY: { - RID sky = environment_get_sky(p_environment); - if (sky.is_valid()) { - - RENDER_TIMESTAMP("Setup Sky"); - CameraMatrix projection = p_cam_projection; - if (p_reflection_probe.is_valid()) { - CameraMatrix correction; - correction.set_depth_correction(true); - projection = correction * p_cam_projection; - } - - _setup_sky(p_environment, p_cam_transform.origin, screen_size); - _update_sky(p_environment, projection, p_cam_transform); - radiance_uniform_set = sky_get_radiance_uniform_set_rd(sky, default_shader_rd, RADIANCE_UNIFORM_SET); - - draw_sky = true; - } + draw_sky = true; } break; case RS::ENV_BG_CANVAS: { keep_color = true; @@ -1858,6 +2290,27 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor default: { } } + // setup sky if used for ambient, reflections, or background + if (draw_sky || environment_get_reflection_source(p_environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(p_environment) == RS::ENV_AMBIENT_SOURCE_SKY) { + RID sky = environment_get_sky(p_environment); + if (sky.is_valid()) { + + RENDER_TIMESTAMP("Setup Sky"); + CameraMatrix projection = p_cam_projection; + if (p_reflection_probe.is_valid()) { + CameraMatrix correction; + correction.set_depth_correction(true); + projection = correction * p_cam_projection; + } + + _setup_sky(p_environment, p_cam_transform.origin, screen_size); + _update_sky(p_environment, projection, p_cam_transform); + radiance_uniform_set = sky_get_radiance_uniform_set_rd(sky, default_shader_rd, RADIANCE_UNIFORM_SET); + } else { + // do not try to draw sky if invalid + draw_sky = false; + } + } } else { clear_color = p_default_bg_color; @@ -1879,9 +2332,23 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor if (depth_pre_pass) { //depth pre pass RENDER_TIMESTAMP("Render Depth Pre-Pass"); - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(depth_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, using_ssao ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, depth_pass_clear); + bool finish_depth = using_ssao; + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(depth_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, finish_depth ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, depth_pass_clear); _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(depth_framebuffer), render_list.elements, render_list.element_count, false, depth_pass_mode, render_buffer == nullptr, radiance_uniform_set, RID()); RD::get_singleton()->draw_list_end(); + + if (render_buffer && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) { + if (finish_depth) { + RD::get_singleton()->texture_resolve_multisample(render_buffer->depth_msaa, render_buffer->depth, true); + } + + if (depth_pass_mode == PASS_MODE_DEPTH_NORMAL || depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS) { + RD::get_singleton()->texture_resolve_multisample(render_buffer->normal_buffer_msaa, render_buffer->normal_buffer, true); + if (depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS) { + RD::get_singleton()->texture_resolve_multisample(render_buffer->roughness_buffer_msaa, render_buffer->roughness_buffer, true); + } + } + } } if (using_ssao) { @@ -1961,6 +2428,19 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor _draw_sky(can_continue_color, can_continue_depth, opaque_framebuffer, p_environment, projection, p_cam_transform); } + if (render_buffer && !can_continue_color && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) { + + RD::get_singleton()->texture_resolve_multisample(render_buffer->color_msaa, render_buffer->color, true); + if (using_separate_specular) { + RD::get_singleton()->texture_resolve_multisample(render_buffer->specular_msaa, render_buffer->specular, true); + } + } + + if (render_buffer && !can_continue_depth && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) { + + RD::get_singleton()->texture_resolve_multisample(render_buffer->depth_msaa, render_buffer->depth, true); + } + if (using_separate_specular) { if (using_sss) { @@ -1970,11 +2450,11 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor if (using_ssr) { RENDER_TIMESTAMP("Screen Space Reflection"); - _process_ssr(p_render_buffer, render_buffer->color_fb, render_buffer->normal_buffer, render_buffer->roughness_buffer, render_buffer->specular, render_buffer->specular, Color(0, 0, 0, 1), p_environment, p_cam_projection, true); + _process_ssr(p_render_buffer, render_buffer->color_fb, render_buffer->normal_buffer, render_buffer->roughness_buffer, render_buffer->specular, render_buffer->specular, Color(0, 0, 0, 1), p_environment, p_cam_projection, render_buffer->msaa == RS::VIEWPORT_MSAA_DISABLED); } else { //just mix specular back RENDER_TIMESTAMP("Merge Specular"); - storage->get_effects()->merge_specular(render_buffer->color_fb, render_buffer->specular, RID(), RID()); + storage->get_effects()->merge_specular(render_buffer->color_fb, render_buffer->specular, render_buffer->msaa == RS::VIEWPORT_MSAA_DISABLED ? RID() : render_buffer->color, RID()); } } @@ -1992,78 +2472,13 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor RD::get_singleton()->draw_list_end(); } - //_render_list -#if 0 - if (state.directional_light_count == 0) { - directional_light = nullptr; - _render_list(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, p_cam_transform, p_cam_projection, env_radiance_tex, false, true, false, false, shadow_atlas != nullptr); - } else { - for (int i = 0; i < state.directional_light_count; i++) { - directional_light = directional_lights[i]; - _setup_directional_light(i, p_cam_transform.affine_inverse(), shadow_atlas != nullptr && shadow_atlas->size > 0); - _render_list(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, p_cam_transform, p_cam_projection, env_radiance_tex, false, true, false, i > 0, shadow_atlas != nullptr); - } - } -#endif - -#if 0 - _post_process(env, p_cam_projection); - // Needed only for debugging - /* if (shadow_atlas && storage->frame.current_rt) { - - //_copy_texture_to_front_buffer(shadow_atlas->depth); - storage->canvas->canvas_begin(); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, shadow_atlas->depth); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE); - storage->canvas->draw_generic_textured_rect(Rect2(0, 0, storage->frame.current_rt->width / 2, storage->frame.current_rt->height / 2), Rect2(0, 0, 1, 1)); - } - - if (storage->frame.current_rt) { + if (render_buffer && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) { - //_copy_texture_to_front_buffer(shadow_atlas->depth); - storage->canvas->canvas_begin(); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, exposure_shrink[4].color); - //glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->exposure.color); - storage->canvas->draw_generic_textured_rect(Rect2(0, 0, storage->frame.current_rt->width / 16, storage->frame.current_rt->height / 16), Rect2(0, 0, 1, 1)); + RD::get_singleton()->texture_resolve_multisample(render_buffer->color_msaa, render_buffer->color, true); } - - if (reflection_atlas && storage->frame.current_rt) { - - //_copy_texture_to_front_buffer(shadow_atlas->depth); - storage->canvas->canvas_begin(); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, reflection_atlas->color); - storage->canvas->draw_generic_textured_rect(Rect2(0, 0, storage->frame.current_rt->width / 2, storage->frame.current_rt->height / 2), Rect2(0, 0, 1, 1)); - } - - if (directional_shadow.fbo) { - - //_copy_texture_to_front_buffer(shadow_atlas->depth); - storage->canvas->canvas_begin(); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, directional_shadow.depth); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE); - storage->canvas->draw_generic_textured_rect(Rect2(0, 0, storage->frame.current_rt->width / 2, storage->frame.current_rt->height / 2), Rect2(0, 0, 1, 1)); - } - - if ( env_radiance_tex) { - - //_copy_texture_to_front_buffer(shadow_atlas->depth); - storage->canvas->canvas_begin(); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, env_radiance_tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - storage->canvas->draw_generic_textured_rect(Rect2(0, 0, storage->frame.current_rt->width / 2, storage->frame.current_rt->height / 2), Rect2(0, 0, 1, 1)); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - }*/ - //disable all stuff -#endif } -void RasterizerSceneHighEndRD::_render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip) { + +void RasterizerSceneHighEndRD::_render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake) { RENDER_TIMESTAMP("Setup Rendering Shadow"); @@ -2071,11 +2486,9 @@ void RasterizerSceneHighEndRD::_render_shadow(RID p_framebuffer, InstanceBase ** render_pass++; - scene_state.ubo.shadow_z_offset = p_bias; - scene_state.ubo.shadow_z_slope_scale = p_normal_bias; scene_state.ubo.dual_paraboloid_side = p_use_dp_flip ? -1 : 1; - _setup_environment(RID(), p_projection, p_transform, RID(), true, Vector2(1, 1), RID(), true, Color(), 0, p_zfar); + _setup_environment(RID(), p_projection, p_transform, RID(), true, Vector2(1, 1), RID(), true, Color(), 0, p_zfar, false, p_use_pancake); render_list.clear(); @@ -2106,8 +2519,6 @@ void RasterizerSceneHighEndRD::_render_material(const Transform &p_cam_transform render_pass++; - scene_state.ubo.shadow_z_offset = 0; - scene_state.ubo.shadow_z_slope_scale = 0; scene_state.ubo.dual_paraboloid_side = 0; _setup_environment(RID(), p_cam_projection, p_cam_transform, RID(), true, Vector2(1, 1), RID(), false, Color(), 0, 0); @@ -2204,7 +2615,7 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { { RD::Uniform u; u.binding = 5; - u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(scene_state.light_buffer); uniforms.push_back(u); } @@ -2267,17 +2678,40 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { uniforms.push_back(u); } - { RD::Uniform u; u.binding = 10; u.type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.push_back(cluster_builder.get_cluster_texture()); + RID decal_atlas = storage->decal_atlas_get_texture(); + u.ids.push_back(decal_atlas); uniforms.push_back(u); } { RD::Uniform u; u.binding = 11; + u.type = RD::UNIFORM_TYPE_TEXTURE; + RID decal_atlas = storage->decal_atlas_get_texture_srgb(); + u.ids.push_back(decal_atlas); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 12; + u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.ids.push_back(scene_state.decal_buffer); + uniforms.push_back(u); + } + + { + RD::Uniform u; + u.binding = 13; + u.type = RD::UNIFORM_TYPE_TEXTURE; + u.ids.push_back(cluster_builder.get_cluster_texture()); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 14; u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(cluster_builder.get_cluster_indices_buffer()); uniforms.push_back(u); @@ -2285,7 +2719,7 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { { RD::Uniform u; - u.binding = 12; + u.binding = 15; u.type = RD::UNIFORM_TYPE_TEXTURE; if (directional_shadow_get_texture().is_valid()) { u.ids.push_back(directional_shadow_get_texture()); @@ -2295,6 +2729,14 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { uniforms.push_back(u); } + { + RD::Uniform u; + u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.binding = 16; + u.ids.push_back(storage->global_variables_get_storage_buffer()); + uniforms.push_back(u); + } + render_base_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, SCENE_UNIFORM_SET); } } @@ -2463,11 +2905,11 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag } { //lights - scene_state.max_lights = MIN(65536, uniform_max_size) / sizeof(LightData); + scene_state.max_lights = MIN(1024 * 1024, uniform_max_size) / sizeof(LightData); //1mb of lights uint32_t light_buffer_size = scene_state.max_lights * sizeof(LightData); scene_state.lights = memnew_arr(LightData, scene_state.max_lights); - scene_state.light_buffer = RD::get_singleton()->uniform_buffer_create(light_buffer_size); - defines += "\n#define MAX_LIGHT_DATA_STRUCTS " + itos(scene_state.max_lights) + "\n"; + scene_state.light_buffer = RD::get_singleton()->storage_buffer_create(light_buffer_size); + //defines += "\n#define MAX_LIGHT_DATA_STRUCTS " + itos(scene_state.max_lights) + "\n"; scene_state.max_directional_lights = 8; uint32_t directional_light_buffer_size = scene_state.max_directional_lights * sizeof(DirectionalLightData); @@ -2506,6 +2948,13 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag defines += "\n#define MAX_GI_PROBES " + itos(scene_state.max_gi_probes) + "\n"; } + { //decals + scene_state.max_decals = MIN(1024 * 1024, uniform_max_size) / sizeof(DecalData); //1mb of decals + uint32_t decal_buffer_size = scene_state.max_decals * sizeof(DecalData); + scene_state.decals = memnew_arr(DecalData, scene_state.max_decals); + scene_state.decal_buffer = RD::get_singleton()->storage_buffer_create(decal_buffer_size); + } + Vector<String> shader_versions; shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n"); shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_DUAL_PARABOLOID\n"); @@ -2569,7 +3018,11 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag actions.renames["ANISOTROPY"] = "anisotropy"; actions.renames["ANISOTROPY_FLOW"] = "anisotropy_flow"; actions.renames["SSS_STRENGTH"] = "sss_strength"; - actions.renames["TRANSMISSION"] = "transmission"; + actions.renames["SSS_TRANSMITTANCE_COLOR"] = "transmittance_color"; + actions.renames["SSS_TRANSMITTANCE_DEPTH"] = "transmittance_depth"; + actions.renames["SSS_TRANSMITTANCE_CURVE"] = "transmittance_curve"; + actions.renames["SSS_TRANSMITTANCE_BOOST"] = "transmittance_boost"; + actions.renames["BACKLIGHT"] = "backlight"; actions.renames["AO"] = "ao"; actions.renames["AO_LIGHT_AFFECT"] = "ao_light_affect"; actions.renames["EMISSION"] = "emission"; @@ -2609,7 +3062,8 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag actions.usage_defines["POSITION"] = "#define OVERRIDE_POSITION\n"; actions.usage_defines["SSS_STRENGTH"] = "#define ENABLE_SSS\n"; - actions.usage_defines["TRANSMISSION"] = "#define LIGHT_TRANSMISSION_USED\n"; + actions.usage_defines["SSS_TRANSMITTANCE_DEPTH"] = "#define ENABLE_TRANSMITTANCE\n"; + actions.usage_defines["BACKLIGHT"] = "#define LIGHT_BACKLIGHT_USED\n"; actions.usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n"; actions.usage_defines["SCREEN_UV"] = "#define SCREEN_UV_USED\n"; @@ -2659,6 +3113,8 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP; actions.default_repeat = ShaderLanguage::REPEAT_ENABLE; + actions.global_buffer_array_variable = "global_variables.data"; + actions.instance_uniform_index_variable = "instances.data[instance_index].instance_uniforms_ofs"; shader.compiler.initialize(actions); } @@ -2780,10 +3236,12 @@ RasterizerSceneHighEndRD::~RasterizerSceneHighEndRD() { RD::get_singleton()->free(scene_state.directional_light_buffer); RD::get_singleton()->free(scene_state.light_buffer); RD::get_singleton()->free(scene_state.reflection_buffer); + RD::get_singleton()->free(scene_state.decal_buffer); memdelete_arr(scene_state.instances); memdelete_arr(scene_state.gi_probes); memdelete_arr(scene_state.directional_lights); memdelete_arr(scene_state.lights); memdelete_arr(scene_state.reflections); + memdelete_arr(scene_state.decals); } } diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h index e79bf2b378..a48e2e2259 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h @@ -138,6 +138,7 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { bool unshaded; bool uses_vertex; bool uses_sss; + bool uses_transmittance; bool uses_screen_texture; bool uses_depth_texture; bool uses_normal_texture; @@ -151,6 +152,8 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { virtual void set_code(const String &p_Code); virtual void set_default_texture_param(const StringName &p_name, RID p_texture); virtual void get_param_list(List<PropertyInfo> *p_param_list) const; + void get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const; + virtual bool is_param_texture(const StringName &p_param) const; virtual bool is_animated() const; virtual bool casts_shadows() const; @@ -197,11 +200,22 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { struct RenderBufferDataHighEnd : public RenderBufferData { //for rendering, may be MSAAd + RID color; RID depth; RID specular; RID normal_buffer; RID roughness_buffer; + + RS::ViewportMSAA msaa; + RD::TextureSamples texture_samples; + + RID color_msaa; + RID depth_msaa; + RID specular_msaa; + RID normal_buffer_msaa; + RID roughness_buffer_msaa; + RID depth_fb; RID depth_normal_fb; RID depth_normal_roughness_fb; @@ -253,13 +267,21 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { float position[3]; float inv_radius; float direction[3]; + float size; uint16_t attenuation_energy[2]; //16 bits attenuation, then energy uint8_t color_specular[4]; //rgb color, a specular (8 bit unorm) uint16_t cone_attenuation_angle[2]; // attenuation and angle, (16bit float) - uint32_t mask; uint8_t shadow_color_enabled[4]; //shadow rgb color, a>0.5 enabled (8bit unorm) float atlas_rect[4]; // in omni, used for atlas uv, in spot, used for projector uv float shadow_matrix[16]; + float shadow_bias; + float shadow_normal_bias; + float transmittance_bias; + float soft_shadow_size; + float soft_shadow_scale; + uint32_t mask; + uint32_t pad[2]; + float projector_rect[4]; }; struct DirectionalLightData { @@ -267,15 +289,30 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { float direction[3]; float energy; float color[3]; + float size; float specular; - float shadow_color[3]; uint32_t mask; + float softshadow_angle; + float soft_shadow_scale; uint32_t blend_splits; uint32_t shadow_enabled; float fade_from; float fade_to; + float shadow_bias[4]; + float shadow_normal_bias[4]; + float shadow_transmittance_bias[4]; + float shadow_transmittance_z_scale[4]; + float shadow_range_begin[4]; float shadow_split_offsets[4]; float shadow_matrices[4][16]; + float shadow_color1[4]; + float shadow_color2[4]; + float shadow_color3[4]; + float shadow_color4[4]; + float uv_scale1[2]; + float uv_scale2[2]; + float uv_scale3[2]; + float uv_scale4[2]; }; struct GIProbeData { @@ -294,6 +331,24 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { uint32_t pad[1]; }; + struct DecalData { + float xform[16]; + float inv_extents[3]; + float albedo_mix; + float albedo_rect[4]; + float normal_rect[4]; + float orm_rect[4]; + float emission_rect[4]; + float modulate[4]; + float emission_energy; + uint32_t mask; + float upper_fade; + float lower_fade; + float normal_xform[12]; + float normal[3]; + float normal_fade; + }; + enum { INSTANCE_DATA_FLAG_MULTIMESH = 1 << 12, INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D = 1 << 13, @@ -308,7 +363,7 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { float transform[16]; float normal_transform[16]; uint32_t flags; - uint32_t instance_ofs; //instance_offset in instancing/skeleton buffer + uint32_t instance_uniforms_ofs; //instance_offset in instancing/skeleton buffer uint32_t gi_offset; //GI information when using lightmapping (VCT or lightmap) uint32_t mask; }; @@ -324,12 +379,22 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { float viewport_size[2]; float screen_pixel_size[2]; - float shadow_z_offset; - float shadow_z_slope_scale; - float time; float reflection_multiplier; + uint32_t pancake_shadows; + uint32_t pad; + + float directional_penumbra_shadow_kernel[128]; //32 vec4s + float directional_soft_shadow_kernel[128]; + float penumbra_shadow_kernel[128]; + float soft_shadow_kernel[128]; + + uint32_t directional_penumbra_shadow_samples; + uint32_t directional_soft_shadow_samples; + uint32_t penumbra_shadow_samples; + uint32_t soft_shadow_samples; + float ambient_light_color_energy[4]; float ambient_color_sky_mix; @@ -369,6 +434,10 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { RID gi_probe_buffer; uint32_t max_gi_probe_probes_per_instance; + DecalData *decals; + uint32_t max_decals; + RID decal_buffer; + LightData *lights; uint32_t max_lights; RID light_buffer; @@ -558,8 +627,9 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { PASS_MODE_DEPTH_MATERIAL, }; - void _setup_environment(RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers = false); + void _setup_environment(RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers = false, bool p_pancake_shadows = false); void _setup_lights(RID *p_light_cull_result, int p_light_cull_count, const Transform &p_camera_inverse_transform, RID p_shadow_atlas, bool p_using_shadows); + void _setup_decals(const RID *p_decal_instances, int p_decal_count, const Transform &p_camera_inverse_xform); void _setup_reflections(RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, const Transform &p_camera_inverse_transform, RID p_environment); void _setup_gi_probes(RID *p_gi_probe_probe_cull_result, int p_gi_probe_probe_cull_count, const Transform &p_camera_transform); @@ -571,8 +641,8 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { void _fill_render_list(InstanceBase **p_cull_result, int p_cull_count, PassMode p_pass_mode, bool p_no_gi); protected: - virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color); - virtual void _render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip); + virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color); + virtual void _render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake); virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region); public: diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp index e4c5f1c984..8877de87ac 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp @@ -36,6 +36,18 @@ uint64_t RasterizerSceneRD::auto_exposure_counter = 2; +void get_vogel_disk(float *r_kernel, int p_sample_count) { + const float golden_angle = 2.4; + + for (int i = 0; i < p_sample_count; i++) { + float r = Math::sqrt(float(i) + 0.5) / Math::sqrt(float(p_sample_count)); + float theta = float(i) * golden_angle; + + r_kernel[i * 4] = Math::cos(theta) * r; + r_kernel[i * 4 + 1] = Math::sin(theta) * r; + } +} + void RasterizerSceneRD::_clear_reflection_data(ReflectionData &rd) { rd.layers.clear(); @@ -181,10 +193,9 @@ void RasterizerSceneRD::_update_reflection_mipmaps(ReflectionData &rd) { for (int j = 0; j < rd.layers[i].mipmaps.size() - 1; j++) { for (int k = 0; k < 6; k++) { RID view = rd.layers[i].mipmaps[j].views[k]; - RID fb = rd.layers[i].mipmaps[j + 1].framebuffers[k]; - Vector2 size = rd.layers[i].mipmaps[j].size; - size = Vector2(1.0 / size.x, 1.0 / size.y); - storage->get_effects()->make_mipmap(view, fb, size); + RID texture = rd.layers[i].mipmaps[j + 1].views[k]; + Size2i size = rd.layers[i].mipmaps[j + 1].size; + storage->get_effects()->make_mipmap(view, texture, size); } } } @@ -644,7 +655,8 @@ void RasterizerSceneRD::_setup_sky(RID p_environment, const Vector3 &p_position, sky_scene_state.directional_lights[i].color[0] != sky_scene_state.last_frame_directional_lights[i].color[0] || sky_scene_state.directional_lights[i].color[1] != sky_scene_state.last_frame_directional_lights[i].color[1] || sky_scene_state.directional_lights[i].color[2] != sky_scene_state.last_frame_directional_lights[i].color[2] || - sky_scene_state.directional_lights[i].enabled != sky_scene_state.last_frame_directional_lights[i].enabled) { + sky_scene_state.directional_lights[i].enabled != sky_scene_state.last_frame_directional_lights[i].enabled || + sky_scene_state.directional_lights[i].size != sky_scene_state.last_frame_directional_lights[i].size) { light_data_dirty = true; break; } @@ -840,18 +852,22 @@ void RasterizerSceneRD::SkyShaderData::set_code(const String &p_code) { actions.usage_flag_pointers["LIGHT0_ENERGY"] = &uses_light; actions.usage_flag_pointers["LIGHT0_DIRECTION"] = &uses_light; actions.usage_flag_pointers["LIGHT0_COLOR"] = &uses_light; + actions.usage_flag_pointers["LIGHT0_SIZE"] = &uses_light; actions.usage_flag_pointers["LIGHT1_ENABLED"] = &uses_light; actions.usage_flag_pointers["LIGHT1_ENERGY"] = &uses_light; actions.usage_flag_pointers["LIGHT1_DIRECTION"] = &uses_light; actions.usage_flag_pointers["LIGHT1_COLOR"] = &uses_light; + actions.usage_flag_pointers["LIGHT1_SIZE"] = &uses_light; actions.usage_flag_pointers["LIGHT2_ENABLED"] = &uses_light; actions.usage_flag_pointers["LIGHT2_ENERGY"] = &uses_light; actions.usage_flag_pointers["LIGHT2_DIRECTION"] = &uses_light; actions.usage_flag_pointers["LIGHT2_COLOR"] = &uses_light; + actions.usage_flag_pointers["LIGHT2_SIZE"] = &uses_light; actions.usage_flag_pointers["LIGHT3_ENABLED"] = &uses_light; actions.usage_flag_pointers["LIGHT3_ENERGY"] = &uses_light; actions.usage_flag_pointers["LIGHT3_DIRECTION"] = &uses_light; actions.usage_flag_pointers["LIGHT3_COLOR"] = &uses_light; + actions.usage_flag_pointers["LIGHT3_SIZE"] = &uses_light; actions.uniforms = &uniforms; @@ -915,6 +931,10 @@ void RasterizerSceneRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_para for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { + if (E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { + continue; + } + if (E->get().texture_order >= 0) { order[E->get().texture_order + 100000] = E->key(); } else { @@ -930,6 +950,23 @@ void RasterizerSceneRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_para } } +void RasterizerSceneRD::SkyShaderData::get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const { + + for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { + + if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { + continue; + } + + RasterizerStorage::InstanceShaderParam p; + p.info = ShaderLanguage::uniform_to_property_info(E->get()); + p.info.name = E->key(); //supply name + p.index = E->get().instance_index; + p.default_value = ShaderLanguage::constant_value_to_variant(E->get().default_value, E->get().type, E->get().hint); + p_param_list->push_back(p); + } +} + bool RasterizerSceneRD::SkyShaderData::is_param_texture(const StringName &p_param) const { if (!uniforms.has(p_param)) { return false; @@ -1168,12 +1205,12 @@ Color RasterizerSceneRD::environment_get_ambient_light_color(RID p_env) const { ERR_FAIL_COND_V(!env, Color()); return env->ambient_light; } -RS::EnvironmentAmbientSource RasterizerSceneRD::environment_get_ambient_light_ambient_source(RID p_env) const { +RS::EnvironmentAmbientSource RasterizerSceneRD::environment_get_ambient_source(RID p_env) const { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, RS::ENV_AMBIENT_SOURCE_BG); return env->ambient_source; } -float RasterizerSceneRD::environment_get_ambient_light_ambient_energy(RID p_env) const { +float RasterizerSceneRD::environment_get_ambient_light_energy(RID p_env) const { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, 0); return env->ambient_light_energy; @@ -1599,7 +1636,6 @@ void RasterizerSceneRD::shadow_atlas_set_size(RID p_atlas, int p_size) { if (shadow_atlas->depth.is_valid()) { RD::get_singleton()->free(shadow_atlas->depth); shadow_atlas->depth = RID(); - shadow_atlas->fb = RID(); } for (int i = 0; i < 4; i++) { //clear subdivisions @@ -1625,13 +1661,9 @@ void RasterizerSceneRD::shadow_atlas_set_size(RID p_atlas, int p_size) { tf.format = RD::DATA_FORMAT_R32_SFLOAT; tf.width = shadow_atlas->size; tf.height = shadow_atlas->size; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; shadow_atlas->depth = RD::get_singleton()->texture_create(tf, RD::TextureView()); - - Vector<RID> fb; - fb.push_back(shadow_atlas->depth); - shadow_atlas->fb = RD::get_singleton()->framebuffer_create(fb); } } @@ -1901,7 +1933,6 @@ void RasterizerSceneRD::directional_shadow_atlas_set_size(int p_size) { if (directional_shadow.depth.is_valid()) { RD::get_singleton()->free(directional_shadow.depth); directional_shadow.depth = RID(); - directional_shadow.fb = RID(); } if (p_size > 0) { @@ -1910,12 +1941,9 @@ void RasterizerSceneRD::directional_shadow_atlas_set_size(int p_size) { tf.format = RD::DATA_FORMAT_R32_SFLOAT; tf.width = p_size; tf.height = p_size; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; directional_shadow.depth = RD::get_singleton()->texture_create(tf, RD::TextureView()); - Vector<RID> fb; - fb.push_back(directional_shadow.depth); - directional_shadow.fb = RD::get_singleton()->framebuffer_create(fb); } _base_uniforms_changed(); @@ -2032,7 +2060,7 @@ void RasterizerSceneRD::light_instance_set_transform(RID p_light_instance, const light_instance->transform = p_transform; } -void RasterizerSceneRD::light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale) { +void RasterizerSceneRD::light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) { LightInstance *light_instance = light_instance_owner.getornull(p_light_instance); ERR_FAIL_COND(!light_instance); @@ -2048,6 +2076,9 @@ void RasterizerSceneRD::light_instance_set_shadow_transform(RID p_light_instance light_instance->shadow_transform[p_pass].farplane = p_far; light_instance->shadow_transform[p_pass].split = p_split; light_instance->shadow_transform[p_pass].bias_scale = p_bias_scale; + light_instance->shadow_transform[p_pass].range_begin = p_range_begin; + light_instance->shadow_transform[p_pass].shadow_texel_size = p_shadow_texel_size; + light_instance->shadow_transform[p_pass].uv_scale = p_uv_scale; } void RasterizerSceneRD::light_instance_mark_visible(RID p_light_instance) { @@ -2111,6 +2142,21 @@ RasterizerSceneRD::ShadowMap *RasterizerSceneRD::_get_shadow_map(const Size2i &p return &shadow_maps[p_size]; } + +////////////////////////// + +RID RasterizerSceneRD::decal_instance_create(RID p_decal) { + DecalInstance di; + di.decal = p_decal; + return decal_instance_owner.make_rid(di); +} + +void RasterizerSceneRD::decal_instance_set_transform(RID p_decal, const Transform &p_transform) { + DecalInstance *di = decal_instance_owner.getornull(p_decal); + ERR_FAIL_COND(!di); + di->transform = p_transform; +} + ///////////////////////////////// RID RasterizerSceneRD::gi_probe_instance_create(RID p_base) { @@ -3059,7 +3105,7 @@ void RasterizerSceneRD::_allocate_blur_textures(RenderBuffers *rb) { tf.width = rb->width; tf.height = rb->height; tf.type = RD::TEXTURE_TYPE_2D; - tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; + tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; tf.mipmaps = mipmaps_required; rb->blur[0].texture = RD::get_singleton()->texture_create(tf, RD::TextureView()); @@ -3076,11 +3122,6 @@ void RasterizerSceneRD::_allocate_blur_textures(RenderBuffers *rb) { RenderBuffers::Blur::Mipmap mm; mm.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->blur[0].texture, 0, i); - { - Vector<RID> fbs; - fbs.push_back(mm.texture); - mm.framebuffer = RD::get_singleton()->framebuffer_create(fbs); - } mm.width = base_width; mm.height = base_height; @@ -3090,11 +3131,6 @@ void RasterizerSceneRD::_allocate_blur_textures(RenderBuffers *rb) { if (i > 0) { mm.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->blur[1].texture, 0, i - 1); - { - Vector<RID> fbs; - fbs.push_back(mm.texture); - mm.framebuffer = RD::get_singleton()->framebuffer_create(fbs); - } rb->blur[1].mipmaps.push_back(mm); } @@ -3421,9 +3457,9 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu if (env->auto_exposure && rb->luminance.current.is_valid()) { luminance_texture = rb->luminance.current; } - storage->get_effects()->gaussian_glow(rb->texture, rb->blur[0].mipmaps[i + 1].framebuffer, rb->blur[0].mipmaps[i + 1].texture, rb->blur[1].mipmaps[i].framebuffer, Vector2(1.0 / vp_w, 1.0 / vp_h), env->glow_strength, true, env->glow_hdr_luminance_cap, env->exposure, env->glow_bloom, env->glow_hdr_bleed_threshold, env->glow_hdr_bleed_scale, luminance_texture, env->auto_exp_scale); + storage->get_effects()->gaussian_glow(rb->texture, rb->blur[0].mipmaps[i + 1].texture, rb->blur[1].mipmaps[i].texture, Size2i(vp_w, vp_h), env->glow_strength, true, env->glow_hdr_luminance_cap, env->exposure, env->glow_bloom, env->glow_hdr_bleed_threshold, env->glow_hdr_bleed_scale, luminance_texture, env->auto_exp_scale); } else { - storage->get_effects()->gaussian_glow(rb->blur[1].mipmaps[i - 1].texture, rb->blur[0].mipmaps[i + 1].framebuffer, rb->blur[0].mipmaps[i + 1].texture, rb->blur[1].mipmaps[i].framebuffer, Vector2(1.0 / vp_w, 1.0 / vp_h), env->glow_strength); + storage->get_effects()->gaussian_glow(rb->blur[1].mipmaps[i - 1].texture, rb->blur[0].mipmaps[i + 1].texture, rb->blur[1].mipmaps[i].texture, Size2i(vp_w, vp_h), env->glow_strength); } } } @@ -3456,6 +3492,12 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu tonemap.glow_texture = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_BLACK); } + if (rb->screen_space_aa == RS::VIEWPORT_SCREEN_SPACE_AA_FXAA) { + tonemap.use_fxaa = true; + } + + tonemap.texture_size = Vector2i(rb->width, rb->height); + if (env) { tonemap.tonemap_mode = env->tone_mapper; tonemap.white = env->white; @@ -3479,7 +3521,7 @@ void RasterizerSceneRD::_render_buffers_debug_draw(RID p_render_buffers, RID p_s RID shadow_atlas_texture = shadow_atlas_get_texture(p_shadow_atlas); Size2 rtsize = storage->render_target_get_size(rb->render_target); - effects->copy_to_rect(shadow_atlas_texture, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize / 2), false, true); + effects->copy_to_fb_rect(shadow_atlas_texture, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize / 2), false, true); } } @@ -3488,7 +3530,17 @@ void RasterizerSceneRD::_render_buffers_debug_draw(RID p_render_buffers, RID p_s RID shadow_atlas_texture = directional_shadow_get_texture(); Size2 rtsize = storage->render_target_get_size(rb->render_target); - effects->copy_to_rect(shadow_atlas_texture, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize / 2), false, true); + effects->copy_to_fb_rect(shadow_atlas_texture, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize / 2), false, true); + } + } + + if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_DECAL_ATLAS) { + RID decal_atlas = storage->decal_atlas_get_texture(); + + if (decal_atlas.is_valid()) { + Size2 rtsize = storage->render_target_get_size(rb->render_target); + + effects->copy_to_fb_rect(decal_atlas, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize / 2), false, false, true); } } @@ -3496,24 +3548,24 @@ void RasterizerSceneRD::_render_buffers_debug_draw(RID p_render_buffers, RID p_s if (rb->luminance.current.is_valid()) { Size2 rtsize = storage->render_target_get_size(rb->render_target); - effects->copy_to_rect(rb->luminance.current, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize / 8), false, true); + effects->copy_to_fb_rect(rb->luminance.current, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize / 8), false, true); } } if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SSAO && rb->ssao.ao[0].is_valid()) { Size2 rtsize = storage->render_target_get_size(rb->render_target); RID ao_buf = rb->ssao.ao_full.is_valid() ? rb->ssao.ao_full : rb->ssao.ao[0]; - effects->copy_to_rect(ao_buf, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, true); + effects->copy_to_fb_rect(ao_buf, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, true); } if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_ROUGHNESS_LIMITER && _render_buffers_get_roughness_texture(p_render_buffers).is_valid()) { Size2 rtsize = storage->render_target_get_size(rb->render_target); - effects->copy_to_rect(_render_buffers_get_roughness_texture(p_render_buffers), storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, true); + effects->copy_to_fb_rect(_render_buffers_get_roughness_texture(p_render_buffers), storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, true); } if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER && _render_buffers_get_normal_texture(p_render_buffers).is_valid()) { Size2 rtsize = storage->render_target_get_size(rb->render_target); - effects->copy_to_rect(_render_buffers_get_normal_texture(p_render_buffers), storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize)); + effects->copy_to_fb_rect(_render_buffers_get_normal_texture(p_render_buffers), storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false); } } @@ -3534,13 +3586,14 @@ RID RasterizerSceneRD::render_buffers_get_ao_texture(RID p_render_buffers) { return rb->ssao.ao_full.is_valid() ? rb->ssao.ao_full : rb->ssao.ao[0]; } -void RasterizerSceneRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa) { +void RasterizerSceneRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); rb->width = p_width; rb->height = p_height; rb->render_target = p_render_target; rb->msaa = p_msaa; + rb->screen_space_aa = p_screen_space_aa; _free_render_buffer_data(rb); { @@ -3548,7 +3601,12 @@ void RasterizerSceneRD::render_buffers_configure(RID p_render_buffers, RID p_ren tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; tf.width = rb->width; tf.height = rb->height; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; + if (rb->msaa != RS::VIEWPORT_MSAA_DISABLED) { + tf.usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; + } else { + tf.usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; + } rb->texture = RD::get_singleton()->texture_create(tf, RD::TextureView()); } @@ -3559,6 +3617,9 @@ void RasterizerSceneRD::render_buffers_configure(RID p_render_buffers, RID p_ren tf.width = p_width; tf.height = p_height; tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + if (rb->msaa != RS::VIEWPORT_MSAA_DISABLED) { + tf.usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; + } rb->depth_texture = RD::get_singleton()->texture_create(tf, RD::TextureView()); } @@ -3580,6 +3641,88 @@ void RasterizerSceneRD::sub_surface_scattering_set_scale(float p_scale, float p_ sss_depth_scale = p_depth_scale; } +void RasterizerSceneRD::shadows_quality_set(RS::ShadowQuality p_quality) { + + ERR_FAIL_INDEX_MSG(p_quality, RS::SHADOW_QUALITY_MAX, "Shadow quality too high, please see RenderingServer's ShadowQuality enum"); + + if (shadows_quality != p_quality) { + shadows_quality = p_quality; + + switch (shadows_quality) { + case RS::SHADOW_QUALITY_HARD: { + penumbra_shadow_samples = 4; + soft_shadow_samples = 1; + shadows_quality_radius = 1.0; + } break; + case RS::SHADOW_QUALITY_SOFT_LOW: { + penumbra_shadow_samples = 8; + soft_shadow_samples = 4; + shadows_quality_radius = 2.0; + } break; + case RS::SHADOW_QUALITY_SOFT_MEDIUM: { + penumbra_shadow_samples = 12; + soft_shadow_samples = 8; + shadows_quality_radius = 2.0; + } break; + case RS::SHADOW_QUALITY_SOFT_HIGH: { + penumbra_shadow_samples = 24; + soft_shadow_samples = 16; + shadows_quality_radius = 3.0; + } break; + case RS::SHADOW_QUALITY_SOFT_ULTRA: { + penumbra_shadow_samples = 32; + soft_shadow_samples = 32; + shadows_quality_radius = 4.0; + } break; + case RS::SHADOW_QUALITY_MAX: + break; + } + get_vogel_disk(penumbra_shadow_kernel, penumbra_shadow_samples); + get_vogel_disk(soft_shadow_kernel, soft_shadow_samples); + } +} + +void RasterizerSceneRD::directional_shadow_quality_set(RS::ShadowQuality p_quality) { + + ERR_FAIL_INDEX_MSG(p_quality, RS::SHADOW_QUALITY_MAX, "Shadow quality too high, please see RenderingServer's ShadowQuality enum"); + + if (directional_shadow_quality != p_quality) { + directional_shadow_quality = p_quality; + + switch (directional_shadow_quality) { + case RS::SHADOW_QUALITY_HARD: { + directional_penumbra_shadow_samples = 4; + directional_soft_shadow_samples = 1; + directional_shadow_quality_radius = 1.0; + } break; + case RS::SHADOW_QUALITY_SOFT_LOW: { + directional_penumbra_shadow_samples = 8; + directional_soft_shadow_samples = 4; + directional_shadow_quality_radius = 2.0; + } break; + case RS::SHADOW_QUALITY_SOFT_MEDIUM: { + directional_penumbra_shadow_samples = 12; + directional_soft_shadow_samples = 8; + directional_shadow_quality_radius = 2.0; + } break; + case RS::SHADOW_QUALITY_SOFT_HIGH: { + directional_penumbra_shadow_samples = 24; + directional_soft_shadow_samples = 16; + directional_shadow_quality_radius = 3.0; + } break; + case RS::SHADOW_QUALITY_SOFT_ULTRA: { + directional_penumbra_shadow_samples = 32; + directional_soft_shadow_samples = 32; + directional_shadow_quality_radius = 4.0; + } break; + case RS::SHADOW_QUALITY_MAX: + break; + } + get_vogel_disk(directional_penumbra_shadow_kernel, directional_penumbra_shadow_samples); + get_vogel_disk(directional_soft_shadow_kernel, directional_soft_shadow_samples); + } +} + int RasterizerSceneRD::get_roughness_layers() const { return roughness_layers; } @@ -3594,7 +3737,7 @@ RasterizerSceneRD::RenderBufferData *RasterizerSceneRD::render_buffers_get_data( return rb->data; } -void RasterizerSceneRD::render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) { +void RasterizerSceneRD::render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) { Color clear_color; if (p_render_buffers.is_valid()) { @@ -3605,7 +3748,7 @@ void RasterizerSceneRD::render_scene(RID p_render_buffers, const Transform &p_ca clear_color = storage->get_default_clear_color(); } - _render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_ortogonal, p_cull_result, p_cull_count, p_light_cull_result, p_light_cull_count, p_reflection_probe_cull_result, p_reflection_probe_cull_count, p_gi_probe_cull_result, p_gi_probe_cull_count, p_environment, p_camera_effects, p_shadow_atlas, p_reflection_atlas, p_reflection_probe, p_reflection_probe_pass, clear_color); + _render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_ortogonal, p_cull_result, p_cull_count, p_light_cull_result, p_light_cull_count, p_reflection_probe_cull_result, p_reflection_probe_cull_count, p_gi_probe_cull_result, p_gi_probe_cull_count, p_decal_cull_result, p_decal_cull_count, p_environment, p_camera_effects, p_shadow_atlas, p_reflection_atlas, p_reflection_probe, p_reflection_probe_pass, clear_color); if (p_render_buffers.is_valid()) { RENDER_TIMESTAMP("Tonemap"); @@ -3621,16 +3764,19 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas ERR_FAIL_COND(!light_instance); Rect2i atlas_rect; - RID atlas_fb; + RID atlas_texture; bool using_dual_paraboloid = false; bool using_dual_paraboloid_flip = false; + float znear = 0; float zfar = 0; RID render_fb; RID render_texture; float bias = 0; float normal_bias = 0; + bool use_pancake = false; + bool use_linear_depth = false; bool render_cubemap = false; bool finalize_cubemap = false; @@ -3645,6 +3791,7 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas light_instance->last_scene_shadow_pass = scene_pass; } + use_pancake = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE) > 0; light_projection = light_instance->shadow_transform[p_pass].camera; light_transform = light_instance->shadow_transform[p_pass].transform; @@ -3683,7 +3830,7 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas light_instance->shadow_transform[p_pass].atlas_rect.position /= directional_shadow.size; light_instance->shadow_transform[p_pass].atlas_rect.size /= directional_shadow.size; - float bias_mult = Math::lerp(1.0f, light_instance->shadow_transform[p_pass].bias_scale, storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE)); + float bias_mult = light_instance->shadow_transform[p_pass].bias_scale; zfar = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_RANGE); bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_BIAS) * bias_mult; normal_bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * bias_mult; @@ -3691,7 +3838,7 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas ShadowMap *shadow_map = _get_shadow_map(atlas_rect.size); render_fb = shadow_map->fb; render_texture = shadow_map->depth; - atlas_fb = directional_shadow.fb; + atlas_texture = directional_shadow.depth; } else { //set from shadow atlas @@ -3718,7 +3865,7 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas atlas_rect.size.width = shadow_size; atlas_rect.size.height = shadow_size; - atlas_fb = shadow_atlas->fb; + atlas_texture = shadow_atlas->depth; zfar = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_RANGE); bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_BIAS); @@ -3762,26 +3909,33 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas ShadowMap *shadow_map = _get_shadow_map(atlas_rect.size); render_fb = shadow_map->fb; render_texture = shadow_map->depth; + + znear = light_instance->shadow_transform[0].camera.get_z_near(); + use_linear_depth = true; } } if (render_cubemap) { //rendering to cubemap - _render_shadow(render_fb, p_cull_result, p_cull_count, light_projection, light_transform, zfar, 0, 0, false, false); + _render_shadow(render_fb, p_cull_result, p_cull_count, light_projection, light_transform, zfar, 0, 0, false, false, use_pancake); if (finalize_cubemap) { //reblit atlas_rect.size.height /= 2; - storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect, light_projection.get_z_near(), light_projection.get_z_far(), bias, false); + storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_texture, atlas_rect, light_projection.get_z_near(), light_projection.get_z_far(), 0.0, false); atlas_rect.position.y += atlas_rect.size.height; - storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect, light_projection.get_z_near(), light_projection.get_z_far(), bias, true); + storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_texture, atlas_rect, light_projection.get_z_near(), light_projection.get_z_far(), 0.0, true); } } else { //render shadow - _render_shadow(render_fb, p_cull_result, p_cull_count, light_projection, light_transform, zfar, bias, normal_bias, using_dual_paraboloid, using_dual_paraboloid_flip); + _render_shadow(render_fb, p_cull_result, p_cull_count, light_projection, light_transform, zfar, bias, normal_bias, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake); //copy to atlas - storage->get_effects()->copy_to_rect(render_texture, atlas_fb, atlas_rect, true); + if (use_linear_depth) { + storage->get_effects()->copy_depth_to_rect_and_linearize(render_texture, atlas_texture, atlas_rect, true, znear, zfar); + } else { + storage->get_effects()->copy_depth_to_rect(render_texture, atlas_texture, atlas_rect, true); + } //does not work from depth to color //RD::get_singleton()->texture_copy(render_texture, atlas_texture, Vector3(0, 0, 0), Vector3(atlas_rect.position.x, atlas_rect.position.y, 0), Vector3(atlas_rect.size.x, atlas_rect.size.y, 1), 0, 0, 0, 0, true); @@ -3814,6 +3968,8 @@ bool RasterizerSceneRD::free(RID p_rid) { //ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_rid); reflection_probe_release_atlas_index(p_rid); reflection_probe_instance_owner.free(p_rid); + } else if (decal_instance_owner.owns(p_rid)) { + decal_instance_owner.free(p_rid); } else if (gi_probe_instance_owner.owns(p_rid)) { GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_rid); if (gi_probe->texture.is_valid()) { @@ -4057,21 +4213,25 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) { actions.renames["QUARTER_RES_COLOR"] = "quarter_res_color"; actions.renames["RADIANCE"] = "radiance"; actions.renames["LIGHT0_ENABLED"] = "directional_lights.data[0].enabled"; - actions.renames["LIGHT0_DIRECTION"] = "directional_lights.data[0].direction"; - actions.renames["LIGHT0_ENERGY"] = "directional_lights.data[0].energy"; - actions.renames["LIGHT0_COLOR"] = "directional_lights.data[0].color"; + actions.renames["LIGHT0_DIRECTION"] = "directional_lights.data[0].direction_energy.xyz"; + actions.renames["LIGHT0_ENERGY"] = "directional_lights.data[0].direction_energy.w"; + actions.renames["LIGHT0_COLOR"] = "directional_lights.data[0].color_size.xyz"; + actions.renames["LIGHT0_SIZE"] = "directional_lights.data[0].color_size.w"; actions.renames["LIGHT1_ENABLED"] = "directional_lights.data[1].enabled"; - actions.renames["LIGHT1_DIRECTION"] = "directional_lights.data[1].direction"; - actions.renames["LIGHT1_ENERGY"] = "directional_lights.data[1].energy"; - actions.renames["LIGHT1_COLOR"] = "directional_lights.data[1].color"; + actions.renames["LIGHT1_DIRECTION"] = "directional_lights.data[1].direction_energy.xyz"; + actions.renames["LIGHT1_ENERGY"] = "directional_lights.data[1].direction_energy.w"; + actions.renames["LIGHT1_COLOR"] = "directional_lights.data[1].color_size.xyz"; + actions.renames["LIGHT1_SIZE"] = "directional_lights.data[1].color_size.w"; actions.renames["LIGHT2_ENABLED"] = "directional_lights.data[2].enabled"; - actions.renames["LIGHT2_DIRECTION"] = "directional_lights.data[2].direction"; - actions.renames["LIGHT2_ENERGY"] = "directional_lights.data[2].energy"; - actions.renames["LIGHT2_COLOR"] = "directional_lights.data[2].color"; + actions.renames["LIGHT2_DIRECTION"] = "directional_lights.data[2].direction_energy.xyz"; + actions.renames["LIGHT2_ENERGY"] = "directional_lights.data[2].direction_energy.w"; + actions.renames["LIGHT2_COLOR"] = "directional_lights.data[2].color_size.xyz"; + actions.renames["LIGHT2_SIZE"] = "directional_lights.data[2].color_size.w"; actions.renames["LIGHT3_ENABLED"] = "directional_lights.data[3].enabled"; - actions.renames["LIGHT3_DIRECTION"] = "directional_lights.data[3].direction"; - actions.renames["LIGHT3_ENERGY"] = "directional_lights.data[3].energy"; - actions.renames["LIGHT3_COLOR"] = "directional_lights.data[3].color"; + actions.renames["LIGHT3_DIRECTION"] = "directional_lights.data[3].direction_energy.xyz"; + actions.renames["LIGHT3_ENERGY"] = "directional_lights.data[3].direction_energy.w"; + actions.renames["LIGHT3_COLOR"] = "directional_lights.data[3].color_size.xyz"; + actions.renames["LIGHT3_SIZE"] = "directional_lights.data[3].color_size.w"; actions.renames["AT_CUBEMAP_PASS"] = "AT_CUBEMAP_PASS"; actions.renames["AT_HALF_RES_PASS"] = "AT_HALF_RES_PASS"; actions.renames["AT_QUARTER_RES_PASS"] = "AT_QUARTER_RES_PASS"; @@ -4087,6 +4247,7 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) { actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP; actions.default_repeat = ShaderLanguage::REPEAT_ENABLE; + actions.global_buffer_array_variable = "global_variables.data"; sky_shader.compiler.initialize(actions); } @@ -4094,7 +4255,7 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) { { // default material and shader for sky shader sky_shader.default_shader = storage->shader_create(); - storage->shader_set_code(sky_shader.default_shader, "shader_type sky; void fragment() { COLOR = mix(vec3(0.3), vec3(0.2, 0.4, 0.9), smoothstep(0.0, 0.05, EYEDIR.y)); } \n"); + storage->shader_set_code(sky_shader.default_shader, "shader_type sky; void fragment() { COLOR = vec3(0.0); } \n"); sky_shader.default_material = storage->material_create(); storage->material_set_shader(sky_shader.default_material, sky_shader.default_shader); @@ -4124,19 +4285,33 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) { uniforms.push_back(u); } + { + RD::Uniform u; + u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.binding = 1; + u.ids.push_back(storage->global_variables_get_storage_buffer()); + uniforms.push_back(u); + } + sky_scene_state.sampler_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sky_shader.default_shader_rd, SKY_SET_SAMPLERS); } - camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape(int(GLOBAL_GET("rendering/quality/filters/depth_of_field_bokeh_shape")))); - camera_effects_set_dof_blur_quality(RS::DOFBlurQuality(int(GLOBAL_GET("rendering/quality/filters/depth_of_field_bokeh_quality"))), GLOBAL_GET("rendering/quality/filters/depth_of_field_use_jitter")); + camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape(int(GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_bokeh_shape")))); + camera_effects_set_dof_blur_quality(RS::DOFBlurQuality(int(GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_bokeh_quality"))), GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_use_jitter")); environment_set_ssao_quality(RS::EnvironmentSSAOQuality(int(GLOBAL_GET("rendering/quality/ssao/quality"))), GLOBAL_GET("rendering/quality/ssao/half_size")); - screen_space_roughness_limiter = GLOBAL_GET("rendering/quality/filters/screen_space_roughness_limiter"); - screen_space_roughness_limiter_curve = GLOBAL_GET("rendering/quality/filters/screen_space_roughness_limiter_curve"); + screen_space_roughness_limiter = GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter"); + screen_space_roughness_limiter_curve = GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_curve"); glow_bicubic_upscale = int(GLOBAL_GET("rendering/quality/glow/upscale_mode")) > 0; ssr_roughness_quality = RS::EnvironmentSSRRoughnessQuality(int(GLOBAL_GET("rendering/quality/screen_space_reflection/roughness_quality"))); sss_quality = RS::SubSurfaceScatteringQuality(int(GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_quality"))); sss_scale = GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_scale"); sss_depth_scale = GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale"); + directional_penumbra_shadow_kernel = memnew_arr(float, 128); + directional_soft_shadow_kernel = memnew_arr(float, 128); + penumbra_shadow_kernel = memnew_arr(float, 128); + soft_shadow_kernel = memnew_arr(float, 128); + shadows_quality_set(RS::ShadowQuality(int(GLOBAL_GET("rendering/quality/shadows/soft_shadow_quality")))); + directional_shadow_quality_set(RS::ShadowQuality(int(GLOBAL_GET("rendering/quality/directional_shadow/soft_shadow_quality")))); } RasterizerSceneRD::~RasterizerSceneRD() { @@ -4165,4 +4340,8 @@ RasterizerSceneRD::~RasterizerSceneRD() { memdelete_arr(sky_scene_state.last_frame_directional_lights); storage->free(sky_shader.default_shader); storage->free(sky_shader.default_material); + memdelete_arr(directional_penumbra_shadow_kernel); + memdelete_arr(directional_soft_shadow_kernel); + memdelete_arr(penumbra_shadow_kernel); + memdelete_arr(soft_shadow_kernel); } diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h index 3f71f7dbc1..a511838e16 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h @@ -56,7 +56,9 @@ protected: float direction[3]; float energy; float color[3]; + float size; uint32_t enabled; + uint32_t pad[3]; }; struct SkySceneState { @@ -78,8 +80,8 @@ protected: }; virtual RenderBufferData *_create_render_buffer_data() = 0; - virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_color) = 0; - virtual void _render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool use_dp_flip) = 0; + virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_color) = 0; + virtual void _render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool use_dp_flip, bool p_use_pancake) = 0; virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) = 0; virtual void _debug_giprobe(RID p_gi_probe, RenderingDevice::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha); @@ -189,6 +191,7 @@ private: virtual void set_code(const String &p_Code); virtual void set_default_texture_param(const StringName &p_name, RID p_texture); virtual void get_param_list(List<PropertyInfo> *p_param_list) const; + virtual void get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const; virtual bool is_param_texture(const StringName &p_param) const; virtual bool is_animated() const; virtual bool casts_shadows() const; @@ -324,6 +327,16 @@ private: mutable RID_Owner<ReflectionProbeInstance> reflection_probe_instance_owner; + /* REFLECTION PROBE INSTANCE */ + + struct DecalInstance { + + RID decal; + Transform transform; + }; + + mutable RID_Owner<DecalInstance> decal_instance_owner; + /* GIPROBE INSTANCE */ struct GIProbeLight { @@ -527,11 +540,24 @@ private: bool _shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow); + RS::ShadowQuality shadows_quality = RS::SHADOW_QUALITY_MAX; //So it always updates when first set + RS::ShadowQuality directional_shadow_quality = RS::SHADOW_QUALITY_MAX; + float shadows_quality_radius = 1.0; + float directional_shadow_quality_radius = 1.0; + + float *directional_penumbra_shadow_kernel; + float *directional_soft_shadow_kernel; + float *penumbra_shadow_kernel; + float *soft_shadow_kernel; + int directional_penumbra_shadow_samples = 0; + int directional_soft_shadow_samples = 0; + int penumbra_shadow_samples = 0; + int soft_shadow_samples = 0; + /* DIRECTIONAL SHADOW */ struct DirectionalShadow { RID depth; - RID fb; //for copying int light_count = 0; int size = 0; @@ -570,7 +596,10 @@ private: float farplane; float split; float bias_scale; + float shadow_texel_size; + float range_begin; Rect2 atlas_rect; + Vector2 uv_scale; }; RS::LightType light_type = RS::LIGHT_DIRECTIONAL; @@ -712,6 +741,8 @@ private: RenderBufferData *data = nullptr; int width = 0, height = 0; RS::ViewportMSAA msaa = RS::VIEWPORT_MSAA_DISABLED; + RS::ViewportScreenSpaceAA screen_space_aa = RS::VIEWPORT_SCREEN_SPACE_AA_DISABLED; + RID render_target; uint64_t auto_exposure_version = 1; @@ -725,7 +756,6 @@ private: struct Mipmap { RID texture; - RID framebuffer; int width; int height; }; @@ -839,8 +869,8 @@ public: float environment_get_bg_energy(RID p_env) const; int environment_get_canvas_max_layer(RID p_env) const; Color environment_get_ambient_light_color(RID p_env) const; - RS::EnvironmentAmbientSource environment_get_ambient_light_ambient_source(RID p_env) const; - float environment_get_ambient_light_ambient_energy(RID p_env) const; + RS::EnvironmentAmbientSource environment_get_ambient_source(RID p_env) const; + float environment_get_ambient_light_energy(RID p_env) const; float environment_get_ambient_sky_contribution(RID p_env) const; RS::EnvironmentReflectionSource environment_get_reflection_source(RID p_env) const; Color environment_get_ao_color(RID p_env) const; @@ -880,7 +910,7 @@ public: RID light_instance_create(RID p_light); void light_instance_set_transform(RID p_light_instance, const Transform &p_transform); - void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale = 1.0); + void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()); void light_instance_mark_visible(RID p_light_instance); _FORCE_INLINE_ RID light_instance_get_base_light(RID p_light_instance) { @@ -926,11 +956,55 @@ public: return li->shadow_transform[p_index].camera; } - _FORCE_INLINE_ Transform light_instance_get_shadow_transform(RID p_light_instance, int p_index) { + _FORCE_INLINE_ float light_instance_get_shadow_texel_size(RID p_light_instance, RID p_shadow_atlas) { + +#ifdef DEBUG_ENABLED + LightInstance *li = light_instance_owner.getornull(p_light_instance); + ERR_FAIL_COND_V(!li->shadow_atlases.has(p_shadow_atlas), 0); +#endif + ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas); + ERR_FAIL_COND_V(!shadow_atlas, 0); +#ifdef DEBUG_ENABLED + ERR_FAIL_COND_V(!shadow_atlas->shadow_owners.has(p_light_instance), 0); +#endif + uint32_t key = shadow_atlas->shadow_owners[p_light_instance]; + + uint32_t quadrant = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3; + + uint32_t quadrant_size = shadow_atlas->size >> 1; + + uint32_t shadow_size = (quadrant_size / shadow_atlas->quadrants[quadrant].subdivision); + + return float(1.0) / shadow_size; + } + + _FORCE_INLINE_ Transform + light_instance_get_shadow_transform(RID p_light_instance, int p_index) { LightInstance *li = light_instance_owner.getornull(p_light_instance); return li->shadow_transform[p_index].transform; } + _FORCE_INLINE_ float light_instance_get_shadow_bias_scale(RID p_light_instance, int p_index) { + + LightInstance *li = light_instance_owner.getornull(p_light_instance); + return li->shadow_transform[p_index].bias_scale; + } + _FORCE_INLINE_ float light_instance_get_shadow_range(RID p_light_instance, int p_index) { + + LightInstance *li = light_instance_owner.getornull(p_light_instance); + return li->shadow_transform[p_index].farplane; + } + _FORCE_INLINE_ float light_instance_get_shadow_range_begin(RID p_light_instance, int p_index) { + + LightInstance *li = light_instance_owner.getornull(p_light_instance); + return li->shadow_transform[p_index].range_begin; + } + + _FORCE_INLINE_ Vector2 light_instance_get_shadow_uv_scale(RID p_light_instance, int p_index) { + + LightInstance *li = light_instance_owner.getornull(p_light_instance); + return li->shadow_transform[p_index].uv_scale; + } _FORCE_INLINE_ Rect2 light_instance_get_directional_shadow_atlas_rect(RID p_light_instance, int p_index) { @@ -944,6 +1018,12 @@ public: return li->shadow_transform[p_index].split; } + _FORCE_INLINE_ float light_instance_get_directional_shadow_texel_size(RID p_light_instance, int p_index) { + + LightInstance *li = light_instance_owner.getornull(p_light_instance); + return li->shadow_transform[p_index].shadow_texel_size; + } + _FORCE_INLINE_ void light_instance_set_render_pass(RID p_light_instance, uint64_t p_pass) { LightInstance *li = light_instance_owner.getornull(p_light_instance); li->last_pass = p_pass; @@ -1036,6 +1116,19 @@ public: return rpi->atlas_index; } + virtual RID decal_instance_create(RID p_decal); + virtual void decal_instance_set_transform(RID p_decal, const Transform &p_transform); + + _FORCE_INLINE_ RID decal_instance_get_base(RID p_decal) const { + DecalInstance *decal = decal_instance_owner.getornull(p_decal); + return decal->decal; + } + + _FORCE_INLINE_ Transform decal_instance_get_transform(RID p_decal) const { + DecalInstance *decal = decal_instance_owner.getornull(p_decal); + return decal->transform; + } + RID gi_probe_instance_create(RID p_base); void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform); bool gi_probe_needs_update(RID p_probe) const; @@ -1096,19 +1189,23 @@ public: GIProbeQuality gi_probe_get_quality() const; RID render_buffers_create(); - void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa); + void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa); RID render_buffers_get_ao_texture(RID p_render_buffers); RID render_buffers_get_back_buffer_texture(RID p_render_buffers); - void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID p_environment, RID p_shadow_atlas, RID p_camera_effects, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass); + void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, RID p_environment, RID p_shadow_atlas, RID p_camera_effects, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass); void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count); void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region); - virtual void set_scene_pass(uint64_t p_pass) { scene_pass = p_pass; } - _FORCE_INLINE_ uint64_t get_scene_pass() { return scene_pass; } + virtual void set_scene_pass(uint64_t p_pass) { + scene_pass = p_pass; + } + _FORCE_INLINE_ uint64_t get_scene_pass() { + return scene_pass; + } virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_curve); virtual bool screen_space_roughness_limiter_is_active() const; @@ -1118,6 +1215,23 @@ public: RS::SubSurfaceScatteringQuality sub_surface_scattering_get_quality() const; virtual void sub_surface_scattering_set_scale(float p_scale, float p_depth_scale); + virtual void shadows_quality_set(RS::ShadowQuality p_quality); + virtual void directional_shadow_quality_set(RS::ShadowQuality p_quality); + _FORCE_INLINE_ RS::ShadowQuality shadows_quality_get() const { return shadows_quality; } + _FORCE_INLINE_ RS::ShadowQuality directional_shadow_quality_get() const { return directional_shadow_quality; } + _FORCE_INLINE_ float shadows_quality_radius_get() const { return shadows_quality_radius; } + _FORCE_INLINE_ float directional_shadow_quality_radius_get() const { return directional_shadow_quality_radius; } + + _FORCE_INLINE_ float *directional_penumbra_shadow_kernel_get() { return directional_penumbra_shadow_kernel; } + _FORCE_INLINE_ float *directional_soft_shadow_kernel_get() { return directional_soft_shadow_kernel; } + _FORCE_INLINE_ float *penumbra_shadow_kernel_get() { return penumbra_shadow_kernel; } + _FORCE_INLINE_ float *soft_shadow_kernel_get() { return soft_shadow_kernel; } + + _FORCE_INLINE_ int directional_penumbra_shadow_samples_get() const { return directional_penumbra_shadow_samples; } + _FORCE_INLINE_ int directional_soft_shadow_samples_get() const { return directional_soft_shadow_samples; } + _FORCE_INLINE_ int penumbra_shadow_samples_get() const { return penumbra_shadow_samples; } + _FORCE_INLINE_ int soft_shadow_samples_get() const { return soft_shadow_samples; } + int get_roughness_layers() const; bool is_using_radiance_cubemap_array() const; @@ -1126,7 +1240,9 @@ public: virtual void update(); virtual void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw); - _FORCE_INLINE_ RS::ViewportDebugDraw get_debug_draw_mode() const { return debug_draw; } + _FORCE_INLINE_ RS::ViewportDebugDraw get_debug_draw_mode() const { + return debug_draw; + } virtual void set_time(double p_time, double p_step); diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp index 322e89ef9a..0689429014 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp @@ -31,6 +31,7 @@ #include "rasterizer_storage_rd.h" #include "core/engine.h" +#include "core/io/resource_loader.h" #include "core/project_settings.h" #include "servers/rendering/shader_language.h" @@ -809,6 +810,12 @@ void RasterizerStorageRD::texture_replace(RID p_texture, RID p_by_texture) { } //delete last, so proxies can be updated texture_owner.free(p_by_texture); + + if (decal_atlas.textures.has(p_texture)) { + //belongs to decal atlas.. + + decal_atlas.dirty = true; //mark it dirty since it was most likely modified + } } void RasterizerStorageRD::texture_set_size_override(RID p_texture, int p_width, int p_height) { Texture *tex = texture_owner.getornull(p_texture); @@ -915,6 +922,7 @@ void RasterizerStorageRD::shader_set_code(RID p_shader, const String &p_code) { Material *material = E->get(); if (shader->data) { material->data = material_data_request_func[new_type](shader->data); + material->data->self = material->self; material->data->set_next_pass(material->next_pass); material->data->set_render_priority(material->priority); } @@ -1015,8 +1023,8 @@ void RasterizerStorageRD::_material_queue_update(Material *material, bool p_unif material->update_next = material_update_list; material_update_list = material; material->update_requested = true; - material->uniform_dirty = p_uniform; - material->texture_dirty = p_texture; + material->uniform_dirty = material->uniform_dirty || p_uniform; + material->texture_dirty = material->texture_dirty || p_texture; } void RasterizerStorageRD::material_set_shader(RID p_material, RID p_shader) { @@ -1053,6 +1061,7 @@ void RasterizerStorageRD::material_set_shader(RID p_material, RID p_shader) { ERR_FAIL_COND(shader->data == nullptr); material->data = material_data_request_func[shader->type](shader->data); + material->data->self = p_material; material->data->set_next_pass(material->next_pass); material->data->set_render_priority(material->priority); //updating happens later @@ -1138,6 +1147,19 @@ bool RasterizerStorageRD::material_casts_shadows(RID p_material) { return true; //by default everything casts shadows } +void RasterizerStorageRD::material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) { + + Material *material = material_owner.getornull(p_material); + ERR_FAIL_COND(!material); + if (material->shader && material->shader->data) { + material->shader->data->get_instance_param_list(r_parameters); + + if (material->next_pass.is_valid()) { + material_get_instance_shader_parameters(material->next_pass, r_parameters); + } + } +} + void RasterizerStorageRD::material_update_dependency(RID p_material, RasterizerScene::InstanceBase *p_instance) { Material *material = material_owner.getornull(p_material); ERR_FAIL_COND(!material); @@ -1625,11 +1647,36 @@ _FORCE_INLINE_ static void _fill_std140_ubo_empty(ShaderLanguage::DataType type, void RasterizerStorageRD::MaterialData::update_uniform_buffer(const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Map<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color) { + bool uses_global_buffer = false; + for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = p_uniforms.front(); E; E = E->next()) { if (E->get().order < 0) continue; // texture, does not go here + if (E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { + continue; //instance uniforms don't appear in the bufferr + } + + if (E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL) { + //this is a global variable, get the index to it + RasterizerStorageRD *rs = base_singleton; + + GlobalVariables::Variable *gv = rs->global_variables.variables.getptr(E->key()); + uint32_t index = 0; + if (gv) { + index = gv->buffer_index; + } else { + WARN_PRINT("Shader uses global uniform '" + E->key() + "', but it was removed at some point. Material will not display correctly."); + } + + uint32_t offset = p_uniform_offsets[E->get().order]; + uint32_t *intptr = (uint32_t *)&p_buffer[offset]; + *intptr = index; + uses_global_buffer = true; + continue; + } + //regular uniform uint32_t offset = p_uniform_offsets[E->get().order]; #ifdef DEBUG_ENABLED @@ -1658,6 +1705,38 @@ void RasterizerStorageRD::MaterialData::update_uniform_buffer(const Map<StringNa } } } + + if (uses_global_buffer != (global_buffer_E != nullptr)) { + RasterizerStorageRD *rs = base_singleton; + if (uses_global_buffer) { + global_buffer_E = rs->global_variables.materials_using_buffer.push_back(self); + } else { + rs->global_variables.materials_using_buffer.erase(global_buffer_E); + global_buffer_E = nullptr; + } + } +} + +RasterizerStorageRD::MaterialData::~MaterialData() { + if (global_buffer_E) { + //unregister global buffers + RasterizerStorageRD *rs = base_singleton; + rs->global_variables.materials_using_buffer.erase(global_buffer_E); + } + + if (global_texture_E) { + //unregister global textures + RasterizerStorageRD *rs = base_singleton; + + for (Map<StringName, uint64_t>::Element *E = used_global_textures.front(); E; E = E->next()) { + GlobalVariables::Variable *v = rs->global_variables.variables.getptr(E->key()); + if (v) { + v->texture_materials.erase(self); + } + } + //unregister material from those using global textures + rs->global_variables.materials_using_texture.erase(global_texture_E); + } } void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, RID> &p_default_textures, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color) { @@ -1669,22 +1748,57 @@ void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Va Texture *normal_detect_texture = nullptr; #endif + bool uses_global_textures = false; + global_textures_pass++; + for (int i = 0; i < p_texture_uniforms.size(); i++) { const StringName &uniform_name = p_texture_uniforms[i].name; RID texture; - const Map<StringName, Variant>::Element *V = p_parameters.find(uniform_name); - if (V) { - texture = V->get(); - } + if (p_texture_uniforms[i].global) { + + RasterizerStorageRD *rs = base_singleton; + + uses_global_textures = true; + + GlobalVariables::Variable *v = rs->global_variables.variables.getptr(uniform_name); + if (v) { + if (v->buffer_index >= 0) { + WARN_PRINT("Shader uses global uniform texture '" + String(uniform_name) + "', but it changed type and is no longer a texture!."); - if (!texture.is_valid()) { - const Map<StringName, RID>::Element *W = p_default_textures.find(uniform_name); - if (W) { + } else { + + Map<StringName, uint64_t>::Element *E = used_global_textures.find(uniform_name); + if (!E) { + E = used_global_textures.insert(uniform_name, global_textures_pass); + v->texture_materials.insert(self); + } else { + E->get() = global_textures_pass; + } - texture = W->get(); + texture = v->override.get_type() != Variant::NIL ? v->override : v->value; + } + + } else { + WARN_PRINT("Shader uses global uniform texture '" + String(uniform_name) + "', but it was removed at some point. Material will not display correctly."); + } + } else { + if (!texture.is_valid()) { + + const Map<StringName, Variant>::Element *V = p_parameters.find(uniform_name); + if (V) { + texture = V->get(); + } + } + + if (!texture.is_valid()) { + const Map<StringName, RID>::Element *W = p_default_textures.find(uniform_name); + if (W) { + + texture = W->get(); + } } } @@ -1747,6 +1861,36 @@ void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Va roughness_detect_texture->detect_roughness_callback(roughness_detect_texture->detect_roughness_callback_ud, normal_detect_texture->path, roughness_channel); } #endif + { + //for textures no longer used, unregister them + List<Map<StringName, uint64_t>::Element *> to_delete; + RasterizerStorageRD *rs = base_singleton; + + for (Map<StringName, uint64_t>::Element *E = used_global_textures.front(); E; E = E->next()) { + if (E->get() != global_textures_pass) { + to_delete.push_back(E); + + GlobalVariables::Variable *v = rs->global_variables.variables.getptr(E->key()); + if (v) { + v->texture_materials.erase(self); + } + } + } + + while (to_delete.front()) { + used_global_textures.erase(to_delete.front()->get()); + to_delete.pop_front(); + } + //handle registering/unregistering global textures + if (uses_global_textures != (global_texture_E != nullptr)) { + if (uses_global_textures) { + global_texture_E = rs->global_variables.materials_using_texture.push_back(self); + } else { + rs->global_variables.materials_using_texture.erase(global_texture_E); + global_texture_E = nullptr; + } + } + } } void RasterizerStorageRD::material_force_update_textures(RID p_material, ShaderType p_shader_type) { @@ -2197,14 +2341,14 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su Mesh::Surface::Version &v = s->versions[version]; - Vector<RD::VertexDescription> attributes; + Vector<RD::VertexAttribute> attributes; Vector<RID> buffers; uint32_t stride = 0; for (int i = 0; i < RS::ARRAY_WEIGHTS; i++) { - RD::VertexDescription vd; + RD::VertexAttribute vd; RID buffer; vd.location = i; @@ -3104,15 +3248,17 @@ RID RasterizerStorageRD::light_create(RS::LightType p_type) { light.param[RS::LIGHT_PARAM_INDIRECT_ENERGY] = 1.0; light.param[RS::LIGHT_PARAM_SPECULAR] = 0.5; light.param[RS::LIGHT_PARAM_RANGE] = 1.0; + light.param[RS::LIGHT_PARAM_SIZE] = 0.0; light.param[RS::LIGHT_PARAM_SPOT_ANGLE] = 45; - light.param[RS::LIGHT_PARAM_CONTACT_SHADOW_SIZE] = 45; light.param[RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE] = 0; light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET] = 0.1; light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET] = 0.3; light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET] = 0.6; light.param[RS::LIGHT_PARAM_SHADOW_FADE_START] = 0.8; - light.param[RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] = 0.1; - light.param[RS::LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE] = 0.1; + light.param[RS::LIGHT_PARAM_SHADOW_BIAS] = 0.02; + light.param[RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] = 1.0; + light.param[RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE] = 20.0; + light.param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS] = 0.05; return light_owner.make_rid(light); } @@ -3138,6 +3284,7 @@ void RasterizerStorageRD::light_set_param(RID p_light, RS::LightParam p_param, f case RS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET: case RS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET: case RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS: + case RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE: case RS::LIGHT_PARAM_SHADOW_BIAS: { light->version++; @@ -3171,7 +3318,19 @@ void RasterizerStorageRD::light_set_projector(RID p_light, RID p_texture) { Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); + if (light->projector == p_texture) { + return; + } + + if (light->type != RS::LIGHT_DIRECTIONAL && light->projector.is_valid()) { + texture_remove_from_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI); + } + light->projector = p_texture; + + if (light->type != RS::LIGHT_DIRECTIONAL && light->projector.is_valid()) { + texture_add_to_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI); + } } void RasterizerStorageRD::light_set_negative(RID p_light, bool p_enable) { @@ -3550,6 +3709,94 @@ float RasterizerStorageRD::reflection_probe_get_interior_ambient_probe_contribut return reflection_probe->interior_ambient_probe_contrib; } +RID RasterizerStorageRD::decal_create() { + return decal_owner.make_rid(Decal()); +} + +void RasterizerStorageRD::decal_set_extents(RID p_decal, const Vector3 &p_extents) { + Decal *decal = decal_owner.getornull(p_decal); + ERR_FAIL_COND(!decal); + decal->extents = p_extents; + decal->instance_dependency.instance_notify_changed(true, false); +} +void RasterizerStorageRD::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) { + Decal *decal = decal_owner.getornull(p_decal); + ERR_FAIL_COND(!decal); + ERR_FAIL_INDEX(p_type, RS::DECAL_TEXTURE_MAX); + + if (decal->textures[p_type] == p_texture) { + return; + } + + ERR_FAIL_COND(p_texture.is_valid() && !texture_owner.owns(p_texture)); + + if (decal->textures[p_type].is_valid() && texture_owner.owns(decal->textures[p_type])) { + texture_remove_from_decal_atlas(decal->textures[p_type]); + } + + decal->textures[p_type] = p_texture; + + if (decal->textures[p_type].is_valid()) { + texture_add_to_decal_atlas(decal->textures[p_type]); + } + + decal->instance_dependency.instance_notify_changed(false, true); +} +void RasterizerStorageRD::decal_set_emission_energy(RID p_decal, float p_energy) { + Decal *decal = decal_owner.getornull(p_decal); + ERR_FAIL_COND(!decal); + decal->emission_energy = p_energy; +} + +void RasterizerStorageRD::decal_set_albedo_mix(RID p_decal, float p_mix) { + Decal *decal = decal_owner.getornull(p_decal); + ERR_FAIL_COND(!decal); + decal->albedo_mix = p_mix; +} + +void RasterizerStorageRD::decal_set_modulate(RID p_decal, const Color &p_modulate) { + Decal *decal = decal_owner.getornull(p_decal); + ERR_FAIL_COND(!decal); + decal->modulate = p_modulate; +} +void RasterizerStorageRD::decal_set_cull_mask(RID p_decal, uint32_t p_layers) { + Decal *decal = decal_owner.getornull(p_decal); + ERR_FAIL_COND(!decal); + decal->cull_mask = p_layers; + decal->instance_dependency.instance_notify_changed(true, false); +} + +void RasterizerStorageRD::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) { + + Decal *decal = decal_owner.getornull(p_decal); + ERR_FAIL_COND(!decal); + decal->distance_fade = p_enabled; + decal->distance_fade_begin = p_begin; + decal->distance_fade_length = p_length; +} + +void RasterizerStorageRD::decal_set_fade(RID p_decal, float p_above, float p_below) { + + Decal *decal = decal_owner.getornull(p_decal); + ERR_FAIL_COND(!decal); + decal->upper_fade = p_above; + decal->lower_fade = p_below; +} + +void RasterizerStorageRD::decal_set_normal_fade(RID p_decal, float p_fade) { + + Decal *decal = decal_owner.getornull(p_decal); + ERR_FAIL_COND(!decal); + decal->normal_fade = p_fade; +} + +AABB RasterizerStorageRD::decal_get_aabb(RID p_decal) const { + Decal *decal = decal_owner.getornull(p_decal); + ERR_FAIL_COND_V(!decal, AABB()); + + return AABB(-decal->extents, decal->extents * 2.0); +} + RID RasterizerStorageRD::gi_probe_create() { return gi_probe_owner.make_rid(GIProbe()); @@ -3911,7 +4158,6 @@ void RasterizerStorageRD::_clear_render_target(RenderTarget *rt) { if (rt->backbuffer.is_valid()) { RD::get_singleton()->free(rt->backbuffer); rt->backbuffer = RID(); - rt->backbuffer_fb = RID(); for (int i = 0; i < rt->backbuffer_mipmaps.size(); i++) { //just erase copies, since the rest are erased by dependency RD::get_singleton()->free(rt->backbuffer_mipmaps[i].mipmap_copy); @@ -4025,17 +4271,11 @@ void RasterizerStorageRD::_create_render_target_backbuffer(RenderTarget *rt) { tf.width = rt->size.width; tf.height = rt->size.height; tf.type = RD::TEXTURE_TYPE_2D; - tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; + tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; tf.mipmaps = mipmaps_required; rt->backbuffer = RD::get_singleton()->texture_create(tf, RD::TextureView()); - - { - Vector<RID> backbuffer_att; - RID backbuffer_fb_tex = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->backbuffer, 0, 0); - backbuffer_att.push_back(backbuffer_fb_tex); - rt->backbuffer_fb = RD::get_singleton()->framebuffer_create(backbuffer_att); - } + rt->backbuffer_mipmap0 = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->backbuffer, 0, 0); //create mipmaps for (uint32_t i = 1; i < mipmaps_required; i++) { @@ -4043,9 +4283,6 @@ void RasterizerStorageRD::_create_render_target_backbuffer(RenderTarget *rt) { RenderTarget::BackbufferMipmap mm; { mm.mipmap = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->backbuffer, 0, i); - Vector<RID> mm_fb_at; - mm_fb_at.push_back(mm.mipmap); - mm.mipmap_fb = RD::get_singleton()->framebuffer_create(mm_fb_at); } { @@ -4057,9 +4294,6 @@ void RasterizerStorageRD::_create_render_target_backbuffer(RenderTarget *rt) { mmtf.mipmaps = 1; mm.mipmap_copy = RD::get_singleton()->texture_create(mmtf, RD::TextureView()); - Vector<RID> mm_fb_at; - mm_fb_at.push_back(mm.mipmap_copy); - mm.mipmap_copy_fb = RD::get_singleton()->framebuffer_create(mm_fb_at); } rt->backbuffer_mipmaps.push_back(mm); @@ -4135,7 +4369,12 @@ RID RasterizerStorageRD::render_target_get_rd_framebuffer(RID p_render_target) { return rt->framebuffer; } +RID RasterizerStorageRD::render_target_get_rd_texture(RID p_render_target) { + RenderTarget *rt = render_target_owner.getornull(p_render_target); + ERR_FAIL_COND_V(!rt, RID()); + return rt->color; +} void RasterizerStorageRD::render_target_request_clear(RID p_render_target, const Color &p_clear_color) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND(!rt); @@ -4185,27 +4424,25 @@ void RasterizerStorageRD::render_target_copy_to_back_buffer(RID p_render_target, } Rect2i region = p_region; - Rect2 blur_region; if (region == Rect2i()) { region.size = rt->size; - } else { - blur_region = region; - blur_region.position /= rt->size; - blur_region.size /= rt->size; } //single texture copy for backbuffer - RD::get_singleton()->texture_copy(rt->color, rt->backbuffer, Vector3(region.position.x, region.position.y, 0), Vector3(region.position.x, region.position.y, 0), Vector3(region.size.x, region.size.y, 1), 0, 0, 0, 0, true); + RD::get_singleton()->texture_copy(rt->color, rt->backbuffer_mipmap0, Vector3(region.position.x, region.position.y, 0), Vector3(region.position.x, region.position.y, 0), Vector3(region.size.x, region.size.y, 1), 0, 0, 0, 0, true); //effects.copy(rt->color, rt->backbuffer_fb, blur_region); //then mipmap blur RID prev_texture = rt->color; //use color, not backbuffer, as bb has mipmaps. - Vector2 pixel_size = Vector2(1.0 / rt->size.width, 1.0 / rt->size.height); for (int i = 0; i < rt->backbuffer_mipmaps.size(); i++) { - pixel_size *= 2.0; //go halfway + region.position.x >>= 1; + region.position.y >>= 1; + region.size.x = MAX(1, region.size.x >> 1); + region.size.y = MAX(1, region.size.y >> 1); + const RenderTarget::BackbufferMipmap &mm = rt->backbuffer_mipmaps[i]; - effects.gaussian_blur(prev_texture, mm.mipmap_copy_fb, mm.mipmap_copy, mm.mipmap_fb, pixel_size, blur_region); + effects.gaussian_blur(prev_texture, mm.mipmap, mm.mipmap_copy, region, true); prev_texture = mm.mipmap; } } @@ -4250,6 +4487,9 @@ void RasterizerStorageRD::base_update_dependency(RID p_base, RasterizerScene::In } else if (reflection_probe_owner.owns(p_base)) { ReflectionProbe *rp = reflection_probe_owner.getornull(p_base); p_instance->update_dependency(&rp->instance_dependency); + } else if (decal_owner.owns(p_base)) { + Decal *decal = decal_owner.getornull(p_base); + p_instance->update_dependency(&decal->instance_dependency); } else if (gi_probe_owner.owns(p_base)) { GIProbe *gip = gi_probe_owner.getornull(p_base); p_instance->update_dependency(&gip->instance_dependency); @@ -4278,6 +4518,9 @@ RS::InstanceType RasterizerStorageRD::get_base_type(RID p_rid) const { if (reflection_probe_owner.owns(p_rid)) { return RS::INSTANCE_REFLECTION_PROBE; } + if (decal_owner.owns(p_rid)) { + return RS::INSTANCE_DECAL; + } if (gi_probe_owner.owns(p_rid)) { return RS::INSTANCE_GI_PROBE; } @@ -4287,10 +4530,924 @@ RS::InstanceType RasterizerStorageRD::get_base_type(RID p_rid) const { return RS::INSTANCE_NONE; } + +void RasterizerStorageRD::texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp) { + if (!decal_atlas.textures.has(p_texture)) { + DecalAtlas::Texture t; + t.users = 1; + t.panorama_to_dp_users = p_panorama_to_dp ? 1 : 0; + decal_atlas.textures[p_texture] = t; + decal_atlas.dirty = true; + } else { + DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture); + t->users++; + if (p_panorama_to_dp) { + t->panorama_to_dp_users++; + } + } +} + +void RasterizerStorageRD::texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp) { + DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture); + ERR_FAIL_COND(!t); + t->users--; + if (p_panorama_to_dp) { + ERR_FAIL_COND(t->panorama_to_dp_users == 0); + t->panorama_to_dp_users--; + } + if (t->users == 0) { + decal_atlas.textures.erase(p_texture); + //do not mark it dirty, there is no need to since it remains working + } +} + +RID RasterizerStorageRD::decal_atlas_get_texture() const { + return decal_atlas.texture; +} + +RID RasterizerStorageRD::decal_atlas_get_texture_srgb() const { + return decal_atlas.texture; +} + +void RasterizerStorageRD::_update_decal_atlas() { + if (!decal_atlas.dirty) { + return; //nothing to do + } + + decal_atlas.dirty = false; + + if (decal_atlas.texture.is_valid()) { + RD::get_singleton()->free(decal_atlas.texture); + decal_atlas.texture = RID(); + decal_atlas.texture_srgb = RID(); + decal_atlas.texture_mipmaps.clear(); + } + + int border = 1 << decal_atlas.mipmaps; + + if (decal_atlas.textures.size()) { + //generate atlas + Vector<DecalAtlas::SortItem> itemsv; + itemsv.resize(decal_atlas.textures.size()); + int base_size = 8; + const RID *K = NULL; + + int idx = 0; + while ((K = decal_atlas.textures.next(K))) { + DecalAtlas::SortItem &si = itemsv.write[idx]; + + Texture *src_tex = texture_owner.getornull(*K); + + si.size.width = (src_tex->width / border) + 1; + si.size.height = (src_tex->height / border) + 1; + si.pixel_size = Size2i(src_tex->width, src_tex->height); + + if (base_size < si.size.width) { + base_size = nearest_power_of_2_templated(si.size.width); + } + + si.texture = *K; + idx++; + } + + //sort items by size + itemsv.sort(); + + //attempt to create atlas + int item_count = itemsv.size(); + DecalAtlas::SortItem *items = itemsv.ptrw(); + + int atlas_height = 0; + + while (true) { + + Vector<int> v_offsetsv; + v_offsetsv.resize(base_size); + + int *v_offsets = v_offsetsv.ptrw(); + zeromem(v_offsets, sizeof(int) * base_size); + + int max_height = 0; + + for (int i = 0; i < item_count; i++) { + //best fit + DecalAtlas::SortItem &si = items[i]; + int best_idx = -1; + int best_height = 0x7FFFFFFF; + for (int j = 0; j <= base_size - si.size.width; j++) { + int height = 0; + for (int k = 0; k < si.size.width; k++) { + int h = v_offsets[k + j]; + if (h > height) { + height = h; + if (height > best_height) { + break; //already bad + } + } + } + + if (height < best_height) { + best_height = height; + best_idx = j; + } + } + + //update + for (int k = 0; k < si.size.width; k++) { + v_offsets[k + best_idx] = best_height + si.size.height; + } + + si.pos.x = best_idx; + si.pos.y = best_height; + + if (si.pos.y + si.size.height > max_height) { + max_height = si.pos.y + si.size.height; + } + } + + if (max_height <= base_size * 2) { + atlas_height = max_height; + break; //good ratio, break; + } + + base_size *= 2; + } + + decal_atlas.size.width = base_size * border; + decal_atlas.size.height = nearest_power_of_2_templated(atlas_height * border); + + for (int i = 0; i < item_count; i++) { + DecalAtlas::Texture *t = decal_atlas.textures.getptr(items[i].texture); + t->uv_rect.position = items[i].pos * border + Vector2i(border / 2, border / 2); + t->uv_rect.size = items[i].pixel_size; + //print_line("blitrect: " + t->uv_rect); + t->uv_rect.position /= Size2(decal_atlas.size); + t->uv_rect.size /= Size2(decal_atlas.size); + } + } else { + + //use border as size, so it at least has enough mipmaps + decal_atlas.size.width = border; + decal_atlas.size.height = border; + } + + //blit textures + + RD::TextureFormat tformat; + tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; + tformat.width = decal_atlas.size.width; + tformat.height = decal_atlas.size.height; + tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; + tformat.type = RD::TEXTURE_TYPE_2D; + tformat.mipmaps = decal_atlas.mipmaps; + tformat.shareable_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_UNORM); + tformat.shareable_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_SRGB); + + decal_atlas.texture = RD::get_singleton()->texture_create(tformat, RD::TextureView()); + + { + //create the framebuffer + + Size2i s = decal_atlas.size; + + for (int i = 0; i < decal_atlas.mipmaps; i++) { + DecalAtlas::MipMap mm; + mm.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), decal_atlas.texture, 0, i); + Vector<RID> fb; + fb.push_back(mm.texture); + mm.fb = RD::get_singleton()->framebuffer_create(fb); + mm.size = s; + decal_atlas.texture_mipmaps.push_back(mm); + + s.width = MAX(1, s.width >> 1); + s.height = MAX(1, s.height >> 1); + } + { + //create the SRGB variant + RD::TextureView rd_view; + rd_view.format_override = RD::DATA_FORMAT_R8G8B8A8_SRGB; + decal_atlas.texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, decal_atlas.texture); + } + } + + RID prev_texture; + for (int i = 0; i < decal_atlas.texture_mipmaps.size(); i++) { + const DecalAtlas::MipMap &mm = decal_atlas.texture_mipmaps[i]; + + Color clear_color(0, 0, 0, 0); + + if (decal_atlas.textures.size()) { + + if (i == 0) { + Vector<Color> cc; + cc.push_back(clear_color); + + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(mm.fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, cc); + + const RID *K = NULL; + while ((K = decal_atlas.textures.next(K))) { + DecalAtlas::Texture *t = decal_atlas.textures.getptr(*K); + Texture *src_tex = texture_owner.getornull(*K); + effects.copy_to_atlas_fb(src_tex->rd_texture, mm.fb, t->uv_rect, draw_list, false, t->panorama_to_dp_users > 0); + } + + RD::get_singleton()->draw_list_end(); + + prev_texture = mm.texture; + } else { + + effects.copy_to_fb_rect(prev_texture, mm.fb, Rect2i(Point2i(), mm.size)); + prev_texture = mm.texture; + } + } else { + RD::get_singleton()->texture_clear(mm.texture, clear_color, 0, 1, 0, 1, false); + } + } +} + +int32_t RasterizerStorageRD::_global_variable_allocate(uint32_t p_elements) { + + int32_t idx = 0; + while (idx + p_elements <= global_variables.buffer_size) { + if (global_variables.buffer_usage[idx].elements == 0) { + bool valid = true; + for (uint32_t i = 1; i < p_elements; i++) { + if (global_variables.buffer_usage[idx + i].elements > 0) { + valid = false; + idx += i + global_variables.buffer_usage[idx + i].elements; + break; + } + } + + if (!valid) { + continue; //if not valid, idx is in new position + } + + return idx; + } else { + idx += global_variables.buffer_usage[idx].elements; + } + } + + return -1; +} + +void RasterizerStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS::GlobalVariableType p_type, const Variant &p_value) { + + switch (p_type) { + case RS::GLOBAL_VAR_TYPE_BOOL: { + + GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + bool b = p_value; + bv.x = b ? 1.0 : 0.0; + bv.y = 0.0; + bv.z = 0.0; + bv.w = 0.0; + + } break; + case RS::GLOBAL_VAR_TYPE_BVEC2: { + GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + uint32_t bvec = p_value; + bv.x = (bvec & 1) ? 1.0 : 0.0; + bv.y = (bvec & 2) ? 1.0 : 0.0; + bv.z = 0.0; + bv.w = 0.0; + } break; + case RS::GLOBAL_VAR_TYPE_BVEC3: { + GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + uint32_t bvec = p_value; + bv.x = (bvec & 1) ? 1.0 : 0.0; + bv.y = (bvec & 2) ? 1.0 : 0.0; + bv.z = (bvec & 4) ? 1.0 : 0.0; + bv.w = 0.0; + } break; + case RS::GLOBAL_VAR_TYPE_BVEC4: { + GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + uint32_t bvec = p_value; + bv.x = (bvec & 1) ? 1.0 : 0.0; + bv.y = (bvec & 2) ? 1.0 : 0.0; + bv.z = (bvec & 4) ? 1.0 : 0.0; + bv.w = (bvec & 8) ? 1.0 : 0.0; + } break; + case RS::GLOBAL_VAR_TYPE_INT: { + GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index]; + int32_t v = p_value; + bv.x = v; + bv.y = 0; + bv.z = 0; + bv.w = 0; + } break; + case RS::GLOBAL_VAR_TYPE_IVEC2: { + GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index]; + Vector2i v = p_value; + bv.x = v.x; + bv.y = v.y; + bv.z = 0; + bv.w = 0; + } break; + case RS::GLOBAL_VAR_TYPE_IVEC3: { + GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index]; + Vector3i v = p_value; + bv.x = v.x; + bv.y = v.y; + bv.z = v.z; + bv.w = 0; + } break; + case RS::GLOBAL_VAR_TYPE_IVEC4: { + GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index]; + Vector<int32_t> v = p_value; + bv.x = v.size() >= 1 ? v[0] : 0; + bv.y = v.size() >= 2 ? v[1] : 0; + bv.z = v.size() >= 3 ? v[2] : 0; + bv.w = v.size() >= 4 ? v[3] : 0; + } break; + case RS::GLOBAL_VAR_TYPE_RECT2I: { + GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index]; + Rect2i v = p_value; + bv.x = v.position.x; + bv.y = v.position.y; + bv.z = v.size.x; + bv.w = v.size.y; + } break; + case RS::GLOBAL_VAR_TYPE_UINT: { + GlobalVariables::ValueUInt &bv = *(GlobalVariables::ValueUInt *)&global_variables.buffer_values[p_index]; + uint32_t v = p_value; + bv.x = v; + bv.y = 0; + bv.z = 0; + bv.w = 0; + } break; + case RS::GLOBAL_VAR_TYPE_UVEC2: { + GlobalVariables::ValueUInt &bv = *(GlobalVariables::ValueUInt *)&global_variables.buffer_values[p_index]; + Vector2i v = p_value; + bv.x = v.x; + bv.y = v.y; + bv.z = 0; + bv.w = 0; + } break; + case RS::GLOBAL_VAR_TYPE_UVEC3: { + GlobalVariables::ValueUInt &bv = *(GlobalVariables::ValueUInt *)&global_variables.buffer_values[p_index]; + Vector3i v = p_value; + bv.x = v.x; + bv.y = v.y; + bv.z = v.z; + bv.w = 0; + } break; + case RS::GLOBAL_VAR_TYPE_UVEC4: { + GlobalVariables::ValueUInt &bv = *(GlobalVariables::ValueUInt *)&global_variables.buffer_values[p_index]; + Vector<int32_t> v = p_value; + bv.x = v.size() >= 1 ? v[0] : 0; + bv.y = v.size() >= 2 ? v[1] : 0; + bv.z = v.size() >= 3 ? v[2] : 0; + bv.w = v.size() >= 4 ? v[3] : 0; + } break; + case RS::GLOBAL_VAR_TYPE_FLOAT: { + GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + float v = p_value; + bv.x = v; + bv.y = 0; + bv.z = 0; + bv.w = 0; + } break; + case RS::GLOBAL_VAR_TYPE_VEC2: { + GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + Vector2 v = p_value; + bv.x = v.x; + bv.y = v.y; + bv.z = 0; + bv.w = 0; + } break; + case RS::GLOBAL_VAR_TYPE_VEC3: { + GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + Vector3 v = p_value; + bv.x = v.x; + bv.y = v.y; + bv.z = v.z; + bv.w = 0; + } break; + case RS::GLOBAL_VAR_TYPE_VEC4: { + GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + Plane v = p_value; + bv.x = v.normal.x; + bv.y = v.normal.y; + bv.z = v.normal.z; + bv.w = v.d; + } break; + case RS::GLOBAL_VAR_TYPE_COLOR: { + GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + Color v = p_value; + bv.x = v.r; + bv.y = v.g; + bv.z = v.b; + bv.w = v.a; + + GlobalVariables::Value &bv_linear = global_variables.buffer_values[p_index + 1]; + v = v.to_linear(); + bv_linear.x = v.r; + bv_linear.y = v.g; + bv_linear.z = v.b; + bv_linear.w = v.a; + + } break; + case RS::GLOBAL_VAR_TYPE_RECT2: { + GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + Rect2 v = p_value; + bv.x = v.position.x; + bv.y = v.position.y; + bv.z = v.size.x; + bv.w = v.size.y; + } break; + case RS::GLOBAL_VAR_TYPE_MAT2: { + GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; + Vector<float> m2 = p_value; + if (m2.size() < 4) { + m2.resize(4); + } + bv[0].x = m2[0]; + bv[0].y = m2[1]; + bv[0].z = 0; + bv[0].w = 0; + + bv[1].x = m2[2]; + bv[1].y = m2[3]; + bv[1].z = 0; + bv[1].w = 0; + + } break; + case RS::GLOBAL_VAR_TYPE_MAT3: { + + GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; + Basis v = p_value; + bv[0].x = v.elements[0][0]; + bv[0].y = v.elements[1][0]; + bv[0].z = v.elements[2][0]; + bv[0].w = 0; + + bv[1].x = v.elements[0][1]; + bv[1].y = v.elements[1][1]; + bv[1].z = v.elements[2][1]; + bv[1].w = 0; + + bv[2].x = v.elements[0][2]; + bv[2].y = v.elements[1][2]; + bv[2].z = v.elements[2][2]; + bv[2].w = 0; + + } break; + case RS::GLOBAL_VAR_TYPE_MAT4: { + + GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; + + Vector<float> m2 = p_value; + if (m2.size() < 16) { + m2.resize(16); + } + + bv[0].x = m2[0]; + bv[0].y = m2[1]; + bv[0].z = m2[2]; + bv[0].w = m2[3]; + + bv[1].x = m2[4]; + bv[1].y = m2[5]; + bv[1].z = m2[6]; + bv[1].w = m2[7]; + + bv[2].x = m2[8]; + bv[2].y = m2[9]; + bv[2].z = m2[10]; + bv[2].w = m2[11]; + + bv[3].x = m2[12]; + bv[3].y = m2[13]; + bv[3].z = m2[14]; + bv[3].w = m2[15]; + + } break; + case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D: { + + GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; + Transform2D v = p_value; + bv[0].x = v.elements[0][0]; + bv[0].y = v.elements[0][1]; + bv[0].z = 0; + bv[0].w = 0; + + bv[1].x = v.elements[1][0]; + bv[1].y = v.elements[1][1]; + bv[1].z = 0; + bv[1].w = 0; + + bv[2].x = v.elements[2][0]; + bv[2].y = v.elements[2][1]; + bv[2].z = 1; + bv[2].w = 0; + + } break; + case RS::GLOBAL_VAR_TYPE_TRANSFORM: { + + GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; + Transform v = p_value; + bv[0].x = v.basis.elements[0][0]; + bv[0].y = v.basis.elements[1][0]; + bv[0].z = v.basis.elements[2][0]; + bv[0].w = 0; + + bv[1].x = v.basis.elements[0][1]; + bv[1].y = v.basis.elements[1][1]; + bv[1].z = v.basis.elements[2][1]; + bv[1].w = 0; + + bv[2].x = v.basis.elements[0][2]; + bv[2].y = v.basis.elements[1][2]; + bv[2].z = v.basis.elements[2][2]; + bv[2].w = 0; + + bv[2].x = v.origin.x; + bv[2].y = v.origin.y; + bv[2].z = v.origin.z; + bv[2].w = 1; + + } break; + default: { + ERR_FAIL(); + } + } +} + +void RasterizerStorageRD::_global_variable_mark_buffer_dirty(int32_t p_index, int32_t p_elements) { + + int32_t prev_chunk = -1; + + for (int32_t i = 0; i < p_elements; i++) { + int32_t chunk = (p_index + i) / GlobalVariables::BUFFER_DIRTY_REGION_SIZE; + if (chunk != prev_chunk) { + if (!global_variables.buffer_dirty_regions[chunk]) { + global_variables.buffer_dirty_regions[chunk] = true; + global_variables.buffer_dirty_region_count++; + } + } + + prev_chunk = chunk; + } +} + +void RasterizerStorageRD::global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) { + + ERR_FAIL_COND(global_variables.variables.has(p_name)); + GlobalVariables::Variable gv; + gv.type = p_type; + gv.value = p_value; + gv.buffer_index = -1; + + if (p_type >= RS::GLOBAL_VAR_TYPE_SAMPLER2D) { + //is texture + global_variables.must_update_texture_materials = true; //normally ther are no + } else { + + gv.buffer_elements = 1; + if (p_type == RS::GLOBAL_VAR_TYPE_COLOR || p_type == RS::GLOBAL_VAR_TYPE_MAT2) { + //color needs to elements to store srgb and linear + gv.buffer_elements = 2; + } + if (p_type == RS::GLOBAL_VAR_TYPE_MAT3 || p_type == RS::GLOBAL_VAR_TYPE_TRANSFORM_2D) { + //color needs to elements to store srgb and linear + gv.buffer_elements = 3; + } + if (p_type == RS::GLOBAL_VAR_TYPE_MAT4 || p_type == RS::GLOBAL_VAR_TYPE_TRANSFORM) { + //color needs to elements to store srgb and linear + gv.buffer_elements = 4; + } + + //is vector, allocate in buffer and update index + gv.buffer_index = _global_variable_allocate(gv.buffer_elements); + ERR_FAIL_COND_MSG(gv.buffer_index < 0, vformat("Failed allocating global variable '%s' out of buffer memory. Consider increasing it in the Project Settings.", String(p_name))); + global_variables.buffer_usage[gv.buffer_index].elements = gv.buffer_elements; + _global_variable_store_in_buffer(gv.buffer_index, gv.type, gv.value); + _global_variable_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements); + + global_variables.must_update_buffer_materials = true; //normally ther are no + } + + global_variables.variables[p_name] = gv; +} + +void RasterizerStorageRD::global_variable_remove(const StringName &p_name) { + if (!global_variables.variables.has(p_name)) { + return; + } + GlobalVariables::Variable &gv = global_variables.variables[p_name]; + + if (gv.buffer_index >= 0) { + global_variables.buffer_usage[gv.buffer_index].elements = 0; + global_variables.must_update_buffer_materials = true; + } else { + global_variables.must_update_texture_materials = true; + } + + global_variables.variables.erase(p_name); +} +Vector<StringName> RasterizerStorageRD::global_variable_get_list() const { + + if (!Engine::get_singleton()->is_editor_hint()) { + ERR_FAIL_V_MSG(Vector<StringName>(), "This function should never be used outside the editor, it can severely damage performance."); + } + + const StringName *K = NULL; + Vector<StringName> names; + while ((K = global_variables.variables.next(K))) { + names.push_back(*K); + } + names.sort_custom<StringName::AlphCompare>(); + return names; +} + +void RasterizerStorageRD::global_variable_set(const StringName &p_name, const Variant &p_value) { + ERR_FAIL_COND(!global_variables.variables.has(p_name)); + GlobalVariables::Variable &gv = global_variables.variables[p_name]; + gv.value = p_value; + if (gv.override.get_type() == Variant::NIL) { + if (gv.buffer_index >= 0) { + //buffer + _global_variable_store_in_buffer(gv.buffer_index, gv.type, gv.value); + _global_variable_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements); + } else { + //texture + for (Set<RID>::Element *E = gv.texture_materials.front(); E; E = E->next()) { + Material *material = material_owner.getornull(E->get()); + ERR_CONTINUE(!material); + _material_queue_update(material, false, true); + } + } + } +} +void RasterizerStorageRD::global_variable_set_override(const StringName &p_name, const Variant &p_value) { + if (!global_variables.variables.has(p_name)) { + return; //variable may not exist + } + GlobalVariables::Variable &gv = global_variables.variables[p_name]; + + gv.override = p_value; + + if (gv.buffer_index >= 0) { + //buffer + if (gv.override.get_type() == Variant::NIL) { + _global_variable_store_in_buffer(gv.buffer_index, gv.type, gv.value); + } else { + _global_variable_store_in_buffer(gv.buffer_index, gv.type, gv.override); + } + + _global_variable_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements); + } else { + //texture + //texture + for (Set<RID>::Element *E = gv.texture_materials.front(); E; E = E->next()) { + Material *material = material_owner.getornull(E->get()); + ERR_CONTINUE(!material); + _material_queue_update(material, false, true); + } + } +} + +Variant RasterizerStorageRD::global_variable_get(const StringName &p_name) const { + + if (!Engine::get_singleton()->is_editor_hint()) { + ERR_FAIL_V_MSG(Variant(), "This function should never be used outside the editor, it can severely damage performance."); + } + + if (!global_variables.variables.has(p_name)) { + return Variant(); + } + + return global_variables.variables[p_name].value; +} + +RS::GlobalVariableType RasterizerStorageRD::global_variable_get_type_internal(const StringName &p_name) const { + + if (!global_variables.variables.has(p_name)) { + return RS::GLOBAL_VAR_TYPE_MAX; + } + + return global_variables.variables[p_name].type; +} + +RS::GlobalVariableType RasterizerStorageRD::global_variable_get_type(const StringName &p_name) const { + if (!Engine::get_singleton()->is_editor_hint()) { + ERR_FAIL_V_MSG(RS::GLOBAL_VAR_TYPE_MAX, "This function should never be used outside the editor, it can severely damage performance."); + } + + return global_variable_get_type_internal(p_name); +} + +void RasterizerStorageRD::global_variables_load_settings(bool p_load_textures) { + + List<PropertyInfo> settings; + ProjectSettings::get_singleton()->get_property_list(&settings); + + for (List<PropertyInfo>::Element *E = settings.front(); E; E = E->next()) { + if (E->get().name.begins_with("shader_globals/")) { + StringName name = E->get().name.get_slice("/", 1); + Dictionary d = ProjectSettings::get_singleton()->get(E->get().name); + + ERR_CONTINUE(!d.has("type")); + ERR_CONTINUE(!d.has("value")); + + String type = d["type"]; + + static const char *global_var_type_names[RS::GLOBAL_VAR_TYPE_MAX] = { + "bool", + "bvec2", + "bvec3", + "bvec4", + "int", + "ivec2", + "ivec3", + "ivec4", + "rect2i", + "uint", + "uvec2", + "uvec3", + "uvec4", + "float", + "vec2", + "vec3", + "vec4", + "color", + "rect2", + "mat2", + "mat3", + "mat4", + "transform_2d", + "transform", + "sampler2D", + "sampler2DArray", + "sampler3D", + "samplerCube", + }; + + RS::GlobalVariableType gvtype = RS::GLOBAL_VAR_TYPE_MAX; + + for (int i = 0; i < RS::GLOBAL_VAR_TYPE_MAX; i++) { + if (global_var_type_names[i] == type) { + gvtype = RS::GlobalVariableType(i); + break; + } + } + + ERR_CONTINUE(gvtype == RS::GLOBAL_VAR_TYPE_MAX); //type invalid + + Variant value = d["value"]; + + if (gvtype >= RS::GLOBAL_VAR_TYPE_SAMPLER2D) { + //textire + if (!p_load_textures) { + value = RID(); + continue; + } + + String path = value; + RES resource = ResourceLoader::load(path); + ERR_CONTINUE(resource.is_null()); + value = resource; + } + + if (global_variables.variables.has(name)) { + //has it, update it + global_variable_set(name, value); + } else { + global_variable_add(name, gvtype, value); + } + } + } +} + +void RasterizerStorageRD::global_variables_clear() { + global_variables.variables.clear(); //not right but for now enough +} + +RID RasterizerStorageRD::global_variables_get_storage_buffer() const { + return global_variables.buffer; +} + +int32_t RasterizerStorageRD::global_variables_instance_allocate(RID p_instance) { + ERR_FAIL_COND_V(global_variables.instance_buffer_pos.has(p_instance), -1); + int32_t pos = _global_variable_allocate(ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES); + global_variables.instance_buffer_pos[p_instance] = pos; //save anyway + ERR_FAIL_COND_V_MSG(pos < 0, -1, "Too many instances using shader instance variables. Increase buffer size in Project Settings."); + global_variables.buffer_usage[pos].elements = ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES; + return pos; +} + +void RasterizerStorageRD::global_variables_instance_free(RID p_instance) { + ERR_FAIL_COND(!global_variables.instance_buffer_pos.has(p_instance)); + int32_t pos = global_variables.instance_buffer_pos[p_instance]; + if (pos >= 0) { + global_variables.buffer_usage[pos].elements = 0; + } + global_variables.instance_buffer_pos.erase(p_instance); +} +void RasterizerStorageRD::global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) { + + if (!global_variables.instance_buffer_pos.has(p_instance)) { + return; //just not allocated, ignore + } + int32_t pos = global_variables.instance_buffer_pos[p_instance]; + + if (pos < 0) { + return; //again, not allocated, ignore + } + ERR_FAIL_INDEX(p_index, ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES); + ERR_FAIL_COND_MSG(p_value.get_type() > Variant::COLOR, "Unsupported variant type for instance parameter: " + Variant::get_type_name(p_value.get_type())); //anything greater not supported + + ShaderLanguage::DataType datatype_from_value[Variant::COLOR + 1] = { + ShaderLanguage::TYPE_MAX, //nil + ShaderLanguage::TYPE_BOOL, //bool + ShaderLanguage::TYPE_INT, //int + ShaderLanguage::TYPE_FLOAT, //float + ShaderLanguage::TYPE_MAX, //string + ShaderLanguage::TYPE_VEC2, //vec2 + ShaderLanguage::TYPE_IVEC2, //vec2i + ShaderLanguage::TYPE_VEC4, //rect2 + ShaderLanguage::TYPE_IVEC4, //rect2i + ShaderLanguage::TYPE_VEC3, // vec3 + ShaderLanguage::TYPE_IVEC3, //vec3i + ShaderLanguage::TYPE_MAX, //xform2d not supported here + ShaderLanguage::TYPE_VEC4, //plane + ShaderLanguage::TYPE_VEC4, //quat + ShaderLanguage::TYPE_MAX, //aabb not supported here + ShaderLanguage::TYPE_MAX, //basis not supported here + ShaderLanguage::TYPE_MAX, //xform not supported here + ShaderLanguage::TYPE_VEC4 //color + }; + + ShaderLanguage::DataType datatype = datatype_from_value[p_value.get_type()]; + + ERR_FAIL_COND_MSG(datatype == ShaderLanguage::TYPE_MAX, "Unsupported variant type for instance parameter: " + Variant::get_type_name(p_value.get_type())); //anything greater not supported + + pos += p_index; + + _fill_std140_variant_ubo_value(datatype, p_value, (uint8_t *)&global_variables.buffer_values[pos], true); //instances always use linear color in this renderer + _global_variable_mark_buffer_dirty(pos, 1); +} + +void RasterizerStorageRD::_update_global_variables() { + + if (global_variables.buffer_dirty_region_count > 0) { + uint32_t total_regions = global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE; + if (total_regions / global_variables.buffer_dirty_region_count <= 4) { + // 25% of regions dirty, just update all buffer + RD::get_singleton()->buffer_update(global_variables.buffer, 0, sizeof(GlobalVariables::Value) * global_variables.buffer_size, global_variables.buffer_values); + zeromem(global_variables.buffer_dirty_regions, sizeof(bool) * total_regions); + } else { + uint32_t region_byte_size = sizeof(GlobalVariables::Value) * GlobalVariables::BUFFER_DIRTY_REGION_SIZE; + + for (uint32_t i = 0; i < total_regions; i++) { + if (global_variables.buffer_dirty_regions[i]) { + + RD::get_singleton()->buffer_update(global_variables.buffer, i * region_byte_size, region_byte_size, global_variables.buffer_values); + + global_variables.buffer_dirty_regions[i] = false; + } + } + } + + global_variables.buffer_dirty_region_count = 0; + } + + if (global_variables.must_update_buffer_materials) { + // only happens in the case of a buffer variable added or removed, + // so not often. + for (List<RID>::Element *E = global_variables.materials_using_buffer.front(); E; E = E->next()) { + Material *material = material_owner.getornull(E->get()); + ERR_CONTINUE(!material); //wtf + + _material_queue_update(material, true, false); + } + + global_variables.must_update_buffer_materials = false; + } + + if (global_variables.must_update_texture_materials) { + // only happens in the case of a buffer variable added or removed, + // so not often. + for (List<RID>::Element *E = global_variables.materials_using_texture.front(); E; E = E->next()) { + Material *material = material_owner.getornull(E->get()); + ERR_CONTINUE(!material); //wtf + + _material_queue_update(material, false, true); + print_line("update material texture?"); + } + + global_variables.must_update_texture_materials = false; + } +} + void RasterizerStorageRD::update_dirty_resources() { + _update_global_variables(); //must do before materials, so it can queue them for update _update_queued_materials(); _update_dirty_multimeshes(); _update_dirty_skeletons(); + _update_decal_atlas(); } bool RasterizerStorageRD::has_os_feature(const String &p_feature) const { @@ -4339,6 +5496,11 @@ bool RasterizerStorageRD::free(RID p_rid) { } } + if (decal_atlas.textures.has(p_rid)) { + decal_atlas.textures.erase(p_rid); + //there is not much a point of making it dirty, just let it be. + } + for (int i = 0; i < t->proxies.size(); i++) { Texture *p = texture_owner.getornull(t->proxies[i]); ERR_CONTINUE(!p); @@ -4389,6 +5551,15 @@ bool RasterizerStorageRD::free(RID p_rid) { ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_rid); reflection_probe->instance_dependency.instance_notify_deleted(p_rid); reflection_probe_owner.free(p_rid); + } else if (decal_owner.owns(p_rid)) { + Decal *decal = decal_owner.getornull(p_rid); + for (int i = 0; i < RS::DECAL_TEXTURE_MAX; i++) { + if (decal->textures[i].is_valid() && texture_owner.owns(decal->textures[i])) { + texture_remove_from_decal_atlas(decal->textures[i]); + } + } + decal->instance_dependency.instance_notify_deleted(p_rid); + decal_owner.free(p_rid); } else if (gi_probe_owner.owns(p_rid)) { gi_probe_allocate(p_rid, Transform(), AABB(), Vector3i(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<int>()); //deallocate GIProbe *gi_probe = gi_probe_owner.getornull(p_rid); @@ -4397,6 +5568,7 @@ bool RasterizerStorageRD::free(RID p_rid) { } else if (light_owner.owns(p_rid)) { + light_set_projector(p_rid, RID()); //clear projector // delete the texture Light *light = light_owner.getornull(p_rid); light->instance_dependency.instance_notify_deleted(p_rid); @@ -4450,12 +5622,27 @@ String RasterizerStorageRD::get_captured_timestamp_name(uint32_t p_index) const return RD::get_singleton()->get_captured_timestamp_name(p_index); } +RasterizerStorageRD *RasterizerStorageRD::base_singleton = nullptr; + RasterizerStorageRD::RasterizerStorageRD() { + base_singleton = this; + for (int i = 0; i < SHADER_TYPE_MAX; i++) { shader_data_request_func[i] = nullptr; } + static_assert(sizeof(GlobalVariables::Value) == 16); + + global_variables.buffer_size = GLOBAL_GET("rendering/high_end/global_shader_variables_buffer_size"); + global_variables.buffer_size = MAX(4096, global_variables.buffer_size); + global_variables.buffer_values = memnew_arr(GlobalVariables::Value, global_variables.buffer_size); + zeromem(global_variables.buffer_values, sizeof(GlobalVariables::Value) * global_variables.buffer_size); + global_variables.buffer_usage = memnew_arr(GlobalVariables::ValueUsage, global_variables.buffer_size); + global_variables.buffer_dirty_regions = memnew_arr(bool, global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE); + zeromem(global_variables.buffer_dirty_regions, sizeof(bool) * global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE); + global_variables.buffer = RD::get_singleton()->storage_buffer_create(sizeof(GlobalVariables::Value) * global_variables.buffer_size); + material_update_list = nullptr; { //create default textures @@ -4492,6 +5679,10 @@ RasterizerStorageRD::RasterizerStorageRD() { Vector<Vector<uint8_t>> vpv; vpv.push_back(pv); default_rd_textures[DEFAULT_RD_TEXTURE_BLACK] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); + + //take the chance and initialize decal atlas to something + decal_atlas.texture = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); + decal_atlas.texture_srgb = decal_atlas.texture; } for (int i = 0; i < 16; i++) { @@ -4644,14 +5835,14 @@ RasterizerStorageRD::RasterizerStorageRD() { sampler_state.min_filter = RD::SAMPLER_FILTER_LINEAR; sampler_state.mip_filter = RD::SAMPLER_FILTER_LINEAR; sampler_state.use_anisotropy = true; - sampler_state.anisotropy_max = GLOBAL_GET("rendering/quality/filters/max_anisotropy"); + sampler_state.anisotropy_max = GLOBAL_GET("rendering/quality/texture_filters/max_anisotropy"); } break; case RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC: { sampler_state.mag_filter = RD::SAMPLER_FILTER_LINEAR; sampler_state.min_filter = RD::SAMPLER_FILTER_LINEAR; sampler_state.mip_filter = RD::SAMPLER_FILTER_LINEAR; sampler_state.use_anisotropy = true; - sampler_state.anisotropy_max = GLOBAL_GET("rendering/quality/filters/max_anisotropy"); + sampler_state.anisotropy_max = GLOBAL_GET("rendering/quality/texture_filters/max_anisotropy"); } break; default: { @@ -4683,9 +5874,11 @@ RasterizerStorageRD::RasterizerStorageRD() { //default rd buffers { - { //vertex + //vertex + { Vector<uint8_t> buffer; + buffer.resize(sizeof(float) * 3); { uint8_t *w = buffer.ptrw(); @@ -4803,6 +5996,11 @@ RasterizerStorageRD::RasterizerStorageRD() { RasterizerStorageRD::~RasterizerStorageRD() { + memdelete_arr(global_variables.buffer_values); + memdelete_arr(global_variables.buffer_usage); + memdelete_arr(global_variables.buffer_dirty_regions); + RD::get_singleton()->free(global_variables.buffer); + //def textures for (int i = 0; i < DEFAULT_RD_TEXTURE_MAX; i++) { RD::get_singleton()->free(default_rd_textures[i]); @@ -4820,4 +6018,12 @@ RasterizerStorageRD::~RasterizerStorageRD() { RD::get_singleton()->free(mesh_default_rd_buffers[i]); } giprobe_sdf_shader.version_free(giprobe_sdf_shader_version); + + if (decal_atlas.textures.size()) { + ERR_PRINT("Decal Atlas: " + itos(decal_atlas.textures.size()) + " textures were not removed from the atlas."); + } + + if (decal_atlas.texture.is_valid()) { + RD::get_singleton()->free(decal_atlas.texture); + } } diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h index 49f77e49e1..f874c3baf8 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h @@ -52,6 +52,8 @@ public: virtual void set_code(const String &p_Code) = 0; virtual void set_default_texture_param(const StringName &p_name, RID p_texture) = 0; virtual void get_param_list(List<PropertyInfo> *p_param_list) const = 0; + + virtual void get_instance_param_list(List<InstanceShaderParam> *p_param_list) const = 0; virtual bool is_param_texture(const StringName &p_param) const = 0; virtual bool is_animated() const = 0; virtual bool casts_shadows() const = 0; @@ -69,7 +71,15 @@ public: virtual void set_render_priority(int p_priority) = 0; virtual void set_next_pass(RID p_pass) = 0; virtual void update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) = 0; - virtual ~MaterialData() {} + virtual ~MaterialData(); + + private: + friend class RasterizerStorageRD; + RID self; + List<RID>::Element *global_buffer_E = nullptr; + List<RID>::Element *global_texture_E = nullptr; + uint64_t global_textures_pass = 0; + Map<StringName, uint64_t> used_global_textures; }; typedef MaterialData *(*MaterialDataRequestFunction)(ShaderData *); @@ -173,6 +183,51 @@ private: RID default_rd_textures[DEFAULT_RD_TEXTURE_MAX]; RID default_rd_samplers[RS::CANVAS_ITEM_TEXTURE_FILTER_MAX][RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX]; + /* DECAL ATLAS */ + + struct DecalAtlas { + struct Texture { + + int panorama_to_dp_users; + int users; + Rect2 uv_rect; + }; + + struct SortItem { + RID texture; + Size2i pixel_size; + Size2i size; + Point2i pos; + + bool operator<(const SortItem &p_item) const { + //sort larger to smaller + if (size.height == p_item.size.height) { + return size.width > p_item.size.width; + } else { + return size.height > p_item.size.height; + } + } + }; + + HashMap<RID, Texture> textures; + bool dirty = true; + int mipmaps = 5; + + RID texture; + RID texture_srgb; + struct MipMap { + RID fb; + RID texture; + Size2i size; + }; + Vector<MipMap> texture_mipmaps; + + Size2i size; + + } decal_atlas; + + void _update_decal_atlas(); + /* SHADER */ struct Material; @@ -403,6 +458,28 @@ private: mutable RID_Owner<ReflectionProbe> reflection_probe_owner; + /* DECAL */ + + struct Decal { + + Vector3 extents = Vector3(1, 1, 1); + RID textures[RS::DECAL_TEXTURE_MAX]; + float emission_energy = 1.0; + float albedo_mix = 1.0; + Color modulate = Color(1, 1, 1, 1); + uint32_t cull_mask = (1 << 20) - 1; + float upper_fade = 0.3; + float lower_fade = 0.3; + bool distance_fade = false; + float distance_fade_begin = 10; + float distance_fade_length = 1; + float normal_fade = 0.0; + + RasterizerScene::InstanceDependency instance_dependency; + }; + + mutable RID_Owner<Decal> decal_owner; + /* GI PROBE */ struct GIProbe { @@ -463,13 +540,11 @@ private: bool flags[RENDER_TARGET_FLAG_MAX]; RID backbuffer; //used for effects - RID backbuffer_fb; + RID backbuffer_mipmap0; struct BackbufferMipmap { RID mipmap; - RID mipmap_fb; RID mipmap_copy; - RID mipmap_copy_fb; }; Vector<BackbufferMipmap> backbuffer_mipmaps; @@ -490,6 +565,73 @@ private: void _update_render_target(RenderTarget *rt); void _create_render_target_backbuffer(RenderTarget *rt); + /* GLOBAL SHADER VARIABLES */ + + struct GlobalVariables { + + enum { + BUFFER_DIRTY_REGION_SIZE = 1024 + }; + struct Variable { + Set<RID> texture_materials; // materials using this + + RS::GlobalVariableType type; + Variant value; + Variant override; + int32_t buffer_index; //for vectors + int32_t buffer_elements; //for vectors + }; + + HashMap<StringName, Variable> variables; + + struct Value { + float x; + float y; + float z; + float w; + }; + + struct ValueInt { + int32_t x; + int32_t y; + int32_t z; + int32_t w; + }; + + struct ValueUInt { + uint32_t x; + uint32_t y; + uint32_t z; + uint32_t w; + }; + + struct ValueUsage { + uint32_t elements = 0; + }; + + List<RID> materials_using_buffer; + List<RID> materials_using_texture; + + RID buffer; + Value *buffer_values; + ValueUsage *buffer_usage; + bool *buffer_dirty_regions; + uint32_t buffer_dirty_region_count = 0; + + uint32_t buffer_size; + + bool must_update_texture_materials = false; + bool must_update_buffer_materials = false; + + HashMap<RID, int32_t> instance_buffer_pos; + + } global_variables; + + int32_t _global_variable_allocate(uint32_t p_elements); + void _global_variable_store_in_buffer(int32_t p_index, RS::GlobalVariableType p_type, const Variant &p_value); + void _global_variable_mark_buffer_dirty(int32_t p_index, int32_t p_elements); + + void _update_global_variables(); /* EFFECTS */ RasterizerEffectsRD effects; @@ -535,6 +677,20 @@ public: virtual Size2 texture_size_with_proxy(RID p_proxy); + virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false); + virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false); + + RID decal_atlas_get_texture() const; + RID decal_atlas_get_texture_srgb() const; + _FORCE_INLINE_ Rect2 decal_atlas_get_texture_rect(RID p_texture) { + DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture); + if (!t) { + return Rect2(); + } + + return t->uv_rect; + } + //internal usage _FORCE_INLINE_ RID texture_get_rd_texture(RID p_texture, bool p_srgb = false) { @@ -596,6 +752,8 @@ public: bool material_is_animated(RID p_material); bool material_casts_shadows(RID p_material); + void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters); + void material_update_dependency(RID p_material, RasterizerScene::InstanceBase *p_instance); void material_force_update_textures(RID p_material, ShaderType p_shader_type); @@ -886,6 +1044,14 @@ public: return light->param[p_param]; } + _FORCE_INLINE_ RID light_get_projector(RID p_light) { + + const Light *light = light_owner.getornull(p_light); + ERR_FAIL_COND_V(!light, RID()); + + return light->projector; + } + _FORCE_INLINE_ Color light_get_color(RID p_light) { const Light *light = light_owner.getornull(p_light); @@ -926,6 +1092,14 @@ public: return light->negative; } + _FORCE_INLINE_ float light_get_transmittance_bias(RID p_light) const { + + const Light *light = light_owner.getornull(p_light); + ERR_FAIL_COND_V(!light, 0.0); + + return light->param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS]; + } + bool light_get_use_gi(RID p_light); uint64_t light_get_version(RID p_light) const; @@ -966,6 +1140,81 @@ public: void base_update_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance); void skeleton_update_dependency(RID p_skeleton, RasterizerScene::InstanceBase *p_instance); + /* DECAL API */ + + virtual RID decal_create(); + virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents); + virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture); + virtual void decal_set_emission_energy(RID p_decal, float p_energy); + virtual void decal_set_albedo_mix(RID p_decal, float p_mix); + virtual void decal_set_modulate(RID p_decal, const Color &p_modulate); + virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers); + virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length); + virtual void decal_set_fade(RID p_decal, float p_above, float p_below); + virtual void decal_set_normal_fade(RID p_decal, float p_fade); + + _FORCE_INLINE_ Vector3 decal_get_extents(RID p_decal) { + const Decal *decal = decal_owner.getornull(p_decal); + return decal->extents; + } + + _FORCE_INLINE_ RID decal_get_texture(RID p_decal, RS::DecalTexture p_texture) { + const Decal *decal = decal_owner.getornull(p_decal); + return decal->textures[p_texture]; + } + + _FORCE_INLINE_ Color decal_get_modulate(RID p_decal) { + const Decal *decal = decal_owner.getornull(p_decal); + return decal->modulate; + } + + _FORCE_INLINE_ float decal_get_emission_energy(RID p_decal) { + const Decal *decal = decal_owner.getornull(p_decal); + return decal->emission_energy; + } + + _FORCE_INLINE_ float decal_get_albedo_mix(RID p_decal) { + const Decal *decal = decal_owner.getornull(p_decal); + return decal->albedo_mix; + } + + _FORCE_INLINE_ uint32_t decal_get_cull_mask(RID p_decal) { + const Decal *decal = decal_owner.getornull(p_decal); + return decal->cull_mask; + } + + _FORCE_INLINE_ float decal_get_upper_fade(RID p_decal) { + const Decal *decal = decal_owner.getornull(p_decal); + return decal->upper_fade; + } + + _FORCE_INLINE_ float decal_get_lower_fade(RID p_decal) { + const Decal *decal = decal_owner.getornull(p_decal); + return decal->lower_fade; + } + + _FORCE_INLINE_ float decal_get_normal_fade(RID p_decal) { + const Decal *decal = decal_owner.getornull(p_decal); + return decal->normal_fade; + } + + _FORCE_INLINE_ bool decal_is_distance_fade_enabled(RID p_decal) { + const Decal *decal = decal_owner.getornull(p_decal); + return decal->distance_fade; + } + + _FORCE_INLINE_ float decal_get_distance_fade_begin(RID p_decal) { + const Decal *decal = decal_owner.getornull(p_decal); + return decal->distance_fade_begin; + } + + _FORCE_INLINE_ float decal_get_distance_fade_length(RID p_decal) { + const Decal *decal = decal_owner.getornull(p_decal); + return decal->distance_fade_length; + } + + virtual AABB decal_get_aabb(RID p_decal) const; + /* GI PROBE API */ RID gi_probe_create(); @@ -1076,6 +1325,27 @@ public: virtual bool particles_is_inactive(RID p_particles) const { return false; } + /* GLOBAL VARIABLES API */ + + virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value); + virtual void global_variable_remove(const StringName &p_name); + virtual Vector<StringName> global_variable_get_list() const; + + virtual void global_variable_set(const StringName &p_name, const Variant &p_value); + virtual void global_variable_set_override(const StringName &p_name, const Variant &p_value); + virtual Variant global_variable_get(const StringName &p_name) const; + virtual RS::GlobalVariableType global_variable_get_type(const StringName &p_name) const; + RS::GlobalVariableType global_variable_get_type_internal(const StringName &p_name) const; + + virtual void global_variables_load_settings(bool p_load_textures = true); + virtual void global_variables_clear(); + + virtual int32_t global_variables_instance_allocate(RID p_instance); + virtual void global_variables_instance_free(RID p_instance); + virtual void global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value); + + RID global_variables_get_storage_buffer() const; + /* RENDER TARGET API */ RID render_target_create(); @@ -1097,6 +1367,7 @@ public: Size2 render_target_get_size(RID p_render_target); RID render_target_get_rd_framebuffer(RID p_render_target); + RID render_target_get_rd_texture(RID p_render_target); RS::InstanceType get_base_type(RID p_rid) const; @@ -1124,7 +1395,7 @@ public: virtual uint64_t get_captured_timestamp_cpu_time(uint32_t p_index) const; virtual String get_captured_timestamp_name(uint32_t p_index) const; - static RasterizerStorage *base_singleton; + static RasterizerStorageRD *base_singleton; RasterizerEffectsRD *get_effects(); diff --git a/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp b/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp index 4a0b4f02b1..9cbff2571a 100644 --- a/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp +++ b/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp @@ -32,6 +32,8 @@ #include "core/os/os.h" #include "core/project_settings.h" +#include "rasterizer_storage_rd.h" +#include "servers/rendering_server.h" #define SL ShaderLanguage @@ -91,6 +93,9 @@ static int _get_datatype_size(SL::DataType p_type) { case SL::TYPE_USAMPLER3D: return 16; case SL::TYPE_SAMPLERCUBE: return 16; case SL::TYPE_STRUCT: return 0; + case SL::TYPE_MAX: { + ERR_FAIL_V(0); + }; } ERR_FAIL_V(0); @@ -131,6 +136,9 @@ static int _get_datatype_alignment(SL::DataType p_type) { case SL::TYPE_USAMPLER3D: return 16; case SL::TYPE_SAMPLERCUBE: return 16; case SL::TYPE_STRUCT: return 0; + case SL::TYPE_MAX: { + ERR_FAIL_V(0); + } } ERR_FAIL_V(0); @@ -341,6 +349,71 @@ void ShaderCompilerRD::_dump_function_deps(const SL::ShaderNode *p_node, const S } } +static String _get_global_variable_from_type_and_index(const String &p_buffer, const String &p_index, ShaderLanguage::DataType p_type) { + switch (p_type) { + case ShaderLanguage::TYPE_BOOL: { + return "(" + p_buffer + "[" + p_index + "].x != 0.0)"; + } + case ShaderLanguage::TYPE_BVEC2: { + return "(" + p_buffer + "[" + p_index + "].xy != vec2(0.0))"; + } + case ShaderLanguage::TYPE_BVEC3: { + return "(" + p_buffer + "[" + p_index + "].xyz != vec3(0.0))"; + } + case ShaderLanguage::TYPE_BVEC4: { + return "(" + p_buffer + "[" + p_index + "].xyzw != vec4(0.0))"; + } + case ShaderLanguage::TYPE_INT: { + return "floatBitsToInt(" + p_buffer + "[" + p_index + "].x)"; + } + case ShaderLanguage::TYPE_IVEC2: { + return "floatBitsToInt(" + p_buffer + "[" + p_index + "].xy)"; + } + case ShaderLanguage::TYPE_IVEC3: { + return "floatBitsToInt(" + p_buffer + "[" + p_index + "].xyz)"; + } + case ShaderLanguage::TYPE_IVEC4: { + return "floatBitsToInt(" + p_buffer + "[" + p_index + "].xyzw)"; + } + case ShaderLanguage::TYPE_UINT: { + return "floatBitsToUInt(" + p_buffer + "[" + p_index + "].x)"; + } + case ShaderLanguage::TYPE_UVEC2: { + return "floatBitsToUInt(" + p_buffer + "[" + p_index + "].xy)"; + } + case ShaderLanguage::TYPE_UVEC3: { + return "floatBitsToUInt(" + p_buffer + "[" + p_index + "].xyz)"; + } + case ShaderLanguage::TYPE_UVEC4: { + return "floatBitsToUInt(" + p_buffer + "[" + p_index + "].xyzw)"; + } + case ShaderLanguage::TYPE_FLOAT: { + return "(" + p_buffer + "[" + p_index + "].x)"; + } + case ShaderLanguage::TYPE_VEC2: { + return "(" + p_buffer + "[" + p_index + "].xy)"; + } + case ShaderLanguage::TYPE_VEC3: { + return "(" + p_buffer + "[" + p_index + "].xyz)"; + } + case ShaderLanguage::TYPE_VEC4: { + return "(" + p_buffer + "[" + p_index + "].xyzw)"; + } + case ShaderLanguage::TYPE_MAT2: { + return "mat2(" + p_buffer + "[" + p_index + "].xy," + p_buffer + "[" + p_index + "+1].xy)"; + } + case ShaderLanguage::TYPE_MAT3: { + return "mat3(" + p_buffer + "[" + p_index + "].xyz," + p_buffer + "[" + p_index + "+1].xyz," + p_buffer + "[" + p_index + "+2].xyz)"; + } + case ShaderLanguage::TYPE_MAT4: { + return "mat4(" + p_buffer + "[" + p_index + "].xyzw," + p_buffer + "[" + p_index + "+1].xyzw," + p_buffer + "[" + p_index + "+2].xyzw," + p_buffer + "[" + p_index + "+3].xyzw)"; + } + default: { + ERR_FAIL_V("void"); + } + } +} + String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning) { String code; @@ -408,10 +481,17 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge int max_uniforms = 0; for (Map<StringName, SL::ShaderNode::Uniform>::Element *E = pnode->uniforms.front(); E; E = E->next()) { - if (SL::is_sampler_type(E->get().type)) + + if (SL::is_sampler_type(E->get().type)) { max_texture_uniforms++; - else + } else { + + if (E->get().scope == SL::ShaderNode::Uniform::SCOPE_INSTANCE) { + continue; //instances are indexed directly, dont need index uniforms + } + max_uniforms++; + } } r_gen_code.texture_uniforms.resize(max_texture_uniforms); @@ -428,12 +508,25 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge String ucode; + if (E->get().scope == SL::ShaderNode::Uniform::SCOPE_INSTANCE) { + //insert, but don't generate any code. + p_actions.uniforms->insert(E->key(), E->get()); + continue; //instances are indexed directly, dont need index uniforms + } if (SL::is_sampler_type(E->get().type)) { ucode = "layout(set = " + itos(actions.texture_layout_set) + ", binding = " + itos(actions.base_texture_binding_index + E->get().texture_order) + ") uniform "; } - ucode += _prestr(E->get().precision); - ucode += _typestr(E->get().type); + bool is_buffer_global = !SL::is_sampler_type(E->get().type) && E->get().scope == SL::ShaderNode::Uniform::SCOPE_GLOBAL; + + if (is_buffer_global) { + //this is an integer to index the global table + ucode += _typestr(ShaderLanguage::TYPE_UINT); + } else { + ucode += _prestr(E->get().precision); + ucode += _typestr(E->get().type); + } + ucode += " " + _mkid(E->key()); ucode += ";\n"; if (SL::is_sampler_type(E->get().type)) { @@ -446,6 +539,10 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge texture.type = E->get().type; texture.filter = E->get().filter; texture.repeat = E->get().repeat; + texture.global = E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL; + if (texture.global) { + r_gen_code.uses_global_textures = true; + } r_gen_code.texture_uniforms.write[E->get().texture_order] = texture; } else { @@ -455,8 +552,14 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge uses_uniforms = true; } uniform_defines.write[E->get().order] = ucode; - uniform_sizes.write[E->get().order] = _get_datatype_size(E->get().type); - uniform_alignments.write[E->get().order] = _get_datatype_alignment(E->get().type); + if (is_buffer_global) { + //globals are indices into the global table + uniform_sizes.write[E->get().order] = _get_datatype_size(ShaderLanguage::TYPE_UINT); + uniform_alignments.write[E->get().order] = _get_datatype_alignment(ShaderLanguage::TYPE_UINT); + } else { + uniform_sizes.write[E->get().order] = _get_datatype_size(E->get().type); + uniform_alignments.write[E->get().order] = _get_datatype_alignment(E->get().type); + } } p_actions.uniforms->insert(E->key(), E->get()); @@ -690,9 +793,29 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge if (p_default_actions.renames.has(vnode->name)) code = p_default_actions.renames[vnode->name]; else { - code = _mkid(vnode->name); - if (actions.base_uniform_string != String() && shader->uniforms.has(vnode->name) && shader->uniforms[vnode->name].texture_order < 0) { - code = actions.base_uniform_string + code; + if (shader->uniforms.has(vnode->name)) { + //its a uniform! + const ShaderLanguage::ShaderNode::Uniform &u = shader->uniforms[vnode->name]; + if (u.texture_order >= 0) { + code = _mkid(vnode->name); //texture, use as is + } else { + //a scalar or vector + if (u.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL) { + code = actions.base_uniform_string + _mkid(vnode->name); //texture, use as is + //global variable, this means the code points to an index to the global table + code = _get_global_variable_from_type_and_index(p_default_actions.global_buffer_array_variable, code, u.type); + } else if (u.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { + //instance variable, index it as such + code = "(" + p_default_actions.instance_uniform_index_variable + "+" + itos(u.instance_index) + ")"; + code = _get_global_variable_from_type_and_index(p_default_actions.global_buffer_array_variable, code, u.type); + } else { + //regular uniform, index from UBO + code = actions.base_uniform_string + _mkid(vnode->name); + } + } + + } else { + code = _mkid(vnode->name); //its something else (local var most likely) use as is } } @@ -1037,9 +1160,14 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge return code; } +ShaderLanguage::DataType ShaderCompilerRD::_get_variable_type(const StringName &p_type) { + RS::GlobalVariableType gvt = ((RasterizerStorageRD *)(RasterizerStorage::base_singleton))->global_variable_get_type_internal(p_type); + return RS::global_variable_type_get_shader_datatype(gvt); +} + Error ShaderCompilerRD::compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code) { - Error err = parser.compile(p_code, ShaderTypes::get_singleton()->get_functions(p_mode), ShaderTypes::get_singleton()->get_modes(p_mode), ShaderTypes::get_singleton()->get_types()); + Error err = parser.compile(p_code, ShaderTypes::get_singleton()->get_functions(p_mode), ShaderTypes::get_singleton()->get_modes(p_mode), ShaderTypes::get_singleton()->get_types(), _get_variable_type); if (err != OK) { @@ -1060,6 +1188,7 @@ Error ShaderCompilerRD::compile(RS::ShaderMode p_mode, const String &p_code, Ide r_gen_code.light = String(); r_gen_code.uses_fragment_time = false; r_gen_code.uses_vertex_time = false; + r_gen_code.uses_global_textures = false; used_name_defines.clear(); used_rmode_defines.clear(); diff --git a/servers/rendering/rasterizer_rd/shader_compiler_rd.h b/servers/rendering/rasterizer_rd/shader_compiler_rd.h index 7d78469e9c..16d53197a7 100644 --- a/servers/rendering/rasterizer_rd/shader_compiler_rd.h +++ b/servers/rendering/rasterizer_rd/shader_compiler_rd.h @@ -57,6 +57,7 @@ public: ShaderLanguage::ShaderNode::Uniform::Hint hint; ShaderLanguage::TextureFilter filter; ShaderLanguage::TextureRepeat repeat; + bool global; }; Vector<Texture> texture_uniforms; @@ -70,6 +71,7 @@ public: String fragment; String light; + bool uses_global_textures; bool uses_fragment_time; bool uses_vertex_time; }; @@ -86,6 +88,8 @@ public: int base_texture_binding_index = 0; int texture_layout_set = 0; String base_uniform_string; + String global_buffer_array_variable; + String instance_uniform_index_variable; uint32_t base_varying_index = 0; }; @@ -113,6 +117,8 @@ private: DefaultIdentifierActions actions; + static ShaderLanguage::DataType _get_variable_type(const StringName &p_type); + public: Error compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code); diff --git a/servers/rendering/rasterizer_rd/shaders/SCsub b/servers/rendering/rasterizer_rd/shaders/SCsub index 04a43e3251..a454d144aa 100644 --- a/servers/rendering/rasterizer_rd/shaders/SCsub +++ b/servers/rendering/rasterizer_rd/shaders/SCsub @@ -5,14 +5,15 @@ Import("env") if "RD_GLSL" in env["BUILDERS"]: env.RD_GLSL("canvas.glsl") env.RD_GLSL("canvas_occlusion.glsl") - env.RD_GLSL("blur.glsl") + env.RD_GLSL("copy.glsl") + env.RD_GLSL("copy_to_fb.glsl") env.RD_GLSL("cubemap_roughness.glsl") env.RD_GLSL("cubemap_downsampler.glsl") env.RD_GLSL("cubemap_filter.glsl") env.RD_GLSL("scene_high_end.glsl") env.RD_GLSL("sky.glsl") env.RD_GLSL("tonemap.glsl") - env.RD_GLSL("copy.glsl") + env.RD_GLSL("cube_to_dp.glsl") env.RD_GLSL("giprobe.glsl") env.RD_GLSL("giprobe_debug.glsl") env.RD_GLSL("giprobe_sdf.glsl") diff --git a/servers/rendering/rasterizer_rd/shaders/blur.glsl b/servers/rendering/rasterizer_rd/shaders/blur.glsl deleted file mode 100644 index 87c20ebaef..0000000000 --- a/servers/rendering/rasterizer_rd/shaders/blur.glsl +++ /dev/null @@ -1,294 +0,0 @@ -/* clang-format off */ -[vertex] - -#version 450 - -VERSION_DEFINES - -#include "blur_inc.glsl" - -layout(location = 0) out vec2 uv_interp; -/* clang-format on */ - -void main() { - - vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); - uv_interp = base_arr[gl_VertexIndex]; - - if (bool(blur.flags & FLAG_USE_BLUR_SECTION)) { - uv_interp = blur.section.xy + uv_interp * blur.section.zw; - } - - gl_Position = vec4(uv_interp * 2.0 - 1.0, 0.0, 1.0); - - if (bool(blur.flags & FLAG_FLIP_Y)) { - uv_interp.y = 1.0 - uv_interp.y; - } -} - -/* clang-format off */ -[fragment] - -#version 450 - -VERSION_DEFINES - -#include "blur_inc.glsl" - -layout(location = 0) in vec2 uv_interp; -/* clang-format on */ - -layout(set = 0, binding = 0) uniform sampler2D source_color; - -#ifdef MODE_SSAO_MERGE -layout(set = 1, binding = 0) uniform sampler2D source_ssao; -#endif - -#ifdef GLOW_USE_AUTO_EXPOSURE -layout(set = 1, binding = 0) uniform sampler2D source_auto_exposure; -#endif - -layout(location = 0) out vec4 frag_color; - -//DOF -#if defined(MODE_DOF_FAR_BLUR) || defined(MODE_DOF_NEAR_BLUR) - -layout(set = 1, binding = 0) uniform sampler2D dof_source_depth; - -#ifdef DOF_NEAR_BLUR_MERGE -layout(set = 2, binding = 0) uniform sampler2D source_dof_original; -#endif - -#ifdef DOF_QUALITY_LOW -const int dof_kernel_size = 5; -const int dof_kernel_from = 2; -const float dof_kernel[5] = float[](0.153388, 0.221461, 0.250301, 0.221461, 0.153388); -#endif - -#ifdef DOF_QUALITY_MEDIUM -const int dof_kernel_size = 11; -const int dof_kernel_from = 5; -const float dof_kernel[11] = float[](0.055037, 0.072806, 0.090506, 0.105726, 0.116061, 0.119726, 0.116061, 0.105726, 0.090506, 0.072806, 0.055037); - -#endif - -#ifdef DOF_QUALITY_HIGH -const int dof_kernel_size = 21; -const int dof_kernel_from = 10; -const float dof_kernel[21] = float[](0.028174, 0.032676, 0.037311, 0.041944, 0.046421, 0.050582, 0.054261, 0.057307, 0.059587, 0.060998, 0.061476, 0.060998, 0.059587, 0.057307, 0.054261, 0.050582, 0.046421, 0.041944, 0.037311, 0.032676, 0.028174); -#endif - -#endif - -void main() { - -#ifdef MODE_MIPMAP - - vec2 pix_size = blur.pixel_size; - vec4 color = texture(source_color, uv_interp + vec2(-0.5, -0.5) * pix_size); - color += texture(source_color, uv_interp + vec2(0.5, -0.5) * pix_size); - color += texture(source_color, uv_interp + vec2(0.5, 0.5) * pix_size); - color += texture(source_color, uv_interp + vec2(-0.5, 0.5) * pix_size); - frag_color = color / 4.0; - -#endif - -#ifdef MODE_GAUSSIAN_BLUR - - //Simpler blur uses SIGMA2 for the gaussian kernel for a stronger effect - - if (bool(blur.flags & FLAG_HORIZONTAL)) { - - vec2 pix_size = blur.pixel_size; - pix_size *= 0.5; //reading from larger buffer, so use more samples - vec4 color = texture(source_color, uv_interp + vec2(0.0, 0.0) * pix_size) * 0.214607; - color += texture(source_color, uv_interp + vec2(1.0, 0.0) * pix_size) * 0.189879; - color += texture(source_color, uv_interp + vec2(2.0, 0.0) * pix_size) * 0.131514; - color += texture(source_color, uv_interp + vec2(3.0, 0.0) * pix_size) * 0.071303; - color += texture(source_color, uv_interp + vec2(-1.0, 0.0) * pix_size) * 0.189879; - color += texture(source_color, uv_interp + vec2(-2.0, 0.0) * pix_size) * 0.131514; - color += texture(source_color, uv_interp + vec2(-3.0, 0.0) * pix_size) * 0.071303; - frag_color = color; - } else { - - vec2 pix_size = blur.pixel_size; - vec4 color = texture(source_color, uv_interp + vec2(0.0, 0.0) * pix_size) * 0.38774; - color += texture(source_color, uv_interp + vec2(0.0, 1.0) * pix_size) * 0.24477; - color += texture(source_color, uv_interp + vec2(0.0, 2.0) * pix_size) * 0.06136; - color += texture(source_color, uv_interp + vec2(0.0, -1.0) * pix_size) * 0.24477; - color += texture(source_color, uv_interp + vec2(0.0, -2.0) * pix_size) * 0.06136; - frag_color = color; - } -#endif - -#ifdef MODE_GAUSSIAN_GLOW - - //Glow uses larger sigma 1 for a more rounded blur effect - -#define GLOW_ADD(m_ofs, m_mult) \ - { \ - vec2 ofs = uv_interp + m_ofs * pix_size; \ - vec4 c = texture(source_color, ofs) * m_mult; \ - if (any(lessThan(ofs, vec2(0.0))) || any(greaterThan(ofs, vec2(1.0)))) { \ - c *= 0.0; \ - } \ - color += c; \ - } - - if (bool(blur.flags & FLAG_HORIZONTAL)) { - - vec2 pix_size = blur.pixel_size; - pix_size *= 0.5; //reading from larger buffer, so use more samples - vec4 color = texture(source_color, uv_interp + vec2(0.0, 0.0) * pix_size) * 0.174938; - GLOW_ADD(vec2(1.0, 0.0), 0.165569); - GLOW_ADD(vec2(2.0, 0.0), 0.140367); - GLOW_ADD(vec2(3.0, 0.0), 0.106595); - GLOW_ADD(vec2(-1.0, 0.0), 0.165569); - GLOW_ADD(vec2(-2.0, 0.0), 0.140367); - GLOW_ADD(vec2(-3.0, 0.0), 0.106595); - color *= blur.glow_strength; - frag_color = color; - } else { - - vec2 pix_size = blur.pixel_size; - vec4 color = texture(source_color, uv_interp + vec2(0.0, 0.0) * pix_size) * 0.288713; - GLOW_ADD(vec2(0.0, 1.0), 0.233062); - GLOW_ADD(vec2(0.0, 2.0), 0.122581); - GLOW_ADD(vec2(0.0, -1.0), 0.233062); - GLOW_ADD(vec2(0.0, -2.0), 0.122581); - color *= blur.glow_strength; - frag_color = color; - } - -#undef GLOW_ADD - - if (bool(blur.flags & FLAG_GLOW_FIRST_PASS)) { -#ifdef GLOW_USE_AUTO_EXPOSURE - - frag_color /= texelFetch(source_auto_exposure, ivec2(0, 0), 0).r / blur.glow_auto_exposure_grey; -#endif - frag_color *= blur.glow_exposure; - - float luminance = max(frag_color.r, max(frag_color.g, frag_color.b)); - float feedback = max(smoothstep(blur.glow_hdr_threshold, blur.glow_hdr_threshold + blur.glow_hdr_scale, luminance), blur.glow_bloom); - - frag_color = min(frag_color * feedback, vec4(blur.glow_luminance_cap)); - } - -#endif - -#ifdef MODE_DOF_FAR_BLUR - - vec4 color_accum = vec4(0.0); - - float depth = texture(dof_source_depth, uv_interp, 0.0).r; - depth = depth * 2.0 - 1.0; - - if (bool(blur.flags & FLAG_USE_ORTHOGONAL_PROJECTION)) { - depth = ((depth + (blur.camera_z_far + blur.camera_z_near) / (blur.camera_z_far - blur.camera_z_near)) * (blur.camera_z_far - blur.camera_z_near)) / 2.0; - } else { - depth = 2.0 * blur.camera_z_near * blur.camera_z_far / (blur.camera_z_far + blur.camera_z_near - depth * (blur.camera_z_far - blur.camera_z_near)); - } - - float amount = smoothstep(blur.dof_begin, blur.dof_end, depth); - float k_accum = 0.0; - - for (int i = 0; i < dof_kernel_size; i++) { - - int int_ofs = i - dof_kernel_from; - vec2 tap_uv = uv_interp + blur.dof_dir * float(int_ofs) * amount * blur.dof_radius; - - float tap_k = dof_kernel[i]; - - float tap_depth = texture(dof_source_depth, tap_uv, 0.0).r; - tap_depth = tap_depth * 2.0 - 1.0; - - if (bool(blur.flags & FLAG_USE_ORTHOGONAL_PROJECTION)) { - - tap_depth = ((tap_depth + (blur.camera_z_far + blur.camera_z_near) / (blur.camera_z_far - blur.camera_z_near)) * (blur.camera_z_far - blur.camera_z_near)) / 2.0; - } else { - tap_depth = 2.0 * blur.camera_z_near * blur.camera_z_far / (blur.camera_z_far + blur.camera_z_near - tap_depth * (blur.camera_z_far - blur.camera_z_near)); - } - - float tap_amount = mix(smoothstep(blur.dof_begin, blur.dof_end, tap_depth), 1.0, int_ofs == 0); - tap_amount *= tap_amount * tap_amount; //prevent undesired glow effect - - vec4 tap_color = texture(source_color, tap_uv, 0.0) * tap_k; - - k_accum += tap_k * tap_amount; - color_accum += tap_color * tap_amount; - } - - if (k_accum > 0.0) { - color_accum /= k_accum; - } - - frag_color = color_accum; ///k_accum; - -#endif - -#ifdef MODE_DOF_NEAR_BLUR - - vec4 color_accum = vec4(0.0); - - float max_accum = 0.0; - - for (int i = 0; i < dof_kernel_size; i++) { - - int int_ofs = i - dof_kernel_from; - vec2 tap_uv = uv_interp + blur.dof_dir * float(int_ofs) * blur.dof_radius; - float ofs_influence = max(0.0, 1.0 - float(abs(int_ofs)) / float(dof_kernel_from)); - - float tap_k = dof_kernel[i]; - - vec4 tap_color = texture(source_color, tap_uv, 0.0); - - float tap_depth = texture(dof_source_depth, tap_uv, 0.0).r; - tap_depth = tap_depth * 2.0 - 1.0; - if (bool(blur.flags & FLAG_USE_ORTHOGONAL_PROJECTION)) { - - tap_depth = ((tap_depth + (blur.camera_z_far + blur.camera_z_near) / (blur.camera_z_far - blur.camera_z_near)) * (blur.camera_z_far - blur.camera_z_near)) / 2.0; - } else { - tap_depth = 2.0 * blur.camera_z_near * blur.camera_z_far / (blur.camera_z_far + blur.camera_z_near - tap_depth * (blur.camera_z_far - blur.camera_z_near)); - } - float tap_amount = 1.0 - smoothstep(blur.dof_end, blur.dof_begin, tap_depth); - tap_amount *= tap_amount * tap_amount; //prevent undesired glow effect - - if (bool(blur.flags & FLAG_DOF_NEAR_FIRST_TAP)) { - tap_color.a = 1.0 - smoothstep(blur.dof_end, blur.dof_begin, tap_depth); - } - - max_accum = max(max_accum, tap_amount * ofs_influence); - - color_accum += tap_color * tap_k; - } - - color_accum.a = max(color_accum.a, sqrt(max_accum)); - -#ifdef DOF_NEAR_BLUR_MERGE - { - vec4 original = texture(source_dof_original, uv_interp, 0.0); - color_accum = mix(original, color_accum, color_accum.a); - } -#endif - - if (bool(blur.flags & FLAG_DOF_NEAR_FIRST_TAP)) { - frag_color = color_accum; - } -#endif - -#ifdef MODE_SIMPLE_COPY - vec4 color = texture(source_color, uv_interp, 0.0); - if (bool(blur.flags & FLAG_COPY_FORCE_LUMINANCE)) { - color.rgb = vec3(max(max(color.r, color.g), color.b)); - } - frag_color = color; -#endif - -#ifdef MODE_SSAO_MERGE - vec4 color = texture(source_color, uv_interp, 0.0); - float ssao = texture(source_ssao, uv_interp, 0.0).r; - frag_color = vec4(mix(color.rgb, color.rgb * mix(blur.ssao_color.rgb, vec3(1.0), ssao), color.a), 1.0); - -#endif -} diff --git a/servers/rendering/rasterizer_rd/shaders/blur_inc.glsl b/servers/rendering/rasterizer_rd/shaders/blur_inc.glsl deleted file mode 100644 index 33ba9de7bb..0000000000 --- a/servers/rendering/rasterizer_rd/shaders/blur_inc.glsl +++ /dev/null @@ -1,35 +0,0 @@ -#define FLAG_HORIZONTAL (1 << 0) -#define FLAG_USE_BLUR_SECTION (1 << 1) -#define FLAG_USE_ORTHOGONAL_PROJECTION (1 << 2) -#define FLAG_DOF_NEAR_FIRST_TAP (1 << 3) -#define FLAG_GLOW_FIRST_PASS (1 << 4) -#define FLAG_FLIP_Y (1 << 5) -#define FLAG_COPY_FORCE_LUMINANCE (1 << 6) - -layout(push_constant, binding = 1, std430) uniform Blur { - vec4 section; - vec2 pixel_size; - uint flags; - uint pad; - // Glow. - float glow_strength; - float glow_bloom; - float glow_hdr_threshold; - float glow_hdr_scale; - float glow_exposure; - float glow_white; - float glow_luminance_cap; - float glow_auto_exposure_grey; - // DOF. - float dof_begin; - float dof_end; - float dof_radius; - float dof_pad; - - vec2 dof_dir; - float camera_z_far; - float camera_z_near; - - vec4 ssao_color; -} -blur; diff --git a/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl b/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl index 1ac43480cd..a39866004b 100644 --- a/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl +++ b/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl @@ -132,6 +132,11 @@ layout(set = 2, binding = 6) uniform sampler shadow_sampler; #endif +layout(set = 2, binding = 7, std430) restrict readonly buffer GlobalVariableData { + vec4 data[]; +} +global_variables; + /* SET3: Render Target Data */ #ifdef SCREEN_TEXTURE_USED diff --git a/servers/rendering/rasterizer_rd/shaders/copy.glsl b/servers/rendering/rasterizer_rd/shaders/copy.glsl index cbb9b546a3..2d7661f65f 100644 --- a/servers/rendering/rasterizer_rd/shaders/copy.glsl +++ b/servers/rendering/rasterizer_rd/shaders/copy.glsl @@ -1,86 +1,220 @@ /* clang-format off */ -[vertex] +[compute] #version 450 VERSION_DEFINES -layout(location = 0) out vec2 uv_interp; +layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; /* clang-format on */ -void main() { +#define FLAG_HORIZONTAL (1 << 0) +#define FLAG_USE_BLUR_SECTION (1 << 1) +#define FLAG_USE_ORTHOGONAL_PROJECTION (1 << 2) +#define FLAG_DOF_NEAR_FIRST_TAP (1 << 3) +#define FLAG_GLOW_FIRST_PASS (1 << 4) +#define FLAG_FLIP_Y (1 << 5) +#define FLAG_FORCE_LUMINANCE (1 << 6) +#define FLAG_COPY_ALL_SOURCE (1 << 7) + +layout(push_constant, binding = 1, std430) uniform Params { + ivec4 section; + ivec2 target; + uint flags; + uint pad; + // Glow. + float glow_strength; + float glow_bloom; + float glow_hdr_threshold; + float glow_hdr_scale; + + float glow_exposure; + float glow_white; + float glow_luminance_cap; + float glow_auto_exposure_grey; + // DOF. + float camera_z_far; + float camera_z_near; + uint pad2[2]; +} +params; - vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); - uv_interp = base_arr[gl_VertexIndex]; +layout(set = 0, binding = 0) uniform sampler2D source_color; - gl_Position = vec4(uv_interp * 2.0 - 1.0, 0.0, 1.0); -} +#ifdef GLOW_USE_AUTO_EXPOSURE +layout(set = 1, binding = 0) uniform sampler2D source_auto_exposure; +#endif -/* clang-format off */ -[fragment] +#if defined(MODE_LINEARIZE_DEPTH_COPY) || defined(MODE_SIMPLE_COPY_DEPTH) +layout(r32f, set = 3, binding = 0) uniform restrict writeonly image2D dest_buffer; +#elif defined(DST_IMAGE_8BIT) +layout(rgba8, set = 3, binding = 0) uniform restrict writeonly image2D dest_buffer; +#else +layout(rgba32f, set = 3, binding = 0) uniform restrict writeonly image2D dest_buffer; +#endif -#version 450 +void main() { -VERSION_DEFINES + // Pixel being shaded + ivec2 pos = ivec2(gl_GlobalInvocationID.xy); + if (any(greaterThan(pos, params.section.zw))) { //too large, do nothing + return; + } -layout(location = 0) in vec2 uv_interp; -/* clang-format on */ +#ifdef MODE_MIPMAP + + ivec2 base_pos = (pos + params.section.xy) << 1; + vec4 color = texelFetch(source_color, base_pos, 0); + color += texelFetch(source_color, base_pos + ivec2(0, 1), 0); + color += texelFetch(source_color, base_pos + ivec2(1, 0), 0); + color += texelFetch(source_color, base_pos + ivec2(1, 1), 0); + color /= 4.0; -#ifdef MODE_CUBE_TO_DP + imageStore(dest_buffer, pos + params.target, color); +#endif -layout(set = 0, binding = 0) uniform samplerCube source_cube; +#ifdef MODE_GAUSSIAN_BLUR -layout(push_constant, binding = 0, std430) uniform Params { - float bias; - float z_far; - float z_near; - bool z_flip; -} -params; + //Simpler blur uses SIGMA2 for the gaussian kernel for a stronger effect -layout(location = 0) out float depth_buffer; + if (bool(params.flags & FLAG_HORIZONTAL)) { + ivec2 base_pos = (pos + params.section.xy) << 1; + vec4 color = texelFetch(source_color, base_pos + ivec2(0, 0), 0) * 0.214607; + color += texelFetch(source_color, base_pos + ivec2(1, 0), 0) * 0.189879; + color += texelFetch(source_color, base_pos + ivec2(2, 0), 0) * 0.131514; + color += texelFetch(source_color, base_pos + ivec2(3, 0), 0) * 0.071303; + color += texelFetch(source_color, base_pos + ivec2(-1, 0), 0) * 0.189879; + color += texelFetch(source_color, base_pos + ivec2(-2, 0), 0) * 0.131514; + color += texelFetch(source_color, base_pos + ivec2(-3, 0), 0) * 0.071303; + imageStore(dest_buffer, pos + params.target, color); + } else { + + ivec2 base_pos = (pos + params.section.xy); + vec4 color = texelFetch(source_color, base_pos + ivec2(0, 0), 0) * 0.38774; + color += texelFetch(source_color, base_pos + ivec2(0, 1), 0) * 0.24477; + color += texelFetch(source_color, base_pos + ivec2(0, 2), 0) * 0.06136; + color += texelFetch(source_color, base_pos + ivec2(0, -1), 0) * 0.24477; + color += texelFetch(source_color, base_pos + ivec2(0, -2), 0) * 0.06136; + imageStore(dest_buffer, pos + params.target, color); + } #endif -void main() { +#ifdef MODE_GAUSSIAN_GLOW -#ifdef MODE_CUBE_TO_DP + //Glow uses larger sigma 1 for a more rounded blur effect - vec3 normal = vec3(uv_interp * 2.0 - 1.0, 0.0); +#define GLOW_ADD(m_ofs, m_mult) \ + { \ + ivec2 ofs = base_pos + m_ofs; \ + if (all(greaterThanEqual(ofs, section_begin)) && all(lessThan(ofs, section_end))) { \ + color += texelFetch(source_color, ofs, 0) * m_mult; \ + } \ + } + + vec4 color = vec4(0.0); + + if (bool(params.flags & FLAG_HORIZONTAL)) { + + ivec2 base_pos = (pos + params.section.xy) << 1; + ivec2 section_begin = params.section.xy << 1; + ivec2 section_end = section_begin + (params.section.zw << 1); + + GLOW_ADD(ivec2(0, 0), 0.174938); + GLOW_ADD(ivec2(1, 0), 0.165569); + GLOW_ADD(ivec2(2, 0), 0.140367); + GLOW_ADD(ivec2(3, 0), 0.106595); + GLOW_ADD(ivec2(-1, 0), 0.165569); + GLOW_ADD(ivec2(-2, 0), 0.140367); + GLOW_ADD(ivec2(-3, 0), 0.106595); + color *= params.glow_strength; + } else { - normal.z = 0.5 - 0.5 * ((normal.x * normal.x) + (normal.y * normal.y)); - normal = normalize(normal); + ivec2 base_pos = pos + params.section.xy; + ivec2 section_begin = params.section.xy; + ivec2 section_end = section_begin + params.section.zw; - normal.y = -normal.y; //needs to be flipped to match projection matrix - if (!params.z_flip) { - normal.z = -normal.z; + GLOW_ADD(ivec2(0, 0), 0.288713); + GLOW_ADD(ivec2(0, 1), 0.233062); + GLOW_ADD(ivec2(0, 2), 0.122581); + GLOW_ADD(ivec2(0, -1), 0.233062); + GLOW_ADD(ivec2(0, -2), 0.122581); + color *= params.glow_strength; } - float depth = texture(source_cube, normal).r; +#undef GLOW_ADD - // absolute values for direction cosines, bigger value equals closer to basis axis - vec3 unorm = abs(normal); + if (bool(params.flags & FLAG_GLOW_FIRST_PASS)) { +#ifdef GLOW_USE_AUTO_EXPOSURE + + color /= texelFetch(source_auto_exposure, ivec2(0, 0), 0).r / params.glow_auto_exposure_grey; +#endif + color *= params.glow_exposure; + + float luminance = max(color.r, max(color.g, color.b)); + float feedback = max(smoothstep(params.glow_hdr_threshold, params.glow_hdr_threshold + params.glow_hdr_scale, luminance), params.glow_bloom); + + color = min(color * feedback, vec4(params.glow_luminance_cap)); + } + + imageStore(dest_buffer, pos + params.target, color); + +#endif + +#ifdef MODE_SIMPLE_COPY + + vec4 color; + if (bool(params.flags & FLAG_COPY_ALL_SOURCE)) { + vec2 uv = vec2(pos) / vec2(params.section.zw); + if (bool(params.flags & FLAG_FLIP_Y)) { + uv.y = 1.0 - uv.y; + } + color = textureLod(source_color, uv, 0.0); + + if (bool(params.flags & FLAG_FORCE_LUMINANCE)) { + color.rgb = vec3(max(max(color.r, color.g), color.b)); + } + imageStore(dest_buffer, pos + params.target, color); - if ((unorm.x >= unorm.y) && (unorm.x >= unorm.z)) { - // x code - unorm = normal.x > 0.0 ? vec3(1.0, 0.0, 0.0) : vec3(-1.0, 0.0, 0.0); - } else if ((unorm.y > unorm.x) && (unorm.y >= unorm.z)) { - // y code - unorm = normal.y > 0.0 ? vec3(0.0, 1.0, 0.0) : vec3(0.0, -1.0, 0.0); - } else if ((unorm.z > unorm.x) && (unorm.z > unorm.y)) { - // z code - unorm = normal.z > 0.0 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 0.0, -1.0); } else { - // oh-no we messed up code - // has to be - unorm = vec3(1.0, 0.0, 0.0); + color = texelFetch(source_color, pos + params.section.xy, 0); + + if (bool(params.flags & FLAG_FORCE_LUMINANCE)) { + color.rgb = vec3(max(max(color.r, color.g), color.b)); + } + + if (bool(params.flags & FLAG_FLIP_Y)) { + pos.y = params.section.w - pos.y - 1; + } + + imageStore(dest_buffer, pos + params.target, color); + } + +#endif + +#ifdef MODE_SIMPLE_COPY_DEPTH + + vec4 color = texelFetch(source_color, pos + params.section.xy, 0); + + if (bool(params.flags & FLAG_FLIP_Y)) { + pos.y = params.section.w - pos.y - 1; } - float depth_fix = 1.0 / dot(normal, unorm); + imageStore(dest_buffer, pos + params.target, vec4(color.r)); + +#endif + +#ifdef MODE_LINEARIZE_DEPTH_COPY + + float depth = texelFetch(source_color, pos + params.section.xy, 0).r; + depth = depth * 2.0 - 1.0; + depth = 2.0 * params.camera_z_near * params.camera_z_far / (params.camera_z_far + params.camera_z_near - depth * (params.camera_z_far - params.camera_z_near)); + vec4 color = vec4(depth / params.camera_z_far); - depth = 2.0 * depth - 1.0; - float linear_depth = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - depth * (params.z_far - params.z_near)); - depth_buffer = (linear_depth * depth_fix + params.bias) / params.z_far; + if (bool(params.flags & FLAG_FLIP_Y)) { + pos.y = params.section.w - pos.y - 1; + } + imageStore(dest_buffer, pos + params.target, color); #endif } diff --git a/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl b/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl new file mode 100644 index 0000000000..07f8d09743 --- /dev/null +++ b/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl @@ -0,0 +1,104 @@ +/* clang-format off */ +[vertex] + +#version 450 + +VERSION_DEFINES + +layout(location = 0) out vec2 uv_interp; +/* clang-format on */ + +layout(push_constant, binding = 1, std430) uniform Params { + vec4 section; + vec2 pixel_size; + bool flip_y; + bool use_section; + + bool force_luminance; + uint pad[3]; +} +params; + +void main() { + + vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); + uv_interp = base_arr[gl_VertexIndex]; + + vec2 vpos = uv_interp; + if (params.use_section) { + vpos = params.section.xy + vpos * params.section.zw; + } + + gl_Position = vec4(vpos * 2.0 - 1.0, 0.0, 1.0); + + if (params.flip_y) { + uv_interp.y = 1.0 - uv_interp.y; + } +} + +/* clang-format off */ +[fragment] + +#version 450 + +VERSION_DEFINES + +layout(push_constant, binding = 1, std430) uniform Params { + vec4 section; + vec2 pixel_size; + bool flip_y; + bool use_section; + + bool force_luminance; + bool alpha_to_zero; + uint pad[2]; +} params; + + +layout(location = 0) in vec2 uv_interp; +/* clang-format on */ + +layout(set = 0, binding = 0) uniform sampler2D source_color; + +layout(location = 0) out vec4 frag_color; + +void main() { + + vec2 uv = uv_interp; + +#ifdef MODE_PANORAMA_TO_DP + + //obtain normal from dual paraboloid uv +#define M_PI 3.14159265359 + + float side; + uv.y = modf(uv.y * 2.0, side); + side = side * 2.0 - 1.0; + vec3 normal = vec3(uv * 2.0 - 1.0, 0.0); + normal.z = 0.5 - 0.5 * ((normal.x * normal.x) + (normal.y * normal.y)); + normal *= -side; + normal = normalize(normal); + + //now convert normal to panorama uv + + vec2 st = vec2(atan(normal.x, normal.z), acos(normal.y)); + + if (st.x < 0.0) + st.x += M_PI * 2.0; + + uv = st / vec2(M_PI * 2.0, M_PI); + + if (side < 0.0) { + //uv.y = 1.0 - uv.y; + uv = 1.0 - uv; + } +#endif + vec4 color = textureLod(source_color, uv, 0.0); + if (params.force_luminance) { + color.rgb = vec3(max(max(color.r, color.g), color.b)); + } + if (params.alpha_to_zero) { + color.rgb *= color.a; + } + frag_color = color; +} diff --git a/servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl b/servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl new file mode 100644 index 0000000000..02ebe1a53b --- /dev/null +++ b/servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl @@ -0,0 +1,72 @@ +/* clang-format off */ +[compute] + +#version 450 + +VERSION_DEFINES + +layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; +/* clang-format on */ + +layout(set = 0, binding = 0) uniform samplerCube source_cube; + +layout(push_constant, binding = 1, std430) uniform Params { + ivec2 screen_size; + ivec2 offset; + float bias; + float z_far; + float z_near; + bool z_flip; +} +params; + +layout(r32f, set = 1, binding = 0) uniform restrict writeonly image2D depth_buffer; + +void main() { + + ivec2 pos = ivec2(gl_GlobalInvocationID.xy); + if (any(greaterThan(pos, params.screen_size))) { //too large, do nothing + return; + } + + vec2 pixel_size = 1.0 / vec2(params.screen_size); + vec2 uv = (vec2(pos) + 0.5) * pixel_size; + + vec3 normal = vec3(uv * 2.0 - 1.0, 0.0); + + normal.z = 0.5 - 0.5 * ((normal.x * normal.x) + (normal.y * normal.y)); + normal = normalize(normal); + + normal.y = -normal.y; //needs to be flipped to match projection matrix + if (!params.z_flip) { + normal.z = -normal.z; + } + + float depth = texture(source_cube, normal).r; + + // absolute values for direction cosines, bigger value equals closer to basis axis + vec3 unorm = abs(normal); + + if ((unorm.x >= unorm.y) && (unorm.x >= unorm.z)) { + // x code + unorm = normal.x > 0.0 ? vec3(1.0, 0.0, 0.0) : vec3(-1.0, 0.0, 0.0); + } else if ((unorm.y > unorm.x) && (unorm.y >= unorm.z)) { + // y code + unorm = normal.y > 0.0 ? vec3(0.0, 1.0, 0.0) : vec3(0.0, -1.0, 0.0); + } else if ((unorm.z > unorm.x) && (unorm.z > unorm.y)) { + // z code + unorm = normal.z > 0.0 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 0.0, -1.0); + } else { + // oh-no we messed up code + // has to be + unorm = vec3(1.0, 0.0, 0.0); + } + + float depth_fix = 1.0 / dot(normal, unorm); + + depth = 2.0 * depth - 1.0; + float linear_depth = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - depth * (params.z_far - params.z_near)); + depth = (linear_depth * depth_fix) / params.z_far; + + imageStore(depth_buffer, pos + params.offset, vec4(depth)); +} diff --git a/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl b/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl index 955ae2e588..ec47887036 100644 --- a/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl +++ b/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl @@ -20,9 +20,7 @@ layout(location = 2) in vec4 tangent_attrib; layout(location = 3) in vec4 color_attrib; #endif -#if defined(UV_USED) layout(location = 4) in vec2 uv_attrib; -#endif #if defined(UV2_USED) || defined(USE_LIGHTMAP) layout(location = 5) in vec2 uv2_attrib; @@ -39,9 +37,7 @@ layout(location = 1) out vec3 normal_interp; layout(location = 2) out vec4 color_interp; #endif -#if defined(UV_USED) layout(location = 3) out vec2 uv_interp; -#endif #if defined(UV2_USED) || defined(USE_LIGHTMAP) layout(location = 4) out vec2 uv2_interp; @@ -157,9 +153,7 @@ void main() { #endif } -#if defined(UV_USED) uv_interp = uv_attrib; -#endif #if defined(UV2_USED) || defined(USE_LIGHTMAP) uv2_interp = uv2_attrib; @@ -244,19 +238,13 @@ VERTEX_SHADER_CODE //for dual paraboloid shadow mapping, this is the fastest but least correct way, as it curves straight edges - vec3 vtx = vertex_interp + normalize(vertex_interp) * scene_data.z_offset; + vec3 vtx = vertex_interp; float distance = length(vtx); vtx = normalize(vtx); vtx.xy /= 1.0 - vtx.z; vtx.z = (distance / scene_data.z_far); vtx.z = vtx.z * 2.0 - 1.0; - vertex_interp = vtx; -#else - - float z_ofs = scene_data.z_offset; - z_ofs += max(0.0, 1.0 - abs(normalize(normal_interp).z)) * scene_data.z_slope_scale; - vertex_interp.z -= z_ofs; #endif @@ -267,6 +255,14 @@ VERTEX_SHADER_CODE #else gl_Position = projection_matrix * vec4(vertex_interp, 1.0); #endif + +#ifdef MODE_RENDER_DEPTH + if (scene_data.pancake_shadows) { + if (gl_Position.z <= 0.00001) { + gl_Position.z = 0.00001; + } + } +#endif } /* clang-format off */ @@ -288,9 +284,7 @@ layout(location = 1) in vec3 normal_interp; layout(location = 2) in vec4 color_interp; #endif -#if defined(UV_USED) layout(location = 3) in vec2 uv_interp; -#endif #if defined(UV2_USED) || defined(USE_LIGHTMAP) layout(location = 4) in vec2 uv2_interp; @@ -315,6 +309,11 @@ layout(location = 8) in float dp_clip; #define world_normal_matrix instances.data[instance_index].normal_transform #define projection_matrix scene_data.projection_matrix +#if defined(ENABLE_SSS) && defined(ENABLE_TRANSMITTANCE) +//both required for transmittance to be enabled +#define LIGHT_TRANSMITTANCE_USED +#endif + #ifdef USE_MATERIAL_UNIFORMS layout(set = 5, binding = 0, std140) uniform MaterialUniforms{ /* clang-format off */ @@ -434,9 +433,16 @@ vec3 F0(float metallic, float specular, vec3 albedo) { return mix(vec3(dielectric), albedo, vec3(metallic)); } -void light_compute(vec3 N, vec3 L, vec3 V, vec3 light_color, vec3 attenuation, vec3 diffuse_color, float roughness, float metallic, float specular, float specular_blob_intensity, -#ifdef LIGHT_TRANSMISSION_USED - vec3 transmission, +void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float attenuation, vec3 shadow_attenuation, vec3 diffuse_color, float roughness, float metallic, float specular, float specular_blob_intensity, +#ifdef LIGHT_BACKLIGHT_USED + vec3 backlight, +#endif +#ifdef LIGHT_TRANSMITTANCE_USED + vec4 transmittance_color, + float transmittance_depth, + float transmittance_curve, + float transmittance_boost, + float transmittance_z, #endif #ifdef LIGHT_RIM_USED float rim, float rim_tint, @@ -467,7 +473,7 @@ LIGHT_SHADER_CODE /* clang-format on */ #else - float NdotL = dot(N, L); + float NdotL = min(A + dot(N, L), 1.0); float cNdotL = max(NdotL, 0.0); // clamped NdotL float NdotV = dot(N, V); float cNdotV = max(NdotV, 0.0); @@ -477,11 +483,11 @@ LIGHT_SHADER_CODE #endif #if defined(SPECULAR_BLINN) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED) - float cNdotH = max(dot(N, H), 0.0); + float cNdotH = clamp(A + dot(N, H), 0.0, 1.0); #endif #if defined(DIFFUSE_BURLEY) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED) - float cLdotH = max(dot(L, H), 0.0); + float cLdotH = clamp(A + dot(L, H), 0.0, 1.0); #endif if (metallic < 1.0) { @@ -538,16 +544,48 @@ LIGHT_SHADER_CODE diffuse_brdf_NL = cNdotL * (1.0 / M_PI); #endif - diffuse_light += light_color * diffuse_color * diffuse_brdf_NL * attenuation; + diffuse_light += light_color * diffuse_color * shadow_attenuation * diffuse_brdf_NL * attenuation; -#if defined(LIGHT_TRANSMISSION_USED) - diffuse_light += light_color * diffuse_color * (vec3(1.0 / M_PI) - diffuse_brdf_NL) * transmission * attenuation; +#if defined(LIGHT_BACKLIGHT_USED) + diffuse_light += light_color * diffuse_color * (vec3(1.0 / M_PI) - diffuse_brdf_NL) * backlight * attenuation; #endif #if defined(LIGHT_RIM_USED) float rim_light = pow(max(0.0, 1.0 - cNdotV), max(0.0, (1.0 - roughness) * 16.0)); diffuse_light += rim_light * rim * mix(vec3(1.0), diffuse_color, rim_tint) * light_color; #endif + +#ifdef LIGHT_TRANSMITTANCE_USED + +#ifdef SSS_MODE_SKIN + + { + float scale = 8.25 / transmittance_depth; + float d = scale * abs(transmittance_z); + float dd = -d * d; + vec3 profile = vec3(0.233, 0.455, 0.649) * exp(dd / 0.0064) + + vec3(0.1, 0.336, 0.344) * exp(dd / 0.0484) + + vec3(0.118, 0.198, 0.0) * exp(dd / 0.187) + + vec3(0.113, 0.007, 0.007) * exp(dd / 0.567) + + vec3(0.358, 0.004, 0.0) * exp(dd / 1.99) + + vec3(0.078, 0.0, 0.0) * exp(dd / 7.41); + + diffuse_light += profile * transmittance_color.a * diffuse_color * light_color * clamp(transmittance_boost - NdotL, 0.0, 1.0) * (1.0 / M_PI) * attenuation; + } +#else + + if (transmittance_depth > 0.0) { + float fade = clamp(abs(transmittance_z / transmittance_depth), 0.0, 1.0); + + fade = pow(max(0.0, 1.0 - fade), transmittance_curve); + fade *= clamp(transmittance_boost - NdotL, 0.0, 1.0); + + diffuse_light += diffuse_color * transmittance_color.rgb * light_color * (1.0 / M_PI) * transmittance_color.a * fade * attenuation; + } + +#endif //SSS_MODE_SKIN + +#endif //LIGHT_TRANSMITTANCE_USED } if (roughness > 0.0) { // FIXME: roughness == 0 should not disable specular light entirely @@ -562,18 +600,18 @@ LIGHT_SHADER_CODE blinn *= (shininess + 8.0) * (1.0 / (8.0 * M_PI)); float intensity = blinn; - specular_light += light_color * intensity * specular_blob_intensity * attenuation; + specular_light += light_color * shadow_attenuation * intensity * specular_blob_intensity * attenuation; #elif defined(SPECULAR_PHONG) vec3 R = normalize(-reflect(L, N)); - float cRdotV = max(0.0, dot(R, V)); + float cRdotV = clamp(A + dot(R, V), 0.0, 1.0); float shininess = exp2(15.0 * (1.0 - roughness) + 1.0) * 0.25; float phong = pow(cRdotV, shininess); phong *= (shininess + 8.0) * (1.0 / (8.0 * M_PI)); float intensity = (phong) / max(4.0 * cNdotV * cNdotL, 0.75); - specular_light += light_color * intensity * specular_blob_intensity * attenuation; + specular_light += light_color * shadow_attenuation * intensity * specular_blob_intensity * attenuation; #elif defined(SPECULAR_TOON) @@ -582,7 +620,7 @@ LIGHT_SHADER_CODE float mid = 1.0 - roughness; mid *= mid; float intensity = smoothstep(mid - roughness * 0.5, mid + roughness * 0.5, RdotV) * mid; - diffuse_light += light_color * intensity * specular_blob_intensity * attenuation; // write to diffuse_light, as in toon shading you generally want no reflection + diffuse_light += light_color * shadow_attenuation * intensity * specular_blob_intensity * attenuation; // write to diffuse_light, as in toon shading you generally want no reflection #elif defined(SPECULAR_DISABLED) // none.. @@ -613,7 +651,7 @@ LIGHT_SHADER_CODE vec3 specular_brdf_NL = cNdotL * D * F * G; - specular_light += specular_brdf_NL * light_color * specular_blob_intensity * attenuation; + specular_light += specular_brdf_NL * light_color * shadow_attenuation * specular_blob_intensity * attenuation; #endif #if defined(LIGHT_CLEARCOAT_USED) @@ -627,12 +665,12 @@ LIGHT_SHADER_CODE float clearcoat_specular_brdf_NL = 0.25 * clearcoat * Gr * Fr * Dr * cNdotL; - specular_light += clearcoat_specular_brdf_NL * light_color * specular_blob_intensity * attenuation; + specular_light += clearcoat_specular_brdf_NL * light_color * shadow_attenuation * specular_blob_intensity * attenuation; #endif } #ifdef USE_SHADOW_TO_OPACITY - alpha = min(alpha, clamp(1.0 - length(attenuation), 0.0, 1.0)); + alpha = min(alpha, clamp(1.0 - length(shadow_attenuation * attenuation), 0.0, 1.0)); #endif #endif //defined(USE_LIGHT_SHADER_CODE) @@ -640,53 +678,121 @@ LIGHT_SHADER_CODE #ifndef USE_NO_SHADOWS -float sample_shadow(texture2D shadow, vec2 shadow_pixel_size, vec4 coord) { +// Produces cheap but low-quality white noise, nothing special +float quick_hash(vec2 pos) { + return fract(sin(dot(pos * 19.19, vec2(49.5791, 97.413))) * 49831.189237); +} + +float sample_directional_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec4 coord) { - //todo optimize vec2 pos = coord.xy; float depth = coord.z; -#ifdef SHADOW_MODE_PCF_13 + //if only one sample is taken, take it from the center + if (scene_data.directional_soft_shadow_samples == 1) { + return textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos, depth, 1.0)); + } - float avg = textureProj(shadow, vec4(pos, depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(shadow_pixel_size.x, 0.0), depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(-shadow_pixel_size.x, 0.0), depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(0.0, shadow_pixel_size.y), depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(0.0, -shadow_pixel_size.y), depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(shadow_pixel_size.x, shadow_pixel_size.y), depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(-shadow_pixel_size.x, shadow_pixel_size.y), depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(shadow_pixel_size.x, -shadow_pixel_size.y), depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(-shadow_pixel_size.x, -shadow_pixel_size.y), depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(shadow_pixel_size.x * 2.0, 0.0), depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(-shadow_pixel_size.x * 2.0, 0.0), depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(0.0, shadow_pixel_size.y * 2.0), depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(0.0, -shadow_pixel_size.y * 2.0), depth, 1.0)); - return avg * (1.0 / 13.0); -#endif + mat2 disk_rotation; + { + float r = quick_hash(gl_FragCoord.xy) * 2.0 * M_PI; + float sr = sin(r); + float cr = cos(r); + disk_rotation = mat2(vec2(cr, -sr), vec2(sr, cr)); + } -#ifdef SHADOW_MODE_PCF_5 + float avg = 0.0; - float avg = textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos, depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(shadow_pixel_size.x, 0.0), depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(-shadow_pixel_size.x, 0.0), depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(0.0, shadow_pixel_size.y), depth, 1.0)); - avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + vec2(0.0, -shadow_pixel_size.y), depth, 1.0)); - return avg * (1.0 / 5.0); + for (uint i = 0; i < scene_data.directional_soft_shadow_samples; i++) { + avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + shadow_pixel_size * (disk_rotation * scene_data.directional_soft_shadow_kernel[i].xy), depth, 1.0)); + } -#endif + return avg * (1.0 / float(scene_data.directional_soft_shadow_samples)); +} -#if !defined(SHADOW_MODE_PCF_5) || !defined(SHADOW_MODE_PCF_13) +float sample_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec4 coord) { - return textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos, depth, 1.0)); + vec2 pos = coord.xy; + float depth = coord.z; -#endif + //if only one sample is taken, take it from the center + if (scene_data.soft_shadow_samples == 1) { + return textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos, depth, 1.0)); + } + + mat2 disk_rotation; + { + float r = quick_hash(gl_FragCoord.xy) * 2.0 * M_PI; + float sr = sin(r); + float cr = cos(r); + disk_rotation = mat2(vec2(cr, -sr), vec2(sr, cr)); + } + + float avg = 0.0; + + for (uint i = 0; i < scene_data.soft_shadow_samples; i++) { + avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + shadow_pixel_size * (disk_rotation * scene_data.soft_shadow_kernel[i].xy), depth, 1.0)); + } + + return avg * (1.0 / float(scene_data.soft_shadow_samples)); +} + +float sample_directional_soft_shadow(texture2D shadow, vec3 pssm_coord, vec2 tex_scale) { + + //find blocker + float blocker_count = 0.0; + float blocker_average = 0.0; + + mat2 disk_rotation; + { + float r = quick_hash(gl_FragCoord.xy) * 2.0 * M_PI; + float sr = sin(r); + float cr = cos(r); + disk_rotation = mat2(vec2(cr, -sr), vec2(sr, cr)); + } + + for (uint i = 0; i < scene_data.directional_penumbra_shadow_samples; i++) { + + vec2 suv = pssm_coord.xy + (disk_rotation * scene_data.directional_penumbra_shadow_kernel[i].xy) * tex_scale; + float d = textureLod(sampler2D(shadow, material_samplers[SAMPLER_LINEAR_CLAMP]), suv, 0.0).r; + if (d < pssm_coord.z) { + blocker_average += d; + blocker_count += 1.0; + } + } + + if (blocker_count > 0.0) { + + //blockers found, do soft shadow + blocker_average /= blocker_count; + float penumbra = (pssm_coord.z - blocker_average) / blocker_average; + tex_scale *= penumbra; + + float s = 0.0; + for (uint i = 0; i < scene_data.directional_penumbra_shadow_samples; i++) { + vec2 suv = pssm_coord.xy + (disk_rotation * scene_data.directional_penumbra_shadow_kernel[i].xy) * tex_scale; + s += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(suv, pssm_coord.z, 1.0)); + } + + return s / float(scene_data.directional_penumbra_shadow_samples); + + } else { + //no blockers found, so no shadow + return 1.0; + } } #endif //USE_NO_SHADOWS -void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 albedo, float roughness, float metallic, float specular, float p_blob_intensity, -#ifdef LIGHT_TRANSMISSION_USED - vec3 transmission, +void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 vertex_ddx, vec3 vertex_ddy, vec3 albedo, float roughness, float metallic, float specular, float p_blob_intensity, +#ifdef LIGHT_BACKLIGHT_USED + vec3 backlight, +#endif +#ifdef LIGHT_TRANSMITTANCE_USED + vec4 transmittance_color, + float transmittance_depth, + float transmittance_curve, + float transmittance_boost, #endif #ifdef LIGHT_RIM_USED float rim, float rim_tint, @@ -707,45 +813,269 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 a float normalized_distance = light_length * lights.data[idx].inv_radius; vec2 attenuation_energy = unpackHalf2x16(lights.data[idx].attenuation_energy); float omni_attenuation = pow(max(1.0 - normalized_distance, 0.0), attenuation_energy.x); - vec3 light_attenuation = vec3(omni_attenuation); + float light_attenuation = omni_attenuation; + vec3 shadow_attenuation = vec3(1.0); vec4 color_specular = unpackUnorm4x8(lights.data[idx].color_specular); color_specular.rgb *= attenuation_energy.y; + float size_A = 0.0; + + if (lights.data[idx].size > 0.0) { + + float t = lights.data[idx].size / max(0.001, light_length); + size_A = max(0.0, 1.0 - 1 / sqrt(1 + t * t)); + } + +#ifdef LIGHT_TRANSMITTANCE_USED + float transmittance_z = transmittance_depth; //no transmittance by default +#endif #ifndef USE_NO_SHADOWS vec4 shadow_color_enabled = unpackUnorm4x8(lights.data[idx].shadow_color_enabled); if (shadow_color_enabled.w > 0.5) { // there is a shadowmap - vec4 splane = (lights.data[idx].shadow_matrix * vec4(vertex, 1.0)); - float shadow_len = length(splane); - splane = normalize(splane); - vec4 clamp_rect = lights.data[idx].atlas_rect; + vec4 v = vec4(vertex, 1.0); + + vec4 splane = (lights.data[idx].shadow_matrix * v); + float shadow_len = length(splane.xyz); //need to remember shadow len from here - if (splane.z >= 0.0) { + { + vec3 nofs = normal_interp * lights.data[idx].shadow_normal_bias / lights.data[idx].inv_radius; + nofs *= (1.0 - max(0.0, dot(normalize(light_rel_vec), normalize(normal_interp)))); + v.xyz += nofs; + splane = (lights.data[idx].shadow_matrix * v); + } - splane.z += 1.0; + float shadow; - clamp_rect.y += clamp_rect.w; + if (lights.data[idx].soft_shadow_size > 0.0) { + //soft shadow + + //find blocker + + float blocker_count = 0.0; + float blocker_average = 0.0; + + mat2 disk_rotation; + { + float r = quick_hash(gl_FragCoord.xy) * 2.0 * M_PI; + float sr = sin(r); + float cr = cos(r); + disk_rotation = mat2(vec2(cr, -sr), vec2(sr, cr)); + } + vec3 normal = normalize(splane.xyz); + vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0); + vec3 tangent = normalize(cross(v0, normal)); + vec3 bitangent = normalize(cross(tangent, normal)); + float z_norm = shadow_len * lights.data[idx].inv_radius; + + tangent *= lights.data[idx].soft_shadow_size * lights.data[idx].soft_shadow_scale; + bitangent *= lights.data[idx].soft_shadow_size * lights.data[idx].soft_shadow_scale; + + for (uint i = 0; i < scene_data.penumbra_shadow_samples; i++) { + + vec2 disk = disk_rotation * scene_data.penumbra_shadow_kernel[i].xy; + + vec3 pos = splane.xyz + tangent * disk.x + bitangent * disk.y; + + pos = normalize(pos); + vec4 uv_rect = lights.data[idx].atlas_rect; + + if (pos.z >= 0.0) { + + pos.z += 1.0; + uv_rect.y += uv_rect.w; + } else { + + pos.z = 1.0 - pos.z; + } + + pos.xy /= pos.z; + + pos.xy = pos.xy * 0.5 + 0.5; + pos.xy = uv_rect.xy + pos.xy * uv_rect.zw; + + float d = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), pos.xy, 0.0).r; + if (d < z_norm) { + blocker_average += d; + blocker_count += 1.0; + } + } + + if (blocker_count > 0.0) { + + //blockers found, do soft shadow + blocker_average /= blocker_count; + float penumbra = (z_norm - blocker_average) / blocker_average; + tangent *= penumbra; + bitangent *= penumbra; + + z_norm -= lights.data[idx].inv_radius * lights.data[idx].shadow_bias; + + shadow = 0.0; + for (uint i = 0; i < scene_data.penumbra_shadow_samples; i++) { + + vec2 disk = disk_rotation * scene_data.penumbra_shadow_kernel[i].xy; + vec3 pos = splane.xyz + tangent * disk.x + bitangent * disk.y; + + pos = normalize(pos); + vec4 uv_rect = lights.data[idx].atlas_rect; + + if (pos.z >= 0.0) { + + pos.z += 1.0; + uv_rect.y += uv_rect.w; + } else { + + pos.z = 1.0 - pos.z; + } + + pos.xy /= pos.z; + + pos.xy = pos.xy * 0.5 + 0.5; + pos.xy = uv_rect.xy + pos.xy * uv_rect.zw; + shadow += textureProj(sampler2DShadow(shadow_atlas, shadow_sampler), vec4(pos.xy, z_norm, 1.0)); + } + + shadow /= float(scene_data.penumbra_shadow_samples); + + } else { + //no blockers found, so no shadow + shadow = 1.0; + } } else { - splane.z = 1.0 - splane.z; + splane.xyz = normalize(splane.xyz); + vec4 clamp_rect = lights.data[idx].atlas_rect; + + if (splane.z >= 0.0) { + + splane.z += 1.0; + + clamp_rect.y += clamp_rect.w; + + } else { + splane.z = 1.0 - splane.z; + } + + splane.xy /= splane.z; + + splane.xy = splane.xy * 0.5 + 0.5; + splane.z = (shadow_len - lights.data[idx].shadow_bias) * lights.data[idx].inv_radius; + splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw; + splane.w = 1.0; //needed? i think it should be 1 already + shadow = sample_pcf_shadow(shadow_atlas, lights.data[idx].soft_shadow_scale * scene_data.shadow_atlas_pixel_size, splane); + } + +#ifdef LIGHT_TRANSMITTANCE_USED + { + + vec4 clamp_rect = lights.data[idx].atlas_rect; + + //redo shadowmapping, but shrink the model a bit to avoid arctifacts + splane = (lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * lights.data[idx].transmittance_bias, 1.0)); + + shadow_len = length(splane.xyz); + splane = normalize(splane.xyz); + + if (splane.z >= 0.0) { + + splane.z += 1.0; + + } else { + + splane.z = 1.0 - splane.z; + } + + splane.xy /= splane.z; + splane.xy = splane.xy * 0.5 + 0.5; + splane.z = shadow_len * lights.data[idx].inv_radius; + splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw; + splane.w = 1.0; //needed? i think it should be 1 already + + float shadow_z = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), splane.xy, 0.0).r; + transmittance_z = (splane.z - shadow_z) / lights.data[idx].inv_radius; } +#endif + + vec3 no_shadow = vec3(1.0); + + if (lights.data[idx].projector_rect != vec4(0.0)) { + + vec3 local_v = (lights.data[idx].shadow_matrix * vec4(vertex, 1.0)).xyz; + local_v = normalize(local_v); - splane.xy /= splane.z; - splane.xy = splane.xy * 0.5 + 0.5; - splane.z = shadow_len * lights.data[idx].inv_radius; - splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw; - splane.w = 1.0; //needed? i think it should be 1 already - float shadow = sample_shadow(shadow_atlas, scene_data.shadow_atlas_pixel_size, splane); + vec4 atlas_rect = lights.data[idx].projector_rect; - light_attenuation *= mix(shadow_color_enabled.rgb, vec3(1.0), shadow); + if (local_v.z >= 0.0) { + + local_v.z += 1.0; + atlas_rect.y += atlas_rect.w; + + } else { + + local_v.z = 1.0 - local_v.z; + } + + local_v.xy /= local_v.z; + local_v.xy = local_v.xy * 0.5 + 0.5; + vec2 proj_uv = local_v.xy * atlas_rect.zw; + + vec2 proj_uv_ddx; + vec2 proj_uv_ddy; + { + vec3 local_v_ddx = (lights.data[idx].shadow_matrix * vec4(vertex + vertex_ddx, 1.0)).xyz; + local_v_ddx = normalize(local_v_ddx); + + if (local_v_ddx.z >= 0.0) { + + local_v_ddx.z += 1.0; + } else { + + local_v_ddx.z = 1.0 - local_v_ddx.z; + } + + local_v_ddx.xy /= local_v_ddx.z; + local_v_ddx.xy = local_v_ddx.xy * 0.5 + 0.5; + + proj_uv_ddx = local_v_ddx.xy * atlas_rect.zw - proj_uv; + + vec3 local_v_ddy = (lights.data[idx].shadow_matrix * vec4(vertex + vertex_ddy, 1.0)).xyz; + local_v_ddy = normalize(local_v_ddy); + + if (local_v_ddy.z >= 0.0) { + + local_v_ddy.z += 1.0; + } else { + + local_v_ddy.z = 1.0 - local_v_ddy.z; + } + + local_v_ddy.xy /= local_v_ddy.z; + local_v_ddy.xy = local_v_ddy.xy * 0.5 + 0.5; + + proj_uv_ddy = local_v_ddy.xy * atlas_rect.zw - proj_uv; + } + + vec4 proj = textureGrad(sampler2D(decal_atlas_srgb, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), proj_uv + atlas_rect.xy, proj_uv_ddx, proj_uv_ddy); + no_shadow = mix(no_shadow, proj.rgb, proj.a); + } + + shadow_attenuation = mix(shadow_color_enabled.rgb, no_shadow, shadow); } #endif //USE_NO_SHADOWS - light_compute(normal, normalize(light_rel_vec), eye_vec, color_specular.rgb, light_attenuation, albedo, roughness, metallic, specular, color_specular.a * p_blob_intensity, -#ifdef LIGHT_TRANSMISSION_USED - transmission, + light_compute(normal, normalize(light_rel_vec), eye_vec, size_A, color_specular.rgb, light_attenuation, shadow_attenuation, albedo, roughness, metallic, specular, color_specular.a * p_blob_intensity, +#ifdef LIGHT_BACKLIGHT_USED + backlight, +#endif +#ifdef LIGHT_TRANSMITTANCE_USED + transmittance_color, + transmittance_depth, + transmittance_curve, + transmittance_boost, + transmittance_z, #endif #ifdef LIGHT_RIM_USED rim * omni_attenuation, rim_tint, @@ -763,9 +1093,15 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 a specular_light); } -void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 albedo, float roughness, float metallic, float specular, float p_blob_intensity, -#ifdef LIGHT_TRANSMISSION_USED - vec3 transmission, +void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 vertex_ddx, vec3 vertex_ddy, vec3 albedo, float roughness, float metallic, float specular, float p_blob_intensity, +#ifdef LIGHT_BACKLIGHT_USED + vec3 backlight, +#endif +#ifdef LIGHT_TRANSMITTANCE_USED + vec4 transmittance_color, + float transmittance_depth, + float transmittance_curve, + float transmittance_boost, #endif #ifdef LIGHT_RIM_USED float rim, float rim_tint, @@ -792,31 +1128,162 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 a float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_att_angle.y); float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - spot_att_angle.y)); spot_attenuation *= 1.0 - pow(spot_rim, spot_att_angle.x); - vec3 light_attenuation = vec3(spot_attenuation); + float light_attenuation = spot_attenuation; + vec3 shadow_attenuation = vec3(1.0); vec4 color_specular = unpackUnorm4x8(lights.data[idx].color_specular); color_specular.rgb *= attenuation_energy.y; + float size_A = 0.0; + + if (lights.data[idx].size > 0.0) { + + float t = lights.data[idx].size / max(0.001, light_length); + size_A = max(0.0, 1.0 - 1 / sqrt(1 + t * t)); + } /* if (lights.data[idx].atlas_rect!=vec4(0.0)) { //use projector texture } */ +#ifdef LIGHT_TRANSMITTANCE_USED + float transmittance_z = transmittance_depth; +#endif + #ifndef USE_NO_SHADOWS vec4 shadow_color_enabled = unpackUnorm4x8(lights.data[idx].shadow_color_enabled); if (shadow_color_enabled.w > 0.5) { //there is a shadowmap - vec4 splane = (lights.data[idx].shadow_matrix * vec4(vertex, 1.0)); + vec4 v = vec4(vertex, 1.0); + + v.xyz -= spot_dir * lights.data[idx].shadow_bias; + + float z_norm = dot(spot_dir, -light_rel_vec) * lights.data[idx].inv_radius; + + float depth_bias_scale = 1.0 / (max(0.0001, z_norm)); //the closer to the light origin, the more you have to offset to reach 1px in the map + vec3 normal_bias = normalize(normal_interp) * (1.0 - max(0.0, dot(spot_dir, -normalize(normal_interp)))) * lights.data[idx].shadow_normal_bias * depth_bias_scale; + normal_bias -= spot_dir * dot(spot_dir, normal_bias); //only XY, no Z + v.xyz += normal_bias; + + //adjust with bias + z_norm = dot(spot_dir, v.xyz - lights.data[idx].position) * lights.data[idx].inv_radius; + + float shadow; + + vec4 splane = (lights.data[idx].shadow_matrix * v); splane /= splane.w; - float shadow = sample_shadow(shadow_atlas, scene_data.shadow_atlas_pixel_size, splane); - light_attenuation *= mix(shadow_color_enabled.rgb, vec3(1.0), shadow); + if (lights.data[idx].soft_shadow_size > 0.0) { + //soft shadow + + //find blocker + + vec2 shadow_uv = splane.xy * lights.data[idx].atlas_rect.zw + lights.data[idx].atlas_rect.xy; + + float blocker_count = 0.0; + float blocker_average = 0.0; + + mat2 disk_rotation; + { + float r = quick_hash(gl_FragCoord.xy) * 2.0 * M_PI; + float sr = sin(r); + float cr = cos(r); + disk_rotation = mat2(vec2(cr, -sr), vec2(sr, cr)); + } + + float uv_size = lights.data[idx].soft_shadow_size * z_norm * lights.data[idx].soft_shadow_scale; + vec2 clamp_max = lights.data[idx].atlas_rect.xy + lights.data[idx].atlas_rect.zw; + for (uint i = 0; i < scene_data.penumbra_shadow_samples; i++) { + + vec2 suv = shadow_uv + (disk_rotation * scene_data.penumbra_shadow_kernel[i].xy) * uv_size; + suv = clamp(suv, lights.data[idx].atlas_rect.xy, clamp_max); + float d = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), suv, 0.0).r; + if (d < z_norm) { + blocker_average += d; + blocker_count += 1.0; + } + } + + if (blocker_count > 0.0) { + + //blockers found, do soft shadow + blocker_average /= blocker_count; + float penumbra = (z_norm - blocker_average) / blocker_average; + uv_size *= penumbra; + + shadow = 0.0; + for (uint i = 0; i < scene_data.penumbra_shadow_samples; i++) { + vec2 suv = shadow_uv + (disk_rotation * scene_data.penumbra_shadow_kernel[i].xy) * uv_size; + suv = clamp(suv, lights.data[idx].atlas_rect.xy, clamp_max); + shadow += textureProj(sampler2DShadow(shadow_atlas, shadow_sampler), vec4(suv, z_norm, 1.0)); + } + + shadow /= float(scene_data.penumbra_shadow_samples); + + } else { + //no blockers found, so no shadow + shadow = 1.0; + } + + } else { + //hard shadow + vec4 shadow_uv = vec4(splane.xy * lights.data[idx].atlas_rect.zw + lights.data[idx].atlas_rect.xy, z_norm, 1.0); + + shadow = sample_pcf_shadow(shadow_atlas, lights.data[idx].soft_shadow_scale * scene_data.shadow_atlas_pixel_size, shadow_uv); + } + + vec3 no_shadow = vec3(1.0); + + if (lights.data[idx].projector_rect != vec4(0.0)) { + + splane = (lights.data[idx].shadow_matrix * vec4(vertex, 1.0)); + splane /= splane.w; + + vec2 proj_uv = splane.xy * lights.data[idx].projector_rect.zw; + + //ensure we have proper mipmaps + vec4 splane_ddx = (lights.data[idx].shadow_matrix * vec4(vertex + vertex_ddx, 1.0)); + splane_ddx /= splane_ddx.w; + vec2 proj_uv_ddx = splane_ddx.xy * lights.data[idx].projector_rect.zw - proj_uv; + + vec4 splane_ddy = (lights.data[idx].shadow_matrix * vec4(vertex + vertex_ddy, 1.0)); + splane_ddy /= splane_ddy.w; + vec2 proj_uv_ddy = splane_ddy.xy * lights.data[idx].projector_rect.zw - proj_uv; + + vec4 proj = textureGrad(sampler2D(decal_atlas_srgb, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), proj_uv + lights.data[idx].projector_rect.xy, proj_uv_ddx, proj_uv_ddy); + no_shadow = mix(no_shadow, proj.rgb, proj.a); + } + + shadow_attenuation = mix(shadow_color_enabled.rgb, no_shadow, shadow); + +#ifdef LIGHT_TRANSMITTANCE_USED + { + + splane = (lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * lights.data[idx].transmittance_bias, 1.0)); + splane /= splane.w; + splane.xy = splane.xy * lights.data[idx].atlas_rect.zw + lights.data[idx].atlas_rect.xy; + + float shadow_z = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), splane.xy, 0.0).r; + //reconstruct depth + shadow_z / lights.data[idx].inv_radius; + //distance to light plane + float z = dot(spot_dir, -light_rel_vec); + transmittance_z = z - shadow_z; + } +#endif //LIGHT_TRANSMITTANCE_USED } #endif //USE_NO_SHADOWS - light_compute(normal, normalize(light_rel_vec), eye_vec, color_specular.rgb, light_attenuation, albedo, roughness, metallic, specular, color_specular.a * p_blob_intensity, -#ifdef LIGHT_TRANSMISSION_USED - transmission, + light_compute(normal, normalize(light_rel_vec), eye_vec, size_A, color_specular.rgb, light_attenuation, shadow_attenuation, albedo, roughness, metallic, specular, color_specular.a * p_blob_intensity, +#ifdef LIGHT_BACKLIGHT_USED + backlight, +#endif +#ifdef LIGHT_TRANSMITTANCE_USED + transmittance_color, + transmittance_depth, + transmittance_curve, + transmittance_boost, + transmittance_z, #endif #ifdef LIGHT_RIM_USED rim * spot_attenuation, rim_tint, @@ -1185,7 +1652,11 @@ void main() { vec3 vertex = vertex_interp; vec3 view = -normalize(vertex_interp); vec3 albedo = vec3(1.0); - vec3 transmission = vec3(0.0); + vec3 backlight = vec3(0.0); + vec4 transmittance_color = vec4(0.0); + float transmittance_depth = 0.0; + float transmittance_curve = 1.0; + float transmittance_boost = 0.0; float metallic = 0.0; float specular = 0.5; vec3 emission = vec3(0.0); @@ -1223,9 +1694,7 @@ void main() { } #endif -#if defined(UV_USED) vec2 uv = uv_interp; -#endif #if defined(UV2_USED) || defined(USE_LIGHTMAP) vec2 uv2 = uv2_interp; @@ -1254,6 +1723,14 @@ FRAGMENT_SHADER_CODE /* clang-format on */ } +#if defined(LIGHT_TRANSMITTANCE_USED) +#ifdef SSS_MODE_SKIN + transmittance_color.a = sss_strength; +#else + transmittance_color.a *= sss_strength; +#endif +#endif + #if !defined(USE_SHADOW_TO_OPACITY) #if defined(ALPHA_SCISSOR_USED) @@ -1299,7 +1776,81 @@ FRAGMENT_SHADER_CODE discard; } #endif + /////////////////////// DECALS //////////////////////////////// + +#ifndef MODE_RENDER_DEPTH + + uvec4 cluster_cell = texture(usampler3D(cluster_texture, material_samplers[SAMPLER_NEAREST_CLAMP]), vec3(screen_uv, (abs(vertex.z) - scene_data.z_near) / (scene_data.z_far - scene_data.z_near))); + //used for interpolating anything cluster related + vec3 vertex_ddx = dFdx(vertex); + vec3 vertex_ddy = dFdy(vertex); + + { // process decals + + uint decal_count = cluster_cell.w >> CLUSTER_COUNTER_SHIFT; + uint decal_pointer = cluster_cell.w & CLUSTER_POINTER_MASK; + + //do outside for performance and avoiding arctifacts + + for (uint i = 0; i < decal_count; i++) { + + uint decal_index = cluster_data.indices[decal_pointer + i]; + if (!bool(decals.data[decal_index].mask & instances.data[instance_index].layer_mask)) { + continue; //not masked + } + + vec3 uv_local = (decals.data[decal_index].xform * vec4(vertex, 1.0)).xyz; + if (any(lessThan(uv_local, vec3(0.0, -1.0, 0.0))) || any(greaterThan(uv_local, vec3(1.0)))) { + continue; //out of decal + } + + //we need ddx/ddy for mipmaps, so simulate them + vec2 ddx = (decals.data[decal_index].xform * vec4(vertex_ddx, 0.0)).xz; + vec2 ddy = (decals.data[decal_index].xform * vec4(vertex_ddy, 0.0)).xz; + + float fade = pow(1.0 - (uv_local.y > 0.0 ? uv_local.y : -uv_local.y), uv_local.y > 0.0 ? decals.data[decal_index].upper_fade : decals.data[decal_index].lower_fade); + + if (decals.data[decal_index].normal_fade > 0.0) { + fade *= smoothstep(decals.data[decal_index].normal_fade, 1.0, dot(normal_interp, decals.data[decal_index].normal) * 0.5 + 0.5); + } + + if (decals.data[decal_index].albedo_rect != vec4(0.0)) { + //has albedo + vec4 decal_albedo = textureGrad(sampler2D(decal_atlas_srgb, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].albedo_rect.zw + decals.data[decal_index].albedo_rect.xy, ddx * decals.data[decal_index].albedo_rect.zw, ddy * decals.data[decal_index].albedo_rect.zw); + decal_albedo *= decals.data[decal_index].modulate; + decal_albedo.a *= fade; + albedo = mix(albedo, decal_albedo.rgb, decal_albedo.a * decals.data[decal_index].albedo_mix); + + if (decals.data[decal_index].normal_rect != vec4(0.0)) { + + vec3 decal_normal = textureGrad(sampler2D(decal_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].normal_rect.zw + decals.data[decal_index].normal_rect.xy, ddx * decals.data[decal_index].normal_rect.zw, ddy * decals.data[decal_index].normal_rect.zw).xyz; + decal_normal.xy = decal_normal.xy * vec2(2.0, -2.0) - vec2(1.0, -1.0); //users prefer flipped y normal maps in most authoring software + decal_normal.z = sqrt(max(0.0, 1.0 - dot(decal_normal.xy, decal_normal.xy))); + //convert to view space, use xzy because y is up + decal_normal = (decals.data[decal_index].normal_xform * decal_normal.xzy).xyz; + + normal = normalize(mix(normal, decal_normal, decal_albedo.a)); + } + + if (decals.data[decal_index].orm_rect != vec4(0.0)) { + + vec3 decal_orm = textureGrad(sampler2D(decal_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].orm_rect.zw + decals.data[decal_index].orm_rect.xy, ddx * decals.data[decal_index].orm_rect.zw, ddy * decals.data[decal_index].orm_rect.zw).xyz; +#if defined(AO_USED) + ao = mix(ao, decal_orm.r, decal_albedo.a); +#endif + roughness = mix(roughness, decal_orm.g, decal_albedo.a); + metallic = mix(metallic, decal_orm.b, decal_albedo.a); + } + } + + if (decals.data[decal_index].emission_rect != vec4(0.0)) { + //emission is additive, so its independent from albedo + emission += textureGrad(sampler2D(decal_atlas_srgb, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].emission_rect.zw + decals.data[decal_index].emission_rect.xy, ddx * decals.data[decal_index].emission_rect.zw, ddy * decals.data[decal_index].emission_rect.zw).xyz * decals.data[decal_index].emission_energy * fade; + } + } + } +#endif //not render depth /////////////////////// LIGHTING ////////////////////////////// //apply energy conservation @@ -1404,8 +1955,6 @@ FRAGMENT_SHADER_CODE } #endif - uvec4 cluster_cell = texture(usampler3D(cluster_texture, material_samplers[SAMPLER_NEAREST_CLAMP]), vec3(screen_uv, (abs(vertex.z) - scene_data.z_near) / (scene_data.z_far - scene_data.z_near))); - { // process reflections vec4 reflection_accum = vec4(0.0, 0.0, 0.0, 0.0); @@ -1462,58 +2011,250 @@ FRAGMENT_SHADER_CODE continue; //not masked } - vec3 light_attenuation = vec3(1.0); + vec3 shadow_attenuation = vec3(1.0); + +#ifdef LIGHT_TRANSMITTANCE_USED + float transmittance_z = transmittance_depth; +#endif if (directional_lights.data[i].shadow_enabled) { float depth_z = -vertex.z; vec4 pssm_coord; + vec3 shadow_color = vec3(0.0); + vec3 light_dir = directional_lights.data[i].direction; + +#define BIAS_FUNC(m_var, m_idx) \ + m_var.xyz += light_dir * directional_lights.data[i].shadow_bias[m_idx]; \ + vec3 normal_bias = normalize(normal_interp) * (1.0 - max(0.0, dot(light_dir, -normalize(normal_interp)))) * directional_lights.data[i].shadow_normal_bias[m_idx]; \ + normal_bias -= light_dir * dot(light_dir, normal_bias); \ + m_var.xyz += normal_bias; + + float shadow = 0.0; if (depth_z < directional_lights.data[i].shadow_split_offsets.x) { - pssm_coord = (directional_lights.data[i].shadow_matrix1 * vec4(vertex, 1.0)); + vec4 v = vec4(vertex, 1.0); + + BIAS_FUNC(v, 0) + + pssm_coord = (directional_lights.data[i].shadow_matrix1 * v); + pssm_coord /= pssm_coord.w; + + if (directional_lights.data[i].softshadow_angle > 0) { + float range_pos = dot(directional_lights.data[i].direction, v.xyz); + float range_begin = directional_lights.data[i].shadow_range_begin.x; + float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; + vec2 tex_scale = directional_lights.data[i].uv_scale1 * test_radius; + shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); + } else { + shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); + } + + shadow_color = directional_lights.data[i].shadow_color1.rgb; + +#ifdef LIGHT_TRANSMITTANCE_USED + { + vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.x, 1.0); + vec4 trans_coord = directional_lights.data[i].shadow_matrix1 * trans_vertex; + trans_coord /= trans_coord.w; + + float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; + shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.x; + float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.x; + + transmittance_z = z - shadow_z; + } +#endif } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { - pssm_coord = (directional_lights.data[i].shadow_matrix2 * vec4(vertex, 1.0)); + + vec4 v = vec4(vertex, 1.0); + + BIAS_FUNC(v, 1) + + pssm_coord = (directional_lights.data[i].shadow_matrix2 * v); + pssm_coord /= pssm_coord.w; + + if (directional_lights.data[i].softshadow_angle > 0) { + float range_pos = dot(directional_lights.data[i].direction, v.xyz); + float range_begin = directional_lights.data[i].shadow_range_begin.y; + float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; + vec2 tex_scale = directional_lights.data[i].uv_scale2 * test_radius; + shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); + } else { + shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); + } + + shadow_color = directional_lights.data[i].shadow_color2.rgb; +#ifdef LIGHT_TRANSMITTANCE_USED + { + vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.y, 1.0); + vec4 trans_coord = directional_lights.data[i].shadow_matrix2 * trans_vertex; + trans_coord /= trans_coord.w; + + float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; + shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.y; + float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.y; + + transmittance_z = z - shadow_z; + } +#endif } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { - pssm_coord = (directional_lights.data[i].shadow_matrix3 * vec4(vertex, 1.0)); + + vec4 v = vec4(vertex, 1.0); + + BIAS_FUNC(v, 2) + + pssm_coord = (directional_lights.data[i].shadow_matrix3 * v); + pssm_coord /= pssm_coord.w; + + if (directional_lights.data[i].softshadow_angle > 0) { + float range_pos = dot(directional_lights.data[i].direction, v.xyz); + float range_begin = directional_lights.data[i].shadow_range_begin.z; + float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; + vec2 tex_scale = directional_lights.data[i].uv_scale3 * test_radius; + shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); + } else { + shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); + } + + shadow_color = directional_lights.data[i].shadow_color3.rgb; +#ifdef LIGHT_TRANSMITTANCE_USED + { + vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.z, 1.0); + vec4 trans_coord = directional_lights.data[i].shadow_matrix3 * trans_vertex; + trans_coord /= trans_coord.w; + + float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; + shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.z; + float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.z; + + transmittance_z = z - shadow_z; + } +#endif + } else { - pssm_coord = (directional_lights.data[i].shadow_matrix4 * vec4(vertex, 1.0)); - } - pssm_coord /= pssm_coord.w; + vec4 v = vec4(vertex, 1.0); - float shadow = sample_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size, pssm_coord); + BIAS_FUNC(v, 3) + + pssm_coord = (directional_lights.data[i].shadow_matrix4 * v); + pssm_coord /= pssm_coord.w; + + if (directional_lights.data[i].softshadow_angle > 0) { + float range_pos = dot(directional_lights.data[i].direction, v.xyz); + float range_begin = directional_lights.data[i].shadow_range_begin.w; + float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; + vec2 tex_scale = directional_lights.data[i].uv_scale4 * test_radius; + shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); + } else { + shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); + } + + shadow_color = directional_lights.data[i].shadow_color4.rgb; + +#ifdef LIGHT_TRANSMITTANCE_USED + { + vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.w, 1.0); + vec4 trans_coord = directional_lights.data[i].shadow_matrix4 * trans_vertex; + trans_coord /= trans_coord.w; + + float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; + shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.w; + float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.w; + + transmittance_z = z - shadow_z; + } +#endif + } if (directional_lights.data[i].blend_splits) { + vec3 shadow_color_blend = vec3(0.0); float pssm_blend; + float shadow2; if (depth_z < directional_lights.data[i].shadow_split_offsets.x) { - pssm_coord = (directional_lights.data[i].shadow_matrix2 * vec4(vertex, 1.0)); + vec4 v = vec4(vertex, 1.0); + BIAS_FUNC(v, 1) + pssm_coord = (directional_lights.data[i].shadow_matrix2 * v); + pssm_coord /= pssm_coord.w; + + if (directional_lights.data[i].softshadow_angle > 0) { + float range_pos = dot(directional_lights.data[i].direction, v.xyz); + float range_begin = directional_lights.data[i].shadow_range_begin.y; + float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; + vec2 tex_scale = directional_lights.data[i].uv_scale2 * test_radius; + shadow2 = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); + } else { + shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); + } + pssm_blend = smoothstep(0.0, directional_lights.data[i].shadow_split_offsets.x, depth_z); + shadow_color_blend = directional_lights.data[i].shadow_color2.rgb; } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { - pssm_coord = (directional_lights.data[i].shadow_matrix3 * vec4(vertex, 1.0)); + vec4 v = vec4(vertex, 1.0); + BIAS_FUNC(v, 2) + pssm_coord = (directional_lights.data[i].shadow_matrix3 * v); + pssm_coord /= pssm_coord.w; + + if (directional_lights.data[i].softshadow_angle > 0) { + float range_pos = dot(directional_lights.data[i].direction, v.xyz); + float range_begin = directional_lights.data[i].shadow_range_begin.z; + float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; + vec2 tex_scale = directional_lights.data[i].uv_scale3 * test_radius; + shadow2 = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); + } else { + shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); + } + pssm_blend = smoothstep(directional_lights.data[i].shadow_split_offsets.x, directional_lights.data[i].shadow_split_offsets.y, depth_z); + + shadow_color_blend = directional_lights.data[i].shadow_color3.rgb; } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { - pssm_coord = (directional_lights.data[i].shadow_matrix4 * vec4(vertex, 1.0)); + vec4 v = vec4(vertex, 1.0); + BIAS_FUNC(v, 3) + pssm_coord = (directional_lights.data[i].shadow_matrix4 * v); + pssm_coord /= pssm_coord.w; + if (directional_lights.data[i].softshadow_angle > 0) { + float range_pos = dot(directional_lights.data[i].direction, v.xyz); + float range_begin = directional_lights.data[i].shadow_range_begin.w; + float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; + vec2 tex_scale = directional_lights.data[i].uv_scale4 * test_radius; + shadow2 = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); + } else { + shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); + } + pssm_blend = smoothstep(directional_lights.data[i].shadow_split_offsets.y, directional_lights.data[i].shadow_split_offsets.z, depth_z); + shadow_color_blend = directional_lights.data[i].shadow_color4.rgb; } else { pssm_blend = 0.0; //if no blend, same coord will be used (divide by z will result in same value, and already cached) } - pssm_coord /= pssm_coord.w; + pssm_blend = sqrt(pssm_blend); - float shadow2 = sample_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size, pssm_coord); shadow = mix(shadow, shadow2, pssm_blend); + shadow_color = mix(shadow_color, shadow_color_blend, pssm_blend); } shadow = mix(shadow, 1.0, smoothstep(directional_lights.data[i].fade_from, directional_lights.data[i].fade_to, vertex.z)); //done with negative values for performance - light_attenuation = mix(directional_lights.data[i].shadow_color, vec3(1.0), shadow); + shadow_attenuation = mix(shadow_color, vec3(1.0), shadow); + +#undef BIAS_FUNC } - light_compute(normal, directional_lights.data[i].direction, normalize(view), directional_lights.data[i].color * directional_lights.data[i].energy, light_attenuation, albedo, roughness, metallic, specular, directional_lights.data[i].specular * specular_blob_intensity, -#ifdef LIGHT_TRANSMISSION_USED - transmission, + light_compute(normal, directional_lights.data[i].direction, normalize(view), directional_lights.data[i].size, directional_lights.data[i].color * directional_lights.data[i].energy, 1.0, shadow_attenuation, albedo, roughness, metallic, specular, directional_lights.data[i].specular * specular_blob_intensity, +#ifdef LIGHT_BACKLIGHT_USED + backlight, +#endif +#ifdef LIGHT_TRANSMITTANCE_USED + transmittance_color, + transmittance_depth, + transmittance_curve, + transmittance_boost, + transmittance_z, #endif #ifdef LIGHT_RIM_USED rim, rim_tint, @@ -1545,9 +2286,15 @@ FRAGMENT_SHADER_CODE continue; //not masked } - light_process_omni(light_index, vertex, view, normal, albedo, roughness, metallic, specular, specular_blob_intensity, -#ifdef LIGHT_TRANSMISSION_USED - transmission, + light_process_omni(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, albedo, roughness, metallic, specular, specular_blob_intensity, +#ifdef LIGHT_BACKLIGHT_USED + backlight, +#endif +#ifdef LIGHT_TRANSMITTANCE_USED + transmittance_color, + transmittance_depth, + transmittance_curve, + transmittance_boost, #endif #ifdef LIGHT_RIM_USED rim, @@ -1578,9 +2325,15 @@ FRAGMENT_SHADER_CODE continue; //not masked } - light_process_spot(light_index, vertex, view, normal, albedo, roughness, metallic, specular, specular_blob_intensity, -#ifdef LIGHT_TRANSMISSION_USED - transmission, + light_process_spot(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, albedo, roughness, metallic, specular, specular_blob_intensity, +#ifdef LIGHT_BACKLIGHT_USED + backlight, +#endif +#ifdef LIGHT_TRANSMITTANCE_USED + transmittance_color, + transmittance_depth, + transmittance_curve, + transmittance_boost, #endif #ifdef LIGHT_RIM_USED rim, diff --git a/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl b/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl index baef1e060f..ce4fabf9f2 100644 --- a/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl +++ b/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl @@ -37,13 +37,23 @@ layout(set = 0, binding = 3, std140) uniform SceneData { vec2 viewport_size; vec2 screen_pixel_size; - //used for shadow mapping only - float z_offset; - float z_slope_scale; - float time; float reflection_multiplier; // one normally, zero when rendering reflections + bool pancake_shadows; + uint pad; + + //use vec4s because std140 doesnt play nice with vec2s, z and w are wasted + vec4 directional_penumbra_shadow_kernel[32]; + vec4 directional_soft_shadow_kernel[32]; + vec4 penumbra_shadow_kernel[32]; + vec4 soft_shadow_kernel[32]; + + uint directional_penumbra_shadow_samples; + uint directional_soft_shadow_samples; + uint penumbra_shadow_samples; + uint soft_shadow_samples; + vec4 ambient_light_color_energy; float ambient_color_sky_mix; @@ -124,31 +134,39 @@ struct InstanceData { mat4 transform; mat4 normal_transform; uint flags; - uint instance_ofs; //instance_offset in instancing/skeleton buffer + uint instance_uniforms_ofs; //base offset in global buffer for instance variables uint gi_offset; //GI information when using lightmapping (VCT or lightmap) uint layer_mask; }; -layout(set = 0, binding = 4, std430) buffer Instances { +layout(set = 0, binding = 4, std430) restrict readonly buffer Instances { InstanceData data[]; } instances; -struct LightData { //this structure needs to be 128 bits +struct LightData { //this structure needs to be as packed as possible vec3 position; float inv_radius; vec3 direction; + float size; uint attenuation_energy; //attenuation uint color_specular; //rgb color, a specular (8 bit unorm) uint cone_attenuation_angle; // attenuation and angle, (16bit float) - uint mask; uint shadow_color_enabled; //shadow rgb color, a>0.5 enabled (8bit unorm) - vec4 atlas_rect; //used for shadow atlas uv on omni, and for projection atlas on spot + vec4 atlas_rect; // rect in the shadow atlas mat4 shadow_matrix; + float shadow_bias; + float shadow_normal_bias; + float transmittance_bias; + float soft_shadow_size; // for spot, it's the size in uv coordinates of the light, for omni it's the span angle + float soft_shadow_scale; // scales the shadow kernel for blurrier shadows + uint mask; + uint pad[2]; + vec4 projector_rect; //projector rect in srgb decal atlas }; -layout(set = 0, binding = 5, std140) uniform Lights { - LightData data[MAX_LIGHT_DATA_STRUCTS]; +layout(set = 0, binding = 5, std430) restrict readonly buffer Lights { + LightData data[]; } lights; @@ -173,18 +191,33 @@ struct DirectionalLightData { vec3 direction; float energy; vec3 color; + float size; float specular; - vec3 shadow_color; uint mask; + float softshadow_angle; + float soft_shadow_scale; bool blend_splits; bool shadow_enabled; float fade_from; float fade_to; + vec4 shadow_bias; + vec4 shadow_normal_bias; + vec4 shadow_transmittance_bias; + vec4 shadow_transmittance_z_scale; + vec4 shadow_range_begin; vec4 shadow_split_offsets; mat4 shadow_matrix1; mat4 shadow_matrix2; mat4 shadow_matrix3; mat4 shadow_matrix4; + vec4 shadow_color1; + vec4 shadow_color2; + vec4 shadow_color3; + vec4 shadow_color4; + vec2 uv_scale1; + vec2 uv_scale2; + vec2 uv_scale3; + vec2 uv_scale4; }; layout(set = 0, binding = 7, std140) uniform DirectionalLights { @@ -219,14 +252,45 @@ layout(set = 0, binding = 9) uniform texture3D gi_probe_textures[MAX_GI_PROBE_TE #define CLUSTER_POINTER_MASK ((1 << CLUSTER_COUNTER_SHIFT) - 1) #define CLUSTER_COUNTER_MASK 0xfff -layout(set = 0, binding = 10) uniform utexture3D cluster_texture; +layout(set = 0, binding = 10) uniform texture2D decal_atlas; +layout(set = 0, binding = 11) uniform texture2D decal_atlas_srgb; + +struct DecalData { + mat4 xform; //to decal transform + vec3 inv_extents; + float albedo_mix; + vec4 albedo_rect; + vec4 normal_rect; + vec4 orm_rect; + vec4 emission_rect; + vec4 modulate; + float emission_energy; + uint mask; + float upper_fade; + float lower_fade; + mat3x4 normal_xform; + vec3 normal; + float normal_fade; +}; + +layout(set = 0, binding = 12, std430) restrict readonly buffer Decals { + DecalData data[]; +} +decals; + +layout(set = 0, binding = 13) uniform utexture3D cluster_texture; -layout(set = 0, binding = 11, std430) buffer ClusterData { +layout(set = 0, binding = 14, std430) restrict readonly buffer ClusterData { uint indices[]; } cluster_data; -layout(set = 0, binding = 12) uniform texture2D directional_shadow_atlas; +layout(set = 0, binding = 15) uniform texture2D directional_shadow_atlas; + +layout(set = 0, binding = 16, std430) restrict readonly buffer GlobalVariableData { + vec4 data[]; +} +global_variables; // decal atlas @@ -258,7 +322,7 @@ layout(set = 3, binding = 4) uniform texture2D ao_buffer; /* Set 4 Skeleton & Instancing (Multimesh) */ -layout(set = 4, binding = 0, std430) buffer Transforms { +layout(set = 4, binding = 0, std430) restrict readonly buffer Transforms { vec4 data[]; } transforms; diff --git a/servers/rendering/rasterizer_rd/shaders/sky.glsl b/servers/rendering/rasterizer_rd/shaders/sky.glsl index 469925839a..536077980d 100644 --- a/servers/rendering/rasterizer_rd/shaders/sky.glsl +++ b/servers/rendering/rasterizer_rd/shaders/sky.glsl @@ -58,6 +58,11 @@ params; layout(set = 0, binding = 0) uniform sampler material_samplers[12]; +layout(set = 0, binding = 1, std430) restrict readonly buffer GlobalVariableData { + vec4 data[]; +} +global_variables; + #ifdef USE_MATERIAL_UNIFORMS layout(set = 1, binding = 0, std140) uniform MaterialUniforms{ /* clang-format off */ @@ -96,9 +101,8 @@ layout(set = 2, binding = 2) uniform texture2D quarter_res; #endif struct DirectionalLightData { - vec3 direction; - float energy; - vec3 color; + vec4 direction_energy; + vec4 color_size; bool enabled; }; @@ -178,4 +182,10 @@ FRAGMENT_SHADER_CODE frag_color.rgb = color * params.position_multiplier.w; frag_color.a = alpha; + + // Blending is disabled for Sky, so alpha doesn't blend + // alpha is used for subsurface scattering so make sure it doesn't get applied to Sky + if (!AT_CUBEMAP_PASS && !AT_HALF_RES_PASS && !AT_QUARTER_RES_PASS) { + frag_color.a = 0.0; + } } diff --git a/servers/rendering/rasterizer_rd/shaders/tonemap.glsl b/servers/rendering/rasterizer_rd/shaders/tonemap.glsl index 524ca5e2ea..a142d263e2 100644 --- a/servers/rendering/rasterizer_rd/shaders/tonemap.glsl +++ b/servers/rendering/rasterizer_rd/shaders/tonemap.glsl @@ -48,6 +48,10 @@ layout(push_constant, binding = 1, std430) uniform Params { float exposure; float white; float auto_exposure_grey; + + vec2 pixel_size; + bool use_fxaa; + uint pad; } params; @@ -255,16 +259,63 @@ vec3 apply_color_correction(vec3 color, sampler3D correction_tex) { return texture(correction_tex, color).rgb; } +vec3 do_fxaa(vec3 color, float exposure, vec2 uv_interp) { + + const float FXAA_REDUCE_MIN = (1.0 / 128.0); + const float FXAA_REDUCE_MUL = (1.0 / 8.0); + const float FXAA_SPAN_MAX = 8.0; + + vec3 rgbNW = textureLod(source_color, uv_interp + vec2(-1.0, -1.0) * params.pixel_size, 0.0).xyz * exposure; + vec3 rgbNE = textureLod(source_color, uv_interp + vec2(1.0, -1.0) * params.pixel_size, 0.0).xyz * exposure; + vec3 rgbSW = textureLod(source_color, uv_interp + vec2(-1.0, 1.0) * params.pixel_size, 0.0).xyz * exposure; + vec3 rgbSE = textureLod(source_color, uv_interp + vec2(1.0, 1.0) * params.pixel_size, 0.0).xyz * exposure; + vec3 rgbM = color; + vec3 luma = vec3(0.299, 0.587, 0.114); + float lumaNW = dot(rgbNW, luma); + float lumaNE = dot(rgbNE, luma); + float lumaSW = dot(rgbSW, luma); + float lumaSE = dot(rgbSE, luma); + float lumaM = dot(rgbM, luma); + float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); + float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); + + vec2 dir; + dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); + dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); + + float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * + (0.25 * FXAA_REDUCE_MUL), + FXAA_REDUCE_MIN); + + float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); + dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), + max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), + dir * rcpDirMin)) * + params.pixel_size; + + vec3 rgbA = 0.5 * (textureLod(source_color, uv_interp + dir * (1.0 / 3.0 - 0.5), 0.0).xyz * exposure + textureLod(source_color, uv_interp + dir * (2.0 / 3.0 - 0.5), 0.0).xyz) * exposure; + vec3 rgbB = rgbA * 0.5 + 0.25 * (textureLod(source_color, uv_interp + dir * -0.5, 0.0).xyz * exposure + + textureLod(source_color, uv_interp + dir * 0.5, 0.0).xyz * exposure); + + float lumaB = dot(rgbB, luma); + if ((lumaB < lumaMin) || (lumaB > lumaMax)) + return rgbA; + else + return rgbB; +} + void main() { vec3 color = textureLod(source_color, uv_interp, 0.0f).rgb; // Exposure + float exposure = params.exposure; + if (params.use_auto_exposure) { - color /= texelFetch(source_auto_exposure, ivec2(0, 0), 0).r / params.auto_exposure_grey; + exposure *= 1.0 / (texelFetch(source_auto_exposure, ivec2(0, 0), 0).r / params.auto_exposure_grey); } - color *= params.exposure; + color *= exposure; // Early Tonemap & SRGB Conversion @@ -274,6 +325,9 @@ void main() { color.rgb = mix(color.rgb, glow, params.glow_intensity); } + if (params.use_fxaa) { + color = do_fxaa(color, exposure, uv_interp); + } color = apply_tonemapping(color, params.white); color = linear_to_srgb(color); // regular linear -> SRGB conversion diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index a3799b0e4d..a3bb39cd90 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -29,6 +29,8 @@ /*************************************************************************/ #include "rendering_device.h" +#include "core/method_bind_ext.gen.inc" +#include "rendering_device_binds.h" RenderingDevice *RenderingDevice::singleton = nullptr; @@ -59,6 +61,753 @@ Vector<uint8_t> RenderingDevice::shader_compile_from_source(ShaderStage p_stage, return compile_function(p_stage, p_source_code, p_language, r_error); } +RID RenderingDevice::_texture_create(const Ref<RDTextureFormat> &p_format, const Ref<RDTextureView> &p_view, const TypedArray<PackedByteArray> &p_data) { + + ERR_FAIL_COND_V(p_format.is_null(), RID()); + ERR_FAIL_COND_V(p_view.is_null(), RID()); + Vector<Vector<uint8_t>> data; + for (int i = 0; i < p_data.size(); i++) { + Vector<uint8_t> byte_slice = p_data[i]; + ERR_FAIL_COND_V(byte_slice.empty(), RID()); + data.push_back(byte_slice); + } + return texture_create(p_format->base, p_view->base, data); +} + +RID RenderingDevice::_texture_create_shared(const Ref<RDTextureView> &p_view, RID p_with_texture) { + ERR_FAIL_COND_V(p_view.is_null(), RID()); + + return texture_create_shared(p_view->base, p_with_texture); +} + +RID RenderingDevice::_texture_create_shared_from_slice(const Ref<RDTextureView> &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type) { + ERR_FAIL_COND_V(p_view.is_null(), RID()); + + return texture_create_shared_from_slice(p_view->base, p_with_texture, p_layer, p_mipmap, p_slice_type); +} + +RenderingDevice::FramebufferFormatID RenderingDevice::_framebuffer_format_create(const TypedArray<RDAttachmentFormat> &p_attachments) { + + Vector<AttachmentFormat> attachments; + attachments.resize(p_attachments.size()); + + for (int i = 0; i < p_attachments.size(); i++) { + Ref<RDAttachmentFormat> af = p_attachments[i]; + ERR_FAIL_COND_V(af.is_null(), INVALID_FORMAT_ID); + attachments.write[i] = af->base; + } + return framebuffer_format_create(attachments); +} + +RID RenderingDevice::_framebuffer_create(const Array &p_textures, FramebufferFormatID p_format_check) { + + Vector<RID> textures = Variant(p_textures); + return framebuffer_create(textures, p_format_check); +} + +RID RenderingDevice::_sampler_create(const Ref<RDSamplerState> &p_state) { + ERR_FAIL_COND_V(p_state.is_null(), RID()); + + return sampler_create(p_state->base); +} + +RenderingDevice::VertexFormatID RenderingDevice::_vertex_format_create(const TypedArray<RDVertexAttribute> &p_vertex_formats) { + + Vector<VertexAttribute> descriptions; + descriptions.resize(p_vertex_formats.size()); + + for (int i = 0; i < p_vertex_formats.size(); i++) { + Ref<RDVertexAttribute> af = p_vertex_formats[i]; + ERR_FAIL_COND_V(af.is_null(), INVALID_FORMAT_ID); + descriptions.write[i] = af->base; + } + return vertex_format_create(descriptions); +} + +RID RenderingDevice::_vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const TypedArray<RID> &p_src_buffers) { + + Vector<RID> buffers = Variant(p_src_buffers); + + return vertex_array_create(p_vertex_count, p_vertex_format, buffers); +} + +Ref<RDShaderBytecode> RenderingDevice::_shader_compile_from_source(const Ref<RDShaderSource> &p_source, bool p_allow_cache) { + ERR_FAIL_COND_V(p_source.is_null(), Ref<RDShaderBytecode>()); + + Ref<RDShaderBytecode> bytecode; + bytecode.instance(); + for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { + String error; + + ShaderStage stage = ShaderStage(i); + Vector<uint8_t> spirv = shader_compile_from_source(stage, p_source->get_stage_source(stage), p_source->get_language(), &error, p_allow_cache); + bytecode->set_stage_bytecode(stage, spirv); + bytecode->set_stage_compile_error(stage, error); + } + return bytecode; +} + +RID RenderingDevice::_shader_create(const Ref<RDShaderBytecode> &p_bytecode) { + ERR_FAIL_COND_V(p_bytecode.is_null(), RID()); + + Vector<ShaderStageData> stage_data; + for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { + ShaderStage stage = ShaderStage(i); + ShaderStageData sd; + sd.shader_stage = stage; + String error = p_bytecode->get_stage_compile_error(stage); + ERR_FAIL_COND_V_MSG(error != String(), RID(), "Can't create a shader from an errored bytecode. Check errors in source bytecode."); + sd.spir_v = p_bytecode->get_stage_bytecode(stage); + if (sd.spir_v.empty()) { + continue; + } + stage_data.push_back(sd); + } + + return shader_create(stage_data); +} + +RID RenderingDevice::_uniform_set_create(const Array &p_uniforms, RID p_shader, uint32_t p_shader_set) { + + Vector<Uniform> uniforms; + uniforms.resize(p_uniforms.size()); + for (int i = 0; i < p_uniforms.size(); i++) { + Ref<RDUniform> uniform = p_uniforms[i]; + ERR_FAIL_COND_V(!uniform.is_valid(), RID()); + uniforms.write[i] = uniform->base; + } + return uniform_set_create(uniforms, p_shader, p_shader_set); +} + +Error RenderingDevice::_buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, bool p_sync_with_draw) { + + return buffer_update(p_buffer, p_offset, p_size, p_data.ptr(), p_sync_with_draw); +} + +RID RenderingDevice::_render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags) { + + PipelineRasterizationState rasterization_state; + if (p_rasterization_state.is_valid()) { + rasterization_state = p_rasterization_state->base; + } + + PipelineMultisampleState multisample_state; + if (p_multisample_state.is_valid()) { + multisample_state = p_multisample_state->base; + for (int i = 0; i < p_multisample_state->sample_masks.size(); i++) { + int64_t mask = p_multisample_state->sample_masks[i]; + multisample_state.sample_mask.push_back(mask); + } + } + + PipelineDepthStencilState depth_stencil_state; + if (p_depth_stencil_state.is_valid()) { + depth_stencil_state = p_depth_stencil_state->base; + } + + PipelineColorBlendState color_blend_state; + if (p_blend_state.is_valid()) { + color_blend_state = p_blend_state->base; + for (int i = 0; i < p_blend_state->attachments.size(); i++) { + Ref<RDPipelineColorBlendStateAttachment> attachment = p_blend_state->attachments[i]; + if (attachment.is_valid()) { + color_blend_state.attachments.push_back(attachment->base); + } + } + } + + return render_pipeline_create(p_shader, p_framebuffer_format, p_vertex_format, p_render_primitive, rasterization_state, multisample_state, depth_stencil_state, color_blend_state, p_dynamic_state_flags); +} + +Vector<int64_t> RenderingDevice::_draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region) { + + Vector<DrawListID> splits; + splits.resize(p_splits); + draw_list_begin_split(p_framebuffer, p_splits, splits.ptrw(), p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, p_region); + + Vector<int64_t> split_ids; + split_ids.resize(splits.size()); + for (int i = 0; i < splits.size(); i++) { + split_ids.write[i] = splits[i]; + } + + return split_ids; +} + +void RenderingDevice::_draw_list_set_push_constant(DrawListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size) { + ERR_FAIL_COND((uint32_t)p_data.size() > p_data_size); + draw_list_set_push_constant(p_list, p_data.ptr(), p_data_size); +} + +void RenderingDevice::_compute_list_set_push_constant(ComputeListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size) { + ERR_FAIL_COND((uint32_t)p_data.size() > p_data_size); + compute_list_set_push_constant(p_list, p_data.ptr(), p_data_size); +} + +void RenderingDevice::_bind_methods() { + + ClassDB::bind_method(D_METHOD("texture_create", "format", "view", "data"), &RenderingDevice::_texture_create, DEFVAL(Array())); + ClassDB::bind_method(D_METHOD("texture_create_shared", "view", "with_texture"), &RenderingDevice::_texture_create_shared); + ClassDB::bind_method(D_METHOD("texture_create_shared_from_slice", "view", "with_texture", "layer", "mipmap", "slice_type"), &RenderingDevice::_texture_create_shared_from_slice, DEFVAL(TEXTURE_SLICE_2D)); + + ClassDB::bind_method(D_METHOD("texture_update", "texture", "layer", "data", "sync_with_draw"), &RenderingDevice::texture_update, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("texture_get_data", "texture", "layer"), &RenderingDevice::texture_get_data); + + ClassDB::bind_method(D_METHOD("texture_is_format_supported_for_usage", "format", "usage_flags"), &RenderingDevice::texture_is_format_supported_for_usage); + + ClassDB::bind_method(D_METHOD("texture_is_shared", "texture"), &RenderingDevice::texture_is_shared); + ClassDB::bind_method(D_METHOD("texture_is_valid", "texture"), &RenderingDevice::texture_is_valid); + + ClassDB::bind_method(D_METHOD("texture_copy", "from_texture", "to_texture", "from_pos", "to_pos", "size", "src_mipmap", "dst_mipmap", "src_layer", "dst_layer", "sync_with_draw"), &RenderingDevice::texture_copy, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("texture_clear", "texture", "color", "base_mipmap", "mipmap_count", "base_layer", "layer_count", "sync_with_draw"), &RenderingDevice::texture_clear, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("texture_resolve_multisample", "from_texture", "to_texture", "sync_with_draw"), &RenderingDevice::texture_resolve_multisample, DEFVAL(false)); + + ClassDB::bind_method(D_METHOD("framebuffer_format_create", "attachments"), &RenderingDevice::_framebuffer_format_create); + ClassDB::bind_method(D_METHOD("framebuffer_format_get_texture_samples", "format"), &RenderingDevice::framebuffer_format_get_texture_samples); + ClassDB::bind_method(D_METHOD("framebuffer_create", "textures", "validate_with_format"), &RenderingDevice::_framebuffer_create, DEFVAL(INVALID_FORMAT_ID)); + ClassDB::bind_method(D_METHOD("framebuffer_get_format", "framebuffer"), &RenderingDevice::framebuffer_get_format); + + ClassDB::bind_method(D_METHOD("sampler_create", "state"), &RenderingDevice::_sampler_create); + + ClassDB::bind_method(D_METHOD("vertex_buffer_create", "size_bytes", "data"), &RenderingDevice::vertex_buffer_create, DEFVAL(Vector<uint8_t>())); + ClassDB::bind_method(D_METHOD("vertex_format_create", "vertex_descriptions"), &RenderingDevice::_vertex_format_create); + + ClassDB::bind_method(D_METHOD("index_buffer_create", "size_indices", "format", "data"), &RenderingDevice::index_buffer_create, DEFVAL(Vector<uint8_t>()), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("index_array_create", "index_buffer", "index_offset", "index_count"), &RenderingDevice::index_array_create); + + ClassDB::bind_method(D_METHOD("shader_compile_from_source", "shader_source", "allow_cache"), &RenderingDevice::_shader_compile_from_source, DEFVAL(true)); + ClassDB::bind_method(D_METHOD("shader_create", "shader_data"), &RenderingDevice::_shader_create); + ClassDB::bind_method(D_METHOD("shader_get_vertex_input_attribute_mask", "shader"), &RenderingDevice::shader_get_vertex_input_attribute_mask); + + ClassDB::bind_method(D_METHOD("uniform_buffer_create", "size_bytes", "data"), &RenderingDevice::uniform_buffer_create, DEFVAL(Vector<uint8_t>())); + ClassDB::bind_method(D_METHOD("storage_buffer_create", "size_bytes", "data"), &RenderingDevice::storage_buffer_create, DEFVAL(Vector<uint8_t>())); + ClassDB::bind_method(D_METHOD("texture_buffer_create", "size_bytes", "format", "data"), &RenderingDevice::texture_buffer_create, DEFVAL(Vector<uint8_t>())); + + ClassDB::bind_method(D_METHOD("uniform_set_create", "uniforms", "shader", "shader_set"), &RenderingDevice::_uniform_set_create); + ClassDB::bind_method(D_METHOD("uniform_set_is_valid", "uniform_set"), &RenderingDevice::uniform_set_is_valid); + + ClassDB::bind_method(D_METHOD("buffer_update", "buffer", "offset", "size_bytes", "data", "sync_with_draw"), &RenderingDevice::_buffer_update, DEFVAL(true)); + ClassDB::bind_method(D_METHOD("buffer_get_data", "buffer"), &RenderingDevice::buffer_get_data); + + ClassDB::bind_method(D_METHOD("render_pipeline_create", "shader", "framebuffer_format", "vertex_format", "primitive", "rasterization_state", "multisample_state", "stencil_state", "color_blend_state", "dynamic_state_flags"), &RenderingDevice::_render_pipeline_create, DEFVAL(0)); + ClassDB::bind_method(D_METHOD("render_pipeline_is_valid", "render_pipeline"), &RenderingDevice::render_pipeline_is_valid); + + ClassDB::bind_method(D_METHOD("compute_pipeline_create", "shader"), &RenderingDevice::compute_pipeline_create); + ClassDB::bind_method(D_METHOD("compute_pipeline_is_valid", "compute_pieline"), &RenderingDevice::compute_pipeline_is_valid); + + ClassDB::bind_method(D_METHOD("screen_get_width", "screen"), &RenderingDevice::screen_get_width, DEFVAL(DisplayServer::MAIN_WINDOW_ID)); + ClassDB::bind_method(D_METHOD("screen_get_height", "screen"), &RenderingDevice::screen_get_height, DEFVAL(DisplayServer::MAIN_WINDOW_ID)); + ClassDB::bind_method(D_METHOD("screen_get_framebuffer_format"), &RenderingDevice::screen_get_framebuffer_format); + + ClassDB::bind_method(D_METHOD("draw_list_begin_for_screen", "screen", "clear_color"), &RenderingDevice::draw_list_begin_for_screen, DEFVAL(DisplayServer::MAIN_WINDOW_ID), DEFVAL(Color())); + + ClassDB::bind_method(D_METHOD("draw_list_begin", "framebuffer", "initial_color_action", "final_color_action", "initial_depth_action", "final_depth_action", "clear_color_values", "clear_depth", "clear_stencil", "region"), &RenderingDevice::draw_list_begin, DEFVAL(Vector<Color>()), DEFVAL(1.0), DEFVAL(0), DEFVAL(Rect2i())); + ClassDB::bind_method(D_METHOD("draw_list_begin_split", "framebuffer", "splits", "initial_color_action", "final_color_action", "initial_depth_action", "final_depth_action", "clear_color_values", "clear_depth", "clear_stencil", "region"), &RenderingDevice::_draw_list_begin_split, DEFVAL(Vector<Color>()), DEFVAL(1.0), DEFVAL(0), DEFVAL(Rect2i())); + + ClassDB::bind_method(D_METHOD("draw_list_bind_render_pipeline", "draw_list", "render_pipeline"), &RenderingDevice::draw_list_bind_render_pipeline); + ClassDB::bind_method(D_METHOD("draw_list_bind_uniform_set", "draw_list", "uniform_set", "set_index"), &RenderingDevice::draw_list_bind_uniform_set); + ClassDB::bind_method(D_METHOD("draw_list_bind_vertex_array", "draw_list", "vertex_array"), &RenderingDevice::draw_list_bind_vertex_array); + ClassDB::bind_method(D_METHOD("draw_list_bind_index_array", "draw_list", "index_array"), &RenderingDevice::draw_list_bind_index_array); + ClassDB::bind_method(D_METHOD("draw_list_set_push_constant", "draw_list", "buffer", "size_bytes"), &RenderingDevice::_draw_list_set_push_constant); + + ClassDB::bind_method(D_METHOD("draw_list_draw", "draw_list", "use_indices", "instances", "procedural_vertex_count"), &RenderingDevice::draw_list_draw, DEFVAL(0)); + + ClassDB::bind_method(D_METHOD("draw_list_enable_scissor", "draw_list", "rect"), &RenderingDevice::draw_list_enable_scissor, DEFVAL(Rect2i())); + ClassDB::bind_method(D_METHOD("draw_list_disable_scissor", "draw_list"), &RenderingDevice::draw_list_disable_scissor); + + ClassDB::bind_method(D_METHOD("draw_list_end"), &RenderingDevice::draw_list_end); + + ClassDB::bind_method(D_METHOD("compute_list_begin"), &RenderingDevice::compute_list_begin); + ClassDB::bind_method(D_METHOD("compute_list_bind_compute_pipeline", "compute_list", "compute_pipeline"), &RenderingDevice::compute_list_bind_compute_pipeline); + ClassDB::bind_method(D_METHOD("compute_list_set_push_constant", "compute_list", "buffer", "size_bytes"), &RenderingDevice::_compute_list_set_push_constant); + ClassDB::bind_method(D_METHOD("compute_list_bind_uniform_set", "compute_list", "uniform_set", "set_index"), &RenderingDevice::compute_list_bind_uniform_set); + ClassDB::bind_method(D_METHOD("compute_list_dispatch", "compute_list", "x_groups", "y_groups", "z_groups"), &RenderingDevice::compute_list_dispatch); + ClassDB::bind_method(D_METHOD("compute_list_add_barrier", "compute_list"), &RenderingDevice::compute_list_add_barrier); + ClassDB::bind_method(D_METHOD("compute_list_end"), &RenderingDevice::compute_list_end); + + ClassDB::bind_method(D_METHOD("free", "rid"), &RenderingDevice::free); + + ClassDB::bind_method(D_METHOD("capture_timestamp", "name", "sync_to_draw"), &RenderingDevice::capture_timestamp); + ClassDB::bind_method(D_METHOD("get_captured_timestamps_count"), &RenderingDevice::get_captured_timestamps_count); + ClassDB::bind_method(D_METHOD("get_captured_timestamps_frame"), &RenderingDevice::get_captured_timestamps_frame); + ClassDB::bind_method(D_METHOD("get_captured_timestamp_gpu_time", "index"), &RenderingDevice::get_captured_timestamp_gpu_time); + ClassDB::bind_method(D_METHOD("get_captured_timestamp_cpu_time", "index"), &RenderingDevice::get_captured_timestamp_cpu_time); + ClassDB::bind_method(D_METHOD("get_captured_timestamp_name", "index"), &RenderingDevice::get_captured_timestamp_name); + + ClassDB::bind_method(D_METHOD("limit_get", "limit"), &RenderingDevice::limit_get); + ClassDB::bind_method(D_METHOD("get_frame_delay"), &RenderingDevice::get_frame_delay); + ClassDB::bind_method(D_METHOD("submit"), &RenderingDevice::submit); + ClassDB::bind_method(D_METHOD("sync"), &RenderingDevice::sync); + + ClassDB::bind_method(D_METHOD("create_local_device"), &RenderingDevice::create_local_device); + + BIND_ENUM_CONSTANT(DATA_FORMAT_R4G4_UNORM_PACK8); + BIND_ENUM_CONSTANT(DATA_FORMAT_R4G4B4A4_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_B4G4R4A4_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R5G6B5_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_B5G6R5_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R5G5B5A1_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_B5G5R5A1_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_A1R5G5B5_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8_SRGB); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_SRGB); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_SRGB); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_SRGB); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_SRGB); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_SRGB); + BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_UNORM_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_SNORM_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_USCALED_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_SSCALED_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_UINT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_SINT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_SRGB_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_UNORM_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_SNORM_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_USCALED_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_SSCALED_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_UINT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_SINT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_UNORM_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_SNORM_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_USCALED_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_SSCALED_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_UINT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_SINT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32A32_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32A32_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32A32_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64A64_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64A64_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64A64_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_B10G11R11_UFLOAT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_D16_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_X8_D24_UNORM_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_D32_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_S8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_D16_UNORM_S8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_D24_UNORM_S8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_D32_SFLOAT_S8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC1_RGB_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC1_RGB_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC1_RGBA_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC1_RGBA_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC2_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC2_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC3_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC3_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC4_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC4_SNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC5_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC5_SNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC6H_UFLOAT_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC6H_SFLOAT_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC7_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC7_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_EAC_R11_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_EAC_R11_SNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_EAC_R11G11_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_EAC_R11G11_SNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_4x4_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_4x4_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_5x4_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_5x4_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_5x5_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_5x5_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_6x5_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_6x5_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_6x6_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_6x6_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x5_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x5_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x6_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x6_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x8_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x8_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x5_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x5_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x6_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x6_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x8_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x8_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x10_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x10_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_12x10_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_12x10_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_12x12_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_12x12_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_G8B8G8R8_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8G8_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G8_B8_R8_3PLANE_420_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G8_B8R8_2PLANE_420_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G8_B8_R8_3PLANE_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G8_B8R8_2PLANE_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G8_B8_R8_3PLANE_444_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R10X6_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R10X6G10X6_UNORM_2PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R12X4_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R12X4G12X4_UNORM_2PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G16B16G16R16_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_B16G16R16G16_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16_R16_3PLANE_420_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16R16_2PLANE_420_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16_R16_3PLANE_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16R16_2PLANE_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16_R16_3PLANE_444_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_MAX); + + BIND_ENUM_CONSTANT(TEXTURE_TYPE_1D); + BIND_ENUM_CONSTANT(TEXTURE_TYPE_2D); + BIND_ENUM_CONSTANT(TEXTURE_TYPE_3D); + BIND_ENUM_CONSTANT(TEXTURE_TYPE_CUBE); + BIND_ENUM_CONSTANT(TEXTURE_TYPE_1D_ARRAY); + BIND_ENUM_CONSTANT(TEXTURE_TYPE_2D_ARRAY); + BIND_ENUM_CONSTANT(TEXTURE_TYPE_CUBE_ARRAY); + BIND_ENUM_CONSTANT(TEXTURE_TYPE_MAX); + + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_1); + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_2); + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_4); + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_8); + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_16); + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_32); + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_64); + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_MAX); + + BIND_ENUM_CONSTANT(TEXTURE_USAGE_SAMPLING_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_COLOR_ATTACHMENT_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_STORAGE_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_STORAGE_ATOMIC_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_CPU_READ_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_CAN_UPDATE_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_CAN_COPY_FROM_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_CAN_COPY_TO_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_RESOLVE_ATTACHMENT_BIT); + + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_IDENTITY); + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_ZERO); + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_ONE); + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_R); + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_G); + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_B); + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_A); + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_MAX); + + BIND_ENUM_CONSTANT(TEXTURE_SLICE_2D); + BIND_ENUM_CONSTANT(TEXTURE_SLICE_CUBEMAP); + BIND_ENUM_CONSTANT(TEXTURE_SLICE_3D); + + BIND_ENUM_CONSTANT(SAMPLER_FILTER_NEAREST); + BIND_ENUM_CONSTANT(SAMPLER_FILTER_LINEAR); + BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_REPEAT); + BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_MIRRORED_REPEAT); + BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE); + BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_CLAMP_TO_BORDER); + BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_MIRROR_CLAMP_TO_EDGE); + BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_MAX); + + BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK); + BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_INT_TRANSPARENT_BLACK); + BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_FLOAT_OPAQUE_BLACK); + BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_INT_OPAQUE_BLACK); + BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_FLOAT_OPAQUE_WHITE); + BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_INT_OPAQUE_WHITE); + BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_MAX); + + BIND_ENUM_CONSTANT(VERTEX_FREQUENCY_VERTEX); + BIND_ENUM_CONSTANT(VERTEX_FREQUENCY_INSTANCE); + + BIND_ENUM_CONSTANT(INDEX_BUFFER_FORMAT_UINT16); + BIND_ENUM_CONSTANT(INDEX_BUFFER_FORMAT_UINT32); + + BIND_ENUM_CONSTANT(UNIFORM_TYPE_SAMPLER); //for sampling only (sampler GLSL type) + BIND_ENUM_CONSTANT(UNIFORM_TYPE_SAMPLER_WITH_TEXTURE); // for sampling only); but includes a texture); (samplerXX GLSL type)); first a sampler then a texture + BIND_ENUM_CONSTANT(UNIFORM_TYPE_TEXTURE); //only texture); (textureXX GLSL type) + BIND_ENUM_CONSTANT(UNIFORM_TYPE_IMAGE); // storage image (imageXX GLSL type)); for compute mostly + BIND_ENUM_CONSTANT(UNIFORM_TYPE_TEXTURE_BUFFER); // buffer texture (or TBO); textureBuffer type) + BIND_ENUM_CONSTANT(UNIFORM_TYPE_SAMPLER_WITH_TEXTURE_BUFFER); // buffer texture with a sampler(or TBO); samplerBuffer type) + BIND_ENUM_CONSTANT(UNIFORM_TYPE_IMAGE_BUFFER); //texel buffer); (imageBuffer type)); for compute mostly + BIND_ENUM_CONSTANT(UNIFORM_TYPE_UNIFORM_BUFFER); //regular uniform buffer (or UBO). + BIND_ENUM_CONSTANT(UNIFORM_TYPE_STORAGE_BUFFER); //storage buffer ("buffer" qualifier) like UBO); but supports storage); for compute mostly + BIND_ENUM_CONSTANT(UNIFORM_TYPE_INPUT_ATTACHMENT); //used for sub-pass read/write); for mobile mostly + BIND_ENUM_CONSTANT(UNIFORM_TYPE_MAX); + + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_POINTS); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_LINES); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_LINES_WITH_ADJACENCY); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_LINESTRIPS); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_LINESTRIPS_WITH_ADJACENCY); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TRIANGLES); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TRIANGLES_WITH_ADJACENCY); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TRIANGLE_STRIPS); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TRIANGLE_STRIPS_WITH_AJACENCY); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TRIANGLE_STRIPS_WITH_RESTART_INDEX); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TESSELATION_PATCH); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_MAX); + + BIND_ENUM_CONSTANT(POLYGON_CULL_DISABLED); + BIND_ENUM_CONSTANT(POLYGON_CULL_FRONT); + BIND_ENUM_CONSTANT(POLYGON_CULL_BACK); + + BIND_ENUM_CONSTANT(POLYGON_FRONT_FACE_CLOCKWISE); + BIND_ENUM_CONSTANT(POLYGON_FRONT_FACE_COUNTER_CLOCKWISE); + + BIND_ENUM_CONSTANT(STENCIL_OP_KEEP); + BIND_ENUM_CONSTANT(STENCIL_OP_ZERO); + BIND_ENUM_CONSTANT(STENCIL_OP_REPLACE); + BIND_ENUM_CONSTANT(STENCIL_OP_INCREMENT_AND_CLAMP); + BIND_ENUM_CONSTANT(STENCIL_OP_DECREMENT_AND_CLAMP); + BIND_ENUM_CONSTANT(STENCIL_OP_INVERT); + BIND_ENUM_CONSTANT(STENCIL_OP_INCREMENT_AND_WRAP); + BIND_ENUM_CONSTANT(STENCIL_OP_DECREMENT_AND_WRAP); + BIND_ENUM_CONSTANT(STENCIL_OP_MAX); //not an actual operator); just the amount of operators :D + + BIND_ENUM_CONSTANT(COMPARE_OP_NEVER); + BIND_ENUM_CONSTANT(COMPARE_OP_LESS); + BIND_ENUM_CONSTANT(COMPARE_OP_EQUAL); + BIND_ENUM_CONSTANT(COMPARE_OP_LESS_OR_EQUAL); + BIND_ENUM_CONSTANT(COMPARE_OP_GREATER); + BIND_ENUM_CONSTANT(COMPARE_OP_NOT_EQUAL); + BIND_ENUM_CONSTANT(COMPARE_OP_GREATER_OR_EQUAL); + BIND_ENUM_CONSTANT(COMPARE_OP_ALWAYS); + BIND_ENUM_CONSTANT(COMPARE_OP_MAX); + + BIND_ENUM_CONSTANT(LOGIC_OP_CLEAR); + BIND_ENUM_CONSTANT(LOGIC_OP_AND); + BIND_ENUM_CONSTANT(LOGIC_OP_AND_REVERSE); + BIND_ENUM_CONSTANT(LOGIC_OP_COPY); + BIND_ENUM_CONSTANT(LOGIC_OP_AND_INVERTED); + BIND_ENUM_CONSTANT(LOGIC_OP_NO_OP); + BIND_ENUM_CONSTANT(LOGIC_OP_XOR); + BIND_ENUM_CONSTANT(LOGIC_OP_OR); + BIND_ENUM_CONSTANT(LOGIC_OP_NOR); + BIND_ENUM_CONSTANT(LOGIC_OP_EQUIVALENT); + BIND_ENUM_CONSTANT(LOGIC_OP_INVERT); + BIND_ENUM_CONSTANT(LOGIC_OP_OR_REVERSE); + BIND_ENUM_CONSTANT(LOGIC_OP_COPY_INVERTED); + BIND_ENUM_CONSTANT(LOGIC_OP_OR_INVERTED); + BIND_ENUM_CONSTANT(LOGIC_OP_NAND); + BIND_ENUM_CONSTANT(LOGIC_OP_SET); + BIND_ENUM_CONSTANT(LOGIC_OP_MAX); //not an actual operator); just the amount of operators :D + + BIND_ENUM_CONSTANT(BLEND_FACTOR_ZERO); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE); + BIND_ENUM_CONSTANT(BLEND_FACTOR_SRC_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_SRC_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_DST_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_DST_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_SRC_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_SRC_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_DST_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_DST_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_CONSTANT_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_CONSTANT_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_SRC_ALPHA_SATURATE); + BIND_ENUM_CONSTANT(BLEND_FACTOR_SRC1_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_SRC1_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_SRC1_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_MAX); + + BIND_ENUM_CONSTANT(BLEND_OP_ADD); + BIND_ENUM_CONSTANT(BLEND_OP_SUBTRACT); + BIND_ENUM_CONSTANT(BLEND_OP_REVERSE_SUBTRACT); + BIND_ENUM_CONSTANT(BLEND_OP_MINIMUM); + BIND_ENUM_CONSTANT(BLEND_OP_MAXIMUM); + BIND_ENUM_CONSTANT(BLEND_OP_MAX); + + BIND_ENUM_CONSTANT(DYNAMIC_STATE_LINE_WIDTH); + BIND_ENUM_CONSTANT(DYNAMIC_STATE_DEPTH_BIAS); + BIND_ENUM_CONSTANT(DYNAMIC_STATE_BLEND_CONSTANTS); + BIND_ENUM_CONSTANT(DYNAMIC_STATE_DEPTH_BOUNDS); + BIND_ENUM_CONSTANT(DYNAMIC_STATE_STENCIL_COMPARE_MASK); + BIND_ENUM_CONSTANT(DYNAMIC_STATE_STENCIL_WRITE_MASK); + BIND_ENUM_CONSTANT(DYNAMIC_STATE_STENCIL_REFERENCE); + + BIND_ENUM_CONSTANT(INITIAL_ACTION_CLEAR); //start rendering and clear the framebuffer (supply params) + BIND_ENUM_CONSTANT(INITIAL_ACTION_KEEP); //start rendering); but keep attached color texture contents (depth will be cleared) + BIND_ENUM_CONSTANT(INITIAL_ACTION_DROP); //start rendering); ignore what is there); just write above it + BIND_ENUM_CONSTANT(INITIAL_ACTION_CONTINUE); //continue rendering (framebuffer must have been left in "continue" state as final action previously) + BIND_ENUM_CONSTANT(INITIAL_ACTION_MAX); + + BIND_ENUM_CONSTANT(FINAL_ACTION_READ); //will no longer render to it); allows attached textures to be read again); but depth buffer contents will be dropped (Can't be read from) + BIND_ENUM_CONSTANT(FINAL_ACTION_DISCARD); // discard contents after rendering + BIND_ENUM_CONSTANT(FINAL_ACTION_CONTINUE); //will continue rendering later); attached textures can't be read until re-bound with "finish" + BIND_ENUM_CONSTANT(FINAL_ACTION_MAX); + + BIND_ENUM_CONSTANT(SHADER_STAGE_VERTEX); + BIND_ENUM_CONSTANT(SHADER_STAGE_FRAGMENT); + BIND_ENUM_CONSTANT(SHADER_STAGE_TESSELATION_CONTROL); + BIND_ENUM_CONSTANT(SHADER_STAGE_TESSELATION_EVALUATION); + BIND_ENUM_CONSTANT(SHADER_STAGE_COMPUTE); + BIND_ENUM_CONSTANT(SHADER_STAGE_MAX); + BIND_ENUM_CONSTANT(SHADER_STAGE_VERTEX_BIT); + BIND_ENUM_CONSTANT(SHADER_STAGE_FRAGMENT_BIT); + BIND_ENUM_CONSTANT(SHADER_STAGE_TESSELATION_CONTROL_BIT); + BIND_ENUM_CONSTANT(SHADER_STAGE_TESSELATION_EVALUATION_BIT); + BIND_ENUM_CONSTANT(SHADER_STAGE_COMPUTE_BIT); + + BIND_ENUM_CONSTANT(SHADER_LANGUAGE_GLSL); + BIND_ENUM_CONSTANT(SHADER_LANGUAGE_HLSL); + + BIND_ENUM_CONSTANT(LIMIT_MAX_BOUND_UNIFORM_SETS); + BIND_ENUM_CONSTANT(LIMIT_MAX_FRAMEBUFFER_COLOR_ATTACHMENTS); + BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURES_PER_UNIFORM_SET); + BIND_ENUM_CONSTANT(LIMIT_MAX_SAMPLERS_PER_UNIFORM_SET); + BIND_ENUM_CONSTANT(LIMIT_MAX_STORAGE_BUFFERS_PER_UNIFORM_SET); + BIND_ENUM_CONSTANT(LIMIT_MAX_STORAGE_IMAGES_PER_UNIFORM_SET); + BIND_ENUM_CONSTANT(LIMIT_MAX_UNIFORM_BUFFERS_PER_UNIFORM_SET); + BIND_ENUM_CONSTANT(LIMIT_MAX_DRAW_INDEXED_INDEX); + BIND_ENUM_CONSTANT(LIMIT_MAX_FRAMEBUFFER_HEIGHT); + BIND_ENUM_CONSTANT(LIMIT_MAX_FRAMEBUFFER_WIDTH); + BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURE_ARRAY_LAYERS); + BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURE_SIZE_1D); + BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURE_SIZE_2D); + BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURE_SIZE_3D); + BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURE_SIZE_CUBE); + BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURES_PER_SHADER_STAGE); + BIND_ENUM_CONSTANT(LIMIT_MAX_SAMPLERS_PER_SHADER_STAGE); + BIND_ENUM_CONSTANT(LIMIT_MAX_STORAGE_BUFFERS_PER_SHADER_STAGE); + BIND_ENUM_CONSTANT(LIMIT_MAX_STORAGE_IMAGES_PER_SHADER_STAGE); + BIND_ENUM_CONSTANT(LIMIT_MAX_UNIFORM_BUFFERS_PER_SHADER_STAGE); + BIND_ENUM_CONSTANT(LIMIT_MAX_PUSH_CONSTANT_SIZE); + BIND_ENUM_CONSTANT(LIMIT_MAX_UNIFORM_BUFFER_SIZE); + BIND_ENUM_CONSTANT(LIMIT_MAX_VERTEX_INPUT_ATTRIBUTE_OFFSET); + BIND_ENUM_CONSTANT(LIMIT_MAX_VERTEX_INPUT_ATTRIBUTES); + BIND_ENUM_CONSTANT(LIMIT_MAX_VERTEX_INPUT_BINDINGS); + BIND_ENUM_CONSTANT(LIMIT_MAX_VERTEX_INPUT_BINDING_STRIDE); + BIND_ENUM_CONSTANT(LIMIT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_SHARED_MEMORY_SIZE); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_X); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Y); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Z); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_INVOCATIONS); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_X); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Y); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z); + + BIND_CONSTANT(INVALID_ID); + BIND_CONSTANT(INVALID_FORMAT_ID); +} + RenderingDevice::RenderingDevice() { - singleton = this; + if (singleton == nullptr) { // there may be more rendering devices later + singleton = this; + } } diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index a639ff3641..c76fce5b5c 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -32,8 +32,22 @@ #define RENDERING_DEVICE_H #include "core/object.h" +#include "core/typed_array.h" #include "servers/display_server.h" +class RDTextureFormat; +class RDTextureView; +class RDAttachmentFormat; +class RDSamplerState; +class RDVertexAttribute; +class RDShaderSource; +class RDShaderBytecode; +class RDUniforms; +class RDPipelineRasterizationState; +class RDPipelineMultisampleState; +class RDPipelineDepthStencilState; +class RDPipelineColorBlendState; + class RenderingDevice : public Object { GDCLASS(RenderingDevice, Object) public: @@ -65,10 +79,14 @@ private: static RenderingDevice *singleton; +protected: + static void _bind_methods(); + public: //base numeric ID for all types enum { - INVALID_ID = -1 + INVALID_ID = -1, + INVALID_FORMAT_ID = -1 }; /*****************/ @@ -428,6 +446,7 @@ public: virtual Error texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, bool p_sync_with_draw = false) = 0; virtual Error texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, bool p_sync_with_draw = false) = 0; + virtual Error texture_resolve_multisample(RID p_from_texture, RID p_to_texture, bool p_sync_with_draw = false) = 0; /*********************/ /**** FRAMEBUFFER ****/ @@ -529,13 +548,13 @@ public: VERTEX_FREQUENCY_INSTANCE, }; - struct VertexDescription { + struct VertexAttribute { uint32_t location; //shader location uint32_t offset; DataFormat format; uint32_t stride; VertexFrequency frequency; - VertexDescription() { + VertexAttribute() { location = 0; offset = 0; stride = 0; @@ -548,7 +567,7 @@ public: typedef int64_t VertexFormatID; // This ID is warranted to be unique for the same formats, does not need to be freed - virtual VertexFormatID vertex_format_create(const Vector<VertexDescription> &p_vertex_formats) = 0; + virtual VertexFormatID vertex_format_create(const Vector<VertexAttribute> &p_vertex_formats) = 0; virtual RID vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const Vector<RID> &p_src_buffers) = 0; enum IndexBufferFormat { @@ -594,7 +613,7 @@ public: UNIFORM_TYPE_IMAGE_BUFFER, //texel buffer, (imageBuffer type), for compute mostly UNIFORM_TYPE_UNIFORM_BUFFER, //regular uniform buffer (or UBO). UNIFORM_TYPE_STORAGE_BUFFER, //storage buffer ("buffer" qualifier) like UBO, but supports storage, for compute mostly - UNIFORM_TYPE_INPUT_ATTACHMENT, //used for sub-pass read/write, for compute mostly + UNIFORM_TYPE_INPUT_ATTACHMENT, //used for sub-pass read/write, for mobile mostly UNIFORM_TYPE_MAX }; @@ -795,8 +814,8 @@ public: } }; - StencilOperationState stencil_operation_front; - StencilOperationState stencil_operation_back; + StencilOperationState front_op; + StencilOperationState back_op; PipelineDepthStencilState() { enable_depth_test = false; @@ -883,8 +902,8 @@ public: DYNAMIC_STATE_STENCIL_REFERENCE = (1 << 6), }; - virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0) = 0; virtual bool render_pipeline_is_valid(RID p_pipeline) = 0; + virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0) = 0; /**************************/ /**** COMPUTE PIPELINE ****/ @@ -908,6 +927,7 @@ public: enum InitialAction { INITIAL_ACTION_CLEAR, //start rendering and clear the framebuffer (supply params) INITIAL_ACTION_KEEP, //start rendering, but keep attached color texture contents (depth will be cleared) + INITIAL_ACTION_DROP, //start rendering, ignore what is there, just write above it INITIAL_ACTION_CONTINUE, //continue rendering (framebuffer must have been left in "continue" state as final action previously) INITIAL_ACTION_MAX }; @@ -930,7 +950,7 @@ public: virtual void draw_list_bind_vertex_array(DrawListID p_list, RID p_vertex_array) = 0; virtual void draw_list_bind_index_array(DrawListID p_list, RID p_index_array) = 0; virtual void draw_list_set_line_width(DrawListID p_list, float p_width) = 0; - virtual void draw_list_set_push_constant(DrawListID p_list, void *p_data, uint32_t p_data_size) = 0; + virtual void draw_list_set_push_constant(DrawListID p_list, const void *p_data, uint32_t p_data_size) = 0; virtual void draw_list_draw(DrawListID p_list, bool p_use_indices, uint32_t p_instances = 1, uint32_t p_procedural_vertices = 0) = 0; @@ -948,7 +968,7 @@ public: virtual ComputeListID compute_list_begin() = 0; virtual void compute_list_bind_compute_pipeline(ComputeListID p_list, RID p_compute_pipeline) = 0; virtual void compute_list_bind_uniform_set(ComputeListID p_list, RID p_uniform_set, uint32_t p_index) = 0; - virtual void compute_list_set_push_constant(ComputeListID p_list, void *p_data, uint32_t p_data_size) = 0; + virtual void compute_list_set_push_constant(ComputeListID p_list, const void *p_data, uint32_t p_data_size) = 0; virtual void compute_list_dispatch(ComputeListID p_list, uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups) = 0; virtual void compute_list_add_barrier(ComputeListID p_list) = 0; @@ -1022,11 +1042,67 @@ public: virtual uint32_t get_frame_delay() const = 0; - static RenderingDevice *get_singleton(); + virtual void submit() = 0; + virtual void sync() = 0; + + virtual RenderingDevice *create_local_device() = 0; + static RenderingDevice *get_singleton(); RenderingDevice(); + +protected: + //binders to script API + RID _texture_create(const Ref<RDTextureFormat> &p_format, const Ref<RDTextureView> &p_view, const TypedArray<PackedByteArray> &p_data = Array()); + RID _texture_create_shared(const Ref<RDTextureView> &p_view, RID p_with_texture); + RID _texture_create_shared_from_slice(const Ref<RDTextureView> &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type = TEXTURE_SLICE_2D); + + FramebufferFormatID _framebuffer_format_create(const TypedArray<RDAttachmentFormat> &p_attachments); + RID _framebuffer_create(const Array &p_textures, FramebufferFormatID p_format_check = INVALID_ID); + RID _sampler_create(const Ref<RDSamplerState> &p_state); + VertexFormatID _vertex_format_create(const TypedArray<RDVertexAttribute> &p_vertex_formats); + RID _vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const TypedArray<RID> &p_src_buffers); + + Ref<RDShaderBytecode> _shader_compile_from_source(const Ref<RDShaderSource> &p_source, bool p_allow_cache = true); + RID _shader_create(const Ref<RDShaderBytecode> &p_bytecode); + + RID _uniform_set_create(const Array &p_uniforms, RID p_shader, uint32_t p_shader_set); + + Error _buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, bool p_sync_with_draw = false); + + RID _render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags = 0); + + Vector<int64_t> _draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2()); + void _draw_list_set_push_constant(DrawListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size); + void _compute_list_set_push_constant(ComputeListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size); }; +VARIANT_ENUM_CAST(RenderingDevice::ShaderStage) +VARIANT_ENUM_CAST(RenderingDevice::ShaderLanguage) +VARIANT_ENUM_CAST(RenderingDevice::CompareOperator) +VARIANT_ENUM_CAST(RenderingDevice::DataFormat) +VARIANT_ENUM_CAST(RenderingDevice::TextureType) +VARIANT_ENUM_CAST(RenderingDevice::TextureSamples) +VARIANT_ENUM_CAST(RenderingDevice::TextureUsageBits) +VARIANT_ENUM_CAST(RenderingDevice::TextureSwizzle) +VARIANT_ENUM_CAST(RenderingDevice::TextureSliceType) +VARIANT_ENUM_CAST(RenderingDevice::SamplerFilter) +VARIANT_ENUM_CAST(RenderingDevice::SamplerRepeatMode) +VARIANT_ENUM_CAST(RenderingDevice::SamplerBorderColor) +VARIANT_ENUM_CAST(RenderingDevice::VertexFrequency) +VARIANT_ENUM_CAST(RenderingDevice::IndexBufferFormat) +VARIANT_ENUM_CAST(RenderingDevice::UniformType) +VARIANT_ENUM_CAST(RenderingDevice::RenderPrimitive) +VARIANT_ENUM_CAST(RenderingDevice::PolygonCullMode) +VARIANT_ENUM_CAST(RenderingDevice::PolygonFrontFace) +VARIANT_ENUM_CAST(RenderingDevice::StencilOperation) +VARIANT_ENUM_CAST(RenderingDevice::LogicOperation) +VARIANT_ENUM_CAST(RenderingDevice::BlendFactor) +VARIANT_ENUM_CAST(RenderingDevice::BlendOperation) +VARIANT_ENUM_CAST(RenderingDevice::PipelineDynamicStateFlags) +VARIANT_ENUM_CAST(RenderingDevice::InitialAction) +VARIANT_ENUM_CAST(RenderingDevice::FinalAction) +VARIANT_ENUM_CAST(RenderingDevice::Limit) + typedef RenderingDevice RD; #endif // RENDERING_DEVICE_H diff --git a/servers/rendering/rendering_device_binds.cpp b/servers/rendering/rendering_device_binds.cpp new file mode 100644 index 0000000000..111755eba3 --- /dev/null +++ b/servers/rendering/rendering_device_binds.cpp @@ -0,0 +1,167 @@ +#include "rendering_device_binds.h" + +Error RDShaderFile::parse_versions_from_text(const String &p_text, OpenIncludeFunction p_include_func, void *p_include_func_userdata) { + + Vector<String> lines = p_text.split("\n"); + + bool reading_versions = false; + bool stage_found[RD::SHADER_STAGE_MAX] = { false, false, false, false, false }; + RD::ShaderStage stage = RD::SHADER_STAGE_MAX; + static const char *stage_str[RD::SHADER_STAGE_MAX] = { + "vertex", + "fragment", + "tesselation_control", + "tesselation_evaluation", + "compute" + }; + String stage_code[RD::SHADER_STAGE_MAX]; + int stages_found = 0; + Map<StringName, String> version_texts; + + versions.clear(); + base_error = ""; + + for (int lidx = 0; lidx < lines.size(); lidx++) { + String line = lines[lidx]; + + { + String ls = line.strip_edges(); + if (ls.begins_with("[") && ls.ends_with("]")) { + String section = ls.substr(1, ls.length() - 2).strip_edges(); + if (section == "versions") { + if (stages_found) { + base_error = "Invalid shader file, [version] must be the first section found."; + break; + } + reading_versions = true; + } else { + for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { + if (section == stage_str[i]) { + if (stage_found[i]) { + base_error = "Invalid shader file, stage appears twice: " + section; + break; + } + + stage_found[i] = true; + stages_found++; + + stage = RD::ShaderStage(i); + reading_versions = false; + break; + } + } + + if (base_error != String()) { + break; + } + } + + continue; + } + } + + if (reading_versions) { + String l = line.strip_edges(); + if (l != "") { + int eqpos = l.find("="); + if (eqpos == -1) { + base_error = "Version syntax is version=\"<defines with C escaping>\"."; + break; + } + String version = l.get_slice("=", 0).strip_edges(); + if (!version.is_valid_identifier()) { + base_error = "Version names must be valid identifiers, found '" + version + "' instead."; + break; + } + String define = l.get_slice("=", 1).strip_edges(); + if (!define.begins_with("\"") || !define.ends_with("\"")) { + base_error = "Version text must be quoted using \"\", instead found '" + define + "'."; + break; + } + define = "\n" + define.substr(1, define.length() - 2).c_unescape() + "\n"; //add newline before and after jsut in case + + version_texts[version] = define; + } + } else { + if (stage == RD::SHADER_STAGE_MAX && line.strip_edges() != "") { + base_error = "Text was found that does not belong to a valid section: " + line; + break; + } + + if (stage != RD::SHADER_STAGE_MAX) { + if (line.strip_edges().begins_with("#include")) { + if (p_include_func) { + //process include + String include = line.replace("#include", "").strip_edges(); + if (!include.begins_with("\"") || !include.ends_with("\"")) { + base_error = "Malformed #include syntax, expected #include \"<path>\", found instad: " + include; + break; + } + include = include.substr(1, include.length() - 2).strip_edges(); + String include_text = p_include_func(include, p_include_func_userdata); + if (include_text != String()) { + stage_code[stage] += "\n" + include_text + "\n"; + } else { + base_error = "#include failed for file '" + include + "'"; + } + } else { + base_error = "#include used, but no include function provided."; + } + } else { + + stage_code[stage] += line + "\n"; + } + } + } + } + + Ref<RDShaderFile> shader_file; + shader_file.instance(); + + if (base_error == "") { + + if (stage_found[RD::SHADER_STAGE_COMPUTE] && stages_found > 1) { + ERR_FAIL_V_MSG(ERR_PARSE_ERROR, "When writing compute shaders, [compute] mustbe the only stage present."); + } + + if (version_texts.empty()) { + version_texts[""] = ""; //make sure a default version exists + } + + bool errors_found = false; + + /* STEP 2, Compile the versions, add to shader file */ + + for (Map<StringName, String>::Element *E = version_texts.front(); E; E = E->next()) { + + Ref<RDShaderBytecode> bytecode; + bytecode.instance(); + + for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { + String code = stage_code[i]; + if (code == String()) { + continue; + } + code = code.replace("VERSION_DEFINES", E->get()); + String error; + Vector<uint8_t> spirv = RenderingDevice::get_singleton()->shader_compile_from_source(RD::ShaderStage(i), code, RD::SHADER_LANGUAGE_GLSL, &error, false); + bytecode->set_stage_bytecode(RD::ShaderStage(i), spirv); + if (error != "") { + error += String() + "\n\nStage '" + stage_str[i] + "' source code: \n\n"; + Vector<String> sclines = code.split("\n"); + for (int j = 0; j < sclines.size(); j++) { + error += itos(j + 1) + "\t\t" + sclines[j] + "\n"; + } + errors_found = true; + } + bytecode->set_stage_compile_error(RD::ShaderStage(i), error); + } + + set_bytecode(bytecode, E->key()); + } + + return errors_found ? ERR_PARSE_ERROR : OK; + } else { + return ERR_PARSE_ERROR; + } +} diff --git a/servers/rendering/rendering_device_binds.h b/servers/rendering/rendering_device_binds.h new file mode 100644 index 0000000000..f57f59876d --- /dev/null +++ b/servers/rendering/rendering_device_binds.h @@ -0,0 +1,579 @@ +#ifndef RENDERING_DEVICE_BINDS_H +#define RENDERING_DEVICE_BINDS_H + +#include "servers/rendering/rendering_device.h" + +#define RD_SETGET(m_type, m_member) \ + void set_##m_member(m_type p_##m_member) { base.m_member = p_##m_member; } \ + m_type get_##m_member() const { return base.m_member; } + +#define RD_BIND(m_variant_type, m_class, m_member) \ + ClassDB::bind_method(D_METHOD("set_" _MKSTR(m_member), "p_" _MKSTR(member)), &m_class::set_##m_member); \ + ClassDB::bind_method(D_METHOD("get_" _MKSTR(m_member)), &m_class::get_##m_member); \ + ADD_PROPERTY(PropertyInfo(m_variant_type, #m_member), "set_" _MKSTR(m_member), "get_" _MKSTR(m_member)) + +#define RD_SETGET_SUB(m_type, m_sub, m_member) \ + void set_##m_sub##_##m_member(m_type p_##m_member) { base.m_sub.m_member = p_##m_member; } \ + m_type get_##m_sub##_##m_member() const { return base.m_sub.m_member; } + +#define RD_BIND_SUB(m_variant_type, m_class, m_sub, m_member) \ + ClassDB::bind_method(D_METHOD("set_" _MKSTR(m_sub) "_" _MKSTR(m_member), "p_" _MKSTR(member)), &m_class::set_##m_sub##_##m_member); \ + ClassDB::bind_method(D_METHOD("get_" _MKSTR(m_sub) "_" _MKSTR(m_member)), &m_class::get_##m_sub##_##m_member); \ + ADD_PROPERTY(PropertyInfo(m_variant_type, _MKSTR(m_sub) "_" _MKSTR(m_member)), "set_" _MKSTR(m_sub) "_" _MKSTR(m_member), "get_" _MKSTR(m_sub) "_" _MKSTR(m_member)) + +class RDTextureFormat : public Reference { + GDCLASS(RDTextureFormat, Reference) + friend class RenderingDevice; + + RD::TextureFormat base; + +public: + RD_SETGET(RD::DataFormat, format) + RD_SETGET(uint32_t, width) + RD_SETGET(uint32_t, height) + RD_SETGET(uint32_t, depth) + RD_SETGET(uint32_t, array_layers) + RD_SETGET(uint32_t, mipmaps) + RD_SETGET(RD::TextureType, type) + RD_SETGET(RD::TextureSamples, samples) + RD_SETGET(uint32_t, usage_bits) + + void add_shareable_format(RD::DataFormat p_format) { base.shareable_formats.push_back(p_format); } + void remove_shareable_format(RD::DataFormat p_format) { base.shareable_formats.erase(p_format); } + +protected: + static void _bind_methods() { + RD_BIND(Variant::INT, RDTextureFormat, format); + RD_BIND(Variant::INT, RDTextureFormat, width); + RD_BIND(Variant::INT, RDTextureFormat, height); + RD_BIND(Variant::INT, RDTextureFormat, depth); + RD_BIND(Variant::INT, RDTextureFormat, array_layers); + RD_BIND(Variant::INT, RDTextureFormat, mipmaps); + RD_BIND(Variant::INT, RDTextureFormat, type); + RD_BIND(Variant::INT, RDTextureFormat, samples); + RD_BIND(Variant::INT, RDTextureFormat, usage_bits); + ClassDB::bind_method(D_METHOD("add_shareable_format", "format"), &RDTextureFormat::add_shareable_format); + ClassDB::bind_method(D_METHOD("remove_shareable_format", "format"), &RDTextureFormat::remove_shareable_format); + } +}; + +class RDTextureView : public Reference { + GDCLASS(RDTextureView, Reference) + + friend class RenderingDevice; + + RD::TextureView base; + +public: + RD_SETGET(RD::DataFormat, format_override) + RD_SETGET(RD::TextureSwizzle, swizzle_r) + RD_SETGET(RD::TextureSwizzle, swizzle_g) + RD_SETGET(RD::TextureSwizzle, swizzle_b) + RD_SETGET(RD::TextureSwizzle, swizzle_a) +protected: + static void _bind_methods() { + RD_BIND(Variant::INT, RDTextureView, format_override); + RD_BIND(Variant::INT, RDTextureView, swizzle_r); + RD_BIND(Variant::INT, RDTextureView, swizzle_g); + RD_BIND(Variant::INT, RDTextureView, swizzle_b); + RD_BIND(Variant::INT, RDTextureView, swizzle_a); + } +}; + +class RDAttachmentFormat : public Reference { + GDCLASS(RDAttachmentFormat, Reference) + friend class RenderingDevice; + + RD::AttachmentFormat base; + +public: + RD_SETGET(RD::DataFormat, format) + RD_SETGET(RD::TextureSamples, samples) + RD_SETGET(uint32_t, usage_flags) +protected: + static void _bind_methods() { + RD_BIND(Variant::INT, RDAttachmentFormat, format); + RD_BIND(Variant::INT, RDAttachmentFormat, samples); + RD_BIND(Variant::INT, RDAttachmentFormat, usage_flags); + } +}; + +class RDSamplerState : public Reference { + GDCLASS(RDSamplerState, Reference) + friend class RenderingDevice; + + RD::SamplerState base; + +public: + RD_SETGET(RD::SamplerFilter, mag_filter) + RD_SETGET(RD::SamplerFilter, min_filter) + RD_SETGET(RD::SamplerFilter, mip_filter) + RD_SETGET(RD::SamplerRepeatMode, repeat_u) + RD_SETGET(RD::SamplerRepeatMode, repeat_v) + RD_SETGET(RD::SamplerRepeatMode, repeat_w) + RD_SETGET(float, lod_bias) + RD_SETGET(bool, use_anisotropy) + RD_SETGET(float, anisotropy_max) + RD_SETGET(bool, enable_compare) + RD_SETGET(RD::CompareOperator, compare_op) + RD_SETGET(float, min_lod) + RD_SETGET(float, max_lod) + RD_SETGET(RD::SamplerBorderColor, border_color) + RD_SETGET(bool, unnormalized_uvw) + +protected: + static void _bind_methods() { + + RD_BIND(Variant::INT, RDSamplerState, mag_filter); + RD_BIND(Variant::INT, RDSamplerState, min_filter); + RD_BIND(Variant::INT, RDSamplerState, mip_filter); + RD_BIND(Variant::INT, RDSamplerState, repeat_u); + RD_BIND(Variant::INT, RDSamplerState, repeat_v); + RD_BIND(Variant::INT, RDSamplerState, repeat_w); + RD_BIND(Variant::FLOAT, RDSamplerState, lod_bias); + RD_BIND(Variant::BOOL, RDSamplerState, use_anisotropy); + RD_BIND(Variant::FLOAT, RDSamplerState, anisotropy_max); + RD_BIND(Variant::BOOL, RDSamplerState, enable_compare); + RD_BIND(Variant::INT, RDSamplerState, compare_op); + RD_BIND(Variant::FLOAT, RDSamplerState, min_lod); + RD_BIND(Variant::FLOAT, RDSamplerState, max_lod); + RD_BIND(Variant::INT, RDSamplerState, border_color); + RD_BIND(Variant::BOOL, RDSamplerState, unnormalized_uvw); + } +}; + +class RDVertexAttribute : public Reference { + GDCLASS(RDVertexAttribute, Reference) + friend class RenderingDevice; + RD::VertexAttribute base; + +public: + RD_SETGET(uint32_t, location) + RD_SETGET(uint32_t, offset) + RD_SETGET(RD::DataFormat, format) + RD_SETGET(uint32_t, stride) + RD_SETGET(RD::VertexFrequency, frequency) + +protected: + static void _bind_methods() { + RD_BIND(Variant::INT, RDVertexAttribute, location); + RD_BIND(Variant::INT, RDVertexAttribute, offset); + RD_BIND(Variant::INT, RDVertexAttribute, format); + RD_BIND(Variant::INT, RDVertexAttribute, stride); + RD_BIND(Variant::INT, RDVertexAttribute, frequency); + } +}; +class RDShaderSource : public Reference { + GDCLASS(RDShaderSource, Reference) + String source[RD::SHADER_STAGE_MAX]; + RD::ShaderLanguage language = RD::SHADER_LANGUAGE_GLSL; + +public: + void set_stage_source(RD::ShaderStage p_stage, const String &p_source) { + ERR_FAIL_INDEX(p_stage, RD::SHADER_STAGE_MAX); + source[p_stage] = p_source; + } + + String get_stage_source(RD::ShaderStage p_stage) const { + ERR_FAIL_INDEX_V(p_stage, RD::SHADER_STAGE_MAX, String()); + return source[p_stage]; + } + + void set_language(RD::ShaderLanguage p_language) { + language = p_language; + } + + RD::ShaderLanguage get_language() const { + return language; + } + +protected: + static void _bind_methods() { + ClassDB::bind_method(D_METHOD("set_stage_source", "stage", "source"), &RDShaderSource::set_stage_source); + ClassDB::bind_method(D_METHOD("get_stage_source", "stage"), &RDShaderSource::get_stage_source); + + ClassDB::bind_method(D_METHOD("set_language", "language"), &RDShaderSource::set_language); + ClassDB::bind_method(D_METHOD("get_language"), &RDShaderSource::get_language); + + ADD_GROUP("Source", "source_"); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_vertex"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_VERTEX); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_fragment"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_FRAGMENT); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_tesselation_control"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_TESSELATION_CONTROL); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_tesselation_evaluation"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_TESSELATION_EVALUATION); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_compute"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_COMPUTE); + ADD_GROUP("Syntax", "source_"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "language", PROPERTY_HINT_RANGE, "GLSL,HLSL"), "set_language", "get_language"); + } +}; + +class RDShaderBytecode : public Resource { + GDCLASS(RDShaderBytecode, Resource) + + Vector<uint8_t> bytecode[RD::SHADER_STAGE_MAX]; + String compile_error[RD::SHADER_STAGE_MAX]; + +public: + void set_stage_bytecode(RD::ShaderStage p_stage, const Vector<uint8_t> &p_bytecode) { + ERR_FAIL_INDEX(p_stage, RD::SHADER_STAGE_MAX); + bytecode[p_stage] = p_bytecode; + } + + Vector<uint8_t> get_stage_bytecode(RD::ShaderStage p_stage) const { + ERR_FAIL_INDEX_V(p_stage, RD::SHADER_STAGE_MAX, Vector<uint8_t>()); + return bytecode[p_stage]; + } + + void set_stage_compile_error(RD::ShaderStage p_stage, const String &p_compile_error) { + ERR_FAIL_INDEX(p_stage, RD::SHADER_STAGE_MAX); + compile_error[p_stage] = p_compile_error; + } + + String get_stage_compile_error(RD::ShaderStage p_stage) const { + ERR_FAIL_INDEX_V(p_stage, RD::SHADER_STAGE_MAX, String()); + return compile_error[p_stage]; + } + +protected: + static void _bind_methods() { + ClassDB::bind_method(D_METHOD("set_stage_bytecode", "stage", "bytecode"), &RDShaderBytecode::set_stage_bytecode); + ClassDB::bind_method(D_METHOD("get_stage_bytecode", "stage"), &RDShaderBytecode::get_stage_bytecode); + + ClassDB::bind_method(D_METHOD("set_stage_compile_error", "stage", "compile_error"), &RDShaderBytecode::set_stage_compile_error); + ClassDB::bind_method(D_METHOD("get_stage_compile_error", "stage"), &RDShaderBytecode::get_stage_compile_error); + + ADD_GROUP("Bytecode", "bytecode_"); + ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_vertex"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_VERTEX); + ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_fragment"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_FRAGMENT); + ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_tesselation_control"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_TESSELATION_CONTROL); + ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_tesselation_evaluation"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_TESSELATION_EVALUATION); + ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_compute"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_COMPUTE); + ADD_GROUP("Compile Error", "compile_error_"); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_vertex"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_VERTEX); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_fragment"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_FRAGMENT); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_tesselation_control"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_TESSELATION_CONTROL); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_tesselation_evaluation"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_TESSELATION_EVALUATION); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_compute"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_COMPUTE); + } +}; + +class RDShaderFile : public Resource { + GDCLASS(RDShaderFile, Resource) + + Map<StringName, Ref<RDShaderBytecode>> versions; + String base_error; + +public: + void set_bytecode(const Ref<RDShaderBytecode> &p_bytecode, const StringName &p_version = StringName()) { + ERR_FAIL_COND(p_bytecode.is_null()); + versions[p_version] = p_bytecode; + emit_changed(); + } + + Ref<RDShaderBytecode> get_bytecode(const StringName &p_version = StringName()) const { + ERR_FAIL_COND_V(!versions.has(p_version), Ref<RDShaderBytecode>()); + return versions[p_version]; + } + + Vector<StringName> get_version_list() const { + Vector<StringName> vnames; + for (Map<StringName, Ref<RDShaderBytecode>>::Element *E = versions.front(); E; E = E->next()) { + vnames.push_back(E->key()); + } + vnames.sort_custom<StringName::AlphCompare>(); + return vnames; + } + + void set_base_error(const String &p_error) { + base_error = p_error; + emit_changed(); + } + + String get_base_error() const { + return base_error; + } + + typedef String (*OpenIncludeFunction)(const String &, void *userdata); + Error parse_versions_from_text(const String &p_text, OpenIncludeFunction p_include_func = nullptr, void *p_include_func_userdata = nullptr); + +protected: + Dictionary _get_versions() const { + Vector<StringName> vnames = get_version_list(); + Dictionary ret; + for (int i = 0; i < vnames.size(); i++) { + ret[vnames[i]] = versions[vnames[i]]; + } + return ret; + } + void _set_versions(const Dictionary &p_versions) { + versions.clear(); + List<Variant> keys; + p_versions.get_key_list(&keys); + for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { + StringName name = E->get(); + Ref<RDShaderBytecode> bc = p_versions[E->get()]; + ERR_CONTINUE(bc.is_null()); + versions[name] = bc; + } + + emit_changed(); + } + + static void _bind_methods() { + ClassDB::bind_method(D_METHOD("set_bytecode", "bytecode", "version"), &RDShaderFile::set_bytecode, DEFVAL(StringName())); + ClassDB::bind_method(D_METHOD("get_bytecode", "version"), &RDShaderFile::get_bytecode, DEFVAL(StringName())); + ClassDB::bind_method(D_METHOD("get_version_list"), &RDShaderFile::get_version_list); + + ClassDB::bind_method(D_METHOD("set_base_error", "error"), &RDShaderFile::set_base_error); + ClassDB::bind_method(D_METHOD("get_base_error"), &RDShaderFile::get_base_error); + + ClassDB::bind_method(D_METHOD("_set_versions", "versions"), &RDShaderFile::_set_versions); + ClassDB::bind_method(D_METHOD("_get_versions"), &RDShaderFile::_get_versions); + + ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "_versions", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_versions", "_get_versions"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_error"), "set_base_error", "get_base_error"); + } +}; + +class RDUniform : public Reference { + GDCLASS(RDUniform, Reference) + friend class RenderingDevice; + RD::Uniform base; + +public: + RD_SETGET(RD::UniformType, type) + RD_SETGET(int32_t, binding) + + void add_id(const RID &p_id) { base.ids.push_back(p_id); } + void clear_ids() { base.ids.clear(); } + Array get_ids() const { + Array ids; + for (int i = 0; i < base.ids.size(); i++) { + ids.push_back(base.ids[i]); + } + return ids; + } + +protected: + void _set_ids(const Array &p_ids) { + base.ids.clear(); + for (int i = 0; i < p_ids.size(); i++) { + RID id = p_ids[i]; + ERR_FAIL_COND(id.is_null()); + base.ids.push_back(id); + } + } + static void _bind_methods() { + RD_BIND(Variant::INT, RDUniform, type); + RD_BIND(Variant::INT, RDUniform, binding); + ClassDB::bind_method(D_METHOD("add_id", "id"), &RDUniform::add_id); + ClassDB::bind_method(D_METHOD("clear_ids"), &RDUniform::clear_ids); + ClassDB::bind_method(D_METHOD("_set_ids", "ids"), &RDUniform::_set_ids); + ClassDB::bind_method(D_METHOD("get_ids"), &RDUniform::get_ids); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_ids", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "_set_ids", "get_ids"); + } +}; +class RDPipelineRasterizationState : public Reference { + GDCLASS(RDPipelineRasterizationState, Reference) + friend class RenderingDevice; + + RD::PipelineRasterizationState base; + +public: + RD_SETGET(bool, enable_depth_clamp) + RD_SETGET(bool, discard_primitives) + RD_SETGET(bool, wireframe) + RD_SETGET(RD::PolygonCullMode, cull_mode) + RD_SETGET(RD::PolygonFrontFace, front_face) + RD_SETGET(bool, depth_bias_enable) + RD_SETGET(float, depth_bias_constant_factor) + RD_SETGET(float, depth_bias_clamp) + RD_SETGET(float, depth_bias_slope_factor) + RD_SETGET(float, line_width) + RD_SETGET(uint32_t, patch_control_points) + +protected: + static void _bind_methods() { + RD_BIND(Variant::BOOL, RDPipelineRasterizationState, enable_depth_clamp); + RD_BIND(Variant::BOOL, RDPipelineRasterizationState, discard_primitives); + RD_BIND(Variant::BOOL, RDPipelineRasterizationState, wireframe); + RD_BIND(Variant::INT, RDPipelineRasterizationState, cull_mode); + RD_BIND(Variant::INT, RDPipelineRasterizationState, front_face); + RD_BIND(Variant::BOOL, RDPipelineRasterizationState, depth_bias_enable); + RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, depth_bias_constant_factor); + RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, depth_bias_clamp); + RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, depth_bias_slope_factor); + RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, line_width); + RD_BIND(Variant::INT, RDPipelineRasterizationState, patch_control_points); + } +}; + +class RDPipelineMultisampleState : public Reference { + GDCLASS(RDPipelineMultisampleState, Reference) + friend class RenderingDevice; + + RD::PipelineMultisampleState base; + TypedArray<int64_t> sample_masks; + +public: + RD_SETGET(RD::TextureSamples, sample_count) + RD_SETGET(bool, enable_sample_shading) + RD_SETGET(float, min_sample_shading) + RD_SETGET(bool, enable_alpha_to_coverage) + RD_SETGET(bool, enable_alpha_to_one) + + void set_sample_masks(const TypedArray<int64_t> &p_masks) { sample_masks = p_masks; } + TypedArray<int64_t> get_sample_masks() const { return sample_masks; } + +protected: + static void _bind_methods() { + RD_BIND(Variant::INT, RDPipelineMultisampleState, sample_count); + RD_BIND(Variant::BOOL, RDPipelineMultisampleState, enable_sample_shading); + RD_BIND(Variant::FLOAT, RDPipelineMultisampleState, min_sample_shading); + RD_BIND(Variant::BOOL, RDPipelineMultisampleState, enable_alpha_to_coverage); + RD_BIND(Variant::BOOL, RDPipelineMultisampleState, enable_alpha_to_one); + + ClassDB::bind_method(D_METHOD("set_sample_masks", "masks"), &RDPipelineMultisampleState::set_sample_masks); + ClassDB::bind_method(D_METHOD("get_sample_masks"), &RDPipelineMultisampleState::get_sample_masks); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "sample_masks", PROPERTY_HINT_ARRAY_TYPE, "int"), "set_sample_masks", "get_sample_masks"); + } +}; + +class RDPipelineDepthStencilState : public Reference { + GDCLASS(RDPipelineDepthStencilState, Reference) + friend class RenderingDevice; + + RD::PipelineDepthStencilState base; + +public: + RD_SETGET(bool, enable_depth_test) + RD_SETGET(bool, enable_depth_write) + RD_SETGET(RD::CompareOperator, depth_compare_operator) + RD_SETGET(bool, enable_depth_range) + RD_SETGET(float, depth_range_min) + RD_SETGET(float, depth_range_max) + RD_SETGET(bool, enable_stencil) + + RD_SETGET_SUB(RD::StencilOperation, front_op, fail) + RD_SETGET_SUB(RD::StencilOperation, front_op, pass) + RD_SETGET_SUB(RD::StencilOperation, front_op, depth_fail) + RD_SETGET_SUB(RD::CompareOperator, front_op, compare) + RD_SETGET_SUB(uint32_t, front_op, compare_mask) + RD_SETGET_SUB(uint32_t, front_op, write_mask) + RD_SETGET_SUB(uint32_t, front_op, reference) + + RD_SETGET_SUB(RD::StencilOperation, back_op, fail) + RD_SETGET_SUB(RD::StencilOperation, back_op, pass) + RD_SETGET_SUB(RD::StencilOperation, back_op, depth_fail) + RD_SETGET_SUB(RD::CompareOperator, back_op, compare) + RD_SETGET_SUB(uint32_t, back_op, compare_mask) + RD_SETGET_SUB(uint32_t, back_op, write_mask) + RD_SETGET_SUB(uint32_t, back_op, reference) + +protected: + static void _bind_methods() { + RD_BIND(Variant::BOOL, RDPipelineDepthStencilState, enable_depth_test); + RD_BIND(Variant::BOOL, RDPipelineDepthStencilState, enable_depth_write); + RD_BIND(Variant::INT, RDPipelineDepthStencilState, depth_compare_operator); + RD_BIND(Variant::BOOL, RDPipelineDepthStencilState, enable_depth_range); + RD_BIND(Variant::FLOAT, RDPipelineDepthStencilState, depth_range_min); + RD_BIND(Variant::FLOAT, RDPipelineDepthStencilState, depth_range_max); + RD_BIND(Variant::BOOL, RDPipelineDepthStencilState, enable_stencil); + + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, fail); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, pass); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, depth_fail); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, compare); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, compare_mask); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, write_mask); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, reference); + + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, fail); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, pass); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, depth_fail); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, compare); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, compare_mask); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, write_mask); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, reference); + } +}; + +class RDPipelineColorBlendStateAttachment : public Reference { + GDCLASS(RDPipelineColorBlendStateAttachment, Reference) + friend class RenderingDevice; + RD::PipelineColorBlendState::Attachment base; + +public: + RD_SETGET(bool, enable_blend) + RD_SETGET(RD::BlendFactor, src_color_blend_factor) + RD_SETGET(RD::BlendFactor, dst_color_blend_factor) + RD_SETGET(RD::BlendOperation, color_blend_op) + RD_SETGET(RD::BlendFactor, src_alpha_blend_factor) + RD_SETGET(RD::BlendFactor, dst_alpha_blend_factor) + RD_SETGET(RD::BlendOperation, alpha_blend_op) + RD_SETGET(bool, write_r) + RD_SETGET(bool, write_g) + RD_SETGET(bool, write_b) + RD_SETGET(bool, write_a) + + void set_as_mix() { + + base = RD::PipelineColorBlendState::Attachment(); + base.enable_blend = true; + base.src_color_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA; + base.dst_color_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + base.src_alpha_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA; + base.dst_alpha_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + } + +protected: + static void _bind_methods() { + + ClassDB::bind_method(D_METHOD("set_as_mix"), &RDPipelineColorBlendStateAttachment::set_as_mix); + + RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, enable_blend); + RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, src_color_blend_factor); + RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, dst_color_blend_factor); + RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, color_blend_op); + RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, src_alpha_blend_factor); + RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, dst_alpha_blend_factor); + RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, alpha_blend_op); + RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, write_r); + RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, write_g); + RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, write_b); + RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, write_a); + } +}; + +class RDPipelineColorBlendState : public Reference { + GDCLASS(RDPipelineColorBlendState, Reference) + friend class RenderingDevice; + RD::PipelineColorBlendState base; + + TypedArray<RDPipelineColorBlendStateAttachment> attachments; + +public: + RD_SETGET(bool, enable_logic_op) + RD_SETGET(RD::LogicOperation, logic_op) + RD_SETGET(Color, blend_constant) + + void set_attachments(const TypedArray<RDPipelineColorBlendStateAttachment> &p_attachments) { + attachments.push_back(p_attachments); + } + + TypedArray<RDPipelineColorBlendStateAttachment> get_attachments() const { + return attachments; + } + +protected: + static void _bind_methods() { + RD_BIND(Variant::BOOL, RDPipelineColorBlendState, enable_logic_op); + RD_BIND(Variant::INT, RDPipelineColorBlendState, logic_op); + RD_BIND(Variant::COLOR, RDPipelineColorBlendState, blend_constant); + + ClassDB::bind_method(D_METHOD("set_attachments", "atachments"), &RDPipelineColorBlendState::set_attachments); + ClassDB::bind_method(D_METHOD("get_attachments"), &RDPipelineColorBlendState::get_attachments); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "attachments", PROPERTY_HINT_ARRAY_TYPE, "RDPipelineColorBlendStateAttachment"), "set_attachments", "get_attachments"); + } +}; + +#endif // RENDERING_DEVICE_BINDS_H diff --git a/servers/rendering/rendering_server_raster.cpp b/servers/rendering/rendering_server_raster.cpp index 7cc06527e4..c6f3273339 100644 --- a/servers/rendering/rendering_server_raster.cpp +++ b/servers/rendering/rendering_server_raster.cpp @@ -135,16 +135,27 @@ void RenderingServerRaster::draw(bool p_swap_buffers, double frame_step) { if (RSG::storage->get_captured_timestamps_count()) { Vector<FrameProfileArea> new_profile; - new_profile.resize(RSG::storage->get_captured_timestamps_count()); + if (RSG::storage->capturing_timestamps) { + new_profile.resize(RSG::storage->get_captured_timestamps_count()); + } uint64_t base_cpu = RSG::storage->get_captured_timestamp_cpu_time(0); uint64_t base_gpu = RSG::storage->get_captured_timestamp_gpu_time(0); for (uint32_t i = 0; i < RSG::storage->get_captured_timestamps_count(); i++) { - uint64_t time_cpu = RSG::storage->get_captured_timestamp_cpu_time(i) - base_cpu; - uint64_t time_gpu = RSG::storage->get_captured_timestamp_gpu_time(i) - base_gpu; - new_profile.write[i].gpu_msec = float(time_gpu / 1000) / 1000.0; - new_profile.write[i].cpu_msec = float(time_cpu) / 1000.0; - new_profile.write[i].name = RSG::storage->get_captured_timestamp_name(i); + uint64_t time_cpu = RSG::storage->get_captured_timestamp_cpu_time(i); + uint64_t time_gpu = RSG::storage->get_captured_timestamp_gpu_time(i); + + String name = RSG::storage->get_captured_timestamp_name(i); + + if (name.begins_with("vp_")) { + RSG::viewport->handle_timestamp(name, time_cpu, time_gpu); + } + + if (RSG::storage->capturing_timestamps) { + new_profile.write[i].gpu_msec = float((time_gpu - base_gpu) / 1000) / 1000.0; + new_profile.write[i].cpu_msec = float(time_cpu - base_cpu) / 1000.0; + new_profile.write[i].name = RSG::storage->get_captured_timestamp_name(i); + } } frame_profile = new_profile; diff --git a/servers/rendering/rendering_server_raster.h b/servers/rendering/rendering_server_raster.h index 267efdbacb..f7b963a015 100644 --- a/servers/rendering/rendering_server_raster.h +++ b/servers/rendering/rendering_server_raster.h @@ -98,6 +98,8 @@ public: #define BIND0R(m_r, m_name) \ m_r m_name() { return BINDBASE->m_name(); } +#define BIND0RC(m_r, m_name) \ + m_r m_name() const { return BINDBASE->m_name(); } #define BIND1R(m_r, m_name, m_type1) \ m_r m_name(m_type1 arg1) { return BINDBASE->m_name(arg1); } #define BIND1RC(m_r, m_name, m_type1) \ @@ -111,8 +113,12 @@ public: #define BIND4RC(m_r, m_name, m_type1, m_type2, m_type3, m_type4) \ m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4) const { return BINDBASE->m_name(arg1, arg2, arg3, arg4); } +#define BIND0(m_name) \ + void m_name() { DISPLAY_CHANGED BINDBASE->m_name(); } #define BIND1(m_name, m_type1) \ void m_name(m_type1 arg1) { DISPLAY_CHANGED BINDBASE->m_name(arg1); } +#define BIND1C(m_name, m_type1) \ + void m_name(m_type1 arg1) const { DISPLAY_CHANGED BINDBASE->m_name(arg1); } #define BIND2(m_name, m_type1, m_type2) \ void m_name(m_type1 arg1, m_type2 arg2) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2); } #define BIND2C(m_name, m_type1, m_type2) \ @@ -340,6 +346,20 @@ public: BIND2(reflection_probe_set_cull_mask, RID, uint32_t) BIND2(reflection_probe_set_resolution, RID, int) + /* DECAL API */ + + BIND0R(RID, decal_create) + + BIND2(decal_set_extents, RID, const Vector3 &) + BIND3(decal_set_texture, RID, DecalTexture, RID) + BIND2(decal_set_emission_energy, RID, float) + BIND2(decal_set_albedo_mix, RID, float) + BIND2(decal_set_modulate, RID, const Color &) + BIND2(decal_set_cull_mask, RID, uint32_t) + BIND4(decal_set_distance_fade, RID, bool, float, float) + BIND3(decal_set_fade, RID, float, float) + BIND2(decal_set_normal_fade, RID, float) + /* BAKED LIGHT API */ BIND0R(RID, gi_probe_create) @@ -456,7 +476,7 @@ public: BIND0R(RID, viewport_create) - BIND2(viewport_set_use_arvr, RID, bool) + BIND2(viewport_set_use_xr, RID, bool) BIND3(viewport_set_size, RID, int, int) BIND2(viewport_set_active, RID, bool) @@ -489,10 +509,15 @@ public: BIND2(viewport_set_shadow_atlas_size, RID, int) BIND3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int) BIND2(viewport_set_msaa, RID, ViewportMSAA) + BIND2(viewport_set_screen_space_aa, RID, ViewportScreenSpaceAA) BIND2R(int, viewport_get_render_info, RID, ViewportRenderInfo) BIND2(viewport_set_debug_draw, RID, ViewportDebugDraw) + BIND2(viewport_set_measure_render_time, RID, bool) + BIND1RC(float, viewport_get_measured_render_time_cpu, RID) + BIND1RC(float, viewport_get_measured_render_time_gpu, RID) + /* ENVIRONMENT API */ #undef BINDBASE @@ -554,6 +579,9 @@ public: BIND8(camera_effects_set_dof_blur, RID, bool, float, float, bool, float, float, float) BIND3(camera_effects_set_custom_exposure, RID, bool, float) + BIND1(shadows_quality_set, ShadowQuality); + BIND1(directional_shadow_quality_set, ShadowQuality); + /* SCENARIO API */ #undef BINDBASE @@ -598,6 +626,11 @@ public: BIND5(instance_geometry_set_draw_range, RID, float, float, float, float) BIND2(instance_geometry_set_as_instance_lod, RID, RID) + BIND3(instance_geometry_set_shader_parameter, RID, const StringName &, const Variant &) + BIND2RC(Variant, instance_geometry_get_shader_parameter, RID, const StringName &) + BIND2RC(Variant, instance_geometry_get_shader_parameter_default_value, RID, const StringName &) + BIND2C(instance_geometry_get_shader_parameter_list, RID, List<PropertyInfo> *) + #undef BINDBASE //from now on, calls forwarded to this singleton #define BINDBASE RSG::canvas @@ -695,6 +728,23 @@ public: BIND2(canvas_occluder_polygon_set_cull_mode, RID, CanvasOccluderPolygonCullMode) + /* GLOBAL VARIABLES */ + +#undef BINDBASE +//from now on, calls forwarded to this singleton +#define BINDBASE RSG::storage + + BIND3(global_variable_add, const StringName &, GlobalVariableType, const Variant &) + BIND1(global_variable_remove, const StringName &) + BIND0RC(Vector<StringName>, global_variable_get_list) + BIND2(global_variable_set, const StringName &, const Variant &) + BIND2(global_variable_set_override, const StringName &, const Variant &) + BIND1RC(GlobalVariableType, global_variable_get_type, const StringName &) + BIND1RC(Variant, global_variable_get, const StringName &) + + BIND1(global_variables_load_settings, bool) + BIND0(global_variables_clear) + /* BLACK BARS */ virtual void black_bars_set_margins(int p_left, int p_top, int p_right, int p_bottom); diff --git a/servers/rendering/rendering_server_scene.cpp b/servers/rendering/rendering_server_scene.cpp index 65823e11aa..9d141ea570 100644 --- a/servers/rendering/rendering_server_scene.cpp +++ b/servers/rendering/rendering_server_scene.cpp @@ -155,6 +155,20 @@ void *RenderingServerScene::_instance_pair(void *p_self, OctreeElementID, Instan geom->reflection_dirty = true; return E; //this element should make freeing faster + } else if (B->base_type == RS::INSTANCE_DECAL && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { + + InstanceDecalData *decal = static_cast<InstanceDecalData *>(B->base_data); + InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); + + InstanceDecalData::PairInfo pinfo; + pinfo.geometry = A; + pinfo.L = geom->decals.push_back(B); + + List<InstanceDecalData::PairInfo>::Element *E = decal->geometries.push_back(pinfo); + + geom->decal_dirty = true; + + return E; //this element should make freeing faster } else if (B->base_type == RS::INSTANCE_LIGHTMAP_CAPTURE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { InstanceLightmapCaptureData *lightmap_capture = static_cast<InstanceLightmapCaptureData *>(B->base_data); @@ -233,6 +247,17 @@ void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Insta reflection_probe->geometries.erase(E); geom->reflection_dirty = true; + } else if (B->base_type == RS::INSTANCE_DECAL && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { + + InstanceDecalData *decal = static_cast<InstanceDecalData *>(B->base_data); + InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); + + List<InstanceDecalData::PairInfo>::Element *E = reinterpret_cast<List<InstanceDecalData::PairInfo>::Element *>(udata); + + geom->decals.erase(E->get().L); + decal->geometries.erase(E); + + geom->decal_dirty = true; } else if (B->base_type == RS::INSTANCE_LIGHTMAP_CAPTURE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { InstanceLightmapCaptureData *lightmap_capture = static_cast<InstanceLightmapCaptureData *>(B->base_data); @@ -387,6 +412,12 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { reflection_probe_render_list.remove(&reflection_probe->update_list); } } break; + case RS::INSTANCE_DECAL: { + + InstanceDecalData *decal = static_cast<InstanceDecalData *>(instance->base_data); + RSG::scene_render->free(decal->instance); + + } break; case RS::INSTANCE_LIGHTMAP_CAPTURE: { InstanceLightmapCaptureData *lightmap_capture = static_cast<InstanceLightmapCaptureData *>(instance->base_data); @@ -476,6 +507,14 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { reflection_probe->instance = RSG::scene_render->reflection_probe_instance_create(p_base); } break; + case RS::INSTANCE_DECAL: { + + InstanceDecalData *decal = memnew(InstanceDecalData); + decal->owner = instance; + instance->base_data = decal; + + decal->instance = RSG::scene_render->decal_instance_create(p_base); + } break; case RS::INSTANCE_LIGHTMAP_CAPTURE: { InstanceLightmapCaptureData *lightmap_capture = memnew(InstanceLightmapCaptureData); @@ -691,6 +730,12 @@ void RenderingServerScene::instance_set_visible(RID p_instance, bool p_visible) } } break; + case RS::INSTANCE_DECAL: { + if (instance->octree_id && instance->scenario) { + instance->scenario->octree.set_pairable(instance->octree_id, p_visible, 1 << RS::INSTANCE_DECAL, p_visible ? RS::INSTANCE_GEOMETRY_MASK : 0); + } + + } break; case RS::INSTANCE_LIGHTMAP_CAPTURE: { if (instance->octree_id && instance->scenario) { instance->scenario->octree.set_pairable(instance->octree_id, p_visible, 1 << RS::INSTANCE_LIGHTMAP_CAPTURE, p_visible ? RS::INSTANCE_GEOMETRY_MASK : 0); @@ -923,6 +968,67 @@ void RenderingServerScene::instance_geometry_set_draw_range(RID p_instance, floa void RenderingServerScene::instance_geometry_set_as_instance_lod(RID p_instance, RID p_as_lod_of_instance) { } +void RenderingServerScene::instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value) { + + Instance *instance = instance_owner.getornull(p_instance); + ERR_FAIL_COND(!instance); + + Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter>::Element *E = instance->instance_shader_parameters.find(p_parameter); + + if (!E) { + RasterizerScene::InstanceBase::InstanceShaderParameter isp; + isp.index = -1; + isp.info = PropertyInfo(); + isp.value = p_value; + instance->instance_shader_parameters[p_parameter] = isp; + } else { + E->get().value = p_value; + if (E->get().index >= 0 && instance->instance_allocated_shader_parameters) { + //update directly + RSG::storage->global_variables_instance_update(p_instance, E->get().index, p_value); + } + } +} + +Variant RenderingServerScene::instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const { + + const Instance *instance = const_cast<RenderingServerScene *>(this)->instance_owner.getornull(p_instance); + ERR_FAIL_COND_V(!instance, Variant()); + + if (instance->instance_shader_parameters.has(p_parameter)) { + return instance->instance_shader_parameters[p_parameter].value; + } + return Variant(); +} + +Variant RenderingServerScene::instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const { + + const Instance *instance = const_cast<RenderingServerScene *>(this)->instance_owner.getornull(p_instance); + ERR_FAIL_COND_V(!instance, Variant()); + + if (instance->instance_shader_parameters.has(p_parameter)) { + return instance->instance_shader_parameters[p_parameter].default_value; + } + return Variant(); +} + +void RenderingServerScene::instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const { + const Instance *instance = const_cast<RenderingServerScene *>(this)->instance_owner.getornull(p_instance); + ERR_FAIL_COND(!instance); + + const_cast<RenderingServerScene *>(this)->update_dirty_instances(); + + Vector<StringName> names; + for (Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter>::Element *E = instance->instance_shader_parameters.front(); E; E = E->next()) { + names.push_back(E->key()); + } + names.sort_custom<StringName::AlphCompare>(); + for (int i = 0; i < names.size(); i++) { + PropertyInfo pinfo = instance->instance_shader_parameters[names[i]].info; + p_parameters->push_back(pinfo); + } +} + void RenderingServerScene::_update_instance(Instance *p_instance) { p_instance->version++; @@ -943,6 +1049,13 @@ void RenderingServerScene::_update_instance(Instance *p_instance) { reflection_probe->reflection_dirty = true; } + if (p_instance->base_type == RS::INSTANCE_DECAL) { + + InstanceDecalData *decal = static_cast<InstanceDecalData *>(p_instance->base_data); + + RSG::scene_render->decal_instance_set_transform(decal->instance, p_instance->transform); + } + if (p_instance->base_type == RS::INSTANCE_GI_PROBE) { InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(p_instance->base_data); @@ -1000,7 +1113,7 @@ void RenderingServerScene::_update_instance(Instance *p_instance) { uint32_t pairable_mask = 0; bool pairable = false; - if (p_instance->base_type == RS::INSTANCE_LIGHT || p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE || p_instance->base_type == RS::INSTANCE_LIGHTMAP_CAPTURE) { + if (p_instance->base_type == RS::INSTANCE_LIGHT || p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE || p_instance->base_type == RS::INSTANCE_DECAL || p_instance->base_type == RS::INSTANCE_LIGHTMAP_CAPTURE) { pairable_mask = p_instance->visible ? RS::INSTANCE_GEOMETRY_MASK : 0; pairable = true; @@ -1080,6 +1193,11 @@ void RenderingServerScene::_update_instance_aabb(Instance *p_instance) { new_aabb = RSG::storage->reflection_probe_get_aabb(p_instance->base); } break; + case RenderingServer::INSTANCE_DECAL: { + + new_aabb = RSG::storage->decal_get_aabb(p_instance->base); + + } break; case RenderingServer::INSTANCE_GI_PROBE: { new_aabb = RSG::storage->gi_probe_get_bounds(p_instance->base); @@ -1334,7 +1452,7 @@ void RenderingServerScene::_update_instance_lightmap_captures(Instance *p_instan } } -bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_shadow_atlas, Scenario *p_scenario) { +bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario) { InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data); @@ -1347,16 +1465,18 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c case RS::LIGHT_DIRECTIONAL: { - float max_distance = p_cam_projection.get_z_far(); - float shadow_max = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE); + real_t max_distance = p_cam_projection.get_z_far(); + real_t shadow_max = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE); if (shadow_max > 0 && !p_cam_orthogonal) { //its impractical (and leads to unwanted behaviors) to set max distance in orthogonal camera max_distance = MIN(shadow_max, max_distance); } max_distance = MAX(max_distance, p_cam_projection.get_z_near() + 0.001); - float min_distance = MIN(p_cam_projection.get_z_near(), max_distance); + real_t min_distance = MIN(p_cam_projection.get_z_near(), max_distance); RS::LightDirectionalShadowDepthRangeMode depth_range_mode = RSG::storage->light_directional_get_shadow_depth_range_mode(p_instance->base); + real_t pancake_size = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE); + if (depth_range_mode == RS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_OPTIMIZED) { //optimize min/max Vector<Plane> planes = p_cam_projection.get_projection_planes(p_cam_transform); @@ -1365,8 +1485,8 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c //check distance max and min bool found_items = false; - float z_max = -1e20; - float z_min = 1e20; + real_t z_max = -1e20; + real_t z_min = 1e20; for (int i = 0; i < cull_count; i++) { @@ -1379,7 +1499,7 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c animated_material_found = true; } - float max, min; + real_t max, min; instance->transformed_aabb.project_range_in_plane(base, min, max); if (max > z_max) { @@ -1399,7 +1519,7 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c } } - float range = max_distance - min_distance; + real_t range = max_distance - min_distance; int splits = 0; switch (RSG::storage->light_directional_get_shadow_mode(p_instance->base)) { @@ -1408,7 +1528,7 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS: splits = 4; break; } - float distances[5]; + real_t distances[5]; distances[0] = min_distance; for (int i = 0; i < splits; i++) { @@ -1417,11 +1537,13 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c distances[splits] = max_distance; - float texture_size = RSG::scene_render->get_directional_light_shadow_size(light->instance); + real_t texture_size = RSG::scene_render->get_directional_light_shadow_size(light->instance); bool overlap = RSG::storage->light_directional_get_blend_splits(p_instance->base); - float first_radius = 0.0; + real_t first_radius = 0.0; + + real_t min_distance_bias_scale = pancake_size > 0 ? distances[1] / 10.0 : 0; for (int i = 0; i < splits; i++) { @@ -1430,7 +1552,7 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c // setup a camera matrix for that range! CameraMatrix camera_matrix; - float aspect = p_cam_projection.get_aspect(); + real_t aspect = p_cam_projection.get_aspect(); if (p_cam_orthogonal) { @@ -1439,8 +1561,8 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c camera_matrix.set_orthogonal(vp_he.y * 2.0, aspect, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false); } else { - float fov = p_cam_projection.get_fov(); - camera_matrix.set_perspective(fov, aspect, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false); + real_t fov = p_cam_projection.get_fov(); //this is actually yfov, because set aspect tries to keep it + camera_matrix.set_perspective(fov, aspect, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], true); } //obtain the frustum endpoints @@ -1458,26 +1580,27 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c Vector3 z_vec = transform.basis.get_axis(Vector3::AXIS_Z).normalized(); //z_vec points agsint the camera, like in default opengl - float x_min = 0.f, x_max = 0.f; - float y_min = 0.f, y_max = 0.f; - float z_min = 0.f, z_max = 0.f; + real_t x_min = 0.f, x_max = 0.f; + real_t y_min = 0.f, y_max = 0.f; + real_t z_min = 0.f, z_max = 0.f; // FIXME: z_max_cam is defined, computed, but not used below when setting up // ortho_camera. Commented out for now to fix warnings but should be investigated. - float x_min_cam = 0.f, x_max_cam = 0.f; - float y_min_cam = 0.f, y_max_cam = 0.f; - float z_min_cam = 0.f; - //float z_max_cam = 0.f; + real_t x_min_cam = 0.f, x_max_cam = 0.f; + real_t y_min_cam = 0.f, y_max_cam = 0.f; + real_t z_min_cam = 0.f; + //real_t z_max_cam = 0.f; - float bias_scale = 1.0; + real_t bias_scale = 1.0; + real_t aspect_bias_scale = 1.0; //used for culling for (int j = 0; j < 8; j++) { - float d_x = x_vec.dot(endpoints[j]); - float d_y = y_vec.dot(endpoints[j]); - float d_z = z_vec.dot(endpoints[j]); + real_t d_x = x_vec.dot(endpoints[j]); + real_t d_y = y_vec.dot(endpoints[j]); + real_t d_z = z_vec.dot(endpoints[j]); if (j == 0 || d_x < x_min) x_min = d_x; @@ -1495,11 +1618,13 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c z_max = d_z; } + real_t radius = 0; + real_t soft_shadow_expand = 0; + Vector3 center; + { //camera viewport stuff - Vector3 center; - for (int j = 0; j < 8; j++) { center += endpoints[j]; @@ -1508,11 +1633,9 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c //center=x_vec*(x_max-x_min)*0.5 + y_vec*(y_max-y_min)*0.5 + z_vec*(z_max-z_min)*0.5; - float radius = 0; - for (int j = 0; j < 8; j++) { - float d = center.distance_to(endpoints[j]); + real_t d = center.distance_to(endpoints[j]); if (d > radius) radius = d; } @@ -1525,18 +1648,35 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c bias_scale = radius / first_radius; } - x_max_cam = x_vec.dot(center) + radius; - x_min_cam = x_vec.dot(center) - radius; - y_max_cam = y_vec.dot(center) + radius; - y_min_cam = y_vec.dot(center) - radius; - //z_max_cam = z_vec.dot(center) + radius; z_min_cam = z_vec.dot(center) - radius; + { + + float soft_shadow_angle = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SIZE); + + if (soft_shadow_angle > 0.0 && pancake_size > 0.0) { + + float z_range = (z_vec.dot(center) + radius + pancake_size) - z_min_cam; + soft_shadow_expand = Math::tan(Math::deg2rad(soft_shadow_angle)) * z_range; + + x_max += soft_shadow_expand; + y_max += soft_shadow_expand; + + x_min -= soft_shadow_expand; + y_min -= soft_shadow_expand; + } + } + + x_max_cam = x_vec.dot(center) + radius + soft_shadow_expand; + x_min_cam = x_vec.dot(center) - radius - soft_shadow_expand; + y_max_cam = y_vec.dot(center) + radius + soft_shadow_expand; + y_min_cam = y_vec.dot(center) - radius - soft_shadow_expand; + if (depth_range_mode == RS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE) { //this trick here is what stabilizes the shadow (make potential jaggies to not move) //at the cost of some wasted resolution. Still the quality increase is very well worth it - float unit = radius * 2.0 / texture_size; + real_t unit = radius * 2.0 / texture_size; x_max_cam = Math::stepify(x_max_cam, unit); x_min_cam = Math::stepify(x_min_cam, unit); @@ -1566,9 +1706,10 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c Plane near_plane(light_transform.origin, -light_transform.basis.get_axis(2)); + real_t cull_max = 0; for (int j = 0; j < cull_count; j++) { - float min, max; + real_t min, max; Instance *instance = instance_shadow_cull_result[j]; if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) { cull_count--; @@ -1580,8 +1721,91 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c instance->transformed_aabb.project_range_in_plane(Plane(z_vec, 0), min, max); instance->depth = near_plane.distance_to(instance->transform.origin); instance->depth_layer = 0; - if (max > z_max) - z_max = max; + if (j == 0 || max > cull_max) { + cull_max = max; + } + } + + if (cull_max > z_max) { + z_max = cull_max; + } + + if (pancake_size > 0) { + z_max = z_vec.dot(center) + radius + pancake_size; + } + + if (aspect != 1.0) { + + // if the aspect is different, then the radius will become larger. + // if this happens, then bias needs to be adjusted too, as depth will increase + // to do this, compare the depth of one that would have resulted from a square frustum + + CameraMatrix camera_matrix_square; + if (p_cam_orthogonal) { + + Vector2 vp_he = camera_matrix.get_viewport_half_extents(); + if (p_cam_vaspect) { + camera_matrix_square.set_orthogonal(vp_he.x * 2.0, 1.0, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], true); + } else { + camera_matrix_square.set_orthogonal(vp_he.y * 2.0, 1.0, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false); + } + } else { + Vector2 vp_he = camera_matrix.get_viewport_half_extents(); + if (p_cam_vaspect) { + camera_matrix_square.set_frustum(vp_he.x * 2.0, 1.0, Vector2(), distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], true); + } else { + camera_matrix_square.set_frustum(vp_he.y * 2.0, 1.0, Vector2(), distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false); + } + + if (i == 0) { + //print_line("prev he: " + vp_he + " new he: " + camera_matrix_square.get_viewport_half_extents()); + } + } + + Vector3 endpoints_square[8]; // frustum plane endpoints + res = camera_matrix_square.get_endpoints(p_cam_transform, endpoints_square); + ERR_CONTINUE(!res); + Vector3 center_square; + real_t z_max_square = 0; + + for (int j = 0; j < 8; j++) { + + center_square += endpoints_square[j]; + + real_t d_z = z_vec.dot(endpoints_square[j]); + + if (j == 0 || d_z > z_max_square) + z_max_square = d_z; + } + + if (cull_max > z_max_square) { + z_max_square = cull_max; + } + + center_square /= 8.0; + + real_t radius_square = 0; + + for (int j = 0; j < 8; j++) { + + real_t d = center_square.distance_to(endpoints_square[j]); + if (d > radius_square) + radius_square = d; + } + + radius_square *= texture_size / (texture_size - 2.0); //add a texel by each side + + if (pancake_size > 0) { + z_max_square = z_vec.dot(center_square) + radius_square + pancake_size; + } + + real_t z_min_cam_square = z_vec.dot(center_square) - radius_square; + + aspect_bias_scale = (z_max - z_min_cam) / (z_max_square - z_min_cam_square); + + // this is not entirely perfect, because the cull-adjusted z-max may be different + // but at least it's warranted that it results in a greater bias, so no acne should be present either way. + // pancaking also helps with this. } { @@ -1592,11 +1816,19 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c ortho_camera.set_orthogonal(-half_x, half_x, -half_y, half_y, 0, (z_max - z_min_cam)); + Vector2 uv_scale(1.0 / (x_max_cam - x_min_cam), 1.0 / (y_max_cam - y_min_cam)); + Transform ortho_transform; ortho_transform.basis = transform.basis; ortho_transform.origin = x_vec * (x_min_cam + half_x) + y_vec * (y_min_cam + half_y) + z_vec * z_max; - RSG::scene_render->light_instance_set_shadow_transform(light->instance, ortho_camera, ortho_transform, 0, distances[i + 1], i, bias_scale); + { + Vector3 max_in_view = p_cam_transform.affine_inverse().xform(z_vec * cull_max); + Vector3 dir_in_view = p_cam_transform.xform_inv(z_vec).normalized(); + cull_max = dir_in_view.dot(max_in_view); + } + + RSG::scene_render->light_instance_set_shadow_transform(light->instance, ortho_camera, ortho_transform, z_max - z_min_cam, distances[i + 1], i, radius * 2.0 / texture_size, bias_scale * aspect_bias_scale * min_distance_bias_scale, z_max, uv_scale); } RSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count); @@ -1614,9 +1846,9 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c //using this one ensures that raster deferred will have it RENDER_TIMESTAMP("Culling Shadow Paraboloid" + itos(i)); - float radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE); + real_t radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE); - float z = i == 0 ? -1 : 1; + real_t z = i == 0 ? -1 : 1; Vector<Plane> planes; planes.resize(5); planes.write[0] = light_transform.xform(Plane(Vector3(0, 0, z), radius)); @@ -1645,12 +1877,12 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c } } - RSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, i); + RSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, i, 0); RSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count); } } else { //shadow cube - float radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE); + real_t radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE); CameraMatrix cm; cm.set_perspective(90, 1, 0.01, radius); @@ -1699,12 +1931,12 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c } } - RSG::scene_render->light_instance_set_shadow_transform(light->instance, cm, xform, radius, 0, i); + RSG::scene_render->light_instance_set_shadow_transform(light->instance, cm, xform, radius, 0, i, 0); RSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count); } //restore the regular DP matrix - RSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, 0); + RSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, 0, 0); } } break; @@ -1712,8 +1944,8 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c RENDER_TIMESTAMP("Culling Spot Light"); - float radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE); - float angle = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SPOT_ANGLE); + real_t radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE); + real_t angle = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SPOT_ANGLE); CameraMatrix cm; cm.set_perspective(angle * 2.0, 1.0, 0.01, radius); @@ -1738,7 +1970,7 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c } } - RSG::scene_render->light_instance_set_shadow_transform(light->instance, cm, light_transform, radius, 0, 0); + RSG::scene_render->light_instance_set_shadow_transform(light->instance, cm, light_transform, radius, 0, 0, 0); RSG::scene_render->render_shadow(light->instance, p_shadow_atlas, 0, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count); } break; @@ -1793,12 +2025,12 @@ void RenderingServerScene::render_camera(RID p_render_buffers, RID p_camera, RID } break; } - _prepare_scene(camera->transform, camera_matrix, ortho, camera->env, camera->effects, camera->visible_layers, p_scenario, p_shadow_atlas, RID()); + _prepare_scene(camera->transform, camera_matrix, ortho, camera->vaspect, camera->env, camera->effects, camera->visible_layers, p_scenario, p_shadow_atlas, RID()); _render_scene(p_render_buffers, camera->transform, camera_matrix, ortho, camera->env, camera->effects, p_scenario, p_shadow_atlas, RID(), -1); #endif } -void RenderingServerScene::render_camera(RID p_render_buffers, Ref<ARVRInterface> &p_interface, ARVRInterface::Eyes p_eye, RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas) { +void RenderingServerScene::render_camera(RID p_render_buffers, Ref<XRInterface> &p_interface, XRInterface::Eyes p_eye, RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas) { // render for AR/VR interface Camera *camera = camera_owner.getornull(p_camera); @@ -1810,16 +2042,14 @@ void RenderingServerScene::render_camera(RID p_render_buffers, Ref<ARVRInterface // We also ignore our camera position, it will have been positioned with a slightly old tracking position. // Instead we take our origin point and have our ar/vr interface add fresh tracking data! Whoohoo! - Transform world_origin = ARVRServer::get_singleton()->get_world_origin(); + Transform world_origin = XRServer::get_singleton()->get_world_origin(); Transform cam_transform = p_interface->get_transform_for_eye(p_eye, world_origin); // For stereo render we only prepare for our left eye and then reuse the outcome for our right eye - if (p_eye == ARVRInterface::EYE_LEFT) { - ///@TODO possibly move responsibility for this into our ARVRServer or ARVRInterface? - + if (p_eye == XRInterface::EYE_LEFT) { // Center our transform, we assume basis is equal. Transform mono_transform = cam_transform; - Transform right_transform = p_interface->get_transform_for_eye(ARVRInterface::EYE_RIGHT, world_origin); + Transform right_transform = p_interface->get_transform_for_eye(XRInterface::EYE_RIGHT, world_origin); mono_transform.origin += right_transform.origin; mono_transform.origin *= 0.5; @@ -1872,17 +2102,17 @@ void RenderingServerScene::render_camera(RID p_render_buffers, Ref<ARVRInterface mono_transform *= apply_z_shift; // now prepare our scene with our adjusted transform projection matrix - _prepare_scene(mono_transform, combined_matrix, false, camera->env, camera->effects, camera->visible_layers, p_scenario, p_shadow_atlas, RID()); - } else if (p_eye == ARVRInterface::EYE_MONO) { + _prepare_scene(mono_transform, combined_matrix, false, false, camera->env, camera->effects, camera->visible_layers, p_scenario, p_shadow_atlas, RID()); + } else if (p_eye == XRInterface::EYE_MONO) { // For mono render, prepare as per usual - _prepare_scene(cam_transform, camera_matrix, false, camera->env, camera->effects, camera->visible_layers, p_scenario, p_shadow_atlas, RID()); + _prepare_scene(cam_transform, camera_matrix, false, false, camera->env, camera->effects, camera->visible_layers, p_scenario, p_shadow_atlas, RID()); } // And render our scene... _render_scene(p_render_buffers, cam_transform, camera_matrix, false, camera->env, camera->effects, p_scenario, p_shadow_atlas, RID(), -1); }; -void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, bool p_using_shadows) { +void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_force_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, bool p_using_shadows) { // Note, in stereo rendering: // - p_cam_transform will be a transform in the middle of our two eyes // - p_cam_projection is a wider frustrum that encompasses both eyes @@ -1908,6 +2138,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const light_cull_count = 0; reflection_probe_cull_count = 0; + decal_cull_count = 0; gi_probe_cull_count = 0; //light_samplers_culled=0; @@ -1977,6 +2208,18 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const } } } + } else if (ins->base_type == RS::INSTANCE_DECAL && ins->visible) { + + if (decal_cull_count < MAX_DECALS_CULLED) { + + InstanceDecalData *decal = static_cast<InstanceDecalData *>(ins->base_data); + + if (!decal->geometries.empty()) { + //do not add this decal if no geometry is affected by it.. + decal_instance_cull_result[decal_cull_count] = decal->instance; + decal_cull_count++; + } + } } else if (ins->base_type == RS::INSTANCE_GI_PROBE && ins->visible) { @@ -2112,7 +2355,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const RENDER_TIMESTAMP(">Rendering Directional Light " + itos(i)); - _light_instance_update_shadow(lights_with_shadow[i], p_cam_transform, p_cam_projection, p_cam_orthogonal, p_shadow_atlas, scenario); + _light_instance_update_shadow(lights_with_shadow[i], p_cam_transform, p_cam_projection, p_cam_orthogonal, p_cam_vaspect, p_shadow_atlas, scenario); RENDER_TIMESTAMP("<Rendering Directional Light " + itos(i)); } @@ -2214,7 +2457,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const if (redraw) { //must redraw! RENDER_TIMESTAMP(">Rendering Light " + itos(i)); - light->shadow_dirty = _light_instance_update_shadow(ins, p_cam_transform, p_cam_projection, p_cam_orthogonal, p_shadow_atlas, scenario); + light->shadow_dirty = _light_instance_update_shadow(ins, p_cam_transform, p_cam_projection, p_cam_orthogonal, p_cam_vaspect, p_shadow_atlas, scenario); RENDER_TIMESTAMP("<Rendering Light " + itos(i)); } } @@ -2244,7 +2487,7 @@ void RenderingServerScene::_render_scene(RID p_render_buffers, const Transform p /* PROCESS GEOMETRY AND DRAW SCENE */ RENDER_TIMESTAMP("Render Scene "); - RSG::scene_render->render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_orthogonal, (RasterizerScene::InstanceBase **)instance_cull_result, instance_cull_count, light_instance_cull_result, light_cull_count + directional_light_count, reflection_probe_instance_cull_result, reflection_probe_cull_count, gi_probe_instance_cull_result, gi_probe_cull_count, environment, camera_effects, p_shadow_atlas, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass); + RSG::scene_render->render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_orthogonal, (RasterizerScene::InstanceBase **)instance_cull_result, instance_cull_count, light_instance_cull_result, light_cull_count + directional_light_count, reflection_probe_instance_cull_result, reflection_probe_cull_count, gi_probe_instance_cull_result, gi_probe_cull_count, decal_instance_cull_result, decal_cull_count, environment, camera_effects, p_shadow_atlas, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass); } void RenderingServerScene::render_empty_scene(RID p_render_buffers, RID p_scenario, RID p_shadow_atlas) { @@ -2259,7 +2502,7 @@ void RenderingServerScene::render_empty_scene(RID p_render_buffers, RID p_scenar else environment = scenario->fallback_environment; RENDER_TIMESTAMP("Render Empty Scene "); - RSG::scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, environment, RID(), p_shadow_atlas, scenario->reflection_atlas, RID(), 0); + RSG::scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, environment, RID(), p_shadow_atlas, scenario->reflection_atlas, RID(), 0); #endif } @@ -2324,7 +2567,7 @@ bool RenderingServerScene::_render_reflection_probe_step(Instance *p_instance, i } RENDER_TIMESTAMP("Render Reflection Probe, Step " + itos(p_step)); - _prepare_scene(xform, cm, false, RID(), RID(), RSG::storage->reflection_probe_get_cull_mask(p_instance->base), p_instance->scenario->self, shadow_atlas, reflection_probe->instance, use_shadows); + _prepare_scene(xform, cm, false, false, RID(), RID(), RSG::storage->reflection_probe_get_cull_mask(p_instance->base), p_instance->scenario->self, shadow_atlas, reflection_probe->instance, use_shadows); _render_scene(RID(), xform, cm, false, RID(), RID(), p_instance->scenario->self, shadow_atlas, reflection_probe->instance, p_step); } else { @@ -2579,6 +2822,35 @@ void RenderingServerScene::render_probes() { } } +void RenderingServerScene::_update_instance_shader_parameters_from_material(Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> &isparams, const Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> &existing_isparams, RID p_material) { + + List<RasterizerStorage::InstanceShaderParam> plist; + RSG::storage->material_get_instance_shader_parameters(p_material, &plist); + for (List<RasterizerStorage::InstanceShaderParam>::Element *E = plist.front(); E; E = E->next()) { + StringName name = E->get().info.name; + if (isparams.has(name)) { + if (isparams[name].info.type != E->get().info.type) { + WARN_PRINT("More than one material in instance export the same instance shader uniform '" + E->get().info.name + "', but they do it with different data types. Only the first one (in order) will display correctly."); + } + if (isparams[name].index != E->get().index) { + WARN_PRINT("More than one material in instance export the same instance shader uniform '" + E->get().info.name + "', but they do it with different indices. Only the first one (in order) will display correctly."); + } + continue; //first one found always has priority + } + + RasterizerScene::InstanceBase::InstanceShaderParameter isp; + isp.index = E->get().index; + isp.info = E->get().info; + isp.default_value = E->get().default_value; + if (existing_isparams.has(name)) { + isp.value = existing_isparams[name].value; + } else { + isp.value = E->get().default_value; + } + isparams[name] = isp; + } +} + void RenderingServerScene::_update_dirty_instance(Instance *p_instance) { if (p_instance->update_aabb) { @@ -2618,12 +2890,18 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) { bool can_cast_shadows = true; bool is_animated = false; + Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> isparams; if (p_instance->cast_shadows == RS::SHADOW_CASTING_SETTING_OFF) { can_cast_shadows = false; - } else if (p_instance->material_override.is_valid()) { - can_cast_shadows = RSG::storage->material_casts_shadows(p_instance->material_override); + } + + if (p_instance->material_override.is_valid()) { + if (!RSG::storage->material_casts_shadows(p_instance->material_override)) { + can_cast_shadows = false; + } is_animated = RSG::storage->material_is_animated(p_instance->material_override); + _update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, p_instance->material_override); } else { if (p_instance->base_type == RS::INSTANCE_MESH) { @@ -2648,6 +2926,8 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) { is_animated = true; } + _update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, mat); + RSG::storage->material_update_dependency(mat, p_instance); } } @@ -2680,6 +2960,8 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) { is_animated = true; } + _update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, mat); + RSG::storage->material_update_dependency(mat, p_instance); } } @@ -2694,13 +2976,19 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) { RID mat = RSG::storage->immediate_get_material(p_instance->base); - can_cast_shadows = !mat.is_valid() || RSG::storage->material_casts_shadows(mat); + if (!(!mat.is_valid() || RSG::storage->material_casts_shadows(mat))) { + can_cast_shadows = false; + } if (mat.is_valid() && RSG::storage->material_is_animated(mat)) { is_animated = true; } if (mat.is_valid()) { + _update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, mat); + } + + if (mat.is_valid()) { RSG::storage->material_update_dependency(mat, p_instance); } @@ -2733,6 +3021,8 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) { is_animated = true; } + _update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, mat); + RSG::storage->material_update_dependency(mat, p_instance); } } @@ -2755,6 +3045,22 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) { } geom->material_is_animated = is_animated; + p_instance->instance_shader_parameters = isparams; + + if (p_instance->instance_allocated_shader_parameters != (p_instance->instance_shader_parameters.size() > 0)) { + p_instance->instance_allocated_shader_parameters = (p_instance->instance_shader_parameters.size() > 0); + if (p_instance->instance_allocated_shader_parameters) { + p_instance->instance_allocated_shader_parameters_offset = RSG::storage->global_variables_instance_allocate(p_instance->self); + for (Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter>::Element *E = p_instance->instance_shader_parameters.front(); E; E = E->next()) { + if (E->get().value.get_type() != Variant::NIL) { + RSG::storage->global_variables_instance_update(p_instance->self, E->get().index, E->get().value); + } + } + } else { + RSG::storage->global_variables_instance_free(p_instance->self); + p_instance->instance_allocated_shader_parameters_offset = -1; + } + } } if (p_instance->skeleton.is_valid()) { @@ -2816,6 +3122,10 @@ bool RenderingServerScene::free(RID p_rid) { instance_geometry_set_material_override(p_rid, RID()); instance_attach_skeleton(p_rid, RID()); + if (instance->instance_allocated_shader_parameters) { + //free the used shader parameters + RSG::storage->global_variables_instance_free(instance->self); + } update_dirty_instances(); //in case something changed this instance_owner.free(p_rid); diff --git a/servers/rendering/rendering_server_scene.h b/servers/rendering/rendering_server_scene.h index 41641b7c75..db2fbd6707 100644 --- a/servers/rendering/rendering_server_scene.h +++ b/servers/rendering/rendering_server_scene.h @@ -39,7 +39,7 @@ #include "core/os/thread.h" #include "core/rid_owner.h" #include "core/self_list.h" -#include "servers/arvr/arvr_interface.h" +#include "servers/xr/xr_interface.h" class RenderingServerScene { public: @@ -48,6 +48,7 @@ public: MAX_INSTANCE_CULL = 65536, MAX_LIGHTS_CULLED = 4096, MAX_REFLECTION_PROBES_CULLED = 4096, + MAX_DECALS_CULLED = 4096, MAX_GI_PROBES_CULLED = 4096, MAX_ROOM_CULL = 32, MAX_EXTERIOR_PORTALS = 128, @@ -237,6 +238,9 @@ public: bool can_cast_shadows; bool material_is_animated; + List<Instance *> decals; + bool decal_dirty; + List<Instance *> reflection_probes; bool reflection_dirty; @@ -252,6 +256,7 @@ public: can_cast_shadows = true; material_is_animated = true; gi_probes_dirty = true; + decal_dirty = true; } }; @@ -279,6 +284,21 @@ public: } }; + struct InstanceDecalData : public InstanceBaseData { + + Instance *owner; + RID instance; + + struct PairInfo { + List<Instance *>::Element *L; //reflection iterator in geometry + Instance *geometry; + }; + List<PairInfo> geometries; + + InstanceDecalData() { + } + }; + SelfList<InstanceReflectionProbeData>::List reflection_probe_render_list; struct InstanceLightData : public InstanceBaseData { @@ -376,7 +396,9 @@ public: int light_cull_count; int directional_light_count; RID reflection_probe_instance_cull_result[MAX_REFLECTION_PROBES_CULLED]; + RID decal_instance_cull_result[MAX_DECALS_CULLED]; int reflection_probe_cull_count; + int decal_cull_count; RID gi_probe_instance_cull_result[MAX_GI_PROBES_CULLED]; int gi_probe_cull_count; @@ -413,20 +435,27 @@ public: virtual void instance_geometry_set_draw_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin); virtual void instance_geometry_set_as_instance_lod(RID p_instance, RID p_as_lod_of_instance); + void _update_instance_shader_parameters_from_material(Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> &isparams, const Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> &existing_isparams, RID p_material); + + virtual void instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value); + virtual void instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const; + virtual Variant instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const; + virtual Variant instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const; + _FORCE_INLINE_ void _update_instance(Instance *p_instance); _FORCE_INLINE_ void _update_instance_aabb(Instance *p_instance); _FORCE_INLINE_ void _update_dirty_instance(Instance *p_instance); _FORCE_INLINE_ void _update_instance_lightmap_captures(Instance *p_instance); - _FORCE_INLINE_ bool _light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_shadow_atlas, Scenario *p_scenario); + _FORCE_INLINE_ bool _light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario); bool _render_reflection_probe_step(Instance *p_instance, int p_step); - void _prepare_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, bool p_using_shadows = true); + void _prepare_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_force_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, bool p_using_shadows = true); void _render_scene(RID p_render_buffers, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, RID p_force_camera_effects, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass); void render_empty_scene(RID p_render_buffers, RID p_scenario, RID p_shadow_atlas); void render_camera(RID p_render_buffers, RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas); - void render_camera(RID p_render_buffers, Ref<ARVRInterface> &p_interface, ARVRInterface::Eyes p_eye, RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas); + void render_camera(RID p_render_buffers, Ref<XRInterface> &p_interface, XRInterface::Eyes p_eye, RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas); void update_dirty_instances(); void render_probes(); diff --git a/servers/rendering/rendering_server_viewport.cpp b/servers/rendering/rendering_server_viewport.cpp index aa65101ddf..6fb8f6ca63 100644 --- a/servers/rendering/rendering_server_viewport.cpp +++ b/servers/rendering/rendering_server_viewport.cpp @@ -62,24 +62,30 @@ static Transform2D _canvas_get_transform(RenderingServerViewport::Viewport *p_vi return xf; } -void RenderingServerViewport::_draw_3d(Viewport *p_viewport, ARVRInterface::Eyes p_eye) { +void RenderingServerViewport::_draw_3d(Viewport *p_viewport, XRInterface::Eyes p_eye) { RENDER_TIMESTAMP(">Begin Rendering 3D Scene"); - Ref<ARVRInterface> arvr_interface; - if (ARVRServer::get_singleton() != nullptr) { - arvr_interface = ARVRServer::get_singleton()->get_primary_interface(); + Ref<XRInterface> xr_interface; + if (XRServer::get_singleton() != nullptr) { + xr_interface = XRServer::get_singleton()->get_primary_interface(); } - if (p_viewport->use_arvr && arvr_interface.is_valid()) { - RSG::scene->render_camera(p_viewport->render_buffers, arvr_interface, p_eye, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); + if (p_viewport->use_xr && xr_interface.is_valid()) { + RSG::scene->render_camera(p_viewport->render_buffers, xr_interface, p_eye, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); } else { RSG::scene->render_camera(p_viewport->render_buffers, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas); } RENDER_TIMESTAMP("<End Rendering 3D Scene"); } -void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::Eyes p_eye) { +void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::Eyes p_eye) { + + if (p_viewport->measure_render_time) { + String rt_id = "vp_begin_" + itos(p_viewport->self.get_id()); + RSG::storage->capture_timestamp(rt_id); + timestamp_vp_map[rt_id] = p_viewport->self; + } /* Camera should always be BEFORE any other 3D */ @@ -113,7 +119,7 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface if ((scenario_draw_canvas_bg || can_draw_3d) && !p_viewport->render_buffers.is_valid()) { //wants to draw 3D but there is no render buffer, create p_viewport->render_buffers = RSG::scene_render->render_buffers_create(); - RSG::scene_render->render_buffers_configure(p_viewport->render_buffers, p_viewport->render_target, p_viewport->size.width, p_viewport->size.height, p_viewport->msaa); + RSG::scene_render->render_buffers_configure(p_viewport->render_buffers, p_viewport->render_target, p_viewport->size.width, p_viewport->size.height, p_viewport->msaa, p_viewport->screen_space_aa); } RSG::storage->render_target_request_clear(p_viewport->render_target, bgcolor); @@ -289,21 +295,27 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface //was never cleared in the end, force clear it RSG::storage->render_target_do_clear_request(p_viewport->render_target); } + + if (p_viewport->measure_render_time) { + String rt_id = "vp_end_" + itos(p_viewport->self.get_id()); + RSG::storage->capture_timestamp(rt_id); + timestamp_vp_map[rt_id] = p_viewport->self; + } } void RenderingServerViewport::draw_viewports() { -#if 0 - // get our arvr interface in case we need it - Ref<ARVRInterface> arvr_interface; + timestamp_vp_map.clear(); + + // get our xr interface in case we need it + Ref<XRInterface> xr_interface; - if (ARVRServer::get_singleton() != nullptr) { - arvr_interface = ARVRServer::get_singleton()->get_primary_interface(); + if (XRServer::get_singleton() != nullptr) { + xr_interface = XRServer::get_singleton()->get_primary_interface(); // process all our active interfaces - ARVRServer::get_singleton()->_process(); + XRServer::get_singleton()->_process(); } -#endif if (Engine::get_singleton()->is_editor_hint()) { set_default_clear_color(GLOBAL_GET("rendering/environment/default_clear_color")); @@ -367,38 +379,41 @@ void RenderingServerViewport::draw_viewports() { RSG::storage->render_target_set_as_unused(vp->render_target); #if 0 - if (vp->use_arvr && arvr_interface.is_valid()) { + // TODO fix up this code after we change our commit_for_eye to accept our new render targets + + if (vp->use_xr && xr_interface.is_valid()) { // override our size, make sure it matches our required size - vp->size = arvr_interface->get_render_targetsize(); + vp->size = xr_interface->get_render_targetsize(); RSG::storage->render_target_set_size(vp->render_target, vp->size.x, vp->size.y); // render mono or left eye first - ARVRInterface::Eyes leftOrMono = arvr_interface->is_stereo() ? ARVRInterface::EYE_LEFT : ARVRInterface::EYE_MONO; + XRInterface::Eyes leftOrMono = xr_interface->is_stereo() ? XRInterface::EYE_LEFT : XRInterface::EYE_MONO; // check for an external texture destination for our left eye/mono - RSG::storage->render_target_set_external_texture(vp->render_target, arvr_interface->get_external_texture_for_eye(leftOrMono)); + // TODO investigate how we're going to make external textures work + RSG::storage->render_target_set_external_texture(vp->render_target, xr_interface->get_external_texture_for_eye(leftOrMono)); // set our render target as current RSG::rasterizer->set_current_render_target(vp->render_target); // and draw left eye/mono _draw_viewport(vp, leftOrMono); - arvr_interface->commit_for_eye(leftOrMono, vp->render_target, vp->viewport_to_screen_rect); + xr_interface->commit_for_eye(leftOrMono, vp->render_target, vp->viewport_to_screen_rect); // render right eye - if (leftOrMono == ARVRInterface::EYE_LEFT) { + if (leftOrMono == XRInterface::EYE_LEFT) { // check for an external texture destination for our right eye - RSG::storage->render_target_set_external_texture(vp->render_target, arvr_interface->get_external_texture_for_eye(ARVRInterface::EYE_RIGHT)); + RSG::storage->render_target_set_external_texture(vp->render_target, xr_interface->get_external_texture_for_eye(XRInterface::EYE_RIGHT)); // commit for eye may have changed the render target RSG::rasterizer->set_current_render_target(vp->render_target); - _draw_viewport(vp, ARVRInterface::EYE_RIGHT); - arvr_interface->commit_for_eye(ARVRInterface::EYE_RIGHT, vp->render_target, vp->viewport_to_screen_rect); + _draw_viewport(vp, XRInterface::EYE_RIGHT); + xr_interface->commit_for_eye(XRInterface::EYE_RIGHT, vp->render_target, vp->viewport_to_screen_rect); } // and for our frame timing, mark when we've finished committing our eyes - ARVRServer::get_singleton()->_mark_commit(); + XRServer::get_singleton()->_mark_commit(); } else { #endif { @@ -470,11 +485,11 @@ RID RenderingServerViewport::viewport_create() { return rid; } -void RenderingServerViewport::viewport_set_use_arvr(RID p_viewport, bool p_use_arvr) { +void RenderingServerViewport::viewport_set_use_xr(RID p_viewport, bool p_use_xr) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); - viewport->use_arvr = p_use_arvr; + viewport->use_xr = p_use_xr; } void RenderingServerViewport::viewport_set_size(RID p_viewport, int p_width, int p_height) { @@ -491,7 +506,7 @@ void RenderingServerViewport::viewport_set_size(RID p_viewport, int p_width, int RSG::scene_render->free(viewport->render_buffers); viewport->render_buffers = RID(); } else { - RSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa); + RSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, viewport->screen_space_aa); } } } @@ -721,7 +736,20 @@ void RenderingServerViewport::viewport_set_msaa(RID p_viewport, RS::ViewportMSAA } viewport->msaa = p_msaa; if (viewport->render_buffers.is_valid()) { - RSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, p_msaa); + RSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, p_msaa, viewport->screen_space_aa); + } +} + +void RenderingServerViewport::viewport_set_screen_space_aa(RID p_viewport, RS::ViewportScreenSpaceAA p_mode) { + Viewport *viewport = viewport_owner.getornull(p_viewport); + ERR_FAIL_COND(!viewport); + + if (viewport->screen_space_aa == p_mode) { + return; + } + viewport->screen_space_aa = p_mode; + if (viewport->render_buffers.is_valid()) { + RSG::scene_render->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, p_mode); } } @@ -744,6 +772,30 @@ void RenderingServerViewport::viewport_set_debug_draw(RID p_viewport, RS::Viewpo viewport->debug_draw = p_draw; } +void RenderingServerViewport::viewport_set_measure_render_time(RID p_viewport, bool p_enable) { + + Viewport *viewport = viewport_owner.getornull(p_viewport); + ERR_FAIL_COND(!viewport); + + viewport->measure_render_time = p_enable; +} + +float RenderingServerViewport::viewport_get_measured_render_time_cpu(RID p_viewport) const { + + Viewport *viewport = viewport_owner.getornull(p_viewport); + ERR_FAIL_COND_V(!viewport, 0); + + return double(viewport->time_cpu_end - viewport->time_cpu_begin) / 1000.0; +} + +float RenderingServerViewport::viewport_get_measured_render_time_gpu(RID p_viewport) const { + + Viewport *viewport = viewport_owner.getornull(p_viewport); + ERR_FAIL_COND_V(!viewport, 0); + + return double((viewport->time_gpu_end - viewport->time_gpu_begin) / 1000) / 1000.0; +} + bool RenderingServerViewport::free(RID p_rid) { if (viewport_owner.owns(p_rid)) { @@ -772,6 +824,29 @@ bool RenderingServerViewport::free(RID p_rid) { return false; } +void RenderingServerViewport::handle_timestamp(String p_timestamp, uint64_t p_cpu_time, uint64_t p_gpu_time) { + + RID *vp = timestamp_vp_map.getptr(p_timestamp); + if (!vp) { + return; + } + + Viewport *viewport = viewport_owner.getornull(*vp); + if (!viewport) { + return; + } + + if (p_timestamp.begins_with("vp_begin")) { + viewport->time_cpu_begin = p_cpu_time; + viewport->time_gpu_begin = p_gpu_time; + } + + if (p_timestamp.begins_with("vp_end")) { + viewport->time_cpu_end = p_cpu_time; + viewport->time_gpu_end = p_gpu_time; + } +} + void RenderingServerViewport::set_default_clear_color(const Color &p_color) { RSG::storage->set_default_clear_color(p_color); } diff --git a/servers/rendering/rendering_server_viewport.h b/servers/rendering/rendering_server_viewport.h index f574c58d96..fcba7886c5 100644 --- a/servers/rendering/rendering_server_viewport.h +++ b/servers/rendering/rendering_server_viewport.h @@ -34,8 +34,8 @@ #include "core/rid_owner.h" #include "core/self_list.h" #include "rasterizer.h" -#include "servers/arvr/arvr_interface.h" #include "servers/rendering_server.h" +#include "servers/xr/xr_interface.h" class RenderingServerViewport { public: @@ -47,7 +47,7 @@ public: RID self; RID parent; - bool use_arvr; /* use arvr interface to override camera positioning and projection matrices and control output */ + bool use_xr; /* use xr interface to override camera positioning and projection matrices and control output */ Size2i size; RID camera; @@ -59,6 +59,7 @@ public: RID render_buffers; RS::ViewportMSAA msaa; + RS::ViewportScreenSpaceAA screen_space_aa; DisplayServer::WindowID viewport_to_screen; Rect2 viewport_to_screen_rect; @@ -67,8 +68,13 @@ public: bool hide_scenario; bool hide_canvas; bool disable_environment; - bool disable_3d_by_usage; - bool keep_3d_linear; + bool measure_render_time; + + uint64_t time_cpu_begin; + uint64_t time_cpu_end; + + uint64_t time_gpu_begin; + uint64_t time_gpu_end; RID shadow_atlas; int shadow_atlas_size; @@ -121,16 +127,27 @@ public: disable_environment = false; viewport_to_screen = DisplayServer::INVALID_WINDOW_ID; shadow_atlas_size = 0; - keep_3d_linear = false; + measure_render_time = false; + debug_draw = RS::VIEWPORT_DEBUG_DRAW_DISABLED; msaa = RS::VIEWPORT_MSAA_DISABLED; + screen_space_aa = RS::VIEWPORT_SCREEN_SPACE_AA_DISABLED; + for (int i = 0; i < RS::VIEWPORT_RENDER_INFO_MAX; i++) { render_info[i] = 0; } - use_arvr = false; + use_xr = false; + + time_cpu_begin = 0; + time_cpu_end = 0; + + time_gpu_begin = 0; + time_gpu_end = 0; } }; + HashMap<String, RID> timestamp_vp_map; + uint64_t draw_viewports_pass = 0; mutable RID_PtrOwner<Viewport> viewport_owner; @@ -152,13 +169,13 @@ public: Vector<Viewport *> active_viewports; private: - void _draw_3d(Viewport *p_viewport, ARVRInterface::Eyes p_eye); - void _draw_viewport(Viewport *p_viewport, ARVRInterface::Eyes p_eye = ARVRInterface::EYE_MONO); + void _draw_3d(Viewport *p_viewport, XRInterface::Eyes p_eye); + void _draw_viewport(Viewport *p_viewport, XRInterface::Eyes p_eye = XRInterface::EYE_MONO); public: RID viewport_create(); - void viewport_set_use_arvr(RID p_viewport, bool p_use_arvr); + void viewport_set_use_xr(RID p_viewport, bool p_use_xr); void viewport_set_size(RID p_viewport, int p_width, int p_height); @@ -192,10 +209,17 @@ public: void viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv); void viewport_set_msaa(RID p_viewport, RS::ViewportMSAA p_msaa); + void viewport_set_screen_space_aa(RID p_viewport, RS::ViewportScreenSpaceAA p_mode); virtual int viewport_get_render_info(RID p_viewport, RS::ViewportRenderInfo p_info); virtual void viewport_set_debug_draw(RID p_viewport, RS::ViewportDebugDraw p_draw); + void viewport_set_measure_render_time(RID p_viewport, bool p_enable); + float viewport_get_measured_render_time_cpu(RID p_viewport) const; + float viewport_get_measured_render_time_gpu(RID p_viewport) const; + + void handle_timestamp(String p_timestamp, uint64_t p_cpu_time, uint64_t p_gpu_time); + void set_default_clear_color(const Color &p_color); void draw_viewports(); diff --git a/servers/rendering/rendering_server_wrap_mt.cpp b/servers/rendering/rendering_server_wrap_mt.cpp index aa3bf583c7..4ca13dbef9 100644 --- a/servers/rendering/rendering_server_wrap_mt.cpp +++ b/servers/rendering/rendering_server_wrap_mt.cpp @@ -126,17 +126,6 @@ void RenderingServerWrapMT::init() { void RenderingServerWrapMT::finish() { - if (thread) { - - command_queue.push(this, &RenderingServerWrapMT::thread_exit); - Thread::wait_to_finish(thread); - memdelete(thread); - - thread = nullptr; - } else { - rendering_server->finish(); - } - sky_free_cached_ids(); shader_free_cached_ids(); material_free_cached_ids(); @@ -161,6 +150,17 @@ void RenderingServerWrapMT::finish() { canvas_item_free_cached_ids(); canvas_light_occluder_free_cached_ids(); canvas_occluder_polygon_free_cached_ids(); + + if (thread) { + + command_queue.push(this, &RenderingServerWrapMT::thread_exit); + Thread::wait_to_finish(thread); + memdelete(thread); + + thread = nullptr; + } else { + rendering_server->finish(); + } } void RenderingServerWrapMT::set_use_vsync_callback(bool p_enable) { diff --git a/servers/rendering/rendering_server_wrap_mt.h b/servers/rendering/rendering_server_wrap_mt.h index d0f711838c..d4e58485b8 100644 --- a/servers/rendering/rendering_server_wrap_mt.h +++ b/servers/rendering/rendering_server_wrap_mt.h @@ -264,6 +264,20 @@ public: FUNC2(reflection_probe_set_cull_mask, RID, uint32_t) FUNC2(reflection_probe_set_resolution, RID, int) + /* DECAL API */ + + FUNCRID(decal) + + FUNC2(decal_set_extents, RID, const Vector3 &) + FUNC3(decal_set_texture, RID, DecalTexture, RID) + FUNC2(decal_set_emission_energy, RID, float) + FUNC2(decal_set_albedo_mix, RID, float) + FUNC2(decal_set_modulate, RID, const Color &) + FUNC2(decal_set_cull_mask, RID, uint32_t) + FUNC4(decal_set_distance_fade, RID, bool, float, float) + FUNC3(decal_set_fade, RID, float, float) + FUNC2(decal_set_normal_fade, RID, float) + /* BAKED LIGHT API */ FUNCRID(gi_probe) @@ -370,7 +384,7 @@ public: FUNCRID(viewport) - FUNC2(viewport_set_use_arvr, RID, bool) + FUNC2(viewport_set_use_xr, RID, bool) FUNC3(viewport_set_size, RID, int, int) @@ -403,6 +417,7 @@ public: FUNC2(viewport_set_shadow_atlas_size, RID, int) FUNC3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int) FUNC2(viewport_set_msaa, RID, ViewportMSAA) + FUNC2(viewport_set_screen_space_aa, RID, ViewportScreenSpaceAA) //this passes directly to avoid stalling, but it's pretty dangerous, so don't call after freeing a viewport virtual int viewport_get_render_info(RID p_viewport, ViewportRenderInfo p_info) { @@ -411,6 +426,14 @@ public: FUNC2(viewport_set_debug_draw, RID, ViewportDebugDraw) + FUNC2(viewport_set_measure_render_time, RID, bool) + virtual float viewport_get_measured_render_time_cpu(RID p_viewport) const { + return rendering_server->viewport_get_measured_render_time_cpu(p_viewport); + } + virtual float viewport_get_measured_render_time_gpu(RID p_viewport) const { + return rendering_server->viewport_get_measured_render_time_gpu(p_viewport); + } + FUNC1(directional_shadow_atlas_set_size, int) /* SKY API */ @@ -467,6 +490,9 @@ public: FUNC8(camera_effects_set_dof_blur, RID, bool, float, float, bool, float, float, float) FUNC3(camera_effects_set_custom_exposure, RID, bool, float) + FUNC1(shadows_quality_set, ShadowQuality); + FUNC1(directional_shadow_quality_set, ShadowQuality); + FUNCRID(scenario) FUNC2(scenario_set_debug, RID, ScenarioDebugMode) @@ -506,6 +532,11 @@ public: FUNC5(instance_geometry_set_draw_range, RID, float, float, float, float) FUNC2(instance_geometry_set_as_instance_lod, RID, RID) + FUNC3(instance_geometry_set_shader_parameter, RID, const StringName &, const Variant &) + FUNC2RC(Variant, instance_geometry_get_shader_parameter, RID, const StringName &) + FUNC2RC(Variant, instance_geometry_get_shader_parameter_default_value, RID, const StringName &) + FUNC2SC(instance_geometry_get_shader_parameter_list, RID, List<PropertyInfo> *) + /* CANVAS (2D) */ FUNCRID(canvas) @@ -599,6 +630,18 @@ public: FUNC2(canvas_occluder_polygon_set_cull_mode, RID, CanvasOccluderPolygonCullMode) + /* GLOBAL VARIABLES */ + + FUNC3(global_variable_add, const StringName &, GlobalVariableType, const Variant &) + FUNC1(global_variable_remove, const StringName &) + FUNC0RC(Vector<StringName>, global_variable_get_list) + FUNC2(global_variable_set, const StringName &, const Variant &) + FUNC2(global_variable_set_override, const StringName &, const Variant &) + FUNC1RC(GlobalVariableType, global_variable_get_type, const StringName &) + FUNC1RC(Variant, global_variable_get, const StringName &) + FUNC1(global_variables_load_settings, bool) + FUNC0(global_variables_clear) + /* BLACK BARS */ FUNC4(black_bars_set_margins, int, int, int, int) diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 76a81a4a1c..bec0958f71 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -194,6 +194,8 @@ const char *ShaderLanguage::token_names[TK_MAX] = { "SEMICOLON", "PERIOD", "UNIFORM", + "INSTANCE", + "GLOBAL", "VARYING", "IN", "OUT", @@ -207,6 +209,7 @@ const char *ShaderLanguage::token_names[TK_MAX] = { "HINT_BLACK_ALBEDO_TEXTURE", "HINT_COLOR", "HINT_RANGE", + "HINT_INSTANCE_INDEX", "FILTER_NEAREST", "FILTER_LINEAR", "FILTER_NEAREST_MIPMAP", @@ -300,6 +303,8 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = { { TK_CF_RETURN, "return" }, { TK_CF_DISCARD, "discard" }, { TK_UNIFORM, "uniform" }, + { TK_INSTANCE, "instance" }, + { TK_GLOBAL, "global" }, { TK_VARYING, "varying" }, { TK_ARG_IN, "in" }, { TK_ARG_OUT, "out" }, @@ -319,6 +324,7 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = { { TK_HINT_BLACK_ALBEDO_TEXTURE, "hint_black_albedo" }, { TK_HINT_COLOR, "hint_color" }, { TK_HINT_RANGE, "hint_range" }, + { TK_HINT_INSTANCE_INDEX, "instance_index" }, { TK_FILTER_NEAREST, "filter_nearest" }, { TK_FILTER_LINEAR, "filter_linear" }, { TK_FILTER_NEAREST_MIPMAP, "filter_nearest_mipmap" }, @@ -864,6 +870,7 @@ String ShaderLanguage::get_datatype_name(DataType p_type) { case TYPE_USAMPLER3D: return "usampler3D"; case TYPE_SAMPLERCUBE: return "samplerCube"; case TYPE_STRUCT: return "struct"; + case TYPE_MAX: return "invalid"; } return ""; @@ -2678,6 +2685,8 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C break; case ShaderLanguage::TYPE_VOID: break; + case ShaderLanguage::TYPE_MAX: + break; } return value; } @@ -2774,6 +2783,8 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform case ShaderLanguage::TYPE_STRUCT: { // FIXME: Implement this. } break; + case ShaderLanguage::TYPE_MAX: + break; } return pi; } @@ -2822,6 +2833,8 @@ uint32_t ShaderLanguage::get_type_size(DataType p_type) { case TYPE_STRUCT: // FIXME: Implement. return 0; + case ShaderLanguage::TYPE_MAX: + return 0; } return 0; } @@ -5685,6 +5698,8 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct int texture_uniforms = 0; int uniforms = 0; + int instance_index = 0; + ShaderNode::Uniform::Scope uniform_scope = ShaderNode::Uniform::SCOPE_LOCAL; while (tk.type != TK_EOF) { @@ -5853,6 +5868,27 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct shader->vstructs.push_back(st); // struct's order is important! } break; + case TK_GLOBAL: { + + tk = _get_token(); + if (tk.type != TK_UNIFORM) { + _set_error("Expected 'uniform' after 'global'"); + return ERR_PARSE_ERROR; + } + uniform_scope = ShaderNode::Uniform::SCOPE_GLOBAL; + }; + [[fallthrough]]; + case TK_INSTANCE: { + if (uniform_scope == ShaderNode::Uniform::SCOPE_LOCAL) { + tk = _get_token(); + if (tk.type != TK_UNIFORM) { + _set_error("Expected 'uniform' after 'instance'"); + return ERR_PARSE_ERROR; + } + uniform_scope = ShaderNode::Uniform::SCOPE_INSTANCE; + } + }; + [[fallthrough]]; case TK_UNIFORM: case TK_VARYING: { @@ -5910,25 +5946,50 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct if (uniform) { + if (uniform_scope == ShaderNode::Uniform::SCOPE_GLOBAL) { + //validate global uniform + DataType gvtype = global_var_get_type_func(name); + if (gvtype == TYPE_MAX) { + _set_error("Global uniform '" + String(name) + "' does not exist. Create it in Project Settings."); + return ERR_PARSE_ERROR; + } + + if (type != gvtype) { + _set_error("Global uniform '" + String(name) + "' must be of type '" + get_datatype_name(gvtype) + "'."); + return ERR_PARSE_ERROR; + } + } ShaderNode::Uniform uniform2; if (is_sampler_type(type)) { + if (uniform_scope == ShaderNode::Uniform::SCOPE_INSTANCE) { + _set_error("Uniforms with 'instance' qualifiers can't be of sampler type."); + return ERR_PARSE_ERROR; + } uniform2.texture_order = texture_uniforms++; uniform2.order = -1; if (_validate_datatype(type) != OK) { return ERR_PARSE_ERROR; } } else { + if (uniform_scope == ShaderNode::Uniform::SCOPE_LOCAL && (type == TYPE_MAT2 || type == TYPE_MAT3 || type == TYPE_MAT4)) { + _set_error("Uniforms with 'instance' qualifiers can't be of matrix type."); + return ERR_PARSE_ERROR; + } + uniform2.texture_order = -1; uniform2.order = uniforms++; } uniform2.type = type; + uniform2.scope = uniform_scope; uniform2.precision = precision; //todo parse default value tk = _get_token(); + int custom_instance_index = -1; + if (tk.type == TK_COLON) { //hint do { @@ -6039,7 +6100,45 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } if (tk.type != TK_PARENTHESIS_CLOSE) { - _set_error("Expected ','"); + _set_error("Expected ')'"); + return ERR_PARSE_ERROR; + } + } else if (tk.type == TK_HINT_INSTANCE_INDEX) { + + if (custom_instance_index != -1) { + _set_error("Can only specify 'instance_index' once."); + return ERR_PARSE_ERROR; + } + + tk = _get_token(); + if (tk.type != TK_PARENTHESIS_OPEN) { + _set_error("Expected '(' after 'instance_index'"); + return ERR_PARSE_ERROR; + } + + tk = _get_token(); + + if (tk.type == TK_OP_SUB) { + _set_error("The instance index can't be negative."); + return ERR_PARSE_ERROR; + } + + if (tk.type != TK_INT_CONSTANT) { + _set_error("Expected integer constant"); + return ERR_PARSE_ERROR; + } + + custom_instance_index = tk.constant; + + if (custom_instance_index >= MAX_INSTANCE_UNIFORM_INDICES) { + _set_error("Allowed instance uniform indices are 0-" + itos(MAX_INSTANCE_UNIFORM_INDICES - 1)); + return ERR_PARSE_ERROR; + } + + tk = _get_token(); + + if (tk.type != TK_PARENTHESIS_CLOSE) { + _set_error("Expected ')'"); return ERR_PARSE_ERROR; } } else if (tk.type == TK_FILTER_LINEAR) { @@ -6072,6 +6171,20 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } while (tk.type == TK_COMMA); } + if (uniform_scope == ShaderNode::Uniform::SCOPE_INSTANCE) { + if (custom_instance_index >= 0) { + uniform2.instance_index = custom_instance_index; + } else { + uniform2.instance_index = instance_index++; + if (instance_index > MAX_INSTANCE_UNIFORM_INDICES) { + _set_error("Too many 'instance' uniforms in shader, maximum supported is " + itos(MAX_INSTANCE_UNIFORM_INDICES)); + return ERR_PARSE_ERROR; + } + } + } + + //reset scope for next uniform + if (tk.type == TK_OP_ASSIGN) { Node *expr = _parse_and_reduce_expression(nullptr, Map<StringName, BuiltInInfo>()); @@ -6094,6 +6207,8 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } shader->uniforms[name] = uniform2; + //reset scope for next uniform + uniform_scope = ShaderNode::Uniform::SCOPE_LOCAL; if (tk.type != TK_SEMICOLON) { _set_error("Expected ';'"); @@ -6639,11 +6754,12 @@ String ShaderLanguage::get_shader_type(const String &p_code) { return String(); } -Error ShaderLanguage::compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types) { +Error ShaderLanguage::compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func) { clear(); code = p_code; + global_var_get_type_func = p_global_variable_type_func; nodes = nullptr; @@ -6656,13 +6772,14 @@ Error ShaderLanguage::compile(const String &p_code, const Map<StringName, Functi return OK; } -Error ShaderLanguage::complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, List<ScriptCodeCompletionOption> *r_options, String &r_call_hint) { +Error ShaderLanguage::complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func, List<ScriptCodeCompletionOption> *r_options, String &r_call_hint) { clear(); code = p_code; nodes = nullptr; + global_var_get_type_func = p_global_variable_type_func; shader = alloc_node<ShaderNode>(); _parse_shader(p_functions, p_render_modes, p_shader_types); diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h index beabae0dda..48f1d1440f 100644 --- a/servers/rendering/shader_language.h +++ b/servers/rendering/shader_language.h @@ -143,6 +143,8 @@ public: TK_SEMICOLON, TK_PERIOD, TK_UNIFORM, + TK_INSTANCE, + TK_GLOBAL, TK_VARYING, TK_ARG_IN, TK_ARG_OUT, @@ -162,6 +164,7 @@ public: TK_HINT_BLACK_ALBEDO_TEXTURE, TK_HINT_COLOR, TK_HINT_RANGE, + TK_HINT_INSTANCE_INDEX, TK_FILTER_NEAREST, TK_FILTER_LINEAR, TK_FILTER_NEAREST_MIPMAP, @@ -216,6 +219,7 @@ public: TYPE_USAMPLER3D, TYPE_SAMPLERCUBE, TYPE_STRUCT, + TYPE_MAX }; enum DataPrecision { @@ -317,6 +321,10 @@ public: REPEAT_DEFAULT, }; + enum { + MAX_INSTANCE_UNIFORM_INDICES = 16 + }; + struct Node { Node *next; @@ -650,15 +658,23 @@ public: HINT_MAX }; + enum Scope { + SCOPE_LOCAL, + SCOPE_INSTANCE, + SCOPE_GLOBAL, + }; + int order; int texture_order; DataType type; DataPrecision precision; Vector<ConstantNode::Value> default_value; + Scope scope; Hint hint; TextureFilter filter; TextureRepeat repeat; float hint_range[3]; + int instance_index; Uniform() : order(0), @@ -667,7 +683,8 @@ public: precision(PRECISION_DEFAULT), hint(HINT_NONE), filter(FILTER_DEFAULT), - repeat(REPEAT_DEFAULT) { + repeat(REPEAT_DEFAULT), + instance_index(0) { hint_range[0] = 0.0f; hint_range[1] = 1.0f; hint_range[2] = 0.001f; @@ -764,6 +781,8 @@ public: }; static bool has_builtin(const Map<StringName, ShaderLanguage::FunctionInfo> &p_functions, const StringName &p_name); + typedef DataType (*GlobalVariableGetTypeFunc)(const StringName &p_name); + private: struct KeyWord { TokenType token; @@ -772,6 +791,8 @@ private: static const KeyWord keyword_list[]; + GlobalVariableGetTypeFunc global_var_get_type_func; + bool error_set; String error_str; int error_line; @@ -884,8 +905,8 @@ public: void clear(); static String get_shader_type(const String &p_code); - Error compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types); - Error complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, List<ScriptCodeCompletionOption> *r_options, String &r_call_hint); + Error compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func); + Error complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func, List<ScriptCodeCompletionOption> *r_options, String &r_call_hint); String get_error_text(); int get_error_line(); diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp index 78fa2c2690..78bbd73db4 100644 --- a/servers/rendering/shader_types.cpp +++ b/servers/rendering/shader_types.cpp @@ -108,7 +108,11 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["ANISOTROPY"] = ShaderLanguage::TYPE_FLOAT; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["ANISOTROPY_FLOW"] = ShaderLanguage::TYPE_VEC2; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_STRENGTH"] = ShaderLanguage::TYPE_FLOAT; - shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["TRANSMISSION"] = ShaderLanguage::TYPE_VEC3; + shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_TRANSMITTANCE_COLOR"] = ShaderLanguage::TYPE_VEC4; + shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_TRANSMITTANCE_DEPTH"] = ShaderLanguage::TYPE_FLOAT; + shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_TRANSMITTANCE_CURVE"] = ShaderLanguage::TYPE_FLOAT; + shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_TRANSMITTANCE_BOOST"] = ShaderLanguage::TYPE_FLOAT; + shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["BACKLIGHT"] = ShaderLanguage::TYPE_VEC3; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["AO"] = ShaderLanguage::TYPE_FLOAT; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["AO_LIGHT_AFFECT"] = ShaderLanguage::TYPE_FLOAT; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["EMISSION"] = ShaderLanguage::TYPE_VEC3; @@ -145,7 +149,7 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["LIGHT_COLOR"] = constt(ShaderLanguage::TYPE_VEC3); shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["ATTENUATION"] = constt(ShaderLanguage::TYPE_VEC3); shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["ALBEDO"] = constt(ShaderLanguage::TYPE_VEC3); - shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["TRANSMISSION"] = constt(ShaderLanguage::TYPE_VEC3); + shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["BACKLIGHT"] = constt(ShaderLanguage::TYPE_VEC3); shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["ROUGHNESS"] = constt(ShaderLanguage::TYPE_FLOAT); shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["DIFFUSE_LIGHT"] = ShaderLanguage::TYPE_VEC3; shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["SPECULAR_LIGHT"] = ShaderLanguage::TYPE_VEC3; @@ -299,18 +303,22 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT0_DIRECTION"] = constt(ShaderLanguage::TYPE_VEC3); shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT0_ENERGY"] = constt(ShaderLanguage::TYPE_FLOAT); shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT0_COLOR"] = constt(ShaderLanguage::TYPE_VEC3); + shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT0_SIZE"] = constt(ShaderLanguage::TYPE_FLOAT); shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT1_ENABLED"] = constt(ShaderLanguage::TYPE_BOOL); shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT1_DIRECTION"] = constt(ShaderLanguage::TYPE_VEC3); shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT1_ENERGY"] = constt(ShaderLanguage::TYPE_FLOAT); shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT1_COLOR"] = constt(ShaderLanguage::TYPE_VEC3); + shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT1_SIZE"] = constt(ShaderLanguage::TYPE_FLOAT); shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT2_ENABLED"] = constt(ShaderLanguage::TYPE_BOOL); shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT2_DIRECTION"] = constt(ShaderLanguage::TYPE_VEC3); shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT2_ENERGY"] = constt(ShaderLanguage::TYPE_FLOAT); shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT2_COLOR"] = constt(ShaderLanguage::TYPE_VEC3); + shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT2_SIZE"] = constt(ShaderLanguage::TYPE_FLOAT); shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT3_ENABLED"] = constt(ShaderLanguage::TYPE_BOOL); shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT3_DIRECTION"] = constt(ShaderLanguage::TYPE_VEC3); shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT3_ENERGY"] = constt(ShaderLanguage::TYPE_FLOAT); shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT3_COLOR"] = constt(ShaderLanguage::TYPE_VEC3); + shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT3_SIZE"] = constt(ShaderLanguage::TYPE_FLOAT); shader_modes[RS::SHADER_SKY].functions["fragment"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC3; shader_modes[RS::SHADER_SKY].functions["fragment"].built_ins["ALPHA"] = ShaderLanguage::TYPE_FLOAT; diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 9db3294e95..57a34f24cf 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -1565,6 +1565,42 @@ Array RenderingServer::_mesh_surface_get_skeleton_aabb_bind(RID p_mesh, int p_su return arr; } #endif + +ShaderLanguage::DataType RenderingServer::global_variable_type_get_shader_datatype(GlobalVariableType p_type) { + + switch (p_type) { + case RS::GLOBAL_VAR_TYPE_BOOL: return ShaderLanguage::TYPE_BOOL; + case RS::GLOBAL_VAR_TYPE_BVEC2: return ShaderLanguage::TYPE_BVEC2; + case RS::GLOBAL_VAR_TYPE_BVEC3: return ShaderLanguage::TYPE_BVEC3; + case RS::GLOBAL_VAR_TYPE_BVEC4: return ShaderLanguage::TYPE_BVEC4; + case RS::GLOBAL_VAR_TYPE_INT: return ShaderLanguage::TYPE_INT; + case RS::GLOBAL_VAR_TYPE_IVEC2: return ShaderLanguage::TYPE_IVEC2; + case RS::GLOBAL_VAR_TYPE_IVEC3: return ShaderLanguage::TYPE_IVEC3; + case RS::GLOBAL_VAR_TYPE_IVEC4: return ShaderLanguage::TYPE_IVEC4; + case RS::GLOBAL_VAR_TYPE_RECT2I: return ShaderLanguage::TYPE_IVEC4; + case RS::GLOBAL_VAR_TYPE_UINT: return ShaderLanguage::TYPE_UINT; + case RS::GLOBAL_VAR_TYPE_UVEC2: return ShaderLanguage::TYPE_UVEC2; + case RS::GLOBAL_VAR_TYPE_UVEC3: return ShaderLanguage::TYPE_UVEC3; + case RS::GLOBAL_VAR_TYPE_UVEC4: return ShaderLanguage::TYPE_UVEC4; + case RS::GLOBAL_VAR_TYPE_FLOAT: return ShaderLanguage::TYPE_FLOAT; + case RS::GLOBAL_VAR_TYPE_VEC2: return ShaderLanguage::TYPE_VEC2; + case RS::GLOBAL_VAR_TYPE_VEC3: return ShaderLanguage::TYPE_VEC3; + case RS::GLOBAL_VAR_TYPE_VEC4: return ShaderLanguage::TYPE_VEC4; + case RS::GLOBAL_VAR_TYPE_COLOR: return ShaderLanguage::TYPE_VEC4; + case RS::GLOBAL_VAR_TYPE_RECT2: return ShaderLanguage::TYPE_VEC4; + case RS::GLOBAL_VAR_TYPE_MAT2: return ShaderLanguage::TYPE_MAT2; + case RS::GLOBAL_VAR_TYPE_MAT3: return ShaderLanguage::TYPE_MAT3; + case RS::GLOBAL_VAR_TYPE_MAT4: return ShaderLanguage::TYPE_MAT4; + case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D: return ShaderLanguage::TYPE_MAT3; + case RS::GLOBAL_VAR_TYPE_TRANSFORM: return ShaderLanguage::TYPE_MAT4; + case RS::GLOBAL_VAR_TYPE_SAMPLER2D: return ShaderLanguage::TYPE_SAMPLER2D; + case RS::GLOBAL_VAR_TYPE_SAMPLER2DARRAY: return ShaderLanguage::TYPE_SAMPLER2DARRAY; + case RS::GLOBAL_VAR_TYPE_SAMPLER3D: return ShaderLanguage::TYPE_SAMPLER3D; + case RS::GLOBAL_VAR_TYPE_SAMPLERCUBE: return ShaderLanguage::TYPE_SAMPLERCUBE; + default: return ShaderLanguage::TYPE_MAX; //invalid or not found + } +} + void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("force_sync"), &RenderingServer::sync); @@ -1766,7 +1802,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("camera_set_use_vertical_aspect", "camera", "enable"), &RenderingServer::camera_set_use_vertical_aspect); ClassDB::bind_method(D_METHOD("viewport_create"), &RenderingServer::viewport_create); - ClassDB::bind_method(D_METHOD("viewport_set_use_arvr", "viewport", "use_arvr"), &RenderingServer::viewport_set_use_arvr); + ClassDB::bind_method(D_METHOD("viewport_set_use_xr", "viewport", "use_xr"), &RenderingServer::viewport_set_use_xr); ClassDB::bind_method(D_METHOD("viewport_set_size", "viewport", "width", "height"), &RenderingServer::viewport_set_size); ClassDB::bind_method(D_METHOD("viewport_set_active", "viewport", "active"), &RenderingServer::viewport_set_active); ClassDB::bind_method(D_METHOD("viewport_set_parent_viewport", "viewport", "parent_viewport"), &RenderingServer::viewport_set_parent_viewport); @@ -1921,6 +1957,13 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("canvas_occluder_polygon_set_shape_as_lines", "occluder_polygon", "shape"), &RenderingServer::canvas_occluder_polygon_set_shape_as_lines); ClassDB::bind_method(D_METHOD("canvas_occluder_polygon_set_cull_mode", "occluder_polygon", "mode"), &RenderingServer::canvas_occluder_polygon_set_cull_mode); + ClassDB::bind_method(D_METHOD("global_variable_add", "name", "type", "default_value"), &RenderingServer::global_variable_add); + ClassDB::bind_method(D_METHOD("global_variable_remove", "name"), &RenderingServer::global_variable_remove); + ClassDB::bind_method(D_METHOD("global_variable_get_list"), &RenderingServer::global_variable_get_list); + ClassDB::bind_method(D_METHOD("global_variable_set", "name", "value"), &RenderingServer::global_variable_set); + ClassDB::bind_method(D_METHOD("global_variable_get", "name"), &RenderingServer::global_variable_get); + ClassDB::bind_method(D_METHOD("global_variable_get_type", "name"), &RenderingServer::global_variable_get_type); + ClassDB::bind_method(D_METHOD("black_bars_set_margins", "left", "top", "right", "bottom"), &RenderingServer::black_bars_set_margins); ClassDB::bind_method(D_METHOD("black_bars_set_images", "left", "top", "right", "bottom"), &RenderingServer::black_bars_set_images); @@ -1955,9 +1998,6 @@ void RenderingServer::_bind_methods() { BIND_CONSTANT(MAX_GLOW_LEVELS); BIND_CONSTANT(MAX_CURSORS); - BIND_CONSTANT(MATERIAL_RENDER_PRIORITY_MIN); - BIND_CONSTANT(MATERIAL_RENDER_PRIORITY_MAX); - BIND_ENUM_CONSTANT(TEXTURE_LAYERED_2D_ARRAY); BIND_ENUM_CONSTANT(TEXTURE_LAYERED_CUBEMAP); BIND_ENUM_CONSTANT(TEXTURE_LAYERED_CUBEMAP_ARRAY); @@ -1975,6 +2015,9 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(SHADER_SKY); BIND_ENUM_CONSTANT(SHADER_MAX); + BIND_CONSTANT(MATERIAL_RENDER_PRIORITY_MIN); + BIND_CONSTANT(MATERIAL_RENDER_PRIORITY_MAX); + BIND_ENUM_CONSTANT(ARRAY_VERTEX); BIND_ENUM_CONSTANT(ARRAY_NORMAL); BIND_ENUM_CONSTANT(ARRAY_TANGENT); @@ -2002,9 +2045,10 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TEX_UV); BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TEX_UV2); BIND_ENUM_CONSTANT(ARRAY_COMPRESS_INDEX); + BIND_ENUM_CONSTANT(ARRAY_COMPRESS_DEFAULT); + BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_2D_VERTICES); BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_DYNAMIC_UPDATE); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_DEFAULT); BIND_ENUM_CONSTANT(PRIMITIVE_POINTS); BIND_ENUM_CONSTANT(PRIMITIVE_LINES); @@ -2027,10 +2071,10 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(LIGHT_PARAM_INDIRECT_ENERGY); BIND_ENUM_CONSTANT(LIGHT_PARAM_SPECULAR); BIND_ENUM_CONSTANT(LIGHT_PARAM_RANGE); + BIND_ENUM_CONSTANT(LIGHT_PARAM_SIZE); BIND_ENUM_CONSTANT(LIGHT_PARAM_ATTENUATION); BIND_ENUM_CONSTANT(LIGHT_PARAM_SPOT_ANGLE); BIND_ENUM_CONSTANT(LIGHT_PARAM_SPOT_ATTENUATION); - BIND_ENUM_CONSTANT(LIGHT_PARAM_CONTACT_SHADOW_SIZE); BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_MAX_DISTANCE); BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET); BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET); @@ -2038,7 +2082,9 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_FADE_START); BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_NORMAL_BIAS); BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_BIAS); - BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE); + BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_PANCAKE_SIZE); + BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_BLUR); + BIND_ENUM_CONSTANT(LIGHT_PARAM_TRANSMITTANCE_BIAS); BIND_ENUM_CONSTANT(LIGHT_PARAM_MAX); BIND_ENUM_CONSTANT(LIGHT_OMNI_SHADOW_DUAL_PARABOLOID); @@ -2054,6 +2100,12 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(REFLECTION_PROBE_UPDATE_ONCE); BIND_ENUM_CONSTANT(REFLECTION_PROBE_UPDATE_ALWAYS); + BIND_ENUM_CONSTANT(DECAL_TEXTURE_ALBEDO); + BIND_ENUM_CONSTANT(DECAL_TEXTURE_NORMAL); + BIND_ENUM_CONSTANT(DECAL_TEXTURE_ORM); + BIND_ENUM_CONSTANT(DECAL_TEXTURE_EMISSION); + BIND_ENUM_CONSTANT(DECAL_TEXTURE_MAX); + BIND_ENUM_CONSTANT(PARTICLES_DRAW_ORDER_INDEX); BIND_ENUM_CONSTANT(PARTICLES_DRAW_ORDER_LIFETIME); BIND_ENUM_CONSTANT(PARTICLES_DRAW_ORDER_VIEW_DEPTH); @@ -2073,8 +2125,11 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(VIEWPORT_MSAA_4X); BIND_ENUM_CONSTANT(VIEWPORT_MSAA_8X); BIND_ENUM_CONSTANT(VIEWPORT_MSAA_16X); - BIND_ENUM_CONSTANT(VIEWPORT_MSAA_EXT_2X); - BIND_ENUM_CONSTANT(VIEWPORT_MSAA_EXT_4X); + BIND_ENUM_CONSTANT(VIEWPORT_MSAA_MAX); + + BIND_ENUM_CONSTANT(VIEWPORT_SCREEN_SPACE_AA_DISABLED); + BIND_ENUM_CONSTANT(VIEWPORT_SCREEN_SPACE_AA_FXAA); + BIND_ENUM_CONSTANT(VIEWPORT_SCREEN_SPACE_AA_MAX); BIND_ENUM_CONSTANT(VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME); BIND_ENUM_CONSTANT(VIEWPORT_RENDER_INFO_VERTICES_IN_FRAME); @@ -2098,6 +2153,8 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_SCENE_LUMINANCE); BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_SSAO); BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_ROUGHNESS_LIMITER); + BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_PSSM_SPLITS); + BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_DECAL_ATLAS); BIND_ENUM_CONSTANT(SKY_MODE_QUALITY); BIND_ENUM_CONSTANT(SKY_MODE_REALTIME); @@ -2130,6 +2187,11 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_FILMIC); BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_ACES); + BIND_ENUM_CONSTANT(ENV_SSR_ROUGNESS_QUALITY_DISABLED); + BIND_ENUM_CONSTANT(ENV_SSR_ROUGNESS_QUALITY_LOW); + BIND_ENUM_CONSTANT(ENV_SSR_ROUGNESS_QUALITY_MEDIUM); + BIND_ENUM_CONSTANT(ENV_SSR_ROUGNESS_QUALITY_HIGH); + BIND_ENUM_CONSTANT(ENV_SSAO_BLUR_DISABLED); BIND_ENUM_CONSTANT(ENV_SSAO_BLUR_1x1); BIND_ENUM_CONSTANT(ENV_SSAO_BLUR_2x2); @@ -2140,6 +2202,11 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(ENV_SSAO_QUALITY_HIGH); BIND_ENUM_CONSTANT(ENV_SSAO_QUALITY_ULTRA); + BIND_ENUM_CONSTANT(SUB_SURFACE_SCATTERING_QUALITY_DISABLED); + BIND_ENUM_CONSTANT(SUB_SURFACE_SCATTERING_QUALITY_LOW); + BIND_ENUM_CONSTANT(SUB_SURFACE_SCATTERING_QUALITY_MEDIUM); + BIND_ENUM_CONSTANT(SUB_SURFACE_SCATTERING_QUALITY_HIGH); + BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_VERY_LOW); BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_LOW); BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_MEDIUM); @@ -2149,6 +2216,13 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(DOF_BOKEH_HEXAGON); BIND_ENUM_CONSTANT(DOF_BOKEH_CIRCLE); + BIND_ENUM_CONSTANT(SHADOW_QUALITY_HARD); + BIND_ENUM_CONSTANT(SHADOW_QUALITY_SOFT_LOW); + BIND_ENUM_CONSTANT(SHADOW_QUALITY_SOFT_MEDIUM); + BIND_ENUM_CONSTANT(SHADOW_QUALITY_SOFT_HIGH); + BIND_ENUM_CONSTANT(SHADOW_QUALITY_SOFT_ULTRA); + BIND_ENUM_CONSTANT(SHADOW_QUALITY_MAX); + BIND_ENUM_CONSTANT(SCENARIO_DEBUG_DISABLED); BIND_ENUM_CONSTANT(SCENARIO_DEBUG_WIREFRAME); BIND_ENUM_CONSTANT(SCENARIO_DEBUG_OVERDRAW); @@ -2161,6 +2235,7 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(INSTANCE_PARTICLES); BIND_ENUM_CONSTANT(INSTANCE_LIGHT); BIND_ENUM_CONSTANT(INSTANCE_REFLECTION_PROBE); + BIND_ENUM_CONSTANT(INSTANCE_DECAL); BIND_ENUM_CONSTANT(INSTANCE_GI_PROBE); BIND_ENUM_CONSTANT(INSTANCE_LIGHTMAP_CAPTURE); BIND_ENUM_CONSTANT(INSTANCE_MAX); @@ -2209,6 +2284,36 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE); BIND_ENUM_CONSTANT(CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE); + BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_BOOL); + BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_BVEC2); + BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_BVEC3); + BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_BVEC4); + BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_INT); + BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_IVEC2); + BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_IVEC3); + BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_IVEC4); + BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_RECT2I); + BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_UINT); + BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_UVEC2); + BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_UVEC3); + BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_UVEC4); + BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_FLOAT); + BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_VEC2); + BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_VEC3); + BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_VEC4); + BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_COLOR); + BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_RECT2); + BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_MAT2); + BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_MAT3); + BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_MAT4); + BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_TRANSFORM_2D); + BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_TRANSFORM); + BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_SAMPLER2D); + BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_SAMPLER2DARRAY); + BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_SAMPLER3D); + BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_SAMPLERCUBE); + BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_MAX); + BIND_ENUM_CONSTANT(INFO_OBJECTS_IN_FRAME); BIND_ENUM_CONSTANT(INFO_VERTICES_IN_FRAME); BIND_ENUM_CONSTANT(INFO_MATERIAL_CHANGES_IN_FRAME); @@ -2298,6 +2403,14 @@ RenderingServer::RenderingServer() { GLOBAL_DEF("rendering/quality/directional_shadow/size", 4096); GLOBAL_DEF("rendering/quality/directional_shadow/size.mobile", 2048); ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/directional_shadow/size", PropertyInfo(Variant::INT, "rendering/quality/directional_shadow/size", PROPERTY_HINT_RANGE, "256,16384")); + GLOBAL_DEF("rendering/quality/directional_shadow/soft_shadow_quality", 2); + GLOBAL_DEF("rendering/quality/directional_shadow/soft_shadow_quality.mobile", 0); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/directional_shadow/soft_shadow_quality", PropertyInfo(Variant::INT, "rendering/quality/directional_shadow/soft_shadow_quality", PROPERTY_HINT_ENUM, "Hard(Fastest), Soft Low (Fast), Soft Medium (Average), Soft High (Slow), Soft Ultra (Slowest)")); + + GLOBAL_DEF("rendering/quality/shadows/soft_shadow_quality", 2); + GLOBAL_DEF("rendering/quality/shadows/soft_shadow_quality.mobile", 0); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadows/soft_shadow_quality", PropertyInfo(Variant::INT, "rendering/quality/shadows/soft_shadow_quality", PROPERTY_HINT_ENUM, "Hard(Fastest), Soft Low (Fast), Soft Medium (Average), Soft High (Slow), Soft Ultra (Slowest)")); + GLOBAL_DEF("rendering/quality/shadow_atlas/size", 4096); GLOBAL_DEF("rendering/quality/shadow_atlas/size.mobile", 2048); ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/size", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/size", PROPERTY_HINT_RANGE, "256,16384")); @@ -2310,10 +2423,6 @@ RenderingServer::RenderingServer() { ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_2_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_2_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows")); ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_3_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_3_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows")); - GLOBAL_DEF("rendering/quality/shadows/filter_mode", 1); - GLOBAL_DEF("rendering/quality/shadows/filter_mode.mobile", 0); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadows/filter_mode", PropertyInfo(Variant::INT, "rendering/quality/shadows/filter_mode", PROPERTY_HINT_ENUM, "Disabled (Fast),PCF5 (Average),PCF13 (Slow)")); - GLOBAL_DEF("rendering/quality/reflections/roughness_layers", 8); GLOBAL_DEF("rendering/quality/reflections/texture_array_reflections", true); GLOBAL_DEF("rendering/quality/reflections/texture_array_reflections.mobile", false); @@ -2338,23 +2447,23 @@ RenderingServer::RenderingServer() { GLOBAL_DEF("rendering/quality/depth_prepass/enable", true); GLOBAL_DEF("rendering/quality/depth_prepass/disable_for_vendors", "PowerVR,Mali,Adreno,Apple"); - GLOBAL_DEF("rendering/quality/filters/use_nearest_mipmap_filter", false); - GLOBAL_DEF("rendering/quality/filters/max_anisotropy", 4); + GLOBAL_DEF("rendering/quality/texture_filters/use_nearest_mipmap_filter", false); + GLOBAL_DEF("rendering/quality/texture_filters/max_anisotropy", 4); - GLOBAL_DEF("rendering/quality/filters/depth_of_field_bokeh_shape", 1); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/filters/depth_of_field_bokeh_shape", PropertyInfo(Variant::INT, "rendering/quality/filters/depth_of_field_bokeh_shape", PROPERTY_HINT_ENUM, "Box (Fast),Hexagon (Average),Circle (Slow)")); - GLOBAL_DEF("rendering/quality/filters/depth_of_field_bokeh_quality", 2); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/filters/depth_of_field_bokeh_quality", PropertyInfo(Variant::INT, "rendering/quality/filters/depth_of_field_bokeh_quality", PROPERTY_HINT_ENUM, "Very Low (Fastest),Low (Fast),Medium (Average),High (Slow)")); - GLOBAL_DEF("rendering/quality/filters/depth_of_field_use_jitter", false); + GLOBAL_DEF("rendering/quality/depth_of_field/depth_of_field_bokeh_shape", 1); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/depth_of_field/depth_of_field_bokeh_shape", PropertyInfo(Variant::INT, "rendering/quality/depth_of_field/depth_of_field_bokeh_shape", PROPERTY_HINT_ENUM, "Box (Fast),Hexagon (Average),Circle (Slow)")); + GLOBAL_DEF("rendering/quality/depth_of_field/depth_of_field_bokeh_quality", 2); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/depth_of_field/depth_of_field_bokeh_quality", PropertyInfo(Variant::INT, "rendering/quality/depth_of_field/depth_of_field_bokeh_quality", PROPERTY_HINT_ENUM, "Very Low (Fastest),Low (Fast),Medium (Average),High (Slow)")); + GLOBAL_DEF("rendering/quality/depth_of_field/depth_of_field_use_jitter", false); GLOBAL_DEF("rendering/quality/ssao/quality", 1); ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/ssao/quality", PropertyInfo(Variant::INT, "rendering/quality/ssao/quality", PROPERTY_HINT_ENUM, "Low (Fast),Medium (Average),High (Slow),Ultra (Slower)")); GLOBAL_DEF("rendering/quality/ssao/half_size", false); - GLOBAL_DEF("rendering/quality/filters/screen_space_roughness_limiter", 0); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/filters/screen_space_roughness_limiter", PropertyInfo(Variant::INT, "rendering/quality/filters/screen_space_roughness_limiter", PROPERTY_HINT_ENUM, "Disabled (Fast),Enabled (Average)")); - GLOBAL_DEF("rendering/quality/filters/screen_space_roughness_limiter_curve", 1.0); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/filters/screen_space_roughness_limiter_curve", PropertyInfo(Variant::FLOAT, "rendering/quality/filters/screen_space_roughness_limiter_curve", PROPERTY_HINT_EXP_EASING, "0.01,8,0.01")); + GLOBAL_DEF("rendering/quality/screen_filters/screen_space_roughness_limiter", 0); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_filters/screen_space_roughness_limiter", PropertyInfo(Variant::INT, "rendering/quality/screen_filters/screen_space_roughness_limiter", PROPERTY_HINT_ENUM, "Disabled (Fast),Enabled (Average)")); + GLOBAL_DEF("rendering/quality/screen_filters/screen_space_roughness_limiter_curve", 1.0); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_filters/screen_space_roughness_limiter_curve", PropertyInfo(Variant::FLOAT, "rendering/quality/screen_filters/screen_space_roughness_limiter_curve", PROPERTY_HINT_EXP_EASING, "0.01,8,0.01")); GLOBAL_DEF("rendering/quality/glow/upscale_mode", 1); ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/glow/upscale_mode", PropertyInfo(Variant::INT, "rendering/quality/glow/upscale_mode", PROPERTY_HINT_ENUM, "Linear (Fast),Bicubic (Slow)")); @@ -2369,6 +2478,8 @@ RenderingServer::RenderingServer() { ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/subsurface_scattering/subsurface_scattering_scale", PropertyInfo(Variant::FLOAT, "rendering/quality/subsurface_scattering/subsurface_scattering_scale", PROPERTY_HINT_RANGE, "0.001,1,0.001")); GLOBAL_DEF("rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale", 0.01); ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale", PropertyInfo(Variant::FLOAT, "rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale", PROPERTY_HINT_RANGE, "0.001,1,0.001")); + + GLOBAL_DEF("rendering/high_end/global_shader_variables_buffer_size", 65536); } RenderingServer::~RenderingServer() { diff --git a/servers/rendering_server.h b/servers/rendering_server.h index ac8e92be59..8ca070b4a9 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -38,6 +38,7 @@ #include "core/rid.h" #include "core/variant.h" #include "servers/display_server.h" +#include "servers/rendering/shader_language.h" class RenderingServer : public Object { @@ -85,7 +86,6 @@ public: }; enum CubeMapLayer { - CUBEMAP_LAYER_LEFT, CUBEMAP_LAYER_RIGHT, CUBEMAP_LAYER_BOTTOM, @@ -157,7 +157,6 @@ public: /* SHADER API */ enum ShaderMode { - SHADER_SPATIAL, SHADER_CANVAS_ITEM, SHADER_PARTICLES, @@ -181,8 +180,8 @@ public: enum { MATERIAL_RENDER_PRIORITY_MIN = -128, MATERIAL_RENDER_PRIORITY_MAX = 127, - }; + virtual RID material_create() = 0; virtual void material_set_shader(RID p_shader_material, RID p_shader) = 0; @@ -197,7 +196,6 @@ public: /* MESH API */ enum ArrayType { - ARRAY_VERTEX = 0, ARRAY_NORMAL = 1, ARRAY_TANGENT = 2, @@ -229,12 +227,10 @@ public: ARRAY_COMPRESS_TEX_UV = 1 << (ARRAY_TEX_UV + ARRAY_COMPRESS_BASE), ARRAY_COMPRESS_TEX_UV2 = 1 << (ARRAY_TEX_UV2 + ARRAY_COMPRESS_BASE), ARRAY_COMPRESS_INDEX = 1 << (ARRAY_INDEX + ARRAY_COMPRESS_BASE), + ARRAY_COMPRESS_DEFAULT = ARRAY_COMPRESS_NORMAL | ARRAY_COMPRESS_TANGENT | ARRAY_COMPRESS_COLOR | ARRAY_COMPRESS_TEX_UV | ARRAY_COMPRESS_TEX_UV2, ARRAY_FLAG_USE_2D_VERTICES = ARRAY_COMPRESS_INDEX << 1, ARRAY_FLAG_USE_DYNAMIC_UPDATE = ARRAY_COMPRESS_INDEX << 3, - - ARRAY_COMPRESS_DEFAULT = ARRAY_COMPRESS_NORMAL | ARRAY_COMPRESS_TANGENT | ARRAY_COMPRESS_COLOR | ARRAY_COMPRESS_TEX_UV | ARRAY_COMPRESS_TEX_UV2 - }; enum PrimitiveType { @@ -377,15 +373,14 @@ public: }; enum LightParam { - LIGHT_PARAM_ENERGY, LIGHT_PARAM_INDIRECT_ENERGY, LIGHT_PARAM_SPECULAR, LIGHT_PARAM_RANGE, + LIGHT_PARAM_SIZE, LIGHT_PARAM_ATTENUATION, LIGHT_PARAM_SPOT_ANGLE, LIGHT_PARAM_SPOT_ATTENUATION, - LIGHT_PARAM_CONTACT_SHADOW_SIZE, LIGHT_PARAM_SHADOW_MAX_DISTANCE, LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET, LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET, @@ -393,7 +388,9 @@ public: LIGHT_PARAM_SHADOW_FADE_START, LIGHT_PARAM_SHADOW_NORMAL_BIAS, LIGHT_PARAM_SHADOW_BIAS, - LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE, + LIGHT_PARAM_SHADOW_PANCAKE_SIZE, + LIGHT_PARAM_SHADOW_BLUR, + LIGHT_PARAM_TRANSMITTANCE_BIAS, LIGHT_PARAM_MAX }; @@ -460,6 +457,27 @@ public: virtual void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) = 0; virtual void reflection_probe_set_resolution(RID p_probe, int p_resolution) = 0; + /* DECAL API */ + + enum DecalTexture { + DECAL_TEXTURE_ALBEDO, + DECAL_TEXTURE_NORMAL, + DECAL_TEXTURE_ORM, + DECAL_TEXTURE_EMISSION, + DECAL_TEXTURE_MAX + }; + + virtual RID decal_create() = 0; + virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) = 0; + virtual void decal_set_texture(RID p_decal, DecalTexture p_type, RID p_texture) = 0; + virtual void decal_set_emission_energy(RID p_decal, float p_energy) = 0; + virtual void decal_set_albedo_mix(RID p_decal, float p_mix) = 0; + virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) = 0; + virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) = 0; + virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) = 0; + virtual void decal_set_fade(RID p_decal, float p_above, float p_below) = 0; + virtual void decal_set_normal_fade(RID p_decal, float p_fade) = 0; + /* GI PROBE API */ virtual RID gi_probe_create() = 0; @@ -575,12 +593,13 @@ public: }; virtual void particles_set_collision(RID p_particles,ParticlesCollisionMode p_mode,const Transform&, p_xform,const RID p_depth_tex,const RID p_normal_tex)=0; -*/ + */ + /* VIEWPORT TARGET API */ virtual RID viewport_create() = 0; - virtual void viewport_set_use_arvr(RID p_viewport, bool p_use_arvr) = 0; + virtual void viewport_set_use_xr(RID p_viewport, bool p_use_xr) = 0; virtual void viewport_set_size(RID p_viewport, int p_width, int p_height) = 0; virtual void viewport_set_active(RID p_viewport, bool p_active) = 0; virtual void viewport_set_parent_viewport(RID p_viewport, RID p_parent_viewport) = 0; @@ -599,7 +618,6 @@ public: virtual void viewport_set_update_mode(RID p_viewport, ViewportUpdateMode p_mode) = 0; enum ViewportClearMode { - VIEWPORT_CLEAR_ALWAYS, VIEWPORT_CLEAR_NEVER, VIEWPORT_CLEAR_ONLY_NEXT_FRAME @@ -632,21 +650,27 @@ public: VIEWPORT_MSAA_4X, VIEWPORT_MSAA_8X, VIEWPORT_MSAA_16X, - VIEWPORT_MSAA_EXT_2X, - VIEWPORT_MSAA_EXT_4X, + VIEWPORT_MSAA_MAX, }; virtual void viewport_set_msaa(RID p_viewport, ViewportMSAA p_msaa) = 0; - enum ViewportRenderInfo { + enum ViewportScreenSpaceAA { + VIEWPORT_SCREEN_SPACE_AA_DISABLED, + VIEWPORT_SCREEN_SPACE_AA_FXAA, + VIEWPORT_SCREEN_SPACE_AA_MAX, + }; + + virtual void viewport_set_screen_space_aa(RID p_viewport, ViewportScreenSpaceAA p_mode) = 0; + enum ViewportRenderInfo { VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME, VIEWPORT_RENDER_INFO_VERTICES_IN_FRAME, VIEWPORT_RENDER_INFO_MATERIAL_CHANGES_IN_FRAME, VIEWPORT_RENDER_INFO_SHADER_CHANGES_IN_FRAME, VIEWPORT_RENDER_INFO_SURFACE_CHANGES_IN_FRAME, VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME, - VIEWPORT_RENDER_INFO_MAX + VIEWPORT_RENDER_INFO_MAX, }; virtual int viewport_get_render_info(RID p_viewport, ViewportRenderInfo p_info) = 0; @@ -666,11 +690,16 @@ public: VIEWPORT_DEBUG_DRAW_SCENE_LUMINANCE, VIEWPORT_DEBUG_DRAW_SSAO, VIEWPORT_DEBUG_DRAW_ROUGHNESS_LIMITER, - + VIEWPORT_DEBUG_DRAW_PSSM_SPLITS, + VIEWPORT_DEBUG_DRAW_DECAL_ATLAS, }; virtual void viewport_set_debug_draw(RID p_viewport, ViewportDebugDraw p_draw) = 0; + virtual void viewport_set_measure_render_time(RID p_viewport, bool p_enable) = 0; + virtual float viewport_get_measured_render_time_cpu(RID p_viewport) const = 0; + virtual float viewport_get_measured_render_time_gpu(RID p_viewport) const = 0; + virtual void directional_shadow_atlas_set_size(int p_size) = 0; /* SKY API */ @@ -690,7 +719,6 @@ public: virtual RID environment_create() = 0; enum EnvironmentBG { - ENV_BG_CLEAR_COLOR, ENV_BG_COLOR, ENV_BG_SKY, @@ -733,6 +761,7 @@ public: ENV_GLOW_BLEND_MODE_REPLACE, ENV_GLOW_BLEND_MODE_MIX, }; + virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) = 0; virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0; @@ -816,6 +845,18 @@ public: virtual void camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) = 0; virtual void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) = 0; + enum ShadowQuality { + SHADOW_QUALITY_HARD, + SHADOW_QUALITY_SOFT_LOW, + SHADOW_QUALITY_SOFT_MEDIUM, + SHADOW_QUALITY_SOFT_HIGH, + SHADOW_QUALITY_SOFT_ULTRA, + SHADOW_QUALITY_MAX + }; + + virtual void shadows_quality_set(ShadowQuality p_quality) = 0; + virtual void directional_shadow_quality_set(ShadowQuality p_quality) = 0; + /* SCENARIO API */ virtual RID scenario_create() = 0; @@ -825,7 +866,6 @@ public: SCENARIO_DEBUG_WIREFRAME, SCENARIO_DEBUG_OVERDRAW, SCENARIO_DEBUG_SHADELESS, - }; virtual void scenario_set_debug(RID p_scenario, ScenarioDebugMode p_debug_mode) = 0; @@ -836,7 +876,6 @@ public: /* INSTANCING API */ enum InstanceType { - INSTANCE_NONE, INSTANCE_MESH, INSTANCE_MULTIMESH, @@ -844,6 +883,7 @@ public: INSTANCE_PARTICLES, INSTANCE_LIGHT, INSTANCE_REFLECTION_PROBE, + INSTANCE_DECAL, INSTANCE_GI_PROBE, INSTANCE_LIGHTMAP_CAPTURE, INSTANCE_MAX, @@ -903,6 +943,11 @@ public: virtual void instance_geometry_set_draw_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin) = 0; virtual void instance_geometry_set_as_instance_lod(RID p_instance, RID p_as_lod_of_instance) = 0; + virtual void instance_geometry_set_shader_parameter(RID p_instance, const StringName &, const Variant &p_value) = 0; + virtual Variant instance_geometry_get_shader_parameter(RID p_instance, const StringName &) const = 0; + virtual Variant instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &) const = 0; + virtual void instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const = 0; + /* CANVAS (2D) */ virtual RID canvas_create() = 0; @@ -1041,8 +1086,58 @@ public: CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE, CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE, }; + virtual void canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon, CanvasOccluderPolygonCullMode p_mode) = 0; + /* GLOBAL VARIABLES */ + + enum GlobalVariableType { + GLOBAL_VAR_TYPE_BOOL, + GLOBAL_VAR_TYPE_BVEC2, + GLOBAL_VAR_TYPE_BVEC3, + GLOBAL_VAR_TYPE_BVEC4, + GLOBAL_VAR_TYPE_INT, + GLOBAL_VAR_TYPE_IVEC2, + GLOBAL_VAR_TYPE_IVEC3, + GLOBAL_VAR_TYPE_IVEC4, + GLOBAL_VAR_TYPE_RECT2I, + GLOBAL_VAR_TYPE_UINT, + GLOBAL_VAR_TYPE_UVEC2, + GLOBAL_VAR_TYPE_UVEC3, + GLOBAL_VAR_TYPE_UVEC4, + GLOBAL_VAR_TYPE_FLOAT, + GLOBAL_VAR_TYPE_VEC2, + GLOBAL_VAR_TYPE_VEC3, + GLOBAL_VAR_TYPE_VEC4, + GLOBAL_VAR_TYPE_COLOR, + GLOBAL_VAR_TYPE_RECT2, + GLOBAL_VAR_TYPE_MAT2, + GLOBAL_VAR_TYPE_MAT3, + GLOBAL_VAR_TYPE_MAT4, + GLOBAL_VAR_TYPE_TRANSFORM_2D, + GLOBAL_VAR_TYPE_TRANSFORM, + GLOBAL_VAR_TYPE_SAMPLER2D, + GLOBAL_VAR_TYPE_SAMPLER2DARRAY, + GLOBAL_VAR_TYPE_SAMPLER3D, + GLOBAL_VAR_TYPE_SAMPLERCUBE, + GLOBAL_VAR_TYPE_MAX + }; + + virtual void global_variable_add(const StringName &p_name, GlobalVariableType p_type, const Variant &p_value) = 0; + virtual void global_variable_remove(const StringName &p_name) = 0; + virtual Vector<StringName> global_variable_get_list() const = 0; + + virtual void global_variable_set(const StringName &p_name, const Variant &p_value) = 0; + virtual void global_variable_set_override(const StringName &p_name, const Variant &p_value) = 0; + + virtual Variant global_variable_get(const StringName &p_name) const = 0; + virtual GlobalVariableType global_variable_get_type(const StringName &p_name) const = 0; + + virtual void global_variables_load_settings(bool p_load_textures) = 0; + virtual void global_variables_clear() = 0; + + static ShaderLanguage::DataType global_variable_type_get_shader_datatype(GlobalVariableType p_type); + /* BLACK BARS */ virtual void black_bars_set_margins(int p_left, int p_top, int p_right, int p_bottom) = 0; @@ -1065,7 +1160,6 @@ public: /* STATUS INFORMATION */ enum RenderInfo { - INFO_OBJECTS_IN_FRAME, INFO_VERTICES_IN_FRAME, INFO_MATERIAL_CHANGES_IN_FRAME, @@ -1143,10 +1237,12 @@ VARIANT_ENUM_CAST(RenderingServer::LightOmniShadowMode); VARIANT_ENUM_CAST(RenderingServer::LightDirectionalShadowMode); VARIANT_ENUM_CAST(RenderingServer::LightDirectionalShadowDepthRangeMode); VARIANT_ENUM_CAST(RenderingServer::ReflectionProbeUpdateMode); +VARIANT_ENUM_CAST(RenderingServer::DecalTexture); VARIANT_ENUM_CAST(RenderingServer::ParticlesDrawOrder); VARIANT_ENUM_CAST(RenderingServer::ViewportUpdateMode); VARIANT_ENUM_CAST(RenderingServer::ViewportClearMode); VARIANT_ENUM_CAST(RenderingServer::ViewportMSAA); +VARIANT_ENUM_CAST(RenderingServer::ViewportScreenSpaceAA); VARIANT_ENUM_CAST(RenderingServer::ViewportRenderInfo); VARIANT_ENUM_CAST(RenderingServer::ViewportDebugDraw); VARIANT_ENUM_CAST(RenderingServer::SkyMode); @@ -1155,10 +1251,13 @@ VARIANT_ENUM_CAST(RenderingServer::EnvironmentAmbientSource); VARIANT_ENUM_CAST(RenderingServer::EnvironmentReflectionSource); VARIANT_ENUM_CAST(RenderingServer::EnvironmentGlowBlendMode); VARIANT_ENUM_CAST(RenderingServer::EnvironmentToneMapper); -VARIANT_ENUM_CAST(RenderingServer::EnvironmentSSAOQuality); +VARIANT_ENUM_CAST(RenderingServer::EnvironmentSSRRoughnessQuality); VARIANT_ENUM_CAST(RenderingServer::EnvironmentSSAOBlur); +VARIANT_ENUM_CAST(RenderingServer::EnvironmentSSAOQuality); +VARIANT_ENUM_CAST(RenderingServer::SubSurfaceScatteringQuality); VARIANT_ENUM_CAST(RenderingServer::DOFBlurQuality); VARIANT_ENUM_CAST(RenderingServer::DOFBokehShape); +VARIANT_ENUM_CAST(RenderingServer::ShadowQuality); VARIANT_ENUM_CAST(RenderingServer::ScenarioDebugMode); VARIANT_ENUM_CAST(RenderingServer::InstanceType); VARIANT_ENUM_CAST(RenderingServer::InstanceFlags); @@ -1169,10 +1268,11 @@ VARIANT_ENUM_CAST(RenderingServer::CanvasItemTextureRepeat); VARIANT_ENUM_CAST(RenderingServer::CanvasLightMode); VARIANT_ENUM_CAST(RenderingServer::CanvasLightShadowFilter); VARIANT_ENUM_CAST(RenderingServer::CanvasOccluderPolygonCullMode); +VARIANT_ENUM_CAST(RenderingServer::GlobalVariableType); VARIANT_ENUM_CAST(RenderingServer::RenderInfo); VARIANT_ENUM_CAST(RenderingServer::Features); -//typedef RenderingServer VS; // makes it easier to use +// Alias to make it easier to use. #define RS RenderingServer -#endif +#endif // RENDERING_SERVER_H diff --git a/servers/arvr/SCsub b/servers/xr/SCsub index 86681f9c74..86681f9c74 100644 --- a/servers/arvr/SCsub +++ b/servers/xr/SCsub diff --git a/servers/arvr/arvr_interface.cpp b/servers/xr/xr_interface.cpp index 577b4cdd8a..c1233ae810 100644 --- a/servers/arvr/arvr_interface.cpp +++ b/servers/xr/xr_interface.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* arvr_interface.cpp */ +/* xr_interface.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,24 +28,24 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "arvr_interface.h" +#include "xr_interface.h" -void ARVRInterface::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_name"), &ARVRInterface::get_name); - ClassDB::bind_method(D_METHOD("get_capabilities"), &ARVRInterface::get_capabilities); +void XRInterface::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_name"), &XRInterface::get_name); + ClassDB::bind_method(D_METHOD("get_capabilities"), &XRInterface::get_capabilities); - ClassDB::bind_method(D_METHOD("is_primary"), &ARVRInterface::is_primary); - ClassDB::bind_method(D_METHOD("set_is_primary", "enable"), &ARVRInterface::set_is_primary); + ClassDB::bind_method(D_METHOD("is_primary"), &XRInterface::is_primary); + ClassDB::bind_method(D_METHOD("set_is_primary", "enable"), &XRInterface::set_is_primary); - ClassDB::bind_method(D_METHOD("is_initialized"), &ARVRInterface::is_initialized); - ClassDB::bind_method(D_METHOD("set_is_initialized", "initialized"), &ARVRInterface::set_is_initialized); - ClassDB::bind_method(D_METHOD("initialize"), &ARVRInterface::initialize); - ClassDB::bind_method(D_METHOD("uninitialize"), &ARVRInterface::uninitialize); + ClassDB::bind_method(D_METHOD("is_initialized"), &XRInterface::is_initialized); + ClassDB::bind_method(D_METHOD("set_is_initialized", "initialized"), &XRInterface::set_is_initialized); + ClassDB::bind_method(D_METHOD("initialize"), &XRInterface::initialize); + ClassDB::bind_method(D_METHOD("uninitialize"), &XRInterface::uninitialize); - ClassDB::bind_method(D_METHOD("get_tracking_status"), &ARVRInterface::get_tracking_status); + ClassDB::bind_method(D_METHOD("get_tracking_status"), &XRInterface::get_tracking_status); - ClassDB::bind_method(D_METHOD("get_render_targetsize"), &ARVRInterface::get_render_targetsize); - ClassDB::bind_method(D_METHOD("is_stereo"), &ARVRInterface::is_stereo); + ClassDB::bind_method(D_METHOD("get_render_targetsize"), &XRInterface::get_render_targetsize); + ClassDB::bind_method(D_METHOD("is_stereo"), &XRInterface::is_stereo); ADD_GROUP("Interface", "interface_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "interface_is_primary"), "set_is_primary", "is_primary"); @@ -54,55 +54,55 @@ void ARVRInterface::_bind_methods() { // we don't have any properties specific to VR yet.... // but we do have properties specific to AR.... - ClassDB::bind_method(D_METHOD("get_anchor_detection_is_enabled"), &ARVRInterface::get_anchor_detection_is_enabled); - ClassDB::bind_method(D_METHOD("set_anchor_detection_is_enabled", "enable"), &ARVRInterface::set_anchor_detection_is_enabled); - ClassDB::bind_method(D_METHOD("get_camera_feed_id"), &ARVRInterface::get_camera_feed_id); + ClassDB::bind_method(D_METHOD("get_anchor_detection_is_enabled"), &XRInterface::get_anchor_detection_is_enabled); + ClassDB::bind_method(D_METHOD("set_anchor_detection_is_enabled", "enable"), &XRInterface::set_anchor_detection_is_enabled); + ClassDB::bind_method(D_METHOD("get_camera_feed_id"), &XRInterface::get_camera_feed_id); ADD_GROUP("AR", "ar_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ar_is_anchor_detection_enabled"), "set_anchor_detection_is_enabled", "get_anchor_detection_is_enabled"); - BIND_ENUM_CONSTANT(ARVR_NONE); - BIND_ENUM_CONSTANT(ARVR_MONO); - BIND_ENUM_CONSTANT(ARVR_STEREO); - BIND_ENUM_CONSTANT(ARVR_AR); - BIND_ENUM_CONSTANT(ARVR_EXTERNAL); + BIND_ENUM_CONSTANT(XR_NONE); + BIND_ENUM_CONSTANT(XR_MONO); + BIND_ENUM_CONSTANT(XR_STEREO); + BIND_ENUM_CONSTANT(XR_AR); + BIND_ENUM_CONSTANT(XR_EXTERNAL); BIND_ENUM_CONSTANT(EYE_MONO); BIND_ENUM_CONSTANT(EYE_LEFT); BIND_ENUM_CONSTANT(EYE_RIGHT); - BIND_ENUM_CONSTANT(ARVR_NORMAL_TRACKING); - BIND_ENUM_CONSTANT(ARVR_EXCESSIVE_MOTION); - BIND_ENUM_CONSTANT(ARVR_INSUFFICIENT_FEATURES); - BIND_ENUM_CONSTANT(ARVR_UNKNOWN_TRACKING); - BIND_ENUM_CONSTANT(ARVR_NOT_TRACKING); + BIND_ENUM_CONSTANT(XR_NORMAL_TRACKING); + BIND_ENUM_CONSTANT(XR_EXCESSIVE_MOTION); + BIND_ENUM_CONSTANT(XR_INSUFFICIENT_FEATURES); + BIND_ENUM_CONSTANT(XR_UNKNOWN_TRACKING); + BIND_ENUM_CONSTANT(XR_NOT_TRACKING); }; -StringName ARVRInterface::get_name() const { +StringName XRInterface::get_name() const { return "Unknown"; }; -bool ARVRInterface::is_primary() { - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, false); +bool XRInterface::is_primary() { + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, false); - return arvr_server->get_primary_interface() == this; + return xr_server->get_primary_interface() == this; }; -void ARVRInterface::set_is_primary(bool p_is_primary) { - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL(arvr_server); +void XRInterface::set_is_primary(bool p_is_primary) { + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); if (p_is_primary) { ERR_FAIL_COND(!is_initialized()); - arvr_server->set_primary_interface(this); + xr_server->set_primary_interface(this); } else { - arvr_server->clear_primary_interface_if(this); + xr_server->clear_primary_interface_if(this); }; }; -void ARVRInterface::set_is_initialized(bool p_initialized) { +void XRInterface::set_is_initialized(bool p_initialized) { if (p_initialized) { if (!is_initialized()) { initialize(); @@ -114,31 +114,31 @@ void ARVRInterface::set_is_initialized(bool p_initialized) { }; }; -ARVRInterface::Tracking_status ARVRInterface::get_tracking_status() const { +XRInterface::Tracking_status XRInterface::get_tracking_status() const { return tracking_state; }; -ARVRInterface::ARVRInterface() { - tracking_state = ARVR_UNKNOWN_TRACKING; +XRInterface::XRInterface() { + tracking_state = XR_UNKNOWN_TRACKING; }; -ARVRInterface::~ARVRInterface(){}; +XRInterface::~XRInterface(){}; // optional render to external texture which enhances performance on those platforms that require us to submit our end result into special textures. -unsigned int ARVRInterface::get_external_texture_for_eye(ARVRInterface::Eyes p_eye) { +unsigned int XRInterface::get_external_texture_for_eye(XRInterface::Eyes p_eye) { return 0; }; /** these will only be implemented on AR interfaces, so we want dummies for VR **/ -bool ARVRInterface::get_anchor_detection_is_enabled() const { +bool XRInterface::get_anchor_detection_is_enabled() const { return false; }; -void ARVRInterface::set_anchor_detection_is_enabled(bool p_enable){ +void XRInterface::set_anchor_detection_is_enabled(bool p_enable){ // don't do anything here, this needs to be implemented on AR interface to enable/disable things like plane detection etc. }; -int ARVRInterface::get_camera_feed_id() { +int XRInterface::get_camera_feed_id() { // don't do anything here, this needs to be implemented on AR interface to enable/disable things like plane detection etc. return 0; diff --git a/servers/arvr/arvr_interface.h b/servers/xr/xr_interface.h index 861061cbf5..99fcef7925 100644 --- a/servers/arvr/arvr_interface.h +++ b/servers/xr/xr_interface.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* arvr_interface.h */ +/* xr_interface.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,18 +28,18 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef ARVR_INTERFACE_H -#define ARVR_INTERFACE_H +#ifndef XR_INTERFACE_H +#define XR_INTERFACE_H #include "core/math/camera_matrix.h" #include "core/os/thread_safe.h" #include "scene/main/window.h" -#include "servers/arvr_server.h" +#include "servers/xr_server.h" /** @author Bastiaan Olij <mux213@gmail.com> - The ARVR interface is a template class ontop of which we build interface to different AR, VR and tracking SDKs. + The XR interface is a template class ontop of which we build interface to different AR, VR and tracking SDKs. The idea is that we subclass this class, implement the logic, and then instantiate a singleton of each interface when Godot starts. These instances do not initialize themselves but register themselves with the AR/VR server. @@ -48,16 +48,16 @@ Note that we may make this into a fully instantiable class for GDNative support. */ -class ARVRInterface : public Reference { - GDCLASS(ARVRInterface, Reference); +class XRInterface : public Reference { + GDCLASS(XRInterface, Reference); public: enum Capabilities { /* purely meta data, provides some info about what this interface supports */ - ARVR_NONE = 0, /* no capabilities */ - ARVR_MONO = 1, /* can be used with mono output */ - ARVR_STEREO = 2, /* can be used with stereo output */ - ARVR_AR = 4, /* offers a camera feed for AR */ - ARVR_EXTERNAL = 8 /* renders to external device */ + XR_NONE = 0, /* no capabilities */ + XR_MONO = 1, /* can be used with mono output */ + XR_STEREO = 2, /* can be used with stereo output */ + XR_AR = 4, /* offers a camera feed for AR */ + XR_EXTERNAL = 8 /* renders to external device */ }; enum Eyes { @@ -67,11 +67,11 @@ public: }; enum Tracking_status { /* tracking status currently based on AR but we can start doing more with this for VR as well */ - ARVR_NORMAL_TRACKING, - ARVR_EXCESSIVE_MOTION, - ARVR_INSUFFICIENT_FEATURES, - ARVR_UNKNOWN_TRACKING, - ARVR_NOT_TRACKING + XR_NORMAL_TRACKING, + XR_EXCESSIVE_MOTION, + XR_INSUFFICIENT_FEATURES, + XR_UNKNOWN_TRACKING, + XR_NOT_TRACKING }; protected: @@ -107,20 +107,20 @@ public: virtual Size2 get_render_targetsize() = 0; /* returns the recommended render target size per eye for this device */ virtual bool is_stereo() = 0; /* returns true if this interface requires stereo rendering (for VR HMDs) or mono rendering (for mobile AR) */ - virtual Transform get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform) = 0; /* get each eyes camera transform, also implement EYE_MONO */ - virtual CameraMatrix get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) = 0; /* get each eyes projection matrix */ - virtual unsigned int get_external_texture_for_eye(ARVRInterface::Eyes p_eye); /* if applicable return external texture to render to */ - virtual void commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) = 0; /* output the left or right eye */ + virtual Transform get_transform_for_eye(XRInterface::Eyes p_eye, const Transform &p_cam_transform) = 0; /* get each eyes camera transform, also implement EYE_MONO */ + virtual CameraMatrix get_projection_for_eye(XRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) = 0; /* get each eyes projection matrix */ + virtual unsigned int get_external_texture_for_eye(XRInterface::Eyes p_eye); /* if applicable return external texture to render to */ + virtual void commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) = 0; /* output the left or right eye */ virtual void process() = 0; virtual void notification(int p_what) = 0; - ARVRInterface(); - ~ARVRInterface(); + XRInterface(); + ~XRInterface(); }; -VARIANT_ENUM_CAST(ARVRInterface::Capabilities); -VARIANT_ENUM_CAST(ARVRInterface::Eyes); -VARIANT_ENUM_CAST(ARVRInterface::Tracking_status); +VARIANT_ENUM_CAST(XRInterface::Capabilities); +VARIANT_ENUM_CAST(XRInterface::Eyes); +VARIANT_ENUM_CAST(XRInterface::Tracking_status); #endif diff --git a/servers/arvr/arvr_positional_tracker.cpp b/servers/xr/xr_positional_tracker.cpp index dabeb7b86f..808b0a608f 100644 --- a/servers/arvr/arvr_positional_tracker.cpp +++ b/servers/xr/xr_positional_tracker.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* arvr_positional_tracker.cpp */ +/* xr_positional_tracker.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,192 +28,192 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "arvr_positional_tracker.h" +#include "xr_positional_tracker.h" #include "core/input/input_filter.h" -void ARVRPositionalTracker::_bind_methods() { +void XRPositionalTracker::_bind_methods() { BIND_ENUM_CONSTANT(TRACKER_HAND_UNKNOWN); BIND_ENUM_CONSTANT(TRACKER_LEFT_HAND); BIND_ENUM_CONSTANT(TRACKER_RIGHT_HAND); // this class is read only from GDScript, so we only have access to getters.. - ClassDB::bind_method(D_METHOD("get_type"), &ARVRPositionalTracker::get_type); - ClassDB::bind_method(D_METHOD("get_tracker_id"), &ARVRPositionalTracker::get_tracker_id); - ClassDB::bind_method(D_METHOD("get_name"), &ARVRPositionalTracker::get_name); - ClassDB::bind_method(D_METHOD("get_joy_id"), &ARVRPositionalTracker::get_joy_id); - ClassDB::bind_method(D_METHOD("get_tracks_orientation"), &ARVRPositionalTracker::get_tracks_orientation); - ClassDB::bind_method(D_METHOD("get_orientation"), &ARVRPositionalTracker::get_orientation); - ClassDB::bind_method(D_METHOD("get_tracks_position"), &ARVRPositionalTracker::get_tracks_position); - ClassDB::bind_method(D_METHOD("get_position"), &ARVRPositionalTracker::get_position); - ClassDB::bind_method(D_METHOD("get_hand"), &ARVRPositionalTracker::get_hand); - ClassDB::bind_method(D_METHOD("get_transform", "adjust_by_reference_frame"), &ARVRPositionalTracker::get_transform); - ClassDB::bind_method(D_METHOD("get_mesh"), &ARVRPositionalTracker::get_mesh); + ClassDB::bind_method(D_METHOD("get_type"), &XRPositionalTracker::get_type); + ClassDB::bind_method(D_METHOD("get_tracker_id"), &XRPositionalTracker::get_tracker_id); + ClassDB::bind_method(D_METHOD("get_name"), &XRPositionalTracker::get_name); + ClassDB::bind_method(D_METHOD("get_joy_id"), &XRPositionalTracker::get_joy_id); + ClassDB::bind_method(D_METHOD("get_tracks_orientation"), &XRPositionalTracker::get_tracks_orientation); + ClassDB::bind_method(D_METHOD("get_orientation"), &XRPositionalTracker::get_orientation); + ClassDB::bind_method(D_METHOD("get_tracks_position"), &XRPositionalTracker::get_tracks_position); + ClassDB::bind_method(D_METHOD("get_position"), &XRPositionalTracker::get_position); + ClassDB::bind_method(D_METHOD("get_hand"), &XRPositionalTracker::get_hand); + ClassDB::bind_method(D_METHOD("get_transform", "adjust_by_reference_frame"), &XRPositionalTracker::get_transform); + ClassDB::bind_method(D_METHOD("get_mesh"), &XRPositionalTracker::get_mesh); // these functions we don't want to expose to normal users but do need to be callable from GDNative - ClassDB::bind_method(D_METHOD("_set_type", "type"), &ARVRPositionalTracker::set_type); - ClassDB::bind_method(D_METHOD("_set_name", "name"), &ARVRPositionalTracker::set_name); - ClassDB::bind_method(D_METHOD("_set_joy_id", "joy_id"), &ARVRPositionalTracker::set_joy_id); - ClassDB::bind_method(D_METHOD("_set_orientation", "orientation"), &ARVRPositionalTracker::set_orientation); - ClassDB::bind_method(D_METHOD("_set_rw_position", "rw_position"), &ARVRPositionalTracker::set_rw_position); - ClassDB::bind_method(D_METHOD("_set_mesh", "mesh"), &ARVRPositionalTracker::set_mesh); - ClassDB::bind_method(D_METHOD("get_rumble"), &ARVRPositionalTracker::get_rumble); - ClassDB::bind_method(D_METHOD("set_rumble", "rumble"), &ARVRPositionalTracker::set_rumble); + ClassDB::bind_method(D_METHOD("_set_type", "type"), &XRPositionalTracker::set_type); + ClassDB::bind_method(D_METHOD("_set_name", "name"), &XRPositionalTracker::set_name); + ClassDB::bind_method(D_METHOD("_set_joy_id", "joy_id"), &XRPositionalTracker::set_joy_id); + ClassDB::bind_method(D_METHOD("_set_orientation", "orientation"), &XRPositionalTracker::set_orientation); + ClassDB::bind_method(D_METHOD("_set_rw_position", "rw_position"), &XRPositionalTracker::set_rw_position); + ClassDB::bind_method(D_METHOD("_set_mesh", "mesh"), &XRPositionalTracker::set_mesh); + ClassDB::bind_method(D_METHOD("get_rumble"), &XRPositionalTracker::get_rumble); + ClassDB::bind_method(D_METHOD("set_rumble", "rumble"), &XRPositionalTracker::set_rumble); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rumble"), "set_rumble", "get_rumble"); }; -void ARVRPositionalTracker::set_type(ARVRServer::TrackerType p_type) { +void XRPositionalTracker::set_type(XRServer::TrackerType p_type) { if (type != p_type) { type = p_type; - hand = ARVRPositionalTracker::TRACKER_HAND_UNKNOWN; + hand = XRPositionalTracker::TRACKER_HAND_UNKNOWN; - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL(arvr_server); + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); // get a tracker id for our type // note if this is a controller this will be 3 or higher but we may change it later. - tracker_id = arvr_server->get_free_tracker_id_for_type(p_type); + tracker_id = xr_server->get_free_tracker_id_for_type(p_type); }; }; -ARVRServer::TrackerType ARVRPositionalTracker::get_type() const { +XRServer::TrackerType XRPositionalTracker::get_type() const { return type; }; -void ARVRPositionalTracker::set_name(const String &p_name) { +void XRPositionalTracker::set_name(const String &p_name) { name = p_name; }; -StringName ARVRPositionalTracker::get_name() const { +StringName XRPositionalTracker::get_name() const { return name; }; -int ARVRPositionalTracker::get_tracker_id() const { +int XRPositionalTracker::get_tracker_id() const { return tracker_id; }; -void ARVRPositionalTracker::set_joy_id(int p_joy_id) { +void XRPositionalTracker::set_joy_id(int p_joy_id) { joy_id = p_joy_id; }; -int ARVRPositionalTracker::get_joy_id() const { +int XRPositionalTracker::get_joy_id() const { return joy_id; }; -bool ARVRPositionalTracker::get_tracks_orientation() const { +bool XRPositionalTracker::get_tracks_orientation() const { return tracks_orientation; }; -void ARVRPositionalTracker::set_orientation(const Basis &p_orientation) { +void XRPositionalTracker::set_orientation(const Basis &p_orientation) { _THREAD_SAFE_METHOD_ tracks_orientation = true; // obviously we have this orientation = p_orientation; }; -Basis ARVRPositionalTracker::get_orientation() const { +Basis XRPositionalTracker::get_orientation() const { _THREAD_SAFE_METHOD_ return orientation; }; -bool ARVRPositionalTracker::get_tracks_position() const { +bool XRPositionalTracker::get_tracks_position() const { return tracks_position; }; -void ARVRPositionalTracker::set_position(const Vector3 &p_position) { +void XRPositionalTracker::set_position(const Vector3 &p_position) { _THREAD_SAFE_METHOD_ - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL(arvr_server); - real_t world_scale = arvr_server->get_world_scale(); + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); + real_t world_scale = xr_server->get_world_scale(); ERR_FAIL_COND(world_scale == 0); tracks_position = true; // obviously we have this rw_position = p_position / world_scale; }; -Vector3 ARVRPositionalTracker::get_position() const { +Vector3 XRPositionalTracker::get_position() const { _THREAD_SAFE_METHOD_ - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, rw_position); - real_t world_scale = arvr_server->get_world_scale(); + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, rw_position); + real_t world_scale = xr_server->get_world_scale(); return rw_position * world_scale; }; -void ARVRPositionalTracker::set_rw_position(const Vector3 &p_rw_position) { +void XRPositionalTracker::set_rw_position(const Vector3 &p_rw_position) { _THREAD_SAFE_METHOD_ tracks_position = true; // obviously we have this rw_position = p_rw_position; }; -Vector3 ARVRPositionalTracker::get_rw_position() const { +Vector3 XRPositionalTracker::get_rw_position() const { _THREAD_SAFE_METHOD_ return rw_position; }; -void ARVRPositionalTracker::set_mesh(const Ref<Mesh> &p_mesh) { +void XRPositionalTracker::set_mesh(const Ref<Mesh> &p_mesh) { _THREAD_SAFE_METHOD_ mesh = p_mesh; }; -Ref<Mesh> ARVRPositionalTracker::get_mesh() const { +Ref<Mesh> XRPositionalTracker::get_mesh() const { _THREAD_SAFE_METHOD_ return mesh; }; -ARVRPositionalTracker::TrackerHand ARVRPositionalTracker::get_hand() const { +XRPositionalTracker::TrackerHand XRPositionalTracker::get_hand() const { return hand; }; -void ARVRPositionalTracker::set_hand(const ARVRPositionalTracker::TrackerHand p_hand) { - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL(arvr_server); +void XRPositionalTracker::set_hand(const XRPositionalTracker::TrackerHand p_hand) { + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); if (hand != p_hand) { // we can only set this if we've previously set this to be a controller!! - ERR_FAIL_COND((type != ARVRServer::TRACKER_CONTROLLER) && (p_hand != ARVRPositionalTracker::TRACKER_HAND_UNKNOWN)); + ERR_FAIL_COND((type != XRServer::TRACKER_CONTROLLER) && (p_hand != XRPositionalTracker::TRACKER_HAND_UNKNOWN)); hand = p_hand; - if (hand == ARVRPositionalTracker::TRACKER_LEFT_HAND) { - if (!arvr_server->is_tracker_id_in_use_for_type(type, 1)) { + if (hand == XRPositionalTracker::TRACKER_LEFT_HAND) { + if (!xr_server->is_tracker_id_in_use_for_type(type, 1)) { tracker_id = 1; }; - } else if (hand == ARVRPositionalTracker::TRACKER_RIGHT_HAND) { - if (!arvr_server->is_tracker_id_in_use_for_type(type, 2)) { + } else if (hand == XRPositionalTracker::TRACKER_RIGHT_HAND) { + if (!xr_server->is_tracker_id_in_use_for_type(type, 2)) { tracker_id = 2; }; }; }; }; -Transform ARVRPositionalTracker::get_transform(bool p_adjust_by_reference_frame) const { +Transform XRPositionalTracker::get_transform(bool p_adjust_by_reference_frame) const { Transform new_transform; new_transform.basis = get_orientation(); new_transform.origin = get_position(); if (p_adjust_by_reference_frame) { - ARVRServer *arvr_server = ARVRServer::get_singleton(); - ERR_FAIL_NULL_V(arvr_server, new_transform); + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL_V(xr_server, new_transform); - new_transform = arvr_server->get_reference_frame() * new_transform; + new_transform = xr_server->get_reference_frame() * new_transform; }; return new_transform; }; -real_t ARVRPositionalTracker::get_rumble() const { +real_t XRPositionalTracker::get_rumble() const { return rumble; }; -void ARVRPositionalTracker::set_rumble(real_t p_rumble) { +void XRPositionalTracker::set_rumble(real_t p_rumble) { if (p_rumble > 0.0) { rumble = p_rumble; } else { @@ -221,8 +221,8 @@ void ARVRPositionalTracker::set_rumble(real_t p_rumble) { }; }; -ARVRPositionalTracker::ARVRPositionalTracker() { - type = ARVRServer::TRACKER_UNKNOWN; +XRPositionalTracker::XRPositionalTracker() { + type = XRServer::TRACKER_UNKNOWN; name = "Unknown"; joy_id = -1; tracker_id = 0; @@ -232,6 +232,6 @@ ARVRPositionalTracker::ARVRPositionalTracker() { rumble = 0.0; }; -ARVRPositionalTracker::~ARVRPositionalTracker(){ +XRPositionalTracker::~XRPositionalTracker(){ }; diff --git a/servers/arvr/arvr_positional_tracker.h b/servers/xr/xr_positional_tracker.h index 03c6b33ffe..d9d1f909e9 100644 --- a/servers/arvr/arvr_positional_tracker.h +++ b/servers/xr/xr_positional_tracker.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* arvr_positional_tracker.h */ +/* xr_positional_tracker.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,12 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef ARVR_POSITIONAL_TRACKER_H -#define ARVR_POSITIONAL_TRACKER_H +#ifndef XR_POSITIONAL_TRACKER_H +#define XR_POSITIONAL_TRACKER_H #include "core/os/thread_safe.h" #include "scene/resources/mesh.h" -#include "servers/arvr_server.h" +#include "servers/xr_server.h" /** @author Bastiaan Olij <mux213@gmail.com> @@ -43,8 +43,8 @@ This is where potentially additional AR/VR interfaces may be active as there are AR/VR SDKs that solely deal with positional tracking. */ -class ARVRPositionalTracker : public Object { - GDCLASS(ARVRPositionalTracker, Object); +class XRPositionalTracker : public Object { + GDCLASS(XRPositionalTracker, Object); _THREAD_SAFE_CLASS_ public: @@ -55,7 +55,7 @@ public: }; private: - ARVRServer::TrackerType type; // type of tracker + XRServer::TrackerType type; // type of tracker StringName name; // (unique) name of the tracker int tracker_id; // tracker index id that is unique per type int joy_id; // if we also have a related joystick entity, the id of the joystick @@ -65,14 +65,14 @@ private: Vector3 rw_position; // our position "in the real world, so without world_scale applied" Ref<Mesh> mesh; // when available, a mesh that can be used to render this tracker TrackerHand hand; // if known, the hand this tracker is held in - real_t rumble; // rumble strength, 0.0 is off, 1.0 is maximum, note that we only record here, arvr_interface is responsible for execution + real_t rumble; // rumble strength, 0.0 is off, 1.0 is maximum, note that we only record here, xr_interface is responsible for execution protected: static void _bind_methods(); public: - void set_type(ARVRServer::TrackerType p_type); - ARVRServer::TrackerType get_type() const; + void set_type(XRServer::TrackerType p_type); + XRServer::TrackerType get_type() const; void set_name(const String &p_name); StringName get_name() const; int get_tracker_id() const; @@ -86,8 +86,8 @@ public: Vector3 get_position() const; // get position with world_scale applied void set_rw_position(const Vector3 &p_rw_position); Vector3 get_rw_position() const; - ARVRPositionalTracker::TrackerHand get_hand() const; - void set_hand(const ARVRPositionalTracker::TrackerHand p_hand); + XRPositionalTracker::TrackerHand get_hand() const; + void set_hand(const XRPositionalTracker::TrackerHand p_hand); real_t get_rumble() const; void set_rumble(real_t p_rumble); void set_mesh(const Ref<Mesh> &p_mesh); @@ -95,10 +95,10 @@ public: Transform get_transform(bool p_adjust_by_reference_frame) const; - ARVRPositionalTracker(); - ~ARVRPositionalTracker(); + XRPositionalTracker(); + ~XRPositionalTracker(); }; -VARIANT_ENUM_CAST(ARVRPositionalTracker::TrackerHand); +VARIANT_ENUM_CAST(XRPositionalTracker::TrackerHand); #endif diff --git a/servers/arvr_server.cpp b/servers/xr_server.cpp index f5597d8974..a93b99025f 100644 --- a/servers/arvr_server.cpp +++ b/servers/xr_server.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* arvr_server.cpp */ +/* xr_server.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,41 +28,41 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "arvr_server.h" -#include "arvr/arvr_interface.h" -#include "arvr/arvr_positional_tracker.h" +#include "xr_server.h" #include "core/project_settings.h" +#include "xr/xr_interface.h" +#include "xr/xr_positional_tracker.h" -ARVRServer *ARVRServer::singleton = nullptr; +XRServer *XRServer::singleton = nullptr; -ARVRServer *ARVRServer::get_singleton() { +XRServer *XRServer::get_singleton() { return singleton; }; -void ARVRServer::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_world_scale"), &ARVRServer::get_world_scale); - ClassDB::bind_method(D_METHOD("set_world_scale"), &ARVRServer::set_world_scale); - ClassDB::bind_method(D_METHOD("get_reference_frame"), &ARVRServer::get_reference_frame); - ClassDB::bind_method(D_METHOD("center_on_hmd", "rotation_mode", "keep_height"), &ARVRServer::center_on_hmd); - ClassDB::bind_method(D_METHOD("get_hmd_transform"), &ARVRServer::get_hmd_transform); +void XRServer::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_world_scale"), &XRServer::get_world_scale); + ClassDB::bind_method(D_METHOD("set_world_scale"), &XRServer::set_world_scale); + ClassDB::bind_method(D_METHOD("get_reference_frame"), &XRServer::get_reference_frame); + ClassDB::bind_method(D_METHOD("center_on_hmd", "rotation_mode", "keep_height"), &XRServer::center_on_hmd); + ClassDB::bind_method(D_METHOD("get_hmd_transform"), &XRServer::get_hmd_transform); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "world_scale"), "set_world_scale", "get_world_scale"); - ClassDB::bind_method(D_METHOD("get_interface_count"), &ARVRServer::get_interface_count); - ClassDB::bind_method(D_METHOD("get_interface", "idx"), &ARVRServer::get_interface); - ClassDB::bind_method(D_METHOD("get_interfaces"), &ARVRServer::get_interfaces); - ClassDB::bind_method(D_METHOD("find_interface", "name"), &ARVRServer::find_interface); - ClassDB::bind_method(D_METHOD("get_tracker_count"), &ARVRServer::get_tracker_count); - ClassDB::bind_method(D_METHOD("get_tracker", "idx"), &ARVRServer::get_tracker); + ClassDB::bind_method(D_METHOD("get_interface_count"), &XRServer::get_interface_count); + ClassDB::bind_method(D_METHOD("get_interface", "idx"), &XRServer::get_interface); + ClassDB::bind_method(D_METHOD("get_interfaces"), &XRServer::get_interfaces); + ClassDB::bind_method(D_METHOD("find_interface", "name"), &XRServer::find_interface); + ClassDB::bind_method(D_METHOD("get_tracker_count"), &XRServer::get_tracker_count); + ClassDB::bind_method(D_METHOD("get_tracker", "idx"), &XRServer::get_tracker); - ClassDB::bind_method(D_METHOD("get_primary_interface"), &ARVRServer::get_primary_interface); - ClassDB::bind_method(D_METHOD("set_primary_interface", "interface"), &ARVRServer::set_primary_interface); + ClassDB::bind_method(D_METHOD("get_primary_interface"), &XRServer::get_primary_interface); + ClassDB::bind_method(D_METHOD("set_primary_interface", "interface"), &XRServer::set_primary_interface); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "primary_interface"), "set_primary_interface", "get_primary_interface"); - ClassDB::bind_method(D_METHOD("get_last_process_usec"), &ARVRServer::get_last_process_usec); - ClassDB::bind_method(D_METHOD("get_last_commit_usec"), &ARVRServer::get_last_commit_usec); - ClassDB::bind_method(D_METHOD("get_last_frame_usec"), &ARVRServer::get_last_frame_usec); + ClassDB::bind_method(D_METHOD("get_last_process_usec"), &XRServer::get_last_process_usec); + ClassDB::bind_method(D_METHOD("get_last_commit_usec"), &XRServer::get_last_commit_usec); + ClassDB::bind_method(D_METHOD("get_last_frame_usec"), &XRServer::get_last_frame_usec); BIND_ENUM_CONSTANT(TRACKER_CONTROLLER); BIND_ENUM_CONSTANT(TRACKER_BASESTATION); @@ -82,11 +82,11 @@ void ARVRServer::_bind_methods() { ADD_SIGNAL(MethodInfo("tracker_removed", PropertyInfo(Variant::STRING_NAME, "tracker_name"), PropertyInfo(Variant::INT, "type"), PropertyInfo(Variant::INT, "id"))); }; -real_t ARVRServer::get_world_scale() const { +real_t XRServer::get_world_scale() const { return world_scale; }; -void ARVRServer::set_world_scale(real_t p_world_scale) { +void XRServer::set_world_scale(real_t p_world_scale) { if (p_world_scale < 0.01) { p_world_scale = 0.01; } else if (p_world_scale > 1000.0) { @@ -96,25 +96,25 @@ void ARVRServer::set_world_scale(real_t p_world_scale) { world_scale = p_world_scale; }; -Transform ARVRServer::get_world_origin() const { +Transform XRServer::get_world_origin() const { return world_origin; }; -void ARVRServer::set_world_origin(const Transform &p_world_origin) { +void XRServer::set_world_origin(const Transform &p_world_origin) { world_origin = p_world_origin; }; -Transform ARVRServer::get_reference_frame() const { +Transform XRServer::get_reference_frame() const { return reference_frame; }; -void ARVRServer::center_on_hmd(RotationMode p_rotation_mode, bool p_keep_height) { +void XRServer::center_on_hmd(RotationMode p_rotation_mode, bool p_keep_height) { if (primary_interface != nullptr) { // clear our current reference frame or we'll end up double adjusting it reference_frame = Transform(); // requesting our EYE_MONO transform should return our current HMD position - Transform new_reference_frame = primary_interface->get_transform_for_eye(ARVRInterface::EYE_MONO, Transform()); + Transform new_reference_frame = primary_interface->get_transform_for_eye(XRInterface::EYE_MONO, Transform()); // remove our tilt if (p_rotation_mode == 1) { @@ -140,15 +140,15 @@ void ARVRServer::center_on_hmd(RotationMode p_rotation_mode, bool p_keep_height) }; }; -Transform ARVRServer::get_hmd_transform() { +Transform XRServer::get_hmd_transform() { Transform hmd_transform; if (primary_interface != nullptr) { - hmd_transform = primary_interface->get_transform_for_eye(ARVRInterface::EYE_MONO, hmd_transform); + hmd_transform = primary_interface->get_transform_for_eye(XRInterface::EYE_MONO, hmd_transform); }; return hmd_transform; }; -void ARVRServer::add_interface(const Ref<ARVRInterface> &p_interface) { +void XRServer::add_interface(const Ref<XRInterface> &p_interface) { ERR_FAIL_COND(p_interface.is_null()); for (int i = 0; i < interfaces.size(); i++) { @@ -163,7 +163,7 @@ void ARVRServer::add_interface(const Ref<ARVRInterface> &p_interface) { emit_signal("interface_added", p_interface->get_name()); }; -void ARVRServer::remove_interface(const Ref<ARVRInterface> &p_interface) { +void XRServer::remove_interface(const Ref<XRInterface> &p_interface) { ERR_FAIL_COND(p_interface.is_null()); int idx = -1; @@ -178,23 +178,23 @@ void ARVRServer::remove_interface(const Ref<ARVRInterface> &p_interface) { ERR_FAIL_COND(idx == -1); - print_verbose("ARVR: Removed interface" + p_interface->get_name()); + print_verbose("XR: Removed interface" + p_interface->get_name()); emit_signal("interface_removed", p_interface->get_name()); interfaces.remove(idx); }; -int ARVRServer::get_interface_count() const { +int XRServer::get_interface_count() const { return interfaces.size(); }; -Ref<ARVRInterface> ARVRServer::get_interface(int p_index) const { +Ref<XRInterface> XRServer::get_interface(int p_index) const { ERR_FAIL_INDEX_V(p_index, interfaces.size(), nullptr); return interfaces[p_index]; }; -Ref<ARVRInterface> ARVRServer::find_interface(const String &p_name) const { +Ref<XRInterface> XRServer::find_interface(const String &p_name) const { int idx = -1; for (int i = 0; i < interfaces.size(); i++) { @@ -210,7 +210,7 @@ Ref<ARVRInterface> ARVRServer::find_interface(const String &p_name) const { return interfaces[idx]; }; -Array ARVRServer::get_interfaces() const { +Array XRServer::get_interfaces() const { Array ret; for (int i = 0; i < interfaces.size(); i++) { @@ -238,7 +238,7 @@ Array ARVRServer::get_interfaces() const { - using this approach the shield disappears or is no longer tracked, but the gun stays firmly in your right hand because that is still controller 2, further more, if controller 1 is replaced the shield will return. */ -bool ARVRServer::is_tracker_id_in_use_for_type(TrackerType p_tracker_type, int p_tracker_id) const { +bool XRServer::is_tracker_id_in_use_for_type(TrackerType p_tracker_type, int p_tracker_id) const { for (int i = 0; i < trackers.size(); i++) { if (trackers[i]->get_type() == p_tracker_type && trackers[i]->get_tracker_id() == p_tracker_id) { return true; @@ -249,13 +249,13 @@ bool ARVRServer::is_tracker_id_in_use_for_type(TrackerType p_tracker_type, int p return false; }; -int ARVRServer::get_free_tracker_id_for_type(TrackerType p_tracker_type) { +int XRServer::get_free_tracker_id_for_type(TrackerType p_tracker_type) { // We start checking at 1, 0 means that it's not a controller.. // Note that for controller we reserve: // - 1 for the left hand controller and // - 2 for the right hand controller // so we start at 3 :) - int tracker_id = p_tracker_type == ARVRServer::TRACKER_CONTROLLER ? 3 : 1; + int tracker_id = p_tracker_type == XRServer::TRACKER_CONTROLLER ? 3 : 1; while (is_tracker_id_in_use_for_type(p_tracker_type, tracker_id)) { // try the next one @@ -265,14 +265,14 @@ int ARVRServer::get_free_tracker_id_for_type(TrackerType p_tracker_type) { return tracker_id; }; -void ARVRServer::add_tracker(ARVRPositionalTracker *p_tracker) { +void XRServer::add_tracker(XRPositionalTracker *p_tracker) { ERR_FAIL_NULL(p_tracker); trackers.push_back(p_tracker); emit_signal("tracker_added", p_tracker->get_name(), p_tracker->get_type(), p_tracker->get_tracker_id()); }; -void ARVRServer::remove_tracker(ARVRPositionalTracker *p_tracker) { +void XRServer::remove_tracker(XRPositionalTracker *p_tracker) { ERR_FAIL_NULL(p_tracker); int idx = -1; @@ -291,17 +291,17 @@ void ARVRServer::remove_tracker(ARVRPositionalTracker *p_tracker) { trackers.remove(idx); }; -int ARVRServer::get_tracker_count() const { +int XRServer::get_tracker_count() const { return trackers.size(); }; -ARVRPositionalTracker *ARVRServer::get_tracker(int p_index) const { +XRPositionalTracker *XRServer::get_tracker(int p_index) const { ERR_FAIL_INDEX_V(p_index, trackers.size(), nullptr); return trackers[p_index]; }; -ARVRPositionalTracker *ARVRServer::find_by_type_and_id(TrackerType p_tracker_type, int p_tracker_id) const { +XRPositionalTracker *XRServer::find_by_type_and_id(TrackerType p_tracker_type, int p_tracker_id) const { ERR_FAIL_COND_V(p_tracker_id == 0, nullptr); for (int i = 0; i < trackers.size(); i++) { @@ -313,36 +313,36 @@ ARVRPositionalTracker *ARVRServer::find_by_type_and_id(TrackerType p_tracker_typ return nullptr; }; -Ref<ARVRInterface> ARVRServer::get_primary_interface() const { +Ref<XRInterface> XRServer::get_primary_interface() const { return primary_interface; }; -void ARVRServer::set_primary_interface(const Ref<ARVRInterface> &p_primary_interface) { +void XRServer::set_primary_interface(const Ref<XRInterface> &p_primary_interface) { primary_interface = p_primary_interface; - print_verbose("ARVR: Primary interface set to: " + primary_interface->get_name()); + print_verbose("XR: Primary interface set to: " + primary_interface->get_name()); }; -void ARVRServer::clear_primary_interface_if(const Ref<ARVRInterface> &p_primary_interface) { +void XRServer::clear_primary_interface_if(const Ref<XRInterface> &p_primary_interface) { if (primary_interface == p_primary_interface) { - print_verbose("ARVR: Clearing primary interface"); + print_verbose("XR: Clearing primary interface"); primary_interface.unref(); }; }; -uint64_t ARVRServer::get_last_process_usec() { +uint64_t XRServer::get_last_process_usec() { return last_process_usec; }; -uint64_t ARVRServer::get_last_commit_usec() { +uint64_t XRServer::get_last_commit_usec() { return last_commit_usec; }; -uint64_t ARVRServer::get_last_frame_usec() { +uint64_t XRServer::get_last_frame_usec() { return last_frame_usec; }; -void ARVRServer::_process() { +void XRServer::_process() { /* called from rendering_server_viewport.draw_viewports right before we start drawing our viewports */ /* mark for our frame timing */ @@ -358,7 +358,7 @@ void ARVRServer::_process() { }; }; -void ARVRServer::_mark_commit() { +void XRServer::_mark_commit() { /* time this */ last_commit_usec = OS::get_singleton()->get_ticks_usec(); @@ -366,12 +366,12 @@ void ARVRServer::_mark_commit() { last_frame_usec = last_commit_usec - last_process_usec; }; -ARVRServer::ARVRServer() { +XRServer::XRServer() { singleton = this; world_scale = 1.0; }; -ARVRServer::~ARVRServer() { +XRServer::~XRServer() { primary_interface.unref(); while (interfaces.size() > 0) { diff --git a/servers/arvr_server.h b/servers/xr_server.h index ab2f0d721b..e04c7b3592 100644 --- a/servers/arvr_server.h +++ b/servers/xr_server.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* arvr_server.h */ +/* xr_server.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef ARVR_SERVER_H -#define ARVR_SERVER_H +#ifndef XR_SERVER_H +#define XR_SERVER_H #include "core/os/os.h" #include "core/os/thread_safe.h" @@ -37,16 +37,16 @@ #include "core/rid.h" #include "core/variant.h" -class ARVRInterface; -class ARVRPositionalTracker; +class XRInterface; +class XRPositionalTracker; /** @author Bastiaan Olij <mux213@gmail.com> - The ARVR server is a singleton object that gives access to the various + The XR server is a singleton object that gives access to the various objects and SDKs that are available on the system. Because there can be multiple SDKs active this is exposed as an array - and our ARVR server object acts as a pass through + and our XR server object acts as a pass through Also each positioning tracker is accessible from here. I've added some additional info into this header file that should move @@ -54,8 +54,8 @@ class ARVRPositionalTracker; or as a separate PR once this has been merged into the master branch. **/ -class ARVRServer : public Object { - GDCLASS(ARVRServer, Object); +class XRServer : public Object { + GDCLASS(XRServer, Object); _THREAD_SAFE_CLASS_ public: @@ -76,10 +76,10 @@ public: }; private: - Vector<Ref<ARVRInterface>> interfaces; - Vector<ARVRPositionalTracker *> trackers; + Vector<Ref<XRInterface>> interfaces; + Vector<XRPositionalTracker *> trackers; - Ref<ARVRInterface> primary_interface; /* we'll identify one interface as primary, this will be used by our viewports */ + Ref<XRInterface> primary_interface; /* we'll identify one interface as primary, this will be used by our viewports */ real_t world_scale; /* scale by which we multiply our tracker positions */ Transform world_origin; /* our world origin point, maps a location in our virtual world to the origin point in our real world tracking volume */ @@ -90,12 +90,12 @@ private: uint64_t last_frame_usec; /* time it took between process and committing, we should probably average this over the last x frames */ protected: - static ARVRServer *singleton; + static XRServer *singleton; static void _bind_methods(); public: - static ARVRServer *get_singleton(); + static XRServer *get_singleton(); /* World scale allows you to specify a scale factor that is applied to all positioning vectors in our VR world in essence scaling up, or scaling down the world. @@ -105,7 +105,7 @@ public: Most VR platforms, and our assumption, is that 1 unit in our virtual world equates to 1 meter in the real mode. This scale basically effects the unit size relationship to real world size. - I may remove access to this property in GDScript in favour of exposing it on the ARVROrigin node + I may remove access to this property in GDScript in favour of exposing it on the XROrigin3D node */ real_t get_world_scale() const; void set_world_scale(real_t p_world_scale); @@ -116,7 +116,7 @@ public: actions be it straffing, teleporting, etc. Movement of the player by moving through the physical space is always tracked in relation to this point. - Note that the ARVROrigin spatial node in your scene automatically updates this property and it should be used instead of + Note that the XROrigin3D spatial node in your scene automatically updates this property and it should be used instead of direct access to this property and it therefore is not available in GDScript Note: this should not be used in AR and should be ignored by an AR based interface as it would throw what you're looking at in the real world @@ -146,20 +146,20 @@ public: /* Interfaces are objects that 'glue' Godot to an AR or VR SDK such as the Oculus SDK, OpenVR, OpenHMD, etc. */ - void add_interface(const Ref<ARVRInterface> &p_interface); - void remove_interface(const Ref<ARVRInterface> &p_interface); + void add_interface(const Ref<XRInterface> &p_interface); + void remove_interface(const Ref<XRInterface> &p_interface); int get_interface_count() const; - Ref<ARVRInterface> get_interface(int p_index) const; - Ref<ARVRInterface> find_interface(const String &p_name) const; + Ref<XRInterface> get_interface(int p_index) const; + Ref<XRInterface> find_interface(const String &p_name) const; Array get_interfaces() const; /* note, more then one interface can technically be active, especially on mobile, but only one interface is used for rendering. This interface identifies itself by calling set_primary_interface when it is initialized */ - Ref<ARVRInterface> get_primary_interface() const; - void set_primary_interface(const Ref<ARVRInterface> &p_primary_interface); - void clear_primary_interface_if(const Ref<ARVRInterface> &p_primary_interface); /* this is automatically called if an interface destructs */ + Ref<XRInterface> get_primary_interface() const; + void set_primary_interface(const Ref<XRInterface> &p_primary_interface); + void clear_primary_interface_if(const Ref<XRInterface> &p_primary_interface); /* this is automatically called if an interface destructs */ /* Our trackers are objects that expose the orientation and position of physical devices such as controller, anchor points, etc. @@ -167,11 +167,11 @@ public: */ bool is_tracker_id_in_use_for_type(TrackerType p_tracker_type, int p_tracker_id) const; int get_free_tracker_id_for_type(TrackerType p_tracker_type); - void add_tracker(ARVRPositionalTracker *p_tracker); - void remove_tracker(ARVRPositionalTracker *p_tracker); + void add_tracker(XRPositionalTracker *p_tracker); + void remove_tracker(XRPositionalTracker *p_tracker); int get_tracker_count() const; - ARVRPositionalTracker *get_tracker(int p_index) const; - ARVRPositionalTracker *find_by_type_and_id(TrackerType p_tracker_type, int p_tracker_id) const; + XRPositionalTracker *get_tracker(int p_index) const; + XRPositionalTracker *find_by_type_and_id(TrackerType p_tracker_type, int p_tracker_id) const; uint64_t get_last_process_usec(); uint64_t get_last_commit_usec(); @@ -180,13 +180,13 @@ public: void _process(); void _mark_commit(); - ARVRServer(); - ~ARVRServer(); + XRServer(); + ~XRServer(); }; -#define ARVR ARVRServer +#define XR XRServer -VARIANT_ENUM_CAST(ARVRServer::TrackerType); -VARIANT_ENUM_CAST(ARVRServer::RotationMode); +VARIANT_ENUM_CAST(XRServer::TrackerType); +VARIANT_ENUM_CAST(XRServer::RotationMode); #endif diff --git a/thirdparty/README.md b/thirdparty/README.md index 95a6902089..3c6885fd1a 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -182,12 +182,14 @@ Patches in the `patches` directory should be re-applied after updates. ## jpeg-compressor - Upstream: https://github.com/richgel999/jpeg-compressor -- Version: 1.04 +- Version: 2.00 (1eb17d558b9d3b7442d256642a5745974e9eeb1e, 2020) - License: Public domain Files extracted from upstream source: -- `jpgd.{c,h}` +- `jpgd*.{c,h}` + +Patches in the `patches` directory should be re-applied after updates. ## libogg @@ -302,7 +304,7 @@ changes are marked with `// -- GODOT --` comments. ## mbedtls - Upstream: https://tls.mbed.org/ -- Version: 2.16.5 +- Version: 2.16.6 - License: Apache 2.0 File extracted from upstream release tarball (`-apache.tgz` variant): diff --git a/thirdparty/jpeg-compressor/jpgd.cpp b/thirdparty/jpeg-compressor/jpgd.cpp index 62fbd1b72d..257d0b7574 100644 --- a/thirdparty/jpeg-compressor/jpgd.cpp +++ b/thirdparty/jpeg-compressor/jpgd.cpp @@ -1,27 +1,55 @@ -// jpgd.cpp - C++ class for JPEG decompression. -// Public domain, Rich Geldreich <richgel99@gmail.com> +// jpgd.cpp - C++ class for JPEG decompression. Written by Richard Geldreich <richgel99@gmail.com> between 1994-2020. +// Supports progressive and baseline sequential JPEG image files, and the most common chroma subsampling factors: Y, H1V1, H2V1, H1V2, and H2V2. +// Supports box and linear chroma upsampling. +// +// Released under two licenses. You are free to choose which license you want: +// License 1: +// Public Domain +// +// License 2: +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// // Alex Evans: Linear memory allocator (taken from jpge.h). -// v1.04, May. 19, 2012: Code tweaks to fix VS2008 static code analysis warnings (all looked harmless) +// v1.04, May. 19, 2012: Code tweaks to fix VS2008 static code analysis warnings +// v2.00, March 20, 2020: Fuzzed with zzuf and afl. Fixed several issues, converted most assert()'s to run-time checks. Added chroma upsampling. Removed freq. domain upsampling. gcc/clang warnings. // -// Supports progressive and baseline sequential JPEG image files, and the most common chroma subsampling factors: Y, H1V1, H2V1, H1V2, and H2V2. +// Important: +// #define JPGD_USE_SSE2 to 0 to completely disable SSE2 usage. // -// Chroma upsampling quality: H2V2 is upsampled in the frequency domain, H2V1 and H1V2 are upsampled using point sampling. -// Chroma upsampling reference: "Fast Scheme for Image Size Change in the Compressed Domain" -// http://vision.ai.uiuc.edu/~dugad/research/dct/index.html - #include "jpgd.h" #include <string.h> - +#include <algorithm> #include <assert.h> -#define JPGD_ASSERT(x) assert(x) #ifdef _MSC_VER #pragma warning (disable : 4611) // warning C4611: interaction between '_setjmp' and C++ object destruction is non-portable #endif -// Set to 1 to enable freq. domain chroma upsampling on images using H2V2 subsampling (0=faster nearest neighbor sampling). -// This is slower, but results in higher quality on images with highly saturated colors. -#define JPGD_SUPPORT_FREQ_DOMAIN_UPSAMPLING 1 +#ifndef JPGD_USE_SSE2 + + #if defined(__GNUC__) + + #if (defined(__x86_64__) || defined(_M_X64)) + #if defined(__SSE2__) + #define JPGD_USE_SSE2 (1) + #endif + #endif + + #else + #define JPGD_USE_SSE2 (1) + #endif + +#endif #define JPGD_TRUE (1) #define JPGD_FALSE (0) @@ -29,28 +57,28 @@ #define JPGD_MAX(a,b) (((a)>(b)) ? (a) : (b)) #define JPGD_MIN(a,b) (((a)<(b)) ? (a) : (b)) -// TODO: Move to header and use these constants when declaring the arrays. -#define JPGD_HUFF_TREE_MAX_LENGTH 512 -#define JPGD_HUFF_CODE_SIZE_MAX_LENGTH 256 - namespace jpgd { -static inline void *jpgd_malloc(size_t nSize) { return malloc(nSize); } -static inline void jpgd_free(void *p) { free(p); } + static inline void* jpgd_malloc(size_t nSize) { return malloc(nSize); } + static inline void jpgd_free(void* p) { free(p); } -// DCT coefficients are stored in this sequence. -static int g_ZAG[64] = { 0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5,12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28,35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63 }; + // DCT coefficients are stored in this sequence. + static int g_ZAG[64] = { 0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5,12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28,35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63 }; -enum JPEG_MARKER -{ - M_SOF0 = 0xC0, M_SOF1 = 0xC1, M_SOF2 = 0xC2, M_SOF3 = 0xC3, M_SOF5 = 0xC5, M_SOF6 = 0xC6, M_SOF7 = 0xC7, M_JPG = 0xC8, - M_SOF9 = 0xC9, M_SOF10 = 0xCA, M_SOF11 = 0xCB, M_SOF13 = 0xCD, M_SOF14 = 0xCE, M_SOF15 = 0xCF, M_DHT = 0xC4, M_DAC = 0xCC, - M_RST0 = 0xD0, M_RST1 = 0xD1, M_RST2 = 0xD2, M_RST3 = 0xD3, M_RST4 = 0xD4, M_RST5 = 0xD5, M_RST6 = 0xD6, M_RST7 = 0xD7, - M_SOI = 0xD8, M_EOI = 0xD9, M_SOS = 0xDA, M_DQT = 0xDB, M_DNL = 0xDC, M_DRI = 0xDD, M_DHP = 0xDE, M_EXP = 0xDF, - M_APP0 = 0xE0, M_APP15 = 0xEF, M_JPG0 = 0xF0, M_JPG13 = 0xFD, M_COM = 0xFE, M_TEM = 0x01, M_ERROR = 0x100, RST0 = 0xD0 -}; + enum JPEG_MARKER + { + M_SOF0 = 0xC0, M_SOF1 = 0xC1, M_SOF2 = 0xC2, M_SOF3 = 0xC3, M_SOF5 = 0xC5, M_SOF6 = 0xC6, M_SOF7 = 0xC7, M_JPG = 0xC8, + M_SOF9 = 0xC9, M_SOF10 = 0xCA, M_SOF11 = 0xCB, M_SOF13 = 0xCD, M_SOF14 = 0xCE, M_SOF15 = 0xCF, M_DHT = 0xC4, M_DAC = 0xCC, + M_RST0 = 0xD0, M_RST1 = 0xD1, M_RST2 = 0xD2, M_RST3 = 0xD3, M_RST4 = 0xD4, M_RST5 = 0xD5, M_RST6 = 0xD6, M_RST7 = 0xD7, + M_SOI = 0xD8, M_EOI = 0xD9, M_SOS = 0xDA, M_DQT = 0xDB, M_DNL = 0xDC, M_DRI = 0xDD, M_DHP = 0xDE, M_EXP = 0xDF, + M_APP0 = 0xE0, M_APP15 = 0xEF, M_JPG0 = 0xF0, M_JPG13 = 0xFD, M_COM = 0xFE, M_TEM = 0x01, M_ERROR = 0x100, RST0 = 0xD0 + }; -enum JPEG_SUBSAMPLING { JPGD_GRAYSCALE = 0, JPGD_YH1V1, JPGD_YH2V1, JPGD_YH1V2, JPGD_YH2V2 }; + enum JPEG_SUBSAMPLING { JPGD_GRAYSCALE = 0, JPGD_YH1V1, JPGD_YH2V1, JPGD_YH1V2, JPGD_YH2V2 }; + +#if JPGD_USE_SSE2 +#include "jpgd_idct.h" +#endif #define CONST_BITS 13 #define PASS1_BITS 2 @@ -76,3130 +104,3182 @@ enum JPEG_SUBSAMPLING { JPGD_GRAYSCALE = 0, JPGD_YH1V1, JPGD_YH2V1, JPGD_YH1V2, #define CLAMP(i) ((static_cast<uint>(i) > 255) ? (((~i) >> 31) & 0xFF) : (i)) -// Compiler creates a fast path 1D IDCT for X non-zero columns -template <int NONZERO_COLS> -struct Row -{ - static void idct(int* pTemp, const jpgd_block_t* pSrc) - { - // ACCESS_COL() will be optimized at compile time to either an array access, or 0. - #define ACCESS_COL(x) (((x) < NONZERO_COLS) ? (int)pSrc[x] : 0) - - const int z2 = ACCESS_COL(2), z3 = ACCESS_COL(6); - - const int z1 = MULTIPLY(z2 + z3, FIX_0_541196100); - const int tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065); - const int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); - - const int tmp0 = (ACCESS_COL(0) + ACCESS_COL(4)) << CONST_BITS; - const int tmp1 = (ACCESS_COL(0) - ACCESS_COL(4)) << CONST_BITS; - - const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2; - - const int atmp0 = ACCESS_COL(7), atmp1 = ACCESS_COL(5), atmp2 = ACCESS_COL(3), atmp3 = ACCESS_COL(1); - - const int bz1 = atmp0 + atmp3, bz2 = atmp1 + atmp2, bz3 = atmp0 + atmp2, bz4 = atmp1 + atmp3; - const int bz5 = MULTIPLY(bz3 + bz4, FIX_1_175875602); - - const int az1 = MULTIPLY(bz1, - FIX_0_899976223); - const int az2 = MULTIPLY(bz2, - FIX_2_562915447); - const int az3 = MULTIPLY(bz3, - FIX_1_961570560) + bz5; - const int az4 = MULTIPLY(bz4, - FIX_0_390180644) + bz5; - - const int btmp0 = MULTIPLY(atmp0, FIX_0_298631336) + az1 + az3; - const int btmp1 = MULTIPLY(atmp1, FIX_2_053119869) + az2 + az4; - const int btmp2 = MULTIPLY(atmp2, FIX_3_072711026) + az2 + az3; - const int btmp3 = MULTIPLY(atmp3, FIX_1_501321110) + az1 + az4; - - pTemp[0] = DESCALE(tmp10 + btmp3, CONST_BITS-PASS1_BITS); - pTemp[7] = DESCALE(tmp10 - btmp3, CONST_BITS-PASS1_BITS); - pTemp[1] = DESCALE(tmp11 + btmp2, CONST_BITS-PASS1_BITS); - pTemp[6] = DESCALE(tmp11 - btmp2, CONST_BITS-PASS1_BITS); - pTemp[2] = DESCALE(tmp12 + btmp1, CONST_BITS-PASS1_BITS); - pTemp[5] = DESCALE(tmp12 - btmp1, CONST_BITS-PASS1_BITS); - pTemp[3] = DESCALE(tmp13 + btmp0, CONST_BITS-PASS1_BITS); - pTemp[4] = DESCALE(tmp13 - btmp0, CONST_BITS-PASS1_BITS); - } -}; - -template <> -struct Row<0> -{ - static void idct(int* pTemp, const jpgd_block_t* pSrc) - { -#ifdef _MSC_VER - pTemp; pSrc; + static inline int left_shifti(int val, uint32_t bits) + { + return static_cast<int>(static_cast<uint32_t>(val) << bits); + } + + // Compiler creates a fast path 1D IDCT for X non-zero columns + template <int NONZERO_COLS> + struct Row + { + static void idct(int* pTemp, const jpgd_block_coeff_t* pSrc) + { + // ACCESS_COL() will be optimized at compile time to either an array access, or 0. Good compilers will then optimize out muls against 0. +#define ACCESS_COL(x) (((x) < NONZERO_COLS) ? (int)pSrc[x] : 0) + + const int z2 = ACCESS_COL(2), z3 = ACCESS_COL(6); + + const int z1 = MULTIPLY(z2 + z3, FIX_0_541196100); + const int tmp2 = z1 + MULTIPLY(z3, -FIX_1_847759065); + const int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); + + const int tmp0 = left_shifti(ACCESS_COL(0) + ACCESS_COL(4), CONST_BITS); + const int tmp1 = left_shifti(ACCESS_COL(0) - ACCESS_COL(4), CONST_BITS); + + const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2; + + const int atmp0 = ACCESS_COL(7), atmp1 = ACCESS_COL(5), atmp2 = ACCESS_COL(3), atmp3 = ACCESS_COL(1); + + const int bz1 = atmp0 + atmp3, bz2 = atmp1 + atmp2, bz3 = atmp0 + atmp2, bz4 = atmp1 + atmp3; + const int bz5 = MULTIPLY(bz3 + bz4, FIX_1_175875602); + + const int az1 = MULTIPLY(bz1, -FIX_0_899976223); + const int az2 = MULTIPLY(bz2, -FIX_2_562915447); + const int az3 = MULTIPLY(bz3, -FIX_1_961570560) + bz5; + const int az4 = MULTIPLY(bz4, -FIX_0_390180644) + bz5; + + const int btmp0 = MULTIPLY(atmp0, FIX_0_298631336) + az1 + az3; + const int btmp1 = MULTIPLY(atmp1, FIX_2_053119869) + az2 + az4; + const int btmp2 = MULTIPLY(atmp2, FIX_3_072711026) + az2 + az3; + const int btmp3 = MULTIPLY(atmp3, FIX_1_501321110) + az1 + az4; + + pTemp[0] = DESCALE(tmp10 + btmp3, CONST_BITS - PASS1_BITS); + pTemp[7] = DESCALE(tmp10 - btmp3, CONST_BITS - PASS1_BITS); + pTemp[1] = DESCALE(tmp11 + btmp2, CONST_BITS - PASS1_BITS); + pTemp[6] = DESCALE(tmp11 - btmp2, CONST_BITS - PASS1_BITS); + pTemp[2] = DESCALE(tmp12 + btmp1, CONST_BITS - PASS1_BITS); + pTemp[5] = DESCALE(tmp12 - btmp1, CONST_BITS - PASS1_BITS); + pTemp[3] = DESCALE(tmp13 + btmp0, CONST_BITS - PASS1_BITS); + pTemp[4] = DESCALE(tmp13 - btmp0, CONST_BITS - PASS1_BITS); + } + }; + + template <> + struct Row<0> + { + static void idct(int* pTemp, const jpgd_block_coeff_t* pSrc) + { + (void)pTemp; + (void)pSrc; + } + }; + + template <> + struct Row<1> + { + static void idct(int* pTemp, const jpgd_block_coeff_t* pSrc) + { + const int dcval = left_shifti(pSrc[0], PASS1_BITS); + + pTemp[0] = dcval; + pTemp[1] = dcval; + pTemp[2] = dcval; + pTemp[3] = dcval; + pTemp[4] = dcval; + pTemp[5] = dcval; + pTemp[6] = dcval; + pTemp[7] = dcval; + } + }; + + // Compiler creates a fast path 1D IDCT for X non-zero rows + template <int NONZERO_ROWS> + struct Col + { + static void idct(uint8* pDst_ptr, const int* pTemp) + { + // ACCESS_ROW() will be optimized at compile time to either an array access, or 0. +#define ACCESS_ROW(x) (((x) < NONZERO_ROWS) ? pTemp[x * 8] : 0) + + const int z2 = ACCESS_ROW(2); + const int z3 = ACCESS_ROW(6); + + const int z1 = MULTIPLY(z2 + z3, FIX_0_541196100); + const int tmp2 = z1 + MULTIPLY(z3, -FIX_1_847759065); + const int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); + + const int tmp0 = left_shifti(ACCESS_ROW(0) + ACCESS_ROW(4), CONST_BITS); + const int tmp1 = left_shifti(ACCESS_ROW(0) - ACCESS_ROW(4), CONST_BITS); + + const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2; + + const int atmp0 = ACCESS_ROW(7), atmp1 = ACCESS_ROW(5), atmp2 = ACCESS_ROW(3), atmp3 = ACCESS_ROW(1); + + const int bz1 = atmp0 + atmp3, bz2 = atmp1 + atmp2, bz3 = atmp0 + atmp2, bz4 = atmp1 + atmp3; + const int bz5 = MULTIPLY(bz3 + bz4, FIX_1_175875602); + + const int az1 = MULTIPLY(bz1, -FIX_0_899976223); + const int az2 = MULTIPLY(bz2, -FIX_2_562915447); + const int az3 = MULTIPLY(bz3, -FIX_1_961570560) + bz5; + const int az4 = MULTIPLY(bz4, -FIX_0_390180644) + bz5; + + const int btmp0 = MULTIPLY(atmp0, FIX_0_298631336) + az1 + az3; + const int btmp1 = MULTIPLY(atmp1, FIX_2_053119869) + az2 + az4; + const int btmp2 = MULTIPLY(atmp2, FIX_3_072711026) + az2 + az3; + const int btmp3 = MULTIPLY(atmp3, FIX_1_501321110) + az1 + az4; + + int i = DESCALE_ZEROSHIFT(tmp10 + btmp3, CONST_BITS + PASS1_BITS + 3); + pDst_ptr[8 * 0] = (uint8)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp10 - btmp3, CONST_BITS + PASS1_BITS + 3); + pDst_ptr[8 * 7] = (uint8)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp11 + btmp2, CONST_BITS + PASS1_BITS + 3); + pDst_ptr[8 * 1] = (uint8)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp11 - btmp2, CONST_BITS + PASS1_BITS + 3); + pDst_ptr[8 * 6] = (uint8)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp12 + btmp1, CONST_BITS + PASS1_BITS + 3); + pDst_ptr[8 * 2] = (uint8)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp12 - btmp1, CONST_BITS + PASS1_BITS + 3); + pDst_ptr[8 * 5] = (uint8)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp13 + btmp0, CONST_BITS + PASS1_BITS + 3); + pDst_ptr[8 * 3] = (uint8)CLAMP(i); + + i = DESCALE_ZEROSHIFT(tmp13 - btmp0, CONST_BITS + PASS1_BITS + 3); + pDst_ptr[8 * 4] = (uint8)CLAMP(i); + } + }; + + template <> + struct Col<1> + { + static void idct(uint8* pDst_ptr, const int* pTemp) + { + int dcval = DESCALE_ZEROSHIFT(pTemp[0], PASS1_BITS + 3); + const uint8 dcval_clamped = (uint8)CLAMP(dcval); + pDst_ptr[0 * 8] = dcval_clamped; + pDst_ptr[1 * 8] = dcval_clamped; + pDst_ptr[2 * 8] = dcval_clamped; + pDst_ptr[3 * 8] = dcval_clamped; + pDst_ptr[4 * 8] = dcval_clamped; + pDst_ptr[5 * 8] = dcval_clamped; + pDst_ptr[6 * 8] = dcval_clamped; + pDst_ptr[7 * 8] = dcval_clamped; + } + }; + + static const uint8 s_idct_row_table[] = + { + 1,0,0,0,0,0,0,0, 2,0,0,0,0,0,0,0, 2,1,0,0,0,0,0,0, 2,1,1,0,0,0,0,0, 2,2,1,0,0,0,0,0, 3,2,1,0,0,0,0,0, 4,2,1,0,0,0,0,0, 4,3,1,0,0,0,0,0, + 4,3,2,0,0,0,0,0, 4,3,2,1,0,0,0,0, 4,3,2,1,1,0,0,0, 4,3,2,2,1,0,0,0, 4,3,3,2,1,0,0,0, 4,4,3,2,1,0,0,0, 5,4,3,2,1,0,0,0, 6,4,3,2,1,0,0,0, + 6,5,3,2,1,0,0,0, 6,5,4,2,1,0,0,0, 6,5,4,3,1,0,0,0, 6,5,4,3,2,0,0,0, 6,5,4,3,2,1,0,0, 6,5,4,3,2,1,1,0, 6,5,4,3,2,2,1,0, 6,5,4,3,3,2,1,0, + 6,5,4,4,3,2,1,0, 6,5,5,4,3,2,1,0, 6,6,5,4,3,2,1,0, 7,6,5,4,3,2,1,0, 8,6,5,4,3,2,1,0, 8,7,5,4,3,2,1,0, 8,7,6,4,3,2,1,0, 8,7,6,5,3,2,1,0, + 8,7,6,5,4,2,1,0, 8,7,6,5,4,3,1,0, 8,7,6,5,4,3,2,0, 8,7,6,5,4,3,2,1, 8,7,6,5,4,3,2,2, 8,7,6,5,4,3,3,2, 8,7,6,5,4,4,3,2, 8,7,6,5,5,4,3,2, + 8,7,6,6,5,4,3,2, 8,7,7,6,5,4,3,2, 8,8,7,6,5,4,3,2, 8,8,8,6,5,4,3,2, 8,8,8,7,5,4,3,2, 8,8,8,7,6,4,3,2, 8,8,8,7,6,5,3,2, 8,8,8,7,6,5,4,2, + 8,8,8,7,6,5,4,3, 8,8,8,7,6,5,4,4, 8,8,8,7,6,5,5,4, 8,8,8,7,6,6,5,4, 8,8,8,7,7,6,5,4, 8,8,8,8,7,6,5,4, 8,8,8,8,8,6,5,4, 8,8,8,8,8,7,5,4, + 8,8,8,8,8,7,6,4, 8,8,8,8,8,7,6,5, 8,8,8,8,8,7,6,6, 8,8,8,8,8,7,7,6, 8,8,8,8,8,8,7,6, 8,8,8,8,8,8,8,6, 8,8,8,8,8,8,8,7, 8,8,8,8,8,8,8,8, + }; + + static const uint8 s_idct_col_table[] = + { + 1, 1, 2, 3, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 + }; + + // Scalar "fast pathing" IDCT. + static void idct(const jpgd_block_coeff_t* pSrc_ptr, uint8* pDst_ptr, int block_max_zag, bool use_simd) + { + (void)use_simd; + + assert(block_max_zag >= 1); + assert(block_max_zag <= 64); + + if (block_max_zag <= 1) + { + int k = ((pSrc_ptr[0] + 4) >> 3) + 128; + k = CLAMP(k); + k = k | (k << 8); + k = k | (k << 16); + + for (int i = 8; i > 0; i--) + { + *(int*)&pDst_ptr[0] = k; + *(int*)&pDst_ptr[4] = k; + pDst_ptr += 8; + } + return; + } + +#if JPGD_USE_SSE2 + if (use_simd) + { + assert((((uintptr_t)pSrc_ptr) & 15) == 0); + assert((((uintptr_t)pDst_ptr) & 15) == 0); + idctSSEShortU8(pSrc_ptr, pDst_ptr); + return; + } #endif - } -}; - -template <> -struct Row<1> -{ - static void idct(int* pTemp, const jpgd_block_t* pSrc) - { - const int dcval = (pSrc[0] << PASS1_BITS); - - pTemp[0] = dcval; - pTemp[1] = dcval; - pTemp[2] = dcval; - pTemp[3] = dcval; - pTemp[4] = dcval; - pTemp[5] = dcval; - pTemp[6] = dcval; - pTemp[7] = dcval; - } -}; - -// Compiler creates a fast path 1D IDCT for X non-zero rows -template <int NONZERO_ROWS> -struct Col -{ - static void idct(uint8* pDst_ptr, const int* pTemp) - { - // ACCESS_ROW() will be optimized at compile time to either an array access, or 0. - #define ACCESS_ROW(x) (((x) < NONZERO_ROWS) ? pTemp[x * 8] : 0) - - const int z2 = ACCESS_ROW(2); - const int z3 = ACCESS_ROW(6); - - const int z1 = MULTIPLY(z2 + z3, FIX_0_541196100); - const int tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065); - const int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); - - const int tmp0 = (ACCESS_ROW(0) + ACCESS_ROW(4)) << CONST_BITS; - const int tmp1 = (ACCESS_ROW(0) - ACCESS_ROW(4)) << CONST_BITS; - - const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2; - - const int atmp0 = ACCESS_ROW(7), atmp1 = ACCESS_ROW(5), atmp2 = ACCESS_ROW(3), atmp3 = ACCESS_ROW(1); - - const int bz1 = atmp0 + atmp3, bz2 = atmp1 + atmp2, bz3 = atmp0 + atmp2, bz4 = atmp1 + atmp3; - const int bz5 = MULTIPLY(bz3 + bz4, FIX_1_175875602); - - const int az1 = MULTIPLY(bz1, - FIX_0_899976223); - const int az2 = MULTIPLY(bz2, - FIX_2_562915447); - const int az3 = MULTIPLY(bz3, - FIX_1_961570560) + bz5; - const int az4 = MULTIPLY(bz4, - FIX_0_390180644) + bz5; - - const int btmp0 = MULTIPLY(atmp0, FIX_0_298631336) + az1 + az3; - const int btmp1 = MULTIPLY(atmp1, FIX_2_053119869) + az2 + az4; - const int btmp2 = MULTIPLY(atmp2, FIX_3_072711026) + az2 + az3; - const int btmp3 = MULTIPLY(atmp3, FIX_1_501321110) + az1 + az4; - - int i = DESCALE_ZEROSHIFT(tmp10 + btmp3, CONST_BITS+PASS1_BITS+3); - pDst_ptr[8*0] = (uint8)CLAMP(i); - - i = DESCALE_ZEROSHIFT(tmp10 - btmp3, CONST_BITS+PASS1_BITS+3); - pDst_ptr[8*7] = (uint8)CLAMP(i); - - i = DESCALE_ZEROSHIFT(tmp11 + btmp2, CONST_BITS+PASS1_BITS+3); - pDst_ptr[8*1] = (uint8)CLAMP(i); - - i = DESCALE_ZEROSHIFT(tmp11 - btmp2, CONST_BITS+PASS1_BITS+3); - pDst_ptr[8*6] = (uint8)CLAMP(i); - - i = DESCALE_ZEROSHIFT(tmp12 + btmp1, CONST_BITS+PASS1_BITS+3); - pDst_ptr[8*2] = (uint8)CLAMP(i); - - i = DESCALE_ZEROSHIFT(tmp12 - btmp1, CONST_BITS+PASS1_BITS+3); - pDst_ptr[8*5] = (uint8)CLAMP(i); - - i = DESCALE_ZEROSHIFT(tmp13 + btmp0, CONST_BITS+PASS1_BITS+3); - pDst_ptr[8*3] = (uint8)CLAMP(i); - - i = DESCALE_ZEROSHIFT(tmp13 - btmp0, CONST_BITS+PASS1_BITS+3); - pDst_ptr[8*4] = (uint8)CLAMP(i); - } -}; - -template <> -struct Col<1> -{ - static void idct(uint8* pDst_ptr, const int* pTemp) - { - int dcval = DESCALE_ZEROSHIFT(pTemp[0], PASS1_BITS+3); - const uint8 dcval_clamped = (uint8)CLAMP(dcval); - pDst_ptr[0*8] = dcval_clamped; - pDst_ptr[1*8] = dcval_clamped; - pDst_ptr[2*8] = dcval_clamped; - pDst_ptr[3*8] = dcval_clamped; - pDst_ptr[4*8] = dcval_clamped; - pDst_ptr[5*8] = dcval_clamped; - pDst_ptr[6*8] = dcval_clamped; - pDst_ptr[7*8] = dcval_clamped; - } -}; - -static const uint8 s_idct_row_table[] = -{ - 1,0,0,0,0,0,0,0, 2,0,0,0,0,0,0,0, 2,1,0,0,0,0,0,0, 2,1,1,0,0,0,0,0, 2,2,1,0,0,0,0,0, 3,2,1,0,0,0,0,0, 4,2,1,0,0,0,0,0, 4,3,1,0,0,0,0,0, - 4,3,2,0,0,0,0,0, 4,3,2,1,0,0,0,0, 4,3,2,1,1,0,0,0, 4,3,2,2,1,0,0,0, 4,3,3,2,1,0,0,0, 4,4,3,2,1,0,0,0, 5,4,3,2,1,0,0,0, 6,4,3,2,1,0,0,0, - 6,5,3,2,1,0,0,0, 6,5,4,2,1,0,0,0, 6,5,4,3,1,0,0,0, 6,5,4,3,2,0,0,0, 6,5,4,3,2,1,0,0, 6,5,4,3,2,1,1,0, 6,5,4,3,2,2,1,0, 6,5,4,3,3,2,1,0, - 6,5,4,4,3,2,1,0, 6,5,5,4,3,2,1,0, 6,6,5,4,3,2,1,0, 7,6,5,4,3,2,1,0, 8,6,5,4,3,2,1,0, 8,7,5,4,3,2,1,0, 8,7,6,4,3,2,1,0, 8,7,6,5,3,2,1,0, - 8,7,6,5,4,2,1,0, 8,7,6,5,4,3,1,0, 8,7,6,5,4,3,2,0, 8,7,6,5,4,3,2,1, 8,7,6,5,4,3,2,2, 8,7,6,5,4,3,3,2, 8,7,6,5,4,4,3,2, 8,7,6,5,5,4,3,2, - 8,7,6,6,5,4,3,2, 8,7,7,6,5,4,3,2, 8,8,7,6,5,4,3,2, 8,8,8,6,5,4,3,2, 8,8,8,7,5,4,3,2, 8,8,8,7,6,4,3,2, 8,8,8,7,6,5,3,2, 8,8,8,7,6,5,4,2, - 8,8,8,7,6,5,4,3, 8,8,8,7,6,5,4,4, 8,8,8,7,6,5,5,4, 8,8,8,7,6,6,5,4, 8,8,8,7,7,6,5,4, 8,8,8,8,7,6,5,4, 8,8,8,8,8,6,5,4, 8,8,8,8,8,7,5,4, - 8,8,8,8,8,7,6,4, 8,8,8,8,8,7,6,5, 8,8,8,8,8,7,6,6, 8,8,8,8,8,7,7,6, 8,8,8,8,8,8,7,6, 8,8,8,8,8,8,8,6, 8,8,8,8,8,8,8,7, 8,8,8,8,8,8,8,8, -}; - -static const uint8 s_idct_col_table[] = { 1, 1, 2, 3, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }; - -void idct(const jpgd_block_t* pSrc_ptr, uint8* pDst_ptr, int block_max_zag) -{ - JPGD_ASSERT(block_max_zag >= 1); - JPGD_ASSERT(block_max_zag <= 64); - - if (block_max_zag <= 1) - { - int k = ((pSrc_ptr[0] + 4) >> 3) + 128; - k = CLAMP(k); - k = k | (k<<8); - k = k | (k<<16); - - for (int i = 8; i > 0; i--) - { - *(int*)&pDst_ptr[0] = k; - *(int*)&pDst_ptr[4] = k; - pDst_ptr += 8; - } - return; - } - - int temp[64]; - - const jpgd_block_t* pSrc = pSrc_ptr; - int* pTemp = temp; - - const uint8* pRow_tab = &s_idct_row_table[(block_max_zag - 1) * 8]; - int i; - for (i = 8; i > 0; i--, pRow_tab++) - { - switch (*pRow_tab) - { - case 0: Row<0>::idct(pTemp, pSrc); break; - case 1: Row<1>::idct(pTemp, pSrc); break; - case 2: Row<2>::idct(pTemp, pSrc); break; - case 3: Row<3>::idct(pTemp, pSrc); break; - case 4: Row<4>::idct(pTemp, pSrc); break; - case 5: Row<5>::idct(pTemp, pSrc); break; - case 6: Row<6>::idct(pTemp, pSrc); break; - case 7: Row<7>::idct(pTemp, pSrc); break; - case 8: Row<8>::idct(pTemp, pSrc); break; - } - - pSrc += 8; - pTemp += 8; - } - - pTemp = temp; - - const int nonzero_rows = s_idct_col_table[block_max_zag - 1]; - for (i = 8; i > 0; i--) - { - switch (nonzero_rows) - { - case 1: Col<1>::idct(pDst_ptr, pTemp); break; - case 2: Col<2>::idct(pDst_ptr, pTemp); break; - case 3: Col<3>::idct(pDst_ptr, pTemp); break; - case 4: Col<4>::idct(pDst_ptr, pTemp); break; - case 5: Col<5>::idct(pDst_ptr, pTemp); break; - case 6: Col<6>::idct(pDst_ptr, pTemp); break; - case 7: Col<7>::idct(pDst_ptr, pTemp); break; - case 8: Col<8>::idct(pDst_ptr, pTemp); break; - } - - pTemp++; - pDst_ptr++; - } -} - -void idct_4x4(const jpgd_block_t* pSrc_ptr, uint8* pDst_ptr) -{ - int temp[64]; - int* pTemp = temp; - const jpgd_block_t* pSrc = pSrc_ptr; - - for (int i = 4; i > 0; i--) - { - Row<4>::idct(pTemp, pSrc); - pSrc += 8; - pTemp += 8; - } - - pTemp = temp; - for (int i = 8; i > 0; i--) - { - Col<4>::idct(pDst_ptr, pTemp); - pTemp++; - pDst_ptr++; - } -} - -// Retrieve one character from the input stream. -inline uint jpeg_decoder::get_char() -{ - // Any bytes remaining in buffer? - if (!m_in_buf_left) - { - // Try to get more bytes. - prep_in_buffer(); - // Still nothing to get? - if (!m_in_buf_left) - { - // Pad the end of the stream with 0xFF 0xD9 (EOI marker) - int t = m_tem_flag; - m_tem_flag ^= 1; - if (t) - return 0xD9; - else - return 0xFF; - } - } - - uint c = *m_pIn_buf_ofs++; - m_in_buf_left--; - - return c; -} - -// Same as previous method, except can indicate if the character is a pad character or not. -inline uint jpeg_decoder::get_char(bool *pPadding_flag) -{ - if (!m_in_buf_left) - { - prep_in_buffer(); - if (!m_in_buf_left) - { - *pPadding_flag = true; - int t = m_tem_flag; - m_tem_flag ^= 1; - if (t) - return 0xD9; - else - return 0xFF; - } - } - - *pPadding_flag = false; - - uint c = *m_pIn_buf_ofs++; - m_in_buf_left--; - - return c; -} - -// Inserts a previously retrieved character back into the input buffer. -inline void jpeg_decoder::stuff_char(uint8 q) -{ - *(--m_pIn_buf_ofs) = q; - m_in_buf_left++; -} - -// Retrieves one character from the input stream, but does not read past markers. Will continue to return 0xFF when a marker is encountered. -inline uint8 jpeg_decoder::get_octet() -{ - bool padding_flag; - int c = get_char(&padding_flag); - - if (c == 0xFF) - { - if (padding_flag) - return 0xFF; - - c = get_char(&padding_flag); - if (padding_flag) - { - stuff_char(0xFF); - return 0xFF; - } - - if (c == 0x00) - return 0xFF; - else - { - stuff_char(static_cast<uint8>(c)); - stuff_char(0xFF); - return 0xFF; - } - } - - return static_cast<uint8>(c); -} - -// Retrieves a variable number of bits from the input stream. Does not recognize markers. -inline uint jpeg_decoder::get_bits(int num_bits) -{ - if (!num_bits) - return 0; - - uint i = m_bit_buf >> (32 - num_bits); - - if ((m_bits_left -= num_bits) <= 0) - { - m_bit_buf <<= (num_bits += m_bits_left); - - uint c1 = get_char(); - uint c2 = get_char(); - m_bit_buf = (m_bit_buf & 0xFFFF0000) | (c1 << 8) | c2; - - m_bit_buf <<= -m_bits_left; - - m_bits_left += 16; - - JPGD_ASSERT(m_bits_left >= 0); - } - else - m_bit_buf <<= num_bits; - - return i; -} - -// Retrieves a variable number of bits from the input stream. Markers will not be read into the input bit buffer. Instead, an infinite number of all 1's will be returned when a marker is encountered. -inline uint jpeg_decoder::get_bits_no_markers(int num_bits) -{ - if (!num_bits) - return 0; - - uint i = m_bit_buf >> (32 - num_bits); - - if ((m_bits_left -= num_bits) <= 0) - { - m_bit_buf <<= (num_bits += m_bits_left); - - if ((m_in_buf_left < 2) || (m_pIn_buf_ofs[0] == 0xFF) || (m_pIn_buf_ofs[1] == 0xFF)) - { - uint c1 = get_octet(); - uint c2 = get_octet(); - m_bit_buf |= (c1 << 8) | c2; - } - else - { - m_bit_buf |= ((uint)m_pIn_buf_ofs[0] << 8) | m_pIn_buf_ofs[1]; - m_in_buf_left -= 2; - m_pIn_buf_ofs += 2; - } - - m_bit_buf <<= -m_bits_left; - - m_bits_left += 16; - - JPGD_ASSERT(m_bits_left >= 0); - } - else - m_bit_buf <<= num_bits; - - return i; -} - -// Decodes a Huffman encoded symbol. -inline int jpeg_decoder::huff_decode(huff_tables *pH) -{ - JPGD_ASSERT(pH); - - int symbol; - // Check first 8-bits: do we have a complete symbol? - if ((symbol = pH->look_up[m_bit_buf >> 24]) < 0) - { - // Decode more bits, use a tree traversal to find symbol. - int ofs = 23; - do - { - unsigned int idx = -(int)(symbol + ((m_bit_buf >> ofs) & 1)); - JPGD_ASSERT(idx < JPGD_HUFF_TREE_MAX_LENGTH); - symbol = pH->tree[idx]; - ofs--; - } while (symbol < 0); - - get_bits_no_markers(8 + (23 - ofs)); - } - else - { - JPGD_ASSERT(symbol < JPGD_HUFF_CODE_SIZE_MAX_LENGTH); - get_bits_no_markers(pH->code_size[symbol]); - } - - return symbol; -} - -// Decodes a Huffman encoded symbol. -inline int jpeg_decoder::huff_decode(huff_tables *pH, int& extra_bits) -{ - int symbol; - - JPGD_ASSERT(pH); - - // Check first 8-bits: do we have a complete symbol? - if ((symbol = pH->look_up2[m_bit_buf >> 24]) < 0) - { - // Use a tree traversal to find symbol. - int ofs = 23; - do - { - unsigned int idx = -(int)(symbol + ((m_bit_buf >> ofs) & 1)); - JPGD_ASSERT(idx < JPGD_HUFF_TREE_MAX_LENGTH); - symbol = pH->tree[idx]; - ofs--; - } while (symbol < 0); - - get_bits_no_markers(8 + (23 - ofs)); - - extra_bits = get_bits_no_markers(symbol & 0xF); - } - else - { - JPGD_ASSERT(((symbol >> 8) & 31) == pH->code_size[symbol & 255] + ((symbol & 0x8000) ? (symbol & 15) : 0)); - - if (symbol & 0x8000) - { - get_bits_no_markers((symbol >> 8) & 31); - extra_bits = symbol >> 16; - } - else - { - int code_size = (symbol >> 8) & 31; - int num_extra_bits = symbol & 0xF; - int bits = code_size + num_extra_bits; - if (bits <= (m_bits_left + 16)) - extra_bits = get_bits_no_markers(bits) & ((1 << num_extra_bits) - 1); - else - { - get_bits_no_markers(code_size); - extra_bits = get_bits_no_markers(num_extra_bits); - } - } - - symbol &= 0xFF; - } - - return symbol; -} - -// Tables and macro used to fully decode the DPCM differences. -static const int s_extend_test[16] = { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 }; -static const int s_extend_offset[16] = { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1, ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1, ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1, ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 }; -static const int s_extend_mask[] = { 0, (1<<0), (1<<1), (1<<2), (1<<3), (1<<4), (1<<5), (1<<6), (1<<7), (1<<8), (1<<9), (1<<10), (1<<11), (1<<12), (1<<13), (1<<14), (1<<15), (1<<16) }; -// The logical AND's in this macro are to shut up static code analysis (aren't really necessary - couldn't find another way to do this) + + int temp[64]; + + const jpgd_block_coeff_t* pSrc = pSrc_ptr; + int* pTemp = temp; + + const uint8* pRow_tab = &s_idct_row_table[(block_max_zag - 1) * 8]; + int i; + for (i = 8; i > 0; i--, pRow_tab++) + { + switch (*pRow_tab) + { + case 0: Row<0>::idct(pTemp, pSrc); break; + case 1: Row<1>::idct(pTemp, pSrc); break; + case 2: Row<2>::idct(pTemp, pSrc); break; + case 3: Row<3>::idct(pTemp, pSrc); break; + case 4: Row<4>::idct(pTemp, pSrc); break; + case 5: Row<5>::idct(pTemp, pSrc); break; + case 6: Row<6>::idct(pTemp, pSrc); break; + case 7: Row<7>::idct(pTemp, pSrc); break; + case 8: Row<8>::idct(pTemp, pSrc); break; + } + + pSrc += 8; + pTemp += 8; + } + + pTemp = temp; + + const int nonzero_rows = s_idct_col_table[block_max_zag - 1]; + for (i = 8; i > 0; i--) + { + switch (nonzero_rows) + { + case 1: Col<1>::idct(pDst_ptr, pTemp); break; + case 2: Col<2>::idct(pDst_ptr, pTemp); break; + case 3: Col<3>::idct(pDst_ptr, pTemp); break; + case 4: Col<4>::idct(pDst_ptr, pTemp); break; + case 5: Col<5>::idct(pDst_ptr, pTemp); break; + case 6: Col<6>::idct(pDst_ptr, pTemp); break; + case 7: Col<7>::idct(pDst_ptr, pTemp); break; + case 8: Col<8>::idct(pDst_ptr, pTemp); break; + } + + pTemp++; + pDst_ptr++; + } + } + + // Retrieve one character from the input stream. + inline uint jpeg_decoder::get_char() + { + // Any bytes remaining in buffer? + if (!m_in_buf_left) + { + // Try to get more bytes. + prep_in_buffer(); + // Still nothing to get? + if (!m_in_buf_left) + { + // Pad the end of the stream with 0xFF 0xD9 (EOI marker) + int t = m_tem_flag; + m_tem_flag ^= 1; + if (t) + return 0xD9; + else + return 0xFF; + } + } + + uint c = *m_pIn_buf_ofs++; + m_in_buf_left--; + + return c; + } + + // Same as previous method, except can indicate if the character is a pad character or not. + inline uint jpeg_decoder::get_char(bool* pPadding_flag) + { + if (!m_in_buf_left) + { + prep_in_buffer(); + if (!m_in_buf_left) + { + *pPadding_flag = true; + int t = m_tem_flag; + m_tem_flag ^= 1; + if (t) + return 0xD9; + else + return 0xFF; + } + } + + *pPadding_flag = false; + + uint c = *m_pIn_buf_ofs++; + m_in_buf_left--; + + return c; + } + + // Inserts a previously retrieved character back into the input buffer. + inline void jpeg_decoder::stuff_char(uint8 q) + { + // This could write before the input buffer, but we've placed another array there. + *(--m_pIn_buf_ofs) = q; + m_in_buf_left++; + } + + // Retrieves one character from the input stream, but does not read past markers. Will continue to return 0xFF when a marker is encountered. + inline uint8 jpeg_decoder::get_octet() + { + bool padding_flag; + int c = get_char(&padding_flag); + + if (c == 0xFF) + { + if (padding_flag) + return 0xFF; + + c = get_char(&padding_flag); + if (padding_flag) + { + stuff_char(0xFF); + return 0xFF; + } + + if (c == 0x00) + return 0xFF; + else + { + stuff_char(static_cast<uint8>(c)); + stuff_char(0xFF); + return 0xFF; + } + } + + return static_cast<uint8>(c); + } + + // Retrieves a variable number of bits from the input stream. Does not recognize markers. + inline uint jpeg_decoder::get_bits(int num_bits) + { + if (!num_bits) + return 0; + + uint i = m_bit_buf >> (32 - num_bits); + + if ((m_bits_left -= num_bits) <= 0) + { + m_bit_buf <<= (num_bits += m_bits_left); + + uint c1 = get_char(); + uint c2 = get_char(); + m_bit_buf = (m_bit_buf & 0xFFFF0000) | (c1 << 8) | c2; + + m_bit_buf <<= -m_bits_left; + + m_bits_left += 16; + + assert(m_bits_left >= 0); + } + else + m_bit_buf <<= num_bits; + + return i; + } + + // Retrieves a variable number of bits from the input stream. Markers will not be read into the input bit buffer. Instead, an infinite number of all 1's will be returned when a marker is encountered. + inline uint jpeg_decoder::get_bits_no_markers(int num_bits) + { + if (!num_bits) + return 0; + + assert(num_bits <= 16); + + uint i = m_bit_buf >> (32 - num_bits); + + if ((m_bits_left -= num_bits) <= 0) + { + m_bit_buf <<= (num_bits += m_bits_left); + + if ((m_in_buf_left < 2) || (m_pIn_buf_ofs[0] == 0xFF) || (m_pIn_buf_ofs[1] == 0xFF)) + { + uint c1 = get_octet(); + uint c2 = get_octet(); + m_bit_buf |= (c1 << 8) | c2; + } + else + { + m_bit_buf |= ((uint)m_pIn_buf_ofs[0] << 8) | m_pIn_buf_ofs[1]; + m_in_buf_left -= 2; + m_pIn_buf_ofs += 2; + } + + m_bit_buf <<= -m_bits_left; + + m_bits_left += 16; + + assert(m_bits_left >= 0); + } + else + m_bit_buf <<= num_bits; + + return i; + } + + // Decodes a Huffman encoded symbol. + inline int jpeg_decoder::huff_decode(huff_tables* pH) + { + if (!pH) + stop_decoding(JPGD_DECODE_ERROR); + + int symbol; + // Check first 8-bits: do we have a complete symbol? + if ((symbol = pH->look_up[m_bit_buf >> 24]) < 0) + { + // Decode more bits, use a tree traversal to find symbol. + int ofs = 23; + do + { + unsigned int idx = -(int)(symbol + ((m_bit_buf >> ofs) & 1)); + + // This should never happen, but to be safe I'm turning these asserts into a run-time check. + if ((idx >= JPGD_HUFF_TREE_MAX_LENGTH) || (ofs < 0)) + stop_decoding(JPGD_DECODE_ERROR); + + symbol = pH->tree[idx]; + ofs--; + } while (symbol < 0); + + get_bits_no_markers(8 + (23 - ofs)); + } + else + { + assert(symbol < JPGD_HUFF_CODE_SIZE_MAX_LENGTH); + get_bits_no_markers(pH->code_size[symbol]); + } + + return symbol; + } + + // Decodes a Huffman encoded symbol. + inline int jpeg_decoder::huff_decode(huff_tables* pH, int& extra_bits) + { + int symbol; + + if (!pH) + stop_decoding(JPGD_DECODE_ERROR); + + // Check first 8-bits: do we have a complete symbol? + if ((symbol = pH->look_up2[m_bit_buf >> 24]) < 0) + { + // Use a tree traversal to find symbol. + int ofs = 23; + do + { + unsigned int idx = -(int)(symbol + ((m_bit_buf >> ofs) & 1)); + + // This should never happen, but to be safe I'm turning these asserts into a run-time check. + if ((idx >= JPGD_HUFF_TREE_MAX_LENGTH) || (ofs < 0)) + stop_decoding(JPGD_DECODE_ERROR); + + symbol = pH->tree[idx]; + ofs--; + } while (symbol < 0); + + get_bits_no_markers(8 + (23 - ofs)); + + extra_bits = get_bits_no_markers(symbol & 0xF); + } + else + { + if (symbol & 0x8000) + { + //get_bits_no_markers((symbol >> 8) & 31); + assert(((symbol >> 8) & 31) <= 15); + get_bits_no_markers((symbol >> 8) & 15); + extra_bits = symbol >> 16; + } + else + { + int code_size = (symbol >> 8) & 31; + int num_extra_bits = symbol & 0xF; + int bits = code_size + num_extra_bits; + + if (bits <= 16) + extra_bits = get_bits_no_markers(bits) & ((1 << num_extra_bits) - 1); + else + { + get_bits_no_markers(code_size); + extra_bits = get_bits_no_markers(num_extra_bits); + } + } + + symbol &= 0xFF; + } + + return symbol; + } + + // Tables and macro used to fully decode the DPCM differences. + static const int s_extend_test[16] = { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 }; + static const int s_extend_offset[16] = { 0, -1, -3, -7, -15, -31, -63, -127, -255, -511, -1023, -2047, -4095, -8191, -16383, -32767 }; + //static const int s_extend_mask[] = { 0, (1 << 0), (1 << 1), (1 << 2), (1 << 3), (1 << 4), (1 << 5), (1 << 6), (1 << 7), (1 << 8), (1 << 9), (1 << 10), (1 << 11), (1 << 12), (1 << 13), (1 << 14), (1 << 15), (1 << 16) }; + #define JPGD_HUFF_EXTEND(x, s) (((x) < s_extend_test[s & 15]) ? ((x) + s_extend_offset[s & 15]) : (x)) -// Clamps a value between 0-255. -inline uint8 jpeg_decoder::clamp(int i) -{ - if (static_cast<uint>(i) > 255) - i = (((~i) >> 31) & 0xFF); - - return static_cast<uint8>(i); -} - -namespace DCT_Upsample -{ - struct Matrix44 - { - typedef int Element_Type; - enum { NUM_ROWS = 4, NUM_COLS = 4 }; - - Element_Type v[NUM_ROWS][NUM_COLS]; - - inline int rows() const { return NUM_ROWS; } - inline int cols() const { return NUM_COLS; } - - inline const Element_Type & at(int r, int c) const { return v[r][c]; } - inline Element_Type & at(int r, int c) { return v[r][c]; } - - inline Matrix44() { } - - inline Matrix44& operator += (const Matrix44& a) - { - for (int r = 0; r < NUM_ROWS; r++) - { - at(r, 0) += a.at(r, 0); - at(r, 1) += a.at(r, 1); - at(r, 2) += a.at(r, 2); - at(r, 3) += a.at(r, 3); - } - return *this; - } - - inline Matrix44& operator -= (const Matrix44& a) - { - for (int r = 0; r < NUM_ROWS; r++) - { - at(r, 0) -= a.at(r, 0); - at(r, 1) -= a.at(r, 1); - at(r, 2) -= a.at(r, 2); - at(r, 3) -= a.at(r, 3); - } - return *this; - } - - friend inline Matrix44 operator + (const Matrix44& a, const Matrix44& b) - { - Matrix44 ret; - for (int r = 0; r < NUM_ROWS; r++) - { - ret.at(r, 0) = a.at(r, 0) + b.at(r, 0); - ret.at(r, 1) = a.at(r, 1) + b.at(r, 1); - ret.at(r, 2) = a.at(r, 2) + b.at(r, 2); - ret.at(r, 3) = a.at(r, 3) + b.at(r, 3); - } - return ret; - } - - friend inline Matrix44 operator - (const Matrix44& a, const Matrix44& b) - { - Matrix44 ret; - for (int r = 0; r < NUM_ROWS; r++) - { - ret.at(r, 0) = a.at(r, 0) - b.at(r, 0); - ret.at(r, 1) = a.at(r, 1) - b.at(r, 1); - ret.at(r, 2) = a.at(r, 2) - b.at(r, 2); - ret.at(r, 3) = a.at(r, 3) - b.at(r, 3); - } - return ret; - } - - static inline void add_and_store(jpgd_block_t* pDst, const Matrix44& a, const Matrix44& b) - { - for (int r = 0; r < 4; r++) - { - pDst[0*8 + r] = static_cast<jpgd_block_t>(a.at(r, 0) + b.at(r, 0)); - pDst[1*8 + r] = static_cast<jpgd_block_t>(a.at(r, 1) + b.at(r, 1)); - pDst[2*8 + r] = static_cast<jpgd_block_t>(a.at(r, 2) + b.at(r, 2)); - pDst[3*8 + r] = static_cast<jpgd_block_t>(a.at(r, 3) + b.at(r, 3)); - } - } - - static inline void sub_and_store(jpgd_block_t* pDst, const Matrix44& a, const Matrix44& b) - { - for (int r = 0; r < 4; r++) - { - pDst[0*8 + r] = static_cast<jpgd_block_t>(a.at(r, 0) - b.at(r, 0)); - pDst[1*8 + r] = static_cast<jpgd_block_t>(a.at(r, 1) - b.at(r, 1)); - pDst[2*8 + r] = static_cast<jpgd_block_t>(a.at(r, 2) - b.at(r, 2)); - pDst[3*8 + r] = static_cast<jpgd_block_t>(a.at(r, 3) - b.at(r, 3)); - } - } - }; - - const int FRACT_BITS = 10; - const int SCALE = 1 << FRACT_BITS; - - typedef int Temp_Type; - #define D(i) (((i) + (SCALE >> 1)) >> FRACT_BITS) - #define F(i) ((int)((i) * SCALE + .5f)) - - // Any decent C++ compiler will optimize this at compile time to a 0, or an array access. - #define AT(c, r) ((((c)>=NUM_COLS)||((r)>=NUM_ROWS)) ? 0 : pSrc[(c)+(r)*8]) - - // NUM_ROWS/NUM_COLS = # of non-zero rows/cols in input matrix - template<int NUM_ROWS, int NUM_COLS> - struct P_Q - { - static void calc(Matrix44& P, Matrix44& Q, const jpgd_block_t* pSrc) - { - // 4x8 = 4x8 times 8x8, matrix 0 is constant - const Temp_Type X000 = AT(0, 0); - const Temp_Type X001 = AT(0, 1); - const Temp_Type X002 = AT(0, 2); - const Temp_Type X003 = AT(0, 3); - const Temp_Type X004 = AT(0, 4); - const Temp_Type X005 = AT(0, 5); - const Temp_Type X006 = AT(0, 6); - const Temp_Type X007 = AT(0, 7); - const Temp_Type X010 = D(F(0.415735f) * AT(1, 0) + F(0.791065f) * AT(3, 0) + F(-0.352443f) * AT(5, 0) + F(0.277785f) * AT(7, 0)); - const Temp_Type X011 = D(F(0.415735f) * AT(1, 1) + F(0.791065f) * AT(3, 1) + F(-0.352443f) * AT(5, 1) + F(0.277785f) * AT(7, 1)); - const Temp_Type X012 = D(F(0.415735f) * AT(1, 2) + F(0.791065f) * AT(3, 2) + F(-0.352443f) * AT(5, 2) + F(0.277785f) * AT(7, 2)); - const Temp_Type X013 = D(F(0.415735f) * AT(1, 3) + F(0.791065f) * AT(3, 3) + F(-0.352443f) * AT(5, 3) + F(0.277785f) * AT(7, 3)); - const Temp_Type X014 = D(F(0.415735f) * AT(1, 4) + F(0.791065f) * AT(3, 4) + F(-0.352443f) * AT(5, 4) + F(0.277785f) * AT(7, 4)); - const Temp_Type X015 = D(F(0.415735f) * AT(1, 5) + F(0.791065f) * AT(3, 5) + F(-0.352443f) * AT(5, 5) + F(0.277785f) * AT(7, 5)); - const Temp_Type X016 = D(F(0.415735f) * AT(1, 6) + F(0.791065f) * AT(3, 6) + F(-0.352443f) * AT(5, 6) + F(0.277785f) * AT(7, 6)); - const Temp_Type X017 = D(F(0.415735f) * AT(1, 7) + F(0.791065f) * AT(3, 7) + F(-0.352443f) * AT(5, 7) + F(0.277785f) * AT(7, 7)); - const Temp_Type X020 = AT(4, 0); - const Temp_Type X021 = AT(4, 1); - const Temp_Type X022 = AT(4, 2); - const Temp_Type X023 = AT(4, 3); - const Temp_Type X024 = AT(4, 4); - const Temp_Type X025 = AT(4, 5); - const Temp_Type X026 = AT(4, 6); - const Temp_Type X027 = AT(4, 7); - const Temp_Type X030 = D(F(0.022887f) * AT(1, 0) + F(-0.097545f) * AT(3, 0) + F(0.490393f) * AT(5, 0) + F(0.865723f) * AT(7, 0)); - const Temp_Type X031 = D(F(0.022887f) * AT(1, 1) + F(-0.097545f) * AT(3, 1) + F(0.490393f) * AT(5, 1) + F(0.865723f) * AT(7, 1)); - const Temp_Type X032 = D(F(0.022887f) * AT(1, 2) + F(-0.097545f) * AT(3, 2) + F(0.490393f) * AT(5, 2) + F(0.865723f) * AT(7, 2)); - const Temp_Type X033 = D(F(0.022887f) * AT(1, 3) + F(-0.097545f) * AT(3, 3) + F(0.490393f) * AT(5, 3) + F(0.865723f) * AT(7, 3)); - const Temp_Type X034 = D(F(0.022887f) * AT(1, 4) + F(-0.097545f) * AT(3, 4) + F(0.490393f) * AT(5, 4) + F(0.865723f) * AT(7, 4)); - const Temp_Type X035 = D(F(0.022887f) * AT(1, 5) + F(-0.097545f) * AT(3, 5) + F(0.490393f) * AT(5, 5) + F(0.865723f) * AT(7, 5)); - const Temp_Type X036 = D(F(0.022887f) * AT(1, 6) + F(-0.097545f) * AT(3, 6) + F(0.490393f) * AT(5, 6) + F(0.865723f) * AT(7, 6)); - const Temp_Type X037 = D(F(0.022887f) * AT(1, 7) + F(-0.097545f) * AT(3, 7) + F(0.490393f) * AT(5, 7) + F(0.865723f) * AT(7, 7)); - - // 4x4 = 4x8 times 8x4, matrix 1 is constant - P.at(0, 0) = X000; - P.at(0, 1) = D(X001 * F(0.415735f) + X003 * F(0.791065f) + X005 * F(-0.352443f) + X007 * F(0.277785f)); - P.at(0, 2) = X004; - P.at(0, 3) = D(X001 * F(0.022887f) + X003 * F(-0.097545f) + X005 * F(0.490393f) + X007 * F(0.865723f)); - P.at(1, 0) = X010; - P.at(1, 1) = D(X011 * F(0.415735f) + X013 * F(0.791065f) + X015 * F(-0.352443f) + X017 * F(0.277785f)); - P.at(1, 2) = X014; - P.at(1, 3) = D(X011 * F(0.022887f) + X013 * F(-0.097545f) + X015 * F(0.490393f) + X017 * F(0.865723f)); - P.at(2, 0) = X020; - P.at(2, 1) = D(X021 * F(0.415735f) + X023 * F(0.791065f) + X025 * F(-0.352443f) + X027 * F(0.277785f)); - P.at(2, 2) = X024; - P.at(2, 3) = D(X021 * F(0.022887f) + X023 * F(-0.097545f) + X025 * F(0.490393f) + X027 * F(0.865723f)); - P.at(3, 0) = X030; - P.at(3, 1) = D(X031 * F(0.415735f) + X033 * F(0.791065f) + X035 * F(-0.352443f) + X037 * F(0.277785f)); - P.at(3, 2) = X034; - P.at(3, 3) = D(X031 * F(0.022887f) + X033 * F(-0.097545f) + X035 * F(0.490393f) + X037 * F(0.865723f)); - // 40 muls 24 adds - - // 4x4 = 4x8 times 8x4, matrix 1 is constant - Q.at(0, 0) = D(X001 * F(0.906127f) + X003 * F(-0.318190f) + X005 * F(0.212608f) + X007 * F(-0.180240f)); - Q.at(0, 1) = X002; - Q.at(0, 2) = D(X001 * F(-0.074658f) + X003 * F(0.513280f) + X005 * F(0.768178f) + X007 * F(-0.375330f)); - Q.at(0, 3) = X006; - Q.at(1, 0) = D(X011 * F(0.906127f) + X013 * F(-0.318190f) + X015 * F(0.212608f) + X017 * F(-0.180240f)); - Q.at(1, 1) = X012; - Q.at(1, 2) = D(X011 * F(-0.074658f) + X013 * F(0.513280f) + X015 * F(0.768178f) + X017 * F(-0.375330f)); - Q.at(1, 3) = X016; - Q.at(2, 0) = D(X021 * F(0.906127f) + X023 * F(-0.318190f) + X025 * F(0.212608f) + X027 * F(-0.180240f)); - Q.at(2, 1) = X022; - Q.at(2, 2) = D(X021 * F(-0.074658f) + X023 * F(0.513280f) + X025 * F(0.768178f) + X027 * F(-0.375330f)); - Q.at(2, 3) = X026; - Q.at(3, 0) = D(X031 * F(0.906127f) + X033 * F(-0.318190f) + X035 * F(0.212608f) + X037 * F(-0.180240f)); - Q.at(3, 1) = X032; - Q.at(3, 2) = D(X031 * F(-0.074658f) + X033 * F(0.513280f) + X035 * F(0.768178f) + X037 * F(-0.375330f)); - Q.at(3, 3) = X036; - // 40 muls 24 adds - } - }; - - template<int NUM_ROWS, int NUM_COLS> - struct R_S - { - static void calc(Matrix44& R, Matrix44& S, const jpgd_block_t* pSrc) - { - // 4x8 = 4x8 times 8x8, matrix 0 is constant - const Temp_Type X100 = D(F(0.906127f) * AT(1, 0) + F(-0.318190f) * AT(3, 0) + F(0.212608f) * AT(5, 0) + F(-0.180240f) * AT(7, 0)); - const Temp_Type X101 = D(F(0.906127f) * AT(1, 1) + F(-0.318190f) * AT(3, 1) + F(0.212608f) * AT(5, 1) + F(-0.180240f) * AT(7, 1)); - const Temp_Type X102 = D(F(0.906127f) * AT(1, 2) + F(-0.318190f) * AT(3, 2) + F(0.212608f) * AT(5, 2) + F(-0.180240f) * AT(7, 2)); - const Temp_Type X103 = D(F(0.906127f) * AT(1, 3) + F(-0.318190f) * AT(3, 3) + F(0.212608f) * AT(5, 3) + F(-0.180240f) * AT(7, 3)); - const Temp_Type X104 = D(F(0.906127f) * AT(1, 4) + F(-0.318190f) * AT(3, 4) + F(0.212608f) * AT(5, 4) + F(-0.180240f) * AT(7, 4)); - const Temp_Type X105 = D(F(0.906127f) * AT(1, 5) + F(-0.318190f) * AT(3, 5) + F(0.212608f) * AT(5, 5) + F(-0.180240f) * AT(7, 5)); - const Temp_Type X106 = D(F(0.906127f) * AT(1, 6) + F(-0.318190f) * AT(3, 6) + F(0.212608f) * AT(5, 6) + F(-0.180240f) * AT(7, 6)); - const Temp_Type X107 = D(F(0.906127f) * AT(1, 7) + F(-0.318190f) * AT(3, 7) + F(0.212608f) * AT(5, 7) + F(-0.180240f) * AT(7, 7)); - const Temp_Type X110 = AT(2, 0); - const Temp_Type X111 = AT(2, 1); - const Temp_Type X112 = AT(2, 2); - const Temp_Type X113 = AT(2, 3); - const Temp_Type X114 = AT(2, 4); - const Temp_Type X115 = AT(2, 5); - const Temp_Type X116 = AT(2, 6); - const Temp_Type X117 = AT(2, 7); - const Temp_Type X120 = D(F(-0.074658f) * AT(1, 0) + F(0.513280f) * AT(3, 0) + F(0.768178f) * AT(5, 0) + F(-0.375330f) * AT(7, 0)); - const Temp_Type X121 = D(F(-0.074658f) * AT(1, 1) + F(0.513280f) * AT(3, 1) + F(0.768178f) * AT(5, 1) + F(-0.375330f) * AT(7, 1)); - const Temp_Type X122 = D(F(-0.074658f) * AT(1, 2) + F(0.513280f) * AT(3, 2) + F(0.768178f) * AT(5, 2) + F(-0.375330f) * AT(7, 2)); - const Temp_Type X123 = D(F(-0.074658f) * AT(1, 3) + F(0.513280f) * AT(3, 3) + F(0.768178f) * AT(5, 3) + F(-0.375330f) * AT(7, 3)); - const Temp_Type X124 = D(F(-0.074658f) * AT(1, 4) + F(0.513280f) * AT(3, 4) + F(0.768178f) * AT(5, 4) + F(-0.375330f) * AT(7, 4)); - const Temp_Type X125 = D(F(-0.074658f) * AT(1, 5) + F(0.513280f) * AT(3, 5) + F(0.768178f) * AT(5, 5) + F(-0.375330f) * AT(7, 5)); - const Temp_Type X126 = D(F(-0.074658f) * AT(1, 6) + F(0.513280f) * AT(3, 6) + F(0.768178f) * AT(5, 6) + F(-0.375330f) * AT(7, 6)); - const Temp_Type X127 = D(F(-0.074658f) * AT(1, 7) + F(0.513280f) * AT(3, 7) + F(0.768178f) * AT(5, 7) + F(-0.375330f) * AT(7, 7)); - const Temp_Type X130 = AT(6, 0); - const Temp_Type X131 = AT(6, 1); - const Temp_Type X132 = AT(6, 2); - const Temp_Type X133 = AT(6, 3); - const Temp_Type X134 = AT(6, 4); - const Temp_Type X135 = AT(6, 5); - const Temp_Type X136 = AT(6, 6); - const Temp_Type X137 = AT(6, 7); - // 80 muls 48 adds - - // 4x4 = 4x8 times 8x4, matrix 1 is constant - R.at(0, 0) = X100; - R.at(0, 1) = D(X101 * F(0.415735f) + X103 * F(0.791065f) + X105 * F(-0.352443f) + X107 * F(0.277785f)); - R.at(0, 2) = X104; - R.at(0, 3) = D(X101 * F(0.022887f) + X103 * F(-0.097545f) + X105 * F(0.490393f) + X107 * F(0.865723f)); - R.at(1, 0) = X110; - R.at(1, 1) = D(X111 * F(0.415735f) + X113 * F(0.791065f) + X115 * F(-0.352443f) + X117 * F(0.277785f)); - R.at(1, 2) = X114; - R.at(1, 3) = D(X111 * F(0.022887f) + X113 * F(-0.097545f) + X115 * F(0.490393f) + X117 * F(0.865723f)); - R.at(2, 0) = X120; - R.at(2, 1) = D(X121 * F(0.415735f) + X123 * F(0.791065f) + X125 * F(-0.352443f) + X127 * F(0.277785f)); - R.at(2, 2) = X124; - R.at(2, 3) = D(X121 * F(0.022887f) + X123 * F(-0.097545f) + X125 * F(0.490393f) + X127 * F(0.865723f)); - R.at(3, 0) = X130; - R.at(3, 1) = D(X131 * F(0.415735f) + X133 * F(0.791065f) + X135 * F(-0.352443f) + X137 * F(0.277785f)); - R.at(3, 2) = X134; - R.at(3, 3) = D(X131 * F(0.022887f) + X133 * F(-0.097545f) + X135 * F(0.490393f) + X137 * F(0.865723f)); - // 40 muls 24 adds - // 4x4 = 4x8 times 8x4, matrix 1 is constant - S.at(0, 0) = D(X101 * F(0.906127f) + X103 * F(-0.318190f) + X105 * F(0.212608f) + X107 * F(-0.180240f)); - S.at(0, 1) = X102; - S.at(0, 2) = D(X101 * F(-0.074658f) + X103 * F(0.513280f) + X105 * F(0.768178f) + X107 * F(-0.375330f)); - S.at(0, 3) = X106; - S.at(1, 0) = D(X111 * F(0.906127f) + X113 * F(-0.318190f) + X115 * F(0.212608f) + X117 * F(-0.180240f)); - S.at(1, 1) = X112; - S.at(1, 2) = D(X111 * F(-0.074658f) + X113 * F(0.513280f) + X115 * F(0.768178f) + X117 * F(-0.375330f)); - S.at(1, 3) = X116; - S.at(2, 0) = D(X121 * F(0.906127f) + X123 * F(-0.318190f) + X125 * F(0.212608f) + X127 * F(-0.180240f)); - S.at(2, 1) = X122; - S.at(2, 2) = D(X121 * F(-0.074658f) + X123 * F(0.513280f) + X125 * F(0.768178f) + X127 * F(-0.375330f)); - S.at(2, 3) = X126; - S.at(3, 0) = D(X131 * F(0.906127f) + X133 * F(-0.318190f) + X135 * F(0.212608f) + X137 * F(-0.180240f)); - S.at(3, 1) = X132; - S.at(3, 2) = D(X131 * F(-0.074658f) + X133 * F(0.513280f) + X135 * F(0.768178f) + X137 * F(-0.375330f)); - S.at(3, 3) = X136; - // 40 muls 24 adds - } - }; -} // end namespace DCT_Upsample - -// Unconditionally frees all allocated m_blocks. -void jpeg_decoder::free_all_blocks() -{ - m_pStream = NULL; - for (mem_block *b = m_pMem_blocks; b; ) - { - mem_block *n = b->m_pNext; - jpgd_free(b); - b = n; - } - m_pMem_blocks = NULL; -} - -// This method handles all errors. It will never return. -// It could easily be changed to use C++ exceptions. -JPGD_NORETURN void jpeg_decoder::stop_decoding(jpgd_status status) -{ - m_error_code = status; - free_all_blocks(); - longjmp(m_jmp_state, status); -} - -void *jpeg_decoder::alloc(size_t nSize, bool zero) -{ - nSize = (JPGD_MAX(nSize, 1) + 3) & ~3; - char *rv = NULL; - for (mem_block *b = m_pMem_blocks; b; b = b->m_pNext) - { - if ((b->m_used_count + nSize) <= b->m_size) - { - rv = b->m_data + b->m_used_count; - b->m_used_count += nSize; - break; - } - } - if (!rv) - { - int capacity = JPGD_MAX(32768 - 256, (nSize + 2047) & ~2047); - mem_block *b = (mem_block*)jpgd_malloc(sizeof(mem_block) + capacity); - if (!b) { stop_decoding(JPGD_NOTENOUGHMEM); } - b->m_pNext = m_pMem_blocks; m_pMem_blocks = b; - b->m_used_count = nSize; - b->m_size = capacity; - rv = b->m_data; - } - if (zero) memset(rv, 0, nSize); - return rv; -} - -void jpeg_decoder::word_clear(void *p, uint16 c, uint n) -{ - uint8 *pD = (uint8*)p; - const uint8 l = c & 0xFF, h = (c >> 8) & 0xFF; - while (n) - { - pD[0] = l; pD[1] = h; pD += 2; - n--; - } -} - -// Refill the input buffer. -// This method will sit in a loop until (A) the buffer is full or (B) -// the stream's read() method reports and end of file condition. -void jpeg_decoder::prep_in_buffer() -{ - m_in_buf_left = 0; - m_pIn_buf_ofs = m_in_buf; - - if (m_eof_flag) - return; - - do - { - int bytes_read = m_pStream->read(m_in_buf + m_in_buf_left, JPGD_IN_BUF_SIZE - m_in_buf_left, &m_eof_flag); - if (bytes_read == -1) - stop_decoding(JPGD_STREAM_READ); - - m_in_buf_left += bytes_read; - } while ((m_in_buf_left < JPGD_IN_BUF_SIZE) && (!m_eof_flag)); - - m_total_bytes_read += m_in_buf_left; - - // Pad the end of the block with M_EOI (prevents the decompressor from going off the rails if the stream is invalid). - // (This dates way back to when this decompressor was written in C/asm, and the all-asm Huffman decoder did some fancy things to increase perf.) - word_clear(m_pIn_buf_ofs + m_in_buf_left, 0xD9FF, 64); -} - -// Read a Huffman code table. -void jpeg_decoder::read_dht_marker() -{ - int i, index, count; - uint8 huff_num[17]; - uint8 huff_val[256]; - - uint num_left = get_bits(16); - - if (num_left < 2) - stop_decoding(JPGD_BAD_DHT_MARKER); - - num_left -= 2; - - while (num_left) - { - index = get_bits(8); - - huff_num[0] = 0; - - count = 0; - - for (i = 1; i <= 16; i++) - { - huff_num[i] = static_cast<uint8>(get_bits(8)); - count += huff_num[i]; - } - - if (count > 255) - stop_decoding(JPGD_BAD_DHT_COUNTS); - - for (i = 0; i < count; i++) - huff_val[i] = static_cast<uint8>(get_bits(8)); + // Unconditionally frees all allocated m_blocks. + void jpeg_decoder::free_all_blocks() + { + m_pStream = nullptr; + for (mem_block* b = m_pMem_blocks; b; ) + { + mem_block* n = b->m_pNext; + jpgd_free(b); + b = n; + } + m_pMem_blocks = nullptr; + } + + // This method handles all errors. It will never return. + // It could easily be changed to use C++ exceptions. + JPGD_NORETURN void jpeg_decoder::stop_decoding(jpgd_status status) + { + m_error_code = status; + free_all_blocks(); + longjmp(m_jmp_state, status); + } + + void* jpeg_decoder::alloc(size_t nSize, bool zero) + { + nSize = (JPGD_MAX(nSize, 1) + 3) & ~3; + char* rv = nullptr; + for (mem_block* b = m_pMem_blocks; b; b = b->m_pNext) + { + if ((b->m_used_count + nSize) <= b->m_size) + { + rv = b->m_data + b->m_used_count; + b->m_used_count += nSize; + break; + } + } + if (!rv) + { + int capacity = JPGD_MAX(32768 - 256, (nSize + 2047) & ~2047); + mem_block* b = (mem_block*)jpgd_malloc(sizeof(mem_block) + capacity); + if (!b) + { + stop_decoding(JPGD_NOTENOUGHMEM); + } + + b->m_pNext = m_pMem_blocks; + m_pMem_blocks = b; + b->m_used_count = nSize; + b->m_size = capacity; + rv = b->m_data; + } + if (zero) memset(rv, 0, nSize); + return rv; + } + + void* jpeg_decoder::alloc_aligned(size_t nSize, uint32_t align, bool zero) + { + assert((align >= 1U) && ((align & (align - 1U)) == 0U)); + void *p = alloc(nSize + align - 1U, zero); + p = (void *)( ((uintptr_t)p + (align - 1U)) & ~((uintptr_t)(align - 1U)) ); + return p; + } + + void jpeg_decoder::word_clear(void* p, uint16 c, uint n) + { + uint8* pD = (uint8*)p; + const uint8 l = c & 0xFF, h = (c >> 8) & 0xFF; + while (n) + { + pD[0] = l; + pD[1] = h; + pD += 2; + n--; + } + } + + // Refill the input buffer. + // This method will sit in a loop until (A) the buffer is full or (B) + // the stream's read() method reports and end of file condition. + void jpeg_decoder::prep_in_buffer() + { + m_in_buf_left = 0; + m_pIn_buf_ofs = m_in_buf; + + if (m_eof_flag) + return; + + do + { + int bytes_read = m_pStream->read(m_in_buf + m_in_buf_left, JPGD_IN_BUF_SIZE - m_in_buf_left, &m_eof_flag); + if (bytes_read == -1) + stop_decoding(JPGD_STREAM_READ); + + m_in_buf_left += bytes_read; + } while ((m_in_buf_left < JPGD_IN_BUF_SIZE) && (!m_eof_flag)); + + m_total_bytes_read += m_in_buf_left; + + // Pad the end of the block with M_EOI (prevents the decompressor from going off the rails if the stream is invalid). + // (This dates way back to when this decompressor was written in C/asm, and the all-asm Huffman decoder did some fancy things to increase perf.) + word_clear(m_pIn_buf_ofs + m_in_buf_left, 0xD9FF, 64); + } + + // Read a Huffman code table. + void jpeg_decoder::read_dht_marker() + { + int i, index, count; + uint8 huff_num[17]; + uint8 huff_val[256]; + + uint num_left = get_bits(16); + + if (num_left < 2) + stop_decoding(JPGD_BAD_DHT_MARKER); + + num_left -= 2; + + while (num_left) + { + index = get_bits(8); + + huff_num[0] = 0; + + count = 0; + + for (i = 1; i <= 16; i++) + { + huff_num[i] = static_cast<uint8>(get_bits(8)); + count += huff_num[i]; + } + + if (count > 255) + stop_decoding(JPGD_BAD_DHT_COUNTS); + + bool symbol_present[256]; + memset(symbol_present, 0, sizeof(symbol_present)); - i = 1 + 16 + count; + for (i = 0; i < count; i++) + { + const int s = get_bits(8); + + // Check for obviously bogus tables. + if (symbol_present[s]) + stop_decoding(JPGD_BAD_DHT_COUNTS); + + huff_val[i] = static_cast<uint8_t>(s); + symbol_present[s] = true; + } - if (num_left < (uint)i) - stop_decoding(JPGD_BAD_DHT_MARKER); + i = 1 + 16 + count; - num_left -= i; + if (num_left < (uint)i) + stop_decoding(JPGD_BAD_DHT_MARKER); - if ((index & 0x10) > 0x10) - stop_decoding(JPGD_BAD_DHT_INDEX); + num_left -= i; - index = (index & 0x0F) + ((index & 0x10) >> 4) * (JPGD_MAX_HUFF_TABLES >> 1); + if ((index & 0x10) > 0x10) + stop_decoding(JPGD_BAD_DHT_INDEX); - if (index >= JPGD_MAX_HUFF_TABLES) - stop_decoding(JPGD_BAD_DHT_INDEX); + index = (index & 0x0F) + ((index & 0x10) >> 4) * (JPGD_MAX_HUFF_TABLES >> 1); - if (!m_huff_num[index]) - m_huff_num[index] = (uint8 *)alloc(17); + if (index >= JPGD_MAX_HUFF_TABLES) + stop_decoding(JPGD_BAD_DHT_INDEX); - if (!m_huff_val[index]) - m_huff_val[index] = (uint8 *)alloc(256); + if (!m_huff_num[index]) + m_huff_num[index] = (uint8*)alloc(17); - m_huff_ac[index] = (index & 0x10) != 0; - memcpy(m_huff_num[index], huff_num, 17); - memcpy(m_huff_val[index], huff_val, 256); - } -} + if (!m_huff_val[index]) + m_huff_val[index] = (uint8*)alloc(256); -// Read a quantization table. -void jpeg_decoder::read_dqt_marker() -{ - int n, i, prec; - uint num_left; - uint temp; + m_huff_ac[index] = (index & 0x10) != 0; + memcpy(m_huff_num[index], huff_num, 17); + memcpy(m_huff_val[index], huff_val, 256); + } + } - num_left = get_bits(16); + // Read a quantization table. + void jpeg_decoder::read_dqt_marker() + { + int n, i, prec; + uint num_left; + uint temp; - if (num_left < 2) - stop_decoding(JPGD_BAD_DQT_MARKER); + num_left = get_bits(16); - num_left -= 2; + if (num_left < 2) + stop_decoding(JPGD_BAD_DQT_MARKER); - while (num_left) - { - n = get_bits(8); - prec = n >> 4; - n &= 0x0F; + num_left -= 2; - if (n >= JPGD_MAX_QUANT_TABLES) - stop_decoding(JPGD_BAD_DQT_TABLE); + while (num_left) + { + n = get_bits(8); + prec = n >> 4; + n &= 0x0F; - if (!m_quant[n]) - m_quant[n] = (jpgd_quant_t *)alloc(64 * sizeof(jpgd_quant_t)); + if (n >= JPGD_MAX_QUANT_TABLES) + stop_decoding(JPGD_BAD_DQT_TABLE); - // read quantization entries, in zag order - for (i = 0; i < 64; i++) - { - temp = get_bits(8); + if (!m_quant[n]) + m_quant[n] = (jpgd_quant_t*)alloc(64 * sizeof(jpgd_quant_t)); - if (prec) - temp = (temp << 8) + get_bits(8); + // read quantization entries, in zag order + for (i = 0; i < 64; i++) + { + temp = get_bits(8); - m_quant[n][i] = static_cast<jpgd_quant_t>(temp); - } + if (prec) + temp = (temp << 8) + get_bits(8); - i = 64 + 1; + m_quant[n][i] = static_cast<jpgd_quant_t>(temp); + } - if (prec) - i += 64; + i = 64 + 1; - if (num_left < (uint)i) - stop_decoding(JPGD_BAD_DQT_LENGTH); + if (prec) + i += 64; - num_left -= i; - } -} + if (num_left < (uint)i) + stop_decoding(JPGD_BAD_DQT_LENGTH); -// Read the start of frame (SOF) marker. -void jpeg_decoder::read_sof_marker() -{ - int i; - uint num_left; + num_left -= i; + } + } - num_left = get_bits(16); + // Read the start of frame (SOF) marker. + void jpeg_decoder::read_sof_marker() + { + int i; + uint num_left; - if (get_bits(8) != 8) /* precision: sorry, only 8-bit precision is supported right now */ - stop_decoding(JPGD_BAD_PRECISION); + num_left = get_bits(16); - m_image_y_size = get_bits(16); + /* precision: sorry, only 8-bit precision is supported */ + if (get_bits(8) != 8) + stop_decoding(JPGD_BAD_PRECISION); - if ((m_image_y_size < 1) || (m_image_y_size > JPGD_MAX_HEIGHT)) - stop_decoding(JPGD_BAD_HEIGHT); + m_image_y_size = get_bits(16); - m_image_x_size = get_bits(16); + if ((m_image_y_size < 1) || (m_image_y_size > JPGD_MAX_HEIGHT)) + stop_decoding(JPGD_BAD_HEIGHT); - if ((m_image_x_size < 1) || (m_image_x_size > JPGD_MAX_WIDTH)) - stop_decoding(JPGD_BAD_WIDTH); + m_image_x_size = get_bits(16); - m_comps_in_frame = get_bits(8); + if ((m_image_x_size < 1) || (m_image_x_size > JPGD_MAX_WIDTH)) + stop_decoding(JPGD_BAD_WIDTH); - if (m_comps_in_frame > JPGD_MAX_COMPONENTS) - stop_decoding(JPGD_TOO_MANY_COMPONENTS); + m_comps_in_frame = get_bits(8); - if (num_left != (uint)(m_comps_in_frame * 3 + 8)) - stop_decoding(JPGD_BAD_SOF_LENGTH); + if (m_comps_in_frame > JPGD_MAX_COMPONENTS) + stop_decoding(JPGD_TOO_MANY_COMPONENTS); - for (i = 0; i < m_comps_in_frame; i++) - { - m_comp_ident[i] = get_bits(8); - m_comp_h_samp[i] = get_bits(4); - m_comp_v_samp[i] = get_bits(4); - m_comp_quant[i] = get_bits(8); - } -} + if (num_left != (uint)(m_comps_in_frame * 3 + 8)) + stop_decoding(JPGD_BAD_SOF_LENGTH); -// Used to skip unrecognized markers. -void jpeg_decoder::skip_variable_marker() -{ - uint num_left; + for (i = 0; i < m_comps_in_frame; i++) + { + m_comp_ident[i] = get_bits(8); + m_comp_h_samp[i] = get_bits(4); + m_comp_v_samp[i] = get_bits(4); - num_left = get_bits(16); + if (!m_comp_h_samp[i] || !m_comp_v_samp[i] || (m_comp_h_samp[i] > 2) || (m_comp_v_samp[i] > 2)) + stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS); - if (num_left < 2) - stop_decoding(JPGD_BAD_VARIABLE_MARKER); + m_comp_quant[i] = get_bits(8); + if (m_comp_quant[i] >= JPGD_MAX_QUANT_TABLES) + stop_decoding(JPGD_DECODE_ERROR); + } + } + + // Used to skip unrecognized markers. + void jpeg_decoder::skip_variable_marker() + { + uint num_left; + + num_left = get_bits(16); + + if (num_left < 2) + stop_decoding(JPGD_BAD_VARIABLE_MARKER); + + num_left -= 2; + + while (num_left) + { + get_bits(8); + num_left--; + } + } + + // Read a define restart interval (DRI) marker. + void jpeg_decoder::read_dri_marker() + { + if (get_bits(16) != 4) + stop_decoding(JPGD_BAD_DRI_LENGTH); + + m_restart_interval = get_bits(16); + } + + // Read a start of scan (SOS) marker. + void jpeg_decoder::read_sos_marker() + { + uint num_left; + int i, ci, n, c, cc; + + num_left = get_bits(16); + + n = get_bits(8); + + m_comps_in_scan = n; + + num_left -= 3; + + if ((num_left != (uint)(n * 2 + 3)) || (n < 1) || (n > JPGD_MAX_COMPS_IN_SCAN)) + stop_decoding(JPGD_BAD_SOS_LENGTH); + + for (i = 0; i < n; i++) + { + cc = get_bits(8); + c = get_bits(8); + num_left -= 2; + + for (ci = 0; ci < m_comps_in_frame; ci++) + if (cc == m_comp_ident[ci]) + break; + + if (ci >= m_comps_in_frame) + stop_decoding(JPGD_BAD_SOS_COMP_ID); + + if (ci >= JPGD_MAX_COMPONENTS) + stop_decoding(JPGD_DECODE_ERROR); + + m_comp_list[i] = ci; + + m_comp_dc_tab[ci] = (c >> 4) & 15; + m_comp_ac_tab[ci] = (c & 15) + (JPGD_MAX_HUFF_TABLES >> 1); + + if (m_comp_dc_tab[ci] >= JPGD_MAX_HUFF_TABLES) + stop_decoding(JPGD_DECODE_ERROR); + + if (m_comp_ac_tab[ci] >= JPGD_MAX_HUFF_TABLES) + stop_decoding(JPGD_DECODE_ERROR); + } + + m_spectral_start = get_bits(8); + m_spectral_end = get_bits(8); + m_successive_high = get_bits(4); + m_successive_low = get_bits(4); + + if (!m_progressive_flag) + { + m_spectral_start = 0; + m_spectral_end = 63; + } + + num_left -= 3; + + /* read past whatever is num_left */ + while (num_left) + { + get_bits(8); + num_left--; + } + } + + // Finds the next marker. + int jpeg_decoder::next_marker() + { + uint c, bytes; + + bytes = 0; + + do + { + do + { + bytes++; + c = get_bits(8); + } while (c != 0xFF); - num_left -= 2; + do + { + c = get_bits(8); + } while (c == 0xFF); + + } while (c == 0); + + // If bytes > 0 here, there where extra bytes before the marker (not good). + + return c; + } + + // Process markers. Returns when an SOFx, SOI, EOI, or SOS marker is + // encountered. + int jpeg_decoder::process_markers() + { + int c; + + for (; ; ) + { + c = next_marker(); + + switch (c) + { + case M_SOF0: + case M_SOF1: + case M_SOF2: + case M_SOF3: + case M_SOF5: + case M_SOF6: + case M_SOF7: + // case M_JPG: + case M_SOF9: + case M_SOF10: + case M_SOF11: + case M_SOF13: + case M_SOF14: + case M_SOF15: + case M_SOI: + case M_EOI: + case M_SOS: + { + return c; + } + case M_DHT: + { + read_dht_marker(); + break; + } + // No arithmitic support - dumb patents! + case M_DAC: + { + stop_decoding(JPGD_NO_ARITHMITIC_SUPPORT); + break; + } + case M_DQT: + { + read_dqt_marker(); + break; + } + case M_DRI: + { + read_dri_marker(); + break; + } + //case M_APP0: /* no need to read the JFIF marker */ + case M_JPG: + case M_RST0: /* no parameters */ + case M_RST1: + case M_RST2: + case M_RST3: + case M_RST4: + case M_RST5: + case M_RST6: + case M_RST7: + case M_TEM: + { + stop_decoding(JPGD_UNEXPECTED_MARKER); + break; + } + default: /* must be DNL, DHP, EXP, APPn, JPGn, COM, or RESn or APP0 */ + { + skip_variable_marker(); + break; + } + } + } + } + + // Finds the start of image (SOI) marker. + void jpeg_decoder::locate_soi_marker() + { + uint lastchar, thischar; + uint bytesleft; + + lastchar = get_bits(8); + + thischar = get_bits(8); + + /* ok if it's a normal JPEG file without a special header */ + + if ((lastchar == 0xFF) && (thischar == M_SOI)) + return; + + bytesleft = 4096; + + for (; ; ) + { + if (--bytesleft == 0) + stop_decoding(JPGD_NOT_JPEG); + + lastchar = thischar; + + thischar = get_bits(8); + + if (lastchar == 0xFF) + { + if (thischar == M_SOI) + break; + else if (thischar == M_EOI) // get_bits will keep returning M_EOI if we read past the end + stop_decoding(JPGD_NOT_JPEG); + } + } + + // Check the next character after marker: if it's not 0xFF, it can't be the start of the next marker, so the file is bad. + thischar = (m_bit_buf >> 24) & 0xFF; + + if (thischar != 0xFF) + stop_decoding(JPGD_NOT_JPEG); + } + + // Find a start of frame (SOF) marker. + void jpeg_decoder::locate_sof_marker() + { + locate_soi_marker(); + + int c = process_markers(); + + switch (c) + { + case M_SOF2: + { + m_progressive_flag = JPGD_TRUE; + read_sof_marker(); + break; + } + case M_SOF0: /* baseline DCT */ + case M_SOF1: /* extended sequential DCT */ + { + read_sof_marker(); + break; + } + case M_SOF9: /* Arithmitic coding */ + { + stop_decoding(JPGD_NO_ARITHMITIC_SUPPORT); + break; + } + default: + { + stop_decoding(JPGD_UNSUPPORTED_MARKER); + break; + } + } + } - while (num_left) - { - get_bits(8); - num_left--; - } -} + // Find a start of scan (SOS) marker. + int jpeg_decoder::locate_sos_marker() + { + int c; -// Read a define restart interval (DRI) marker. -void jpeg_decoder::read_dri_marker() -{ - if (get_bits(16) != 4) - stop_decoding(JPGD_BAD_DRI_LENGTH); + c = process_markers(); - m_restart_interval = get_bits(16); -} + if (c == M_EOI) + return JPGD_FALSE; + else if (c != M_SOS) + stop_decoding(JPGD_UNEXPECTED_MARKER); -// Read a start of scan (SOS) marker. -void jpeg_decoder::read_sos_marker() -{ - uint num_left; - int i, ci, n, c, cc; + read_sos_marker(); - num_left = get_bits(16); + return JPGD_TRUE; + } - n = get_bits(8); - - m_comps_in_scan = n; - - num_left -= 3; - - if ( (num_left != (uint)(n * 2 + 3)) || (n < 1) || (n > JPGD_MAX_COMPS_IN_SCAN) ) - stop_decoding(JPGD_BAD_SOS_LENGTH); - - for (i = 0; i < n; i++) - { - cc = get_bits(8); - c = get_bits(8); - num_left -= 2; - - for (ci = 0; ci < m_comps_in_frame; ci++) - if (cc == m_comp_ident[ci]) - break; - - if (ci >= m_comps_in_frame) - stop_decoding(JPGD_BAD_SOS_COMP_ID); - - m_comp_list[i] = ci; - m_comp_dc_tab[ci] = (c >> 4) & 15; - m_comp_ac_tab[ci] = (c & 15) + (JPGD_MAX_HUFF_TABLES >> 1); - } - - m_spectral_start = get_bits(8); - m_spectral_end = get_bits(8); - m_successive_high = get_bits(4); - m_successive_low = get_bits(4); - - if (!m_progressive_flag) - { - m_spectral_start = 0; - m_spectral_end = 63; - } - - num_left -= 3; - - while (num_left) /* read past whatever is num_left */ - { - get_bits(8); - num_left--; - } -} - -// Finds the next marker. -int jpeg_decoder::next_marker() -{ - uint c, bytes; - - bytes = 0; - - do - { - do - { - bytes++; - c = get_bits(8); - } while (c != 0xFF); - - do - { - c = get_bits(8); - } while (c == 0xFF); - - } while (c == 0); - - // If bytes > 0 here, there where extra bytes before the marker (not good). - - return c; -} - -// Process markers. Returns when an SOFx, SOI, EOI, or SOS marker is -// encountered. -int jpeg_decoder::process_markers() -{ - int c; - - for ( ; ; ) - { - c = next_marker(); - - switch (c) - { - case M_SOF0: - case M_SOF1: - case M_SOF2: - case M_SOF3: - case M_SOF5: - case M_SOF6: - case M_SOF7: -// case M_JPG: - case M_SOF9: - case M_SOF10: - case M_SOF11: - case M_SOF13: - case M_SOF14: - case M_SOF15: - case M_SOI: - case M_EOI: - case M_SOS: - { - return c; - } - case M_DHT: - { - read_dht_marker(); - break; - } - // No arithmitic support - dumb patents! - case M_DAC: - { - stop_decoding(JPGD_NO_ARITHMITIC_SUPPORT); - break; - } - case M_DQT: - { - read_dqt_marker(); - break; - } - case M_DRI: - { - read_dri_marker(); - break; - } - //case M_APP0: /* no need to read the JFIF marker */ - - case M_JPG: - case M_RST0: /* no parameters */ - case M_RST1: - case M_RST2: - case M_RST3: - case M_RST4: - case M_RST5: - case M_RST6: - case M_RST7: - case M_TEM: - { - stop_decoding(JPGD_UNEXPECTED_MARKER); - break; - } - default: /* must be DNL, DHP, EXP, APPn, JPGn, COM, or RESn or APP0 */ - { - skip_variable_marker(); - break; - } - } - } -} - -// Finds the start of image (SOI) marker. -// This code is rather defensive: it only checks the first 512 bytes to avoid -// false positives. -void jpeg_decoder::locate_soi_marker() -{ - uint lastchar, thischar; - uint bytesleft; - - lastchar = get_bits(8); - - thischar = get_bits(8); - - /* ok if it's a normal JPEG file without a special header */ - - if ((lastchar == 0xFF) && (thischar == M_SOI)) - return; - - bytesleft = 4096; //512; - - for ( ; ; ) - { - if (--bytesleft == 0) - stop_decoding(JPGD_NOT_JPEG); - - lastchar = thischar; - - thischar = get_bits(8); - - if (lastchar == 0xFF) - { - if (thischar == M_SOI) - break; - else if (thischar == M_EOI) // get_bits will keep returning M_EOI if we read past the end - stop_decoding(JPGD_NOT_JPEG); - } - } - - // Check the next character after marker: if it's not 0xFF, it can't be the start of the next marker, so the file is bad. - thischar = (m_bit_buf >> 24) & 0xFF; - - if (thischar != 0xFF) - stop_decoding(JPGD_NOT_JPEG); -} - -// Find a start of frame (SOF) marker. -void jpeg_decoder::locate_sof_marker() -{ - locate_soi_marker(); - - int c = process_markers(); - - switch (c) - { - case M_SOF2: - m_progressive_flag = JPGD_TRUE; - case M_SOF0: /* baseline DCT */ - case M_SOF1: /* extended sequential DCT */ - { - read_sof_marker(); - break; - } - case M_SOF9: /* Arithmitic coding */ - { - stop_decoding(JPGD_NO_ARITHMITIC_SUPPORT); - break; - } - default: - { - stop_decoding(JPGD_UNSUPPORTED_MARKER); - break; - } - } -} - -// Find a start of scan (SOS) marker. -int jpeg_decoder::locate_sos_marker() -{ - int c; - - c = process_markers(); - - if (c == M_EOI) - return JPGD_FALSE; - else if (c != M_SOS) - stop_decoding(JPGD_UNEXPECTED_MARKER); - - read_sos_marker(); - - return JPGD_TRUE; -} - -// Reset everything to default/uninitialized state. -void jpeg_decoder::init(jpeg_decoder_stream *pStream) -{ - m_pMem_blocks = NULL; - m_error_code = JPGD_SUCCESS; - m_ready_flag = false; - m_image_x_size = m_image_y_size = 0; - m_pStream = pStream; - m_progressive_flag = JPGD_FALSE; - - memset(m_huff_ac, 0, sizeof(m_huff_ac)); - memset(m_huff_num, 0, sizeof(m_huff_num)); - memset(m_huff_val, 0, sizeof(m_huff_val)); - memset(m_quant, 0, sizeof(m_quant)); - - m_scan_type = 0; - m_comps_in_frame = 0; - - memset(m_comp_h_samp, 0, sizeof(m_comp_h_samp)); - memset(m_comp_v_samp, 0, sizeof(m_comp_v_samp)); - memset(m_comp_quant, 0, sizeof(m_comp_quant)); - memset(m_comp_ident, 0, sizeof(m_comp_ident)); - memset(m_comp_h_blocks, 0, sizeof(m_comp_h_blocks)); - memset(m_comp_v_blocks, 0, sizeof(m_comp_v_blocks)); - - m_comps_in_scan = 0; - memset(m_comp_list, 0, sizeof(m_comp_list)); - memset(m_comp_dc_tab, 0, sizeof(m_comp_dc_tab)); - memset(m_comp_ac_tab, 0, sizeof(m_comp_ac_tab)); - - m_spectral_start = 0; - m_spectral_end = 0; - m_successive_low = 0; - m_successive_high = 0; - m_max_mcu_x_size = 0; - m_max_mcu_y_size = 0; - m_blocks_per_mcu = 0; - m_max_blocks_per_row = 0; - m_mcus_per_row = 0; - m_mcus_per_col = 0; - m_expanded_blocks_per_component = 0; - m_expanded_blocks_per_mcu = 0; - m_expanded_blocks_per_row = 0; - m_freq_domain_chroma_upsample = false; - - memset(m_mcu_org, 0, sizeof(m_mcu_org)); - - m_total_lines_left = 0; - m_mcu_lines_left = 0; - m_real_dest_bytes_per_scan_line = 0; - m_dest_bytes_per_scan_line = 0; - m_dest_bytes_per_pixel = 0; - - memset(m_pHuff_tabs, 0, sizeof(m_pHuff_tabs)); - - memset(m_dc_coeffs, 0, sizeof(m_dc_coeffs)); - memset(m_ac_coeffs, 0, sizeof(m_ac_coeffs)); - memset(m_block_y_mcu, 0, sizeof(m_block_y_mcu)); - - m_eob_run = 0; - - memset(m_block_y_mcu, 0, sizeof(m_block_y_mcu)); - - m_pIn_buf_ofs = m_in_buf; - m_in_buf_left = 0; - m_eof_flag = false; - m_tem_flag = 0; - - memset(m_in_buf_pad_start, 0, sizeof(m_in_buf_pad_start)); - memset(m_in_buf, 0, sizeof(m_in_buf)); - memset(m_in_buf_pad_end, 0, sizeof(m_in_buf_pad_end)); - - m_restart_interval = 0; - m_restarts_left = 0; - m_next_restart_num = 0; - - m_max_mcus_per_row = 0; - m_max_blocks_per_mcu = 0; - m_max_mcus_per_col = 0; - - memset(m_last_dc_val, 0, sizeof(m_last_dc_val)); - m_pMCU_coefficients = NULL; - m_pSample_buf = NULL; - - m_total_bytes_read = 0; - - m_pScan_line_0 = NULL; - m_pScan_line_1 = NULL; - - // Ready the input buffer. - prep_in_buffer(); - - // Prime the bit buffer. - m_bits_left = 16; - m_bit_buf = 0; - - get_bits(16); - get_bits(16); - - for (int i = 0; i < JPGD_MAX_BLOCKS_PER_MCU; i++) - m_mcu_block_max_zag[i] = 64; -} + // Reset everything to default/uninitialized state. + void jpeg_decoder::init(jpeg_decoder_stream* pStream, uint32_t flags) + { + m_flags = flags; + m_pMem_blocks = nullptr; + m_error_code = JPGD_SUCCESS; + m_ready_flag = false; + m_image_x_size = m_image_y_size = 0; + m_pStream = pStream; + m_progressive_flag = JPGD_FALSE; + + memset(m_huff_ac, 0, sizeof(m_huff_ac)); + memset(m_huff_num, 0, sizeof(m_huff_num)); + memset(m_huff_val, 0, sizeof(m_huff_val)); + memset(m_quant, 0, sizeof(m_quant)); + + m_scan_type = 0; + m_comps_in_frame = 0; + + memset(m_comp_h_samp, 0, sizeof(m_comp_h_samp)); + memset(m_comp_v_samp, 0, sizeof(m_comp_v_samp)); + memset(m_comp_quant, 0, sizeof(m_comp_quant)); + memset(m_comp_ident, 0, sizeof(m_comp_ident)); + memset(m_comp_h_blocks, 0, sizeof(m_comp_h_blocks)); + memset(m_comp_v_blocks, 0, sizeof(m_comp_v_blocks)); + + m_comps_in_scan = 0; + memset(m_comp_list, 0, sizeof(m_comp_list)); + memset(m_comp_dc_tab, 0, sizeof(m_comp_dc_tab)); + memset(m_comp_ac_tab, 0, sizeof(m_comp_ac_tab)); + + m_spectral_start = 0; + m_spectral_end = 0; + m_successive_low = 0; + m_successive_high = 0; + m_max_mcu_x_size = 0; + m_max_mcu_y_size = 0; + m_blocks_per_mcu = 0; + m_max_blocks_per_row = 0; + m_mcus_per_row = 0; + m_mcus_per_col = 0; + + memset(m_mcu_org, 0, sizeof(m_mcu_org)); + + m_total_lines_left = 0; + m_mcu_lines_left = 0; + m_num_buffered_scanlines = 0; + m_real_dest_bytes_per_scan_line = 0; + m_dest_bytes_per_scan_line = 0; + m_dest_bytes_per_pixel = 0; + + memset(m_pHuff_tabs, 0, sizeof(m_pHuff_tabs)); + + memset(m_dc_coeffs, 0, sizeof(m_dc_coeffs)); + memset(m_ac_coeffs, 0, sizeof(m_ac_coeffs)); + memset(m_block_y_mcu, 0, sizeof(m_block_y_mcu)); + + m_eob_run = 0; + + m_pIn_buf_ofs = m_in_buf; + m_in_buf_left = 0; + m_eof_flag = false; + m_tem_flag = 0; + + memset(m_in_buf_pad_start, 0, sizeof(m_in_buf_pad_start)); + memset(m_in_buf, 0, sizeof(m_in_buf)); + memset(m_in_buf_pad_end, 0, sizeof(m_in_buf_pad_end)); + + m_restart_interval = 0; + m_restarts_left = 0; + m_next_restart_num = 0; + + m_max_mcus_per_row = 0; + m_max_blocks_per_mcu = 0; + m_max_mcus_per_col = 0; + + memset(m_last_dc_val, 0, sizeof(m_last_dc_val)); + m_pMCU_coefficients = nullptr; + m_pSample_buf = nullptr; + m_pSample_buf_prev = nullptr; + m_sample_buf_prev_valid = false; + + m_total_bytes_read = 0; + + m_pScan_line_0 = nullptr; + m_pScan_line_1 = nullptr; + + // Ready the input buffer. + prep_in_buffer(); + + // Prime the bit buffer. + m_bits_left = 16; + m_bit_buf = 0; + + get_bits(16); + get_bits(16); + + for (int i = 0; i < JPGD_MAX_BLOCKS_PER_MCU; i++) + m_mcu_block_max_zag[i] = 64; + + m_has_sse2 = false; + +#if JPGD_USE_SSE2 +#ifdef _MSC_VER + int cpu_info[4]; + __cpuid(cpu_info, 1); + const int cpu_info3 = cpu_info[3]; + m_has_sse2 = ((cpu_info3 >> 26U) & 1U) != 0U; +#else + m_has_sse2 = true; +#endif +#endif + } #define SCALEBITS 16 #define ONE_HALF ((int) 1 << (SCALEBITS-1)) #define FIX(x) ((int) ((x) * (1L<<SCALEBITS) + 0.5f)) -// Create a few tables that allow us to quickly convert YCbCr to RGB. -void jpeg_decoder::create_look_ups() -{ - for (int i = 0; i <= 255; i++) - { - int k = i - 128; - m_crr[i] = ( FIX(1.40200f) * k + ONE_HALF) >> SCALEBITS; - m_cbb[i] = ( FIX(1.77200f) * k + ONE_HALF) >> SCALEBITS; - m_crg[i] = (-FIX(0.71414f)) * k; - m_cbg[i] = (-FIX(0.34414f)) * k + ONE_HALF; - } -} - -// This method throws back into the stream any bytes that where read -// into the bit buffer during initial marker scanning. -void jpeg_decoder::fix_in_buffer() -{ - // In case any 0xFF's where pulled into the buffer during marker scanning. - JPGD_ASSERT((m_bits_left & 7) == 0); - - if (m_bits_left == 16) - stuff_char( (uint8)(m_bit_buf & 0xFF)); - - if (m_bits_left >= 8) - stuff_char( (uint8)((m_bit_buf >> 8) & 0xFF)); - - stuff_char((uint8)((m_bit_buf >> 16) & 0xFF)); - stuff_char((uint8)((m_bit_buf >> 24) & 0xFF)); - - m_bits_left = 16; - get_bits_no_markers(16); - get_bits_no_markers(16); -} - -void jpeg_decoder::transform_mcu(int mcu_row) -{ - jpgd_block_t* pSrc_ptr = m_pMCU_coefficients; - if (m_freq_domain_chroma_upsample) { - JPGD_ASSERT(mcu_row * m_blocks_per_mcu < m_expanded_blocks_per_row); - } - else { - JPGD_ASSERT(mcu_row * m_blocks_per_mcu < m_max_blocks_per_row); - } - uint8* pDst_ptr = m_pSample_buf + mcu_row * m_blocks_per_mcu * 64; - - for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++) - { - idct(pSrc_ptr, pDst_ptr, m_mcu_block_max_zag[mcu_block]); - pSrc_ptr += 64; - pDst_ptr += 64; - } -} - -static const uint8 s_max_rc[64] = -{ - 17, 18, 34, 50, 50, 51, 52, 52, 52, 68, 84, 84, 84, 84, 85, 86, 86, 86, 86, 86, - 102, 118, 118, 118, 118, 118, 118, 119, 120, 120, 120, 120, 120, 120, 120, 136, - 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, - 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136 -}; - -void jpeg_decoder::transform_mcu_expand(int mcu_row) -{ - jpgd_block_t* pSrc_ptr = m_pMCU_coefficients; - uint8* pDst_ptr = m_pSample_buf + mcu_row * m_expanded_blocks_per_mcu * 64; - - // Y IDCT - int mcu_block; - for (mcu_block = 0; mcu_block < m_expanded_blocks_per_component; mcu_block++) - { - idct(pSrc_ptr, pDst_ptr, m_mcu_block_max_zag[mcu_block]); - pSrc_ptr += 64; - pDst_ptr += 64; - } - - // Chroma IDCT, with upsampling - jpgd_block_t temp_block[64]; - - for (int i = 0; i < 2; i++) - { - DCT_Upsample::Matrix44 P, Q, R, S; - - JPGD_ASSERT(m_mcu_block_max_zag[mcu_block] >= 1); - JPGD_ASSERT(m_mcu_block_max_zag[mcu_block] <= 64); - - int max_zag = m_mcu_block_max_zag[mcu_block++] - 1; - if (max_zag <= 0) max_zag = 0; // should never happen, only here to shut up static analysis - switch (s_max_rc[max_zag]) - { - case 1*16+1: - DCT_Upsample::P_Q<1, 1>::calc(P, Q, pSrc_ptr); - DCT_Upsample::R_S<1, 1>::calc(R, S, pSrc_ptr); - break; - case 1*16+2: - DCT_Upsample::P_Q<1, 2>::calc(P, Q, pSrc_ptr); - DCT_Upsample::R_S<1, 2>::calc(R, S, pSrc_ptr); - break; - case 2*16+2: - DCT_Upsample::P_Q<2, 2>::calc(P, Q, pSrc_ptr); - DCT_Upsample::R_S<2, 2>::calc(R, S, pSrc_ptr); - break; - case 3*16+2: - DCT_Upsample::P_Q<3, 2>::calc(P, Q, pSrc_ptr); - DCT_Upsample::R_S<3, 2>::calc(R, S, pSrc_ptr); - break; - case 3*16+3: - DCT_Upsample::P_Q<3, 3>::calc(P, Q, pSrc_ptr); - DCT_Upsample::R_S<3, 3>::calc(R, S, pSrc_ptr); - break; - case 3*16+4: - DCT_Upsample::P_Q<3, 4>::calc(P, Q, pSrc_ptr); - DCT_Upsample::R_S<3, 4>::calc(R, S, pSrc_ptr); - break; - case 4*16+4: - DCT_Upsample::P_Q<4, 4>::calc(P, Q, pSrc_ptr); - DCT_Upsample::R_S<4, 4>::calc(R, S, pSrc_ptr); - break; - case 5*16+4: - DCT_Upsample::P_Q<5, 4>::calc(P, Q, pSrc_ptr); - DCT_Upsample::R_S<5, 4>::calc(R, S, pSrc_ptr); - break; - case 5*16+5: - DCT_Upsample::P_Q<5, 5>::calc(P, Q, pSrc_ptr); - DCT_Upsample::R_S<5, 5>::calc(R, S, pSrc_ptr); - break; - case 5*16+6: - DCT_Upsample::P_Q<5, 6>::calc(P, Q, pSrc_ptr); - DCT_Upsample::R_S<5, 6>::calc(R, S, pSrc_ptr); - break; - case 6*16+6: - DCT_Upsample::P_Q<6, 6>::calc(P, Q, pSrc_ptr); - DCT_Upsample::R_S<6, 6>::calc(R, S, pSrc_ptr); - break; - case 7*16+6: - DCT_Upsample::P_Q<7, 6>::calc(P, Q, pSrc_ptr); - DCT_Upsample::R_S<7, 6>::calc(R, S, pSrc_ptr); - break; - case 7*16+7: - DCT_Upsample::P_Q<7, 7>::calc(P, Q, pSrc_ptr); - DCT_Upsample::R_S<7, 7>::calc(R, S, pSrc_ptr); - break; - case 7*16+8: - DCT_Upsample::P_Q<7, 8>::calc(P, Q, pSrc_ptr); - DCT_Upsample::R_S<7, 8>::calc(R, S, pSrc_ptr); - break; - case 8*16+8: - DCT_Upsample::P_Q<8, 8>::calc(P, Q, pSrc_ptr); - DCT_Upsample::R_S<8, 8>::calc(R, S, pSrc_ptr); - break; - default: - JPGD_ASSERT(false); - } - - DCT_Upsample::Matrix44 a(P + Q); P -= Q; - DCT_Upsample::Matrix44& b = P; - DCT_Upsample::Matrix44 c(R + S); R -= S; - DCT_Upsample::Matrix44& d = R; - - DCT_Upsample::Matrix44::add_and_store(temp_block, a, c); - idct_4x4(temp_block, pDst_ptr); - pDst_ptr += 64; - - DCT_Upsample::Matrix44::sub_and_store(temp_block, a, c); - idct_4x4(temp_block, pDst_ptr); - pDst_ptr += 64; - - DCT_Upsample::Matrix44::add_and_store(temp_block, b, d); - idct_4x4(temp_block, pDst_ptr); - pDst_ptr += 64; - - DCT_Upsample::Matrix44::sub_and_store(temp_block, b, d); - idct_4x4(temp_block, pDst_ptr); - pDst_ptr += 64; - - pSrc_ptr += 64; - } -} - -// Loads and dequantizes the next row of (already decoded) coefficients. -// Progressive images only. -void jpeg_decoder::load_next_row() -{ - int i; - jpgd_block_t *p; - jpgd_quant_t *q; - int mcu_row, mcu_block, row_block = 0; - int component_num, component_id; - int block_x_mcu[JPGD_MAX_COMPONENTS]; - - memset(block_x_mcu, 0, JPGD_MAX_COMPONENTS * sizeof(int)); - - for (mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++) - { - int block_x_mcu_ofs = 0, block_y_mcu_ofs = 0; - - for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++) - { - component_id = m_mcu_org[mcu_block]; - JPGD_ASSERT(m_comp_quant[component_id] < JPGD_MAX_QUANT_TABLES); - q = m_quant[m_comp_quant[component_id]]; - - p = m_pMCU_coefficients + 64 * mcu_block; - - jpgd_block_t* pAC = coeff_buf_getp(m_ac_coeffs[component_id], block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs); - jpgd_block_t* pDC = coeff_buf_getp(m_dc_coeffs[component_id], block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs); - p[0] = pDC[0]; - memcpy(&p[1], &pAC[1], 63 * sizeof(jpgd_block_t)); - - for (i = 63; i > 0; i--) - if (p[g_ZAG[i]]) - break; - - m_mcu_block_max_zag[mcu_block] = i + 1; - - for ( ; i >= 0; i--) - if (p[g_ZAG[i]]) - p[g_ZAG[i]] = static_cast<jpgd_block_t>(p[g_ZAG[i]] * q[i]); - - row_block++; - - if (m_comps_in_scan == 1) - block_x_mcu[component_id]++; - else - { - if (++block_x_mcu_ofs == m_comp_h_samp[component_id]) - { - block_x_mcu_ofs = 0; - - if (++block_y_mcu_ofs == m_comp_v_samp[component_id]) - { - block_y_mcu_ofs = 0; - - block_x_mcu[component_id] += m_comp_h_samp[component_id]; - } - } - } - } - - if (m_freq_domain_chroma_upsample) - transform_mcu_expand(mcu_row); - else - transform_mcu(mcu_row); - } - - if (m_comps_in_scan == 1) - m_block_y_mcu[m_comp_list[0]]++; - else - { - for (component_num = 0; component_num < m_comps_in_scan; component_num++) - { - component_id = m_comp_list[component_num]; - - m_block_y_mcu[component_id] += m_comp_v_samp[component_id]; - } - } -} - -// Restart interval processing. -void jpeg_decoder::process_restart() -{ - int i; - int c = 0; - - // Align to a byte boundry - // FIXME: Is this really necessary? get_bits_no_markers() never reads in markers! - //get_bits_no_markers(m_bits_left & 7); - - // Let's scan a little bit to find the marker, but not _too_ far. - // 1536 is a "fudge factor" that determines how much to scan. - for (i = 1536; i > 0; i--) - if (get_char() == 0xFF) - break; - - if (i == 0) - stop_decoding(JPGD_BAD_RESTART_MARKER); - - for ( ; i > 0; i--) - if ((c = get_char()) != 0xFF) - break; - - if (i == 0) - stop_decoding(JPGD_BAD_RESTART_MARKER); - - // Is it the expected marker? If not, something bad happened. - if (c != (m_next_restart_num + M_RST0)) - stop_decoding(JPGD_BAD_RESTART_MARKER); - - // Reset each component's DC prediction values. - memset(&m_last_dc_val, 0, m_comps_in_frame * sizeof(uint)); - - m_eob_run = 0; - - m_restarts_left = m_restart_interval; - - m_next_restart_num = (m_next_restart_num + 1) & 7; - - // Get the bit buffer going again... - - m_bits_left = 16; - get_bits_no_markers(16); - get_bits_no_markers(16); -} - -static inline int dequantize_ac(int c, int q) { c *= q; return c; } - -// Decodes and dequantizes the next row of coefficients. -void jpeg_decoder::decode_next_row() -{ - int row_block = 0; - - for (int mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++) - { - if ((m_restart_interval) && (m_restarts_left == 0)) - process_restart(); - - jpgd_block_t* p = m_pMCU_coefficients; - for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++, p += 64) - { - int component_id = m_mcu_org[mcu_block]; - JPGD_ASSERT(m_comp_quant[component_id] < JPGD_MAX_QUANT_TABLES); - jpgd_quant_t* q = m_quant[m_comp_quant[component_id]]; - - int r, s; - s = huff_decode(m_pHuff_tabs[m_comp_dc_tab[component_id]], r); - s = JPGD_HUFF_EXTEND(r, s); - - m_last_dc_val[component_id] = (s += m_last_dc_val[component_id]); - - p[0] = static_cast<jpgd_block_t>(s * q[0]); - - int prev_num_set = m_mcu_block_max_zag[mcu_block]; - - huff_tables *pH = m_pHuff_tabs[m_comp_ac_tab[component_id]]; - - int k; - for (k = 1; k < 64; k++) - { - int extra_bits; - s = huff_decode(pH, extra_bits); - - r = s >> 4; - s &= 15; - - if (s) - { - if (r) - { - if ((k + r) > 63) - stop_decoding(JPGD_DECODE_ERROR); - - if (k < prev_num_set) - { - int n = JPGD_MIN(r, prev_num_set - k); - int kt = k; - while (n--) - p[g_ZAG[kt++]] = 0; - } - - k += r; - } - - s = JPGD_HUFF_EXTEND(extra_bits, s); - - JPGD_ASSERT(k < 64); - - p[g_ZAG[k]] = static_cast<jpgd_block_t>(dequantize_ac(s, q[k])); //s * q[k]; - } - else - { - if (r == 15) - { - if ((k + 16) > 64) - stop_decoding(JPGD_DECODE_ERROR); - - if (k < prev_num_set) - { - int n = JPGD_MIN(16, prev_num_set - k); - int kt = k; - while (n--) - { - JPGD_ASSERT(kt <= 63); - p[g_ZAG[kt++]] = 0; - } - } - - k += 16 - 1; // - 1 because the loop counter is k - JPGD_ASSERT(p[g_ZAG[k]] == 0); - } - else - break; - } - } - - if (k < prev_num_set) - { - int kt = k; - while (kt < prev_num_set) - p[g_ZAG[kt++]] = 0; - } - - m_mcu_block_max_zag[mcu_block] = k; - - row_block++; - } - - if (m_freq_domain_chroma_upsample) - transform_mcu_expand(mcu_row); - else - transform_mcu(mcu_row); - - m_restarts_left--; - } -} - -// YCbCr H1V1 (1x1:1:1, 3 m_blocks per MCU) to RGB -void jpeg_decoder::H1V1Convert() -{ - int row = m_max_mcu_y_size - m_mcu_lines_left; - uint8 *d = m_pScan_line_0; - uint8 *s = m_pSample_buf + row * 8; - - for (int i = m_max_mcus_per_row; i > 0; i--) - { - for (int j = 0; j < 8; j++) - { - int y = s[j]; - int cb = s[64+j]; - int cr = s[128+j]; - - d[0] = clamp(y + m_crr[cr]); - d[1] = clamp(y + ((m_crg[cr] + m_cbg[cb]) >> 16)); - d[2] = clamp(y + m_cbb[cb]); - d[3] = 255; - - d += 4; - } - - s += 64*3; - } -} - -// YCbCr H2V1 (2x1:1:1, 4 m_blocks per MCU) to RGB -void jpeg_decoder::H2V1Convert() -{ - int row = m_max_mcu_y_size - m_mcu_lines_left; - uint8 *d0 = m_pScan_line_0; - uint8 *y = m_pSample_buf + row * 8; - uint8 *c = m_pSample_buf + 2*64 + row * 8; - - for (int i = m_max_mcus_per_row; i > 0; i--) - { - for (int l = 0; l < 2; l++) - { - for (int j = 0; j < 4; j++) - { - int cb = c[0]; - int cr = c[64]; - - int rc = m_crr[cr]; - int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); - int bc = m_cbb[cb]; - - int yy = y[j<<1]; - d0[0] = clamp(yy+rc); - d0[1] = clamp(yy+gc); - d0[2] = clamp(yy+bc); - d0[3] = 255; - - yy = y[(j<<1)+1]; - d0[4] = clamp(yy+rc); - d0[5] = clamp(yy+gc); - d0[6] = clamp(yy+bc); - d0[7] = 255; - - d0 += 8; - - c++; - } - y += 64; - } - - y += 64*4 - 64*2; - c += 64*4 - 8; - } -} - -// YCbCr H2V1 (1x2:1:1, 4 m_blocks per MCU) to RGB -void jpeg_decoder::H1V2Convert() -{ - int row = m_max_mcu_y_size - m_mcu_lines_left; - uint8 *d0 = m_pScan_line_0; - uint8 *d1 = m_pScan_line_1; - uint8 *y; - uint8 *c; - - if (row < 8) - y = m_pSample_buf + row * 8; - else - y = m_pSample_buf + 64*1 + (row & 7) * 8; - - c = m_pSample_buf + 64*2 + (row >> 1) * 8; - - for (int i = m_max_mcus_per_row; i > 0; i--) - { - for (int j = 0; j < 8; j++) - { - int cb = c[0+j]; - int cr = c[64+j]; - - int rc = m_crr[cr]; - int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); - int bc = m_cbb[cb]; - - int yy = y[j]; - d0[0] = clamp(yy+rc); - d0[1] = clamp(yy+gc); - d0[2] = clamp(yy+bc); - d0[3] = 255; - - yy = y[8+j]; - d1[0] = clamp(yy+rc); - d1[1] = clamp(yy+gc); - d1[2] = clamp(yy+bc); - d1[3] = 255; - - d0 += 4; - d1 += 4; - } - - y += 64*4; - c += 64*4; - } -} - -// YCbCr H2V2 (2x2:1:1, 6 m_blocks per MCU) to RGB -void jpeg_decoder::H2V2Convert() -{ - int row = m_max_mcu_y_size - m_mcu_lines_left; - uint8 *d0 = m_pScan_line_0; - uint8 *d1 = m_pScan_line_1; - uint8 *y; - uint8 *c; - - if (row < 8) - y = m_pSample_buf + row * 8; - else - y = m_pSample_buf + 64*2 + (row & 7) * 8; - - c = m_pSample_buf + 64*4 + (row >> 1) * 8; - - for (int i = m_max_mcus_per_row; i > 0; i--) - { - for (int l = 0; l < 2; l++) - { - for (int j = 0; j < 8; j += 2) - { - int cb = c[0]; - int cr = c[64]; + // Create a few tables that allow us to quickly convert YCbCr to RGB. + void jpeg_decoder::create_look_ups() + { + for (int i = 0; i <= 255; i++) + { + int k = i - 128; + m_crr[i] = (FIX(1.40200f) * k + ONE_HALF) >> SCALEBITS; + m_cbb[i] = (FIX(1.77200f) * k + ONE_HALF) >> SCALEBITS; + m_crg[i] = (-FIX(0.71414f)) * k; + m_cbg[i] = (-FIX(0.34414f)) * k + ONE_HALF; + } + } + + // This method throws back into the stream any bytes that where read + // into the bit buffer during initial marker scanning. + void jpeg_decoder::fix_in_buffer() + { + // In case any 0xFF's where pulled into the buffer during marker scanning. + assert((m_bits_left & 7) == 0); + + if (m_bits_left == 16) + stuff_char((uint8)(m_bit_buf & 0xFF)); + + if (m_bits_left >= 8) + stuff_char((uint8)((m_bit_buf >> 8) & 0xFF)); + + stuff_char((uint8)((m_bit_buf >> 16) & 0xFF)); + stuff_char((uint8)((m_bit_buf >> 24) & 0xFF)); + + m_bits_left = 16; + get_bits_no_markers(16); + get_bits_no_markers(16); + } + + void jpeg_decoder::transform_mcu(int mcu_row) + { + jpgd_block_coeff_t* pSrc_ptr = m_pMCU_coefficients; + if (mcu_row * m_blocks_per_mcu >= m_max_blocks_per_row) + stop_decoding(JPGD_DECODE_ERROR); + + uint8* pDst_ptr = m_pSample_buf + mcu_row * m_blocks_per_mcu * 64; + + for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++) + { + idct(pSrc_ptr, pDst_ptr, m_mcu_block_max_zag[mcu_block], ((m_flags & cFlagDisableSIMD) == 0) && m_has_sse2); + pSrc_ptr += 64; + pDst_ptr += 64; + } + } + + // Loads and dequantizes the next row of (already decoded) coefficients. + // Progressive images only. + void jpeg_decoder::load_next_row() + { + int i; + jpgd_block_coeff_t* p; + jpgd_quant_t* q; + int mcu_row, mcu_block, row_block = 0; + int component_num, component_id; + int block_x_mcu[JPGD_MAX_COMPONENTS]; + + memset(block_x_mcu, 0, JPGD_MAX_COMPONENTS * sizeof(int)); + + for (mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++) + { + int block_x_mcu_ofs = 0, block_y_mcu_ofs = 0; + + for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++) + { + component_id = m_mcu_org[mcu_block]; + if (m_comp_quant[component_id] >= JPGD_MAX_QUANT_TABLES) + stop_decoding(JPGD_DECODE_ERROR); + + q = m_quant[m_comp_quant[component_id]]; + + p = m_pMCU_coefficients + 64 * mcu_block; + + jpgd_block_coeff_t* pAC = coeff_buf_getp(m_ac_coeffs[component_id], block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs); + jpgd_block_coeff_t* pDC = coeff_buf_getp(m_dc_coeffs[component_id], block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs); + p[0] = pDC[0]; + memcpy(&p[1], &pAC[1], 63 * sizeof(jpgd_block_coeff_t)); + + for (i = 63; i > 0; i--) + if (p[g_ZAG[i]]) + break; + + m_mcu_block_max_zag[mcu_block] = i + 1; + + for (; i >= 0; i--) + if (p[g_ZAG[i]]) + p[g_ZAG[i]] = static_cast<jpgd_block_coeff_t>(p[g_ZAG[i]] * q[i]); + + row_block++; + + if (m_comps_in_scan == 1) + block_x_mcu[component_id]++; + else + { + if (++block_x_mcu_ofs == m_comp_h_samp[component_id]) + { + block_x_mcu_ofs = 0; + + if (++block_y_mcu_ofs == m_comp_v_samp[component_id]) + { + block_y_mcu_ofs = 0; + + block_x_mcu[component_id] += m_comp_h_samp[component_id]; + } + } + } + } + + transform_mcu(mcu_row); + } + + if (m_comps_in_scan == 1) + m_block_y_mcu[m_comp_list[0]]++; + else + { + for (component_num = 0; component_num < m_comps_in_scan; component_num++) + { + component_id = m_comp_list[component_num]; + + m_block_y_mcu[component_id] += m_comp_v_samp[component_id]; + } + } + } + + // Restart interval processing. + void jpeg_decoder::process_restart() + { + int i; + int c = 0; + + // Align to a byte boundry + // FIXME: Is this really necessary? get_bits_no_markers() never reads in markers! + //get_bits_no_markers(m_bits_left & 7); + + // Let's scan a little bit to find the marker, but not _too_ far. + // 1536 is a "fudge factor" that determines how much to scan. + for (i = 1536; i > 0; i--) + if (get_char() == 0xFF) + break; + + if (i == 0) + stop_decoding(JPGD_BAD_RESTART_MARKER); + + for (; i > 0; i--) + if ((c = get_char()) != 0xFF) + break; + + if (i == 0) + stop_decoding(JPGD_BAD_RESTART_MARKER); + + // Is it the expected marker? If not, something bad happened. + if (c != (m_next_restart_num + M_RST0)) + stop_decoding(JPGD_BAD_RESTART_MARKER); + + // Reset each component's DC prediction values. + memset(&m_last_dc_val, 0, m_comps_in_frame * sizeof(uint)); + + m_eob_run = 0; + + m_restarts_left = m_restart_interval; + + m_next_restart_num = (m_next_restart_num + 1) & 7; + + // Get the bit buffer going again... + + m_bits_left = 16; + get_bits_no_markers(16); + get_bits_no_markers(16); + } + + static inline int dequantize_ac(int c, int q) { c *= q; return c; } + + // Decodes and dequantizes the next row of coefficients. + void jpeg_decoder::decode_next_row() + { + int row_block = 0; + + for (int mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++) + { + if ((m_restart_interval) && (m_restarts_left == 0)) + process_restart(); + + jpgd_block_coeff_t* p = m_pMCU_coefficients; + for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++, p += 64) + { + int component_id = m_mcu_org[mcu_block]; + if (m_comp_quant[component_id] >= JPGD_MAX_QUANT_TABLES) + stop_decoding(JPGD_DECODE_ERROR); + + jpgd_quant_t* q = m_quant[m_comp_quant[component_id]]; + + int r, s; + s = huff_decode(m_pHuff_tabs[m_comp_dc_tab[component_id]], r); + if (s >= 16) + stop_decoding(JPGD_DECODE_ERROR); + + s = JPGD_HUFF_EXTEND(r, s); + + m_last_dc_val[component_id] = (s += m_last_dc_val[component_id]); + + p[0] = static_cast<jpgd_block_coeff_t>(s * q[0]); + + int prev_num_set = m_mcu_block_max_zag[mcu_block]; + + huff_tables* pH = m_pHuff_tabs[m_comp_ac_tab[component_id]]; + + int k; + for (k = 1; k < 64; k++) + { + int extra_bits; + s = huff_decode(pH, extra_bits); + + r = s >> 4; + s &= 15; + + if (s) + { + if (r) + { + if ((k + r) > 63) + stop_decoding(JPGD_DECODE_ERROR); + + if (k < prev_num_set) + { + int n = JPGD_MIN(r, prev_num_set - k); + int kt = k; + while (n--) + p[g_ZAG[kt++]] = 0; + } + + k += r; + } + + s = JPGD_HUFF_EXTEND(extra_bits, s); + + if (k >= 64) + stop_decoding(JPGD_DECODE_ERROR); + + p[g_ZAG[k]] = static_cast<jpgd_block_coeff_t>(dequantize_ac(s, q[k])); //s * q[k]; + } + else + { + if (r == 15) + { + if ((k + 16) > 64) + stop_decoding(JPGD_DECODE_ERROR); + + if (k < prev_num_set) + { + int n = JPGD_MIN(16, prev_num_set - k); + int kt = k; + while (n--) + { + if (kt > 63) + stop_decoding(JPGD_DECODE_ERROR); + p[g_ZAG[kt++]] = 0; + } + } + + k += 16 - 1; // - 1 because the loop counter is k + + if (p[g_ZAG[k & 63]] != 0) + stop_decoding(JPGD_DECODE_ERROR); + } + else + break; + } + } + + if (k < prev_num_set) + { + int kt = k; + while (kt < prev_num_set) + p[g_ZAG[kt++]] = 0; + } + + m_mcu_block_max_zag[mcu_block] = k; + + row_block++; + } + + transform_mcu(mcu_row); + + m_restarts_left--; + } + } + + // YCbCr H1V1 (1x1:1:1, 3 m_blocks per MCU) to RGB + void jpeg_decoder::H1V1Convert() + { + int row = m_max_mcu_y_size - m_mcu_lines_left; + uint8* d = m_pScan_line_0; + uint8* s = m_pSample_buf + row * 8; + + for (int i = m_max_mcus_per_row; i > 0; i--) + { + for (int j = 0; j < 8; j++) + { + int y = s[j]; + int cb = s[64 + j]; + int cr = s[128 + j]; + + d[0] = clamp(y + m_crr[cr]); + d[1] = clamp(y + ((m_crg[cr] + m_cbg[cb]) >> 16)); + d[2] = clamp(y + m_cbb[cb]); + d[3] = 255; + + d += 4; + } + + s += 64 * 3; + } + } + + // YCbCr H2V1 (2x1:1:1, 4 m_blocks per MCU) to RGB + void jpeg_decoder::H2V1Convert() + { + int row = m_max_mcu_y_size - m_mcu_lines_left; + uint8* d0 = m_pScan_line_0; + uint8* y = m_pSample_buf + row * 8; + uint8* c = m_pSample_buf + 2 * 64 + row * 8; + + for (int i = m_max_mcus_per_row; i > 0; i--) + { + for (int l = 0; l < 2; l++) + { + for (int j = 0; j < 4; j++) + { + int cb = c[0]; + int cr = c[64]; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + int yy = y[j << 1]; + d0[0] = clamp(yy + rc); + d0[1] = clamp(yy + gc); + d0[2] = clamp(yy + bc); + d0[3] = 255; + + yy = y[(j << 1) + 1]; + d0[4] = clamp(yy + rc); + d0[5] = clamp(yy + gc); + d0[6] = clamp(yy + bc); + d0[7] = 255; + + d0 += 8; + + c++; + } + y += 64; + } + + y += 64 * 4 - 64 * 2; + c += 64 * 4 - 8; + } + } + + // YCbCr H2V1 (2x1:1:1, 4 m_blocks per MCU) to RGB + void jpeg_decoder::H2V1ConvertFiltered() + { + const uint BLOCKS_PER_MCU = 4; + int row = m_max_mcu_y_size - m_mcu_lines_left; + uint8* d0 = m_pScan_line_0; + + const int half_image_x_size = (m_image_x_size >> 1) - 1; + const int row_x8 = row * 8; + + for (int x = 0; x < m_image_x_size; x++) + { + int y = m_pSample_buf[check_sample_buf_ofs((x >> 4) * BLOCKS_PER_MCU * 64 + ((x & 8) ? 64 : 0) + (x & 7) + row_x8)]; + + int c_x0 = (x - 1) >> 1; + int c_x1 = JPGD_MIN(c_x0 + 1, half_image_x_size); + c_x0 = JPGD_MAX(c_x0, 0); + + int a = (c_x0 >> 3) * BLOCKS_PER_MCU * 64 + (c_x0 & 7) + row_x8 + 128; + int cb0 = m_pSample_buf[check_sample_buf_ofs(a)]; + int cr0 = m_pSample_buf[check_sample_buf_ofs(a + 64)]; + + int b = (c_x1 >> 3) * BLOCKS_PER_MCU * 64 + (c_x1 & 7) + row_x8 + 128; + int cb1 = m_pSample_buf[check_sample_buf_ofs(b)]; + int cr1 = m_pSample_buf[check_sample_buf_ofs(b + 64)]; + + int w0 = (x & 1) ? 3 : 1; + int w1 = (x & 1) ? 1 : 3; + + int cb = (cb0 * w0 + cb1 * w1 + 2) >> 2; + int cr = (cr0 * w0 + cr1 * w1 + 2) >> 2; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + d0[0] = clamp(y + rc); + d0[1] = clamp(y + gc); + d0[2] = clamp(y + bc); + d0[3] = 255; + + d0 += 4; + } + } + + // YCbCr H2V1 (1x2:1:1, 4 m_blocks per MCU) to RGB + void jpeg_decoder::H1V2Convert() + { + int row = m_max_mcu_y_size - m_mcu_lines_left; + uint8* d0 = m_pScan_line_0; + uint8* d1 = m_pScan_line_1; + uint8* y; + uint8* c; + + if (row < 8) + y = m_pSample_buf + row * 8; + else + y = m_pSample_buf + 64 * 1 + (row & 7) * 8; + + c = m_pSample_buf + 64 * 2 + (row >> 1) * 8; + + for (int i = m_max_mcus_per_row; i > 0; i--) + { + for (int j = 0; j < 8; j++) + { + int cb = c[0 + j]; + int cr = c[64 + j]; int rc = m_crr[cr]; int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); int bc = m_cbb[cb]; int yy = y[j]; - d0[0] = clamp(yy+rc); - d0[1] = clamp(yy+gc); - d0[2] = clamp(yy+bc); + d0[0] = clamp(yy + rc); + d0[1] = clamp(yy + gc); + d0[2] = clamp(yy + bc); d0[3] = 255; - yy = y[j+1]; - d0[4] = clamp(yy+rc); - d0[5] = clamp(yy+gc); - d0[6] = clamp(yy+bc); - d0[7] = 255; - - yy = y[j+8]; - d1[0] = clamp(yy+rc); - d1[1] = clamp(yy+gc); - d1[2] = clamp(yy+bc); + yy = y[8 + j]; + d1[0] = clamp(yy + rc); + d1[1] = clamp(yy + gc); + d1[2] = clamp(yy + bc); d1[3] = 255; - yy = y[j+8+1]; - d1[4] = clamp(yy+rc); - d1[5] = clamp(yy+gc); - d1[6] = clamp(yy+bc); - d1[7] = 255; + d0 += 4; + d1 += 4; + } + + y += 64 * 4; + c += 64 * 4; + } + } + + // YCbCr H2V1 (1x2:1:1, 4 m_blocks per MCU) to RGB + void jpeg_decoder::H1V2ConvertFiltered() + { + const uint BLOCKS_PER_MCU = 4; + int y = m_image_y_size - m_total_lines_left; + int row = y & 15; + + const int half_image_y_size = (m_image_y_size >> 1) - 1; + + uint8* d0 = m_pScan_line_0; + + const int w0 = (row & 1) ? 3 : 1; + const int w1 = (row & 1) ? 1 : 3; + + int c_y0 = (y - 1) >> 1; + int c_y1 = JPGD_MIN(c_y0 + 1, half_image_y_size); + + const uint8_t* p_YSamples = m_pSample_buf; + const uint8_t* p_C0Samples = m_pSample_buf; + if ((c_y0 >= 0) && (((row & 15) == 0) || ((row & 15) == 15)) && (m_total_lines_left > 1)) + { + assert(y > 0); + assert(m_sample_buf_prev_valid); + + if ((row & 15) == 15) + p_YSamples = m_pSample_buf_prev; - d0 += 8; - d1 += 8; + p_C0Samples = m_pSample_buf_prev; + } + + const int y_sample_base_ofs = ((row & 8) ? 64 : 0) + (row & 7) * 8; + const int y0_base = (c_y0 & 7) * 8 + 128; + const int y1_base = (c_y1 & 7) * 8 + 128; + + for (int x = 0; x < m_image_x_size; x++) + { + const int base_ofs = (x >> 3) * BLOCKS_PER_MCU * 64 + (x & 7); + + int y_sample = p_YSamples[check_sample_buf_ofs(base_ofs + y_sample_base_ofs)]; + + int a = base_ofs + y0_base; + int cb0_sample = p_C0Samples[check_sample_buf_ofs(a)]; + int cr0_sample = p_C0Samples[check_sample_buf_ofs(a + 64)]; + + int b = base_ofs + y1_base; + int cb1_sample = m_pSample_buf[check_sample_buf_ofs(b)]; + int cr1_sample = m_pSample_buf[check_sample_buf_ofs(b + 64)]; + + int cb = (cb0_sample * w0 + cb1_sample * w1 + 2) >> 2; + int cr = (cr0_sample * w0 + cr1_sample * w1 + 2) >> 2; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + d0[0] = clamp(y_sample + rc); + d0[1] = clamp(y_sample + gc); + d0[2] = clamp(y_sample + bc); + d0[3] = 255; + + d0 += 4; + } + } + + // YCbCr H2V2 (2x2:1:1, 6 m_blocks per MCU) to RGB + void jpeg_decoder::H2V2Convert() + { + int row = m_max_mcu_y_size - m_mcu_lines_left; + uint8* d0 = m_pScan_line_0; + uint8* d1 = m_pScan_line_1; + uint8* y; + uint8* c; - c++; + if (row < 8) + y = m_pSample_buf + row * 8; + else + y = m_pSample_buf + 64 * 2 + (row & 7) * 8; + + c = m_pSample_buf + 64 * 4 + (row >> 1) * 8; + + for (int i = m_max_mcus_per_row; i > 0; i--) + { + for (int l = 0; l < 2; l++) + { + for (int j = 0; j < 8; j += 2) + { + int cb = c[0]; + int cr = c[64]; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + int yy = y[j]; + d0[0] = clamp(yy + rc); + d0[1] = clamp(yy + gc); + d0[2] = clamp(yy + bc); + d0[3] = 255; + + yy = y[j + 1]; + d0[4] = clamp(yy + rc); + d0[5] = clamp(yy + gc); + d0[6] = clamp(yy + bc); + d0[7] = 255; + + yy = y[j + 8]; + d1[0] = clamp(yy + rc); + d1[1] = clamp(yy + gc); + d1[2] = clamp(yy + bc); + d1[3] = 255; + + yy = y[j + 8 + 1]; + d1[4] = clamp(yy + rc); + d1[5] = clamp(yy + gc); + d1[6] = clamp(yy + bc); + d1[7] = 255; + + d0 += 8; + d1 += 8; + + c++; + } + y += 64; } - y += 64; - } - - y += 64*6 - 64*2; - c += 64*6 - 8; - } -} - -// Y (1 block per MCU) to 8-bit grayscale -void jpeg_decoder::gray_convert() -{ - int row = m_max_mcu_y_size - m_mcu_lines_left; - uint8 *d = m_pScan_line_0; - uint8 *s = m_pSample_buf + row * 8; - - for (int i = m_max_mcus_per_row; i > 0; i--) - { - *(uint *)d = *(uint *)s; - *(uint *)(&d[4]) = *(uint *)(&s[4]); - - s += 64; - d += 8; - } -} - -void jpeg_decoder::expanded_convert() -{ - int row = m_max_mcu_y_size - m_mcu_lines_left; - - uint8* Py = m_pSample_buf + (row / 8) * 64 * m_comp_h_samp[0] + (row & 7) * 8; - - uint8* d = m_pScan_line_0; - - for (int i = m_max_mcus_per_row; i > 0; i--) - { - for (int k = 0; k < m_max_mcu_x_size; k += 8) - { - const int Y_ofs = k * 8; - const int Cb_ofs = Y_ofs + 64 * m_expanded_blocks_per_component; - const int Cr_ofs = Y_ofs + 64 * m_expanded_blocks_per_component * 2; - for (int j = 0; j < 8; j++) - { - int y = Py[Y_ofs + j]; - int cb = Py[Cb_ofs + j]; - int cr = Py[Cr_ofs + j]; - - d[0] = clamp(y + m_crr[cr]); - d[1] = clamp(y + ((m_crg[cr] + m_cbg[cb]) >> 16)); - d[2] = clamp(y + m_cbb[cb]); - d[3] = 255; - - d += 4; - } - } - - Py += 64 * m_expanded_blocks_per_mcu; - } -} - -// Find end of image (EOI) marker, so we can return to the user the exact size of the input stream. -void jpeg_decoder::find_eoi() -{ - if (!m_progressive_flag) - { - // Attempt to read the EOI marker. - //get_bits_no_markers(m_bits_left & 7); - - // Prime the bit buffer - m_bits_left = 16; - get_bits(16); - get_bits(16); - - // The next marker _should_ be EOI - process_markers(); - } - - m_total_bytes_read -= m_in_buf_left; -} - -int jpeg_decoder::decode(const void** pScan_line, uint* pScan_line_len) -{ - if ((m_error_code) || (!m_ready_flag)) - return JPGD_FAILED; - - if (m_total_lines_left == 0) - return JPGD_DONE; - - if (m_mcu_lines_left == 0) - { - if (setjmp(m_jmp_state)) - return JPGD_FAILED; - - if (m_progressive_flag) - load_next_row(); - else - decode_next_row(); - - // Find the EOI marker if that was the last row. - if (m_total_lines_left <= m_max_mcu_y_size) - find_eoi(); - - m_mcu_lines_left = m_max_mcu_y_size; - } - - if (m_freq_domain_chroma_upsample) - { - expanded_convert(); - *pScan_line = m_pScan_line_0; - } - else - { - switch (m_scan_type) - { - case JPGD_YH2V2: - { - if ((m_mcu_lines_left & 1) == 0) - { - H2V2Convert(); - *pScan_line = m_pScan_line_0; - } - else - *pScan_line = m_pScan_line_1; - - break; - } - case JPGD_YH2V1: - { - H2V1Convert(); - *pScan_line = m_pScan_line_0; - break; - } - case JPGD_YH1V2: - { - if ((m_mcu_lines_left & 1) == 0) - { - H1V2Convert(); - *pScan_line = m_pScan_line_0; - } - else - *pScan_line = m_pScan_line_1; - - break; - } - case JPGD_YH1V1: - { - H1V1Convert(); - *pScan_line = m_pScan_line_0; - break; - } - case JPGD_GRAYSCALE: - { - gray_convert(); - *pScan_line = m_pScan_line_0; - - break; - } - } - } - - *pScan_line_len = m_real_dest_bytes_per_scan_line; - - m_mcu_lines_left--; - m_total_lines_left--; - - return JPGD_SUCCESS; -} - -// Creates the tables needed for efficient Huffman decoding. -void jpeg_decoder::make_huff_table(int index, huff_tables *pH) -{ - int p, i, l, si; - uint8 huffsize[257]; - uint huffcode[257]; - uint code; - uint subtree; - int code_size; - int lastp; - int nextfreeentry; - int currententry; - - pH->ac_table = m_huff_ac[index] != 0; - - p = 0; - - for (l = 1; l <= 16; l++) - { - for (i = 1; i <= m_huff_num[index][l]; i++) - { - JPGD_ASSERT(p < 257); - huffsize[p++] = static_cast<uint8>(l); - } - } - - huffsize[p] = 0; - - lastp = p; - - code = 0; - si = huffsize[0]; - p = 0; - - while (huffsize[p]) - { - while (huffsize[p] == si) - { - JPGD_ASSERT(p < 257); - huffcode[p++] = code; - code++; - } - - code <<= 1; - si++; - } - - memset(pH->look_up, 0, sizeof(pH->look_up)); - memset(pH->look_up2, 0, sizeof(pH->look_up2)); - memset(pH->tree, 0, sizeof(pH->tree)); - memset(pH->code_size, 0, sizeof(pH->code_size)); - - nextfreeentry = -1; - - p = 0; - - while (p < lastp) - { - i = m_huff_val[index][p]; - code = huffcode[p]; - code_size = huffsize[p]; - - pH->code_size[i] = static_cast<uint8>(code_size); - - if (code_size <= 8) - { - code <<= (8 - code_size); - - for (l = 1 << (8 - code_size); l > 0; l--) - { - JPGD_ASSERT(i < JPGD_HUFF_CODE_SIZE_MAX_LENGTH); - JPGD_ASSERT(code < JPGD_HUFF_CODE_SIZE_MAX_LENGTH); - - pH->look_up[code] = i; - - bool has_extrabits = false; - int extra_bits = 0; - int num_extra_bits = i & 15; - - int bits_to_fetch = code_size; - if (num_extra_bits) - { - int total_codesize = code_size + num_extra_bits; - if (total_codesize <= 8) - { - has_extrabits = true; - extra_bits = ((1 << num_extra_bits) - 1) & (code >> (8 - total_codesize)); - JPGD_ASSERT(extra_bits <= 0x7FFF); - bits_to_fetch += num_extra_bits; - } - } - - if (!has_extrabits) - pH->look_up2[code] = i | (bits_to_fetch << 8); - else - pH->look_up2[code] = i | 0x8000 | (extra_bits << 16) | (bits_to_fetch << 8); - - code++; - } - } - else - { - subtree = (code >> (code_size - 8)) & 0xFF; - - currententry = pH->look_up[subtree]; - - if (currententry == 0) - { - pH->look_up[subtree] = currententry = nextfreeentry; - pH->look_up2[subtree] = currententry = nextfreeentry; - - nextfreeentry -= 2; - } - - code <<= (16 - (code_size - 8)); - - for (l = code_size; l > 9; l--) - { - if ((code & 0x8000) == 0) - currententry--; - - unsigned int idx = -currententry - 1; - JPGD_ASSERT(idx < JPGD_HUFF_TREE_MAX_LENGTH); - if (pH->tree[idx] == 0) - { - pH->tree[idx] = nextfreeentry; - - currententry = nextfreeentry; - - nextfreeentry -= 2; - } - else { - currententry = pH->tree[idx]; - } - - code <<= 1; - } - - if ((code & 0x8000) == 0) - currententry--; - - pH->tree[-currententry - 1] = i; - } - - p++; - } -} - -// Verifies the quantization tables needed for this scan are available. -void jpeg_decoder::check_quant_tables() -{ - for (int i = 0; i < m_comps_in_scan; i++) - if (m_quant[m_comp_quant[m_comp_list[i]]] == NULL) - stop_decoding(JPGD_UNDEFINED_QUANT_TABLE); -} - -// Verifies that all the Huffman tables needed for this scan are available. -void jpeg_decoder::check_huff_tables() -{ - for (int i = 0; i < m_comps_in_scan; i++) - { - if ((m_spectral_start == 0) && (m_huff_num[m_comp_dc_tab[m_comp_list[i]]] == NULL)) - stop_decoding(JPGD_UNDEFINED_HUFF_TABLE); - - if ((m_spectral_end > 0) && (m_huff_num[m_comp_ac_tab[m_comp_list[i]]] == NULL)) - stop_decoding(JPGD_UNDEFINED_HUFF_TABLE); - } - - for (int i = 0; i < JPGD_MAX_HUFF_TABLES; i++) - if (m_huff_num[i]) - { - if (!m_pHuff_tabs[i]) - m_pHuff_tabs[i] = (huff_tables *)alloc(sizeof(huff_tables)); - - make_huff_table(i, m_pHuff_tabs[i]); - } -} - -// Determines the component order inside each MCU. -// Also calcs how many MCU's are on each row, etc. -void jpeg_decoder::calc_mcu_block_order() -{ - int component_num, component_id; - int max_h_samp = 0, max_v_samp = 0; - - for (component_id = 0; component_id < m_comps_in_frame; component_id++) - { - if (m_comp_h_samp[component_id] > max_h_samp) - max_h_samp = m_comp_h_samp[component_id]; - - if (m_comp_v_samp[component_id] > max_v_samp) - max_v_samp = m_comp_v_samp[component_id]; - } - - for (component_id = 0; component_id < m_comps_in_frame; component_id++) - { - m_comp_h_blocks[component_id] = ((((m_image_x_size * m_comp_h_samp[component_id]) + (max_h_samp - 1)) / max_h_samp) + 7) / 8; - m_comp_v_blocks[component_id] = ((((m_image_y_size * m_comp_v_samp[component_id]) + (max_v_samp - 1)) / max_v_samp) + 7) / 8; - } - - if (m_comps_in_scan == 1) - { - m_mcus_per_row = m_comp_h_blocks[m_comp_list[0]]; - m_mcus_per_col = m_comp_v_blocks[m_comp_list[0]]; - } - else - { - m_mcus_per_row = (((m_image_x_size + 7) / 8) + (max_h_samp - 1)) / max_h_samp; - m_mcus_per_col = (((m_image_y_size + 7) / 8) + (max_v_samp - 1)) / max_v_samp; - } - - if (m_comps_in_scan == 1) - { - m_mcu_org[0] = m_comp_list[0]; - - m_blocks_per_mcu = 1; - } - else - { - m_blocks_per_mcu = 0; - - for (component_num = 0; component_num < m_comps_in_scan; component_num++) - { - int num_blocks; - - component_id = m_comp_list[component_num]; - - num_blocks = m_comp_h_samp[component_id] * m_comp_v_samp[component_id]; - - while (num_blocks--) - m_mcu_org[m_blocks_per_mcu++] = component_id; - } - } -} - -// Starts a new scan. -int jpeg_decoder::init_scan() -{ - if (!locate_sos_marker()) - return JPGD_FALSE; - - calc_mcu_block_order(); - - check_huff_tables(); - - check_quant_tables(); - - memset(m_last_dc_val, 0, m_comps_in_frame * sizeof(uint)); - - m_eob_run = 0; - - if (m_restart_interval) - { - m_restarts_left = m_restart_interval; - m_next_restart_num = 0; - } - - fix_in_buffer(); - - return JPGD_TRUE; -} - -// Starts a frame. Determines if the number of components or sampling factors -// are supported. -void jpeg_decoder::init_frame() -{ - int i; - - if (m_comps_in_frame == 1) - { - if ((m_comp_h_samp[0] != 1) || (m_comp_v_samp[0] != 1)) - stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS); - - m_scan_type = JPGD_GRAYSCALE; - m_max_blocks_per_mcu = 1; - m_max_mcu_x_size = 8; - m_max_mcu_y_size = 8; - } - else if (m_comps_in_frame == 3) - { - if ( ((m_comp_h_samp[1] != 1) || (m_comp_v_samp[1] != 1)) || - ((m_comp_h_samp[2] != 1) || (m_comp_v_samp[2] != 1)) ) - stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS); - - if ((m_comp_h_samp[0] == 1) && (m_comp_v_samp[0] == 1)) - { - m_scan_type = JPGD_YH1V1; - - m_max_blocks_per_mcu = 3; - m_max_mcu_x_size = 8; - m_max_mcu_y_size = 8; - } - else if ((m_comp_h_samp[0] == 2) && (m_comp_v_samp[0] == 1)) - { - m_scan_type = JPGD_YH2V1; - m_max_blocks_per_mcu = 4; - m_max_mcu_x_size = 16; - m_max_mcu_y_size = 8; - } - else if ((m_comp_h_samp[0] == 1) && (m_comp_v_samp[0] == 2)) - { - m_scan_type = JPGD_YH1V2; - m_max_blocks_per_mcu = 4; - m_max_mcu_x_size = 8; - m_max_mcu_y_size = 16; - } - else if ((m_comp_h_samp[0] == 2) && (m_comp_v_samp[0] == 2)) - { - m_scan_type = JPGD_YH2V2; - m_max_blocks_per_mcu = 6; - m_max_mcu_x_size = 16; - m_max_mcu_y_size = 16; - } - else - stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS); - } - else - stop_decoding(JPGD_UNSUPPORTED_COLORSPACE); - - m_max_mcus_per_row = (m_image_x_size + (m_max_mcu_x_size - 1)) / m_max_mcu_x_size; - m_max_mcus_per_col = (m_image_y_size + (m_max_mcu_y_size - 1)) / m_max_mcu_y_size; - - // These values are for the *destination* pixels: after conversion. - if (m_scan_type == JPGD_GRAYSCALE) - m_dest_bytes_per_pixel = 1; - else - m_dest_bytes_per_pixel = 4; - - m_dest_bytes_per_scan_line = ((m_image_x_size + 15) & 0xFFF0) * m_dest_bytes_per_pixel; - - m_real_dest_bytes_per_scan_line = (m_image_x_size * m_dest_bytes_per_pixel); - - // Initialize two scan line buffers. - m_pScan_line_0 = (uint8 *)alloc(m_dest_bytes_per_scan_line, true); - if ((m_scan_type == JPGD_YH1V2) || (m_scan_type == JPGD_YH2V2)) - m_pScan_line_1 = (uint8 *)alloc(m_dest_bytes_per_scan_line, true); - - m_max_blocks_per_row = m_max_mcus_per_row * m_max_blocks_per_mcu; - - // Should never happen - if (m_max_blocks_per_row > JPGD_MAX_BLOCKS_PER_ROW) - stop_decoding(JPGD_ASSERTION_ERROR); - - // Allocate the coefficient buffer, enough for one MCU - m_pMCU_coefficients = (jpgd_block_t*)alloc(m_max_blocks_per_mcu * 64 * sizeof(jpgd_block_t)); - - for (i = 0; i < m_max_blocks_per_mcu; i++) - m_mcu_block_max_zag[i] = 64; - - m_expanded_blocks_per_component = m_comp_h_samp[0] * m_comp_v_samp[0]; - m_expanded_blocks_per_mcu = m_expanded_blocks_per_component * m_comps_in_frame; - m_expanded_blocks_per_row = m_max_mcus_per_row * m_expanded_blocks_per_mcu; - // Freq. domain chroma upsampling is only supported for H2V2 subsampling factor (the most common one I've seen). - m_freq_domain_chroma_upsample = false; -#if JPGD_SUPPORT_FREQ_DOMAIN_UPSAMPLING - m_freq_domain_chroma_upsample = (m_expanded_blocks_per_mcu == 4*3); -#endif - if (m_freq_domain_chroma_upsample) - m_pSample_buf = (uint8 *)alloc(m_expanded_blocks_per_row * 64); - else - m_pSample_buf = (uint8 *)alloc(m_max_blocks_per_row * 64); - - m_total_lines_left = m_image_y_size; - - m_mcu_lines_left = 0; - - create_look_ups(); -} - -// The coeff_buf series of methods originally stored the coefficients -// into a "virtual" file which was located in EMS, XMS, or a disk file. A cache -// was used to make this process more efficient. Now, we can store the entire -// thing in RAM. -jpeg_decoder::coeff_buf* jpeg_decoder::coeff_buf_open(int block_num_x, int block_num_y, int block_len_x, int block_len_y) -{ - coeff_buf* cb = (coeff_buf*)alloc(sizeof(coeff_buf)); - - cb->block_num_x = block_num_x; - cb->block_num_y = block_num_y; - cb->block_len_x = block_len_x; - cb->block_len_y = block_len_y; - cb->block_size = (block_len_x * block_len_y) * sizeof(jpgd_block_t); - cb->pData = (uint8 *)alloc(cb->block_size * block_num_x * block_num_y, true); - return cb; -} - -inline jpgd_block_t *jpeg_decoder::coeff_buf_getp(coeff_buf *cb, int block_x, int block_y) -{ - JPGD_ASSERT((block_x < cb->block_num_x) && (block_y < cb->block_num_y)); - return (jpgd_block_t *)(cb->pData + block_x * cb->block_size + block_y * (cb->block_size * cb->block_num_x)); -} - -// The following methods decode the various types of m_blocks encountered -// in progressively encoded images. -void jpeg_decoder::decode_block_dc_first(jpeg_decoder *pD, int component_id, int block_x, int block_y) -{ - int s, r; - jpgd_block_t *p = pD->coeff_buf_getp(pD->m_dc_coeffs[component_id], block_x, block_y); - - if ((s = pD->huff_decode(pD->m_pHuff_tabs[pD->m_comp_dc_tab[component_id]])) != 0) - { - r = pD->get_bits_no_markers(s); - s = JPGD_HUFF_EXTEND(r, s); - } - - pD->m_last_dc_val[component_id] = (s += pD->m_last_dc_val[component_id]); - - p[0] = static_cast<jpgd_block_t>(s << pD->m_successive_low); -} - -void jpeg_decoder::decode_block_dc_refine(jpeg_decoder *pD, int component_id, int block_x, int block_y) -{ - if (pD->get_bits_no_markers(1)) - { - jpgd_block_t *p = pD->coeff_buf_getp(pD->m_dc_coeffs[component_id], block_x, block_y); - - p[0] |= (1 << pD->m_successive_low); - } -} - -void jpeg_decoder::decode_block_ac_first(jpeg_decoder *pD, int component_id, int block_x, int block_y) -{ - int k, s, r; - - if (pD->m_eob_run) - { - pD->m_eob_run--; - return; - } - - jpgd_block_t *p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y); - - for (k = pD->m_spectral_start; k <= pD->m_spectral_end; k++) - { - unsigned int idx = pD->m_comp_ac_tab[component_id]; - JPGD_ASSERT(idx < JPGD_MAX_HUFF_TABLES); - s = pD->huff_decode(pD->m_pHuff_tabs[idx]); - - r = s >> 4; - s &= 15; - - if (s) - { - if ((k += r) > 63) - pD->stop_decoding(JPGD_DECODE_ERROR); - - r = pD->get_bits_no_markers(s); - s = JPGD_HUFF_EXTEND(r, s); - - p[g_ZAG[k]] = static_cast<jpgd_block_t>(s << pD->m_successive_low); - } - else - { - if (r == 15) - { - if ((k += 15) > 63) - pD->stop_decoding(JPGD_DECODE_ERROR); - } - else - { - pD->m_eob_run = 1 << r; - - if (r) - pD->m_eob_run += pD->get_bits_no_markers(r); - - pD->m_eob_run--; - - break; - } - } - } -} - -void jpeg_decoder::decode_block_ac_refine(jpeg_decoder *pD, int component_id, int block_x, int block_y) -{ - int s, k, r; - int p1 = 1 << pD->m_successive_low; - int m1 = (-1) << pD->m_successive_low; - jpgd_block_t *p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y); - JPGD_ASSERT(pD->m_spectral_end <= 63); - - k = pD->m_spectral_start; - - if (pD->m_eob_run == 0) - { - for ( ; k <= pD->m_spectral_end; k++) - { - unsigned int idx = pD->m_comp_ac_tab[component_id]; - JPGD_ASSERT(idx < JPGD_MAX_HUFF_TABLES); - s = pD->huff_decode(pD->m_pHuff_tabs[idx]); - - r = s >> 4; - s &= 15; - - if (s) - { - if (s != 1) - pD->stop_decoding(JPGD_DECODE_ERROR); - - if (pD->get_bits_no_markers(1)) - s = p1; - else - s = m1; - } - else - { - if (r != 15) - { - pD->m_eob_run = 1 << r; - - if (r) - pD->m_eob_run += pD->get_bits_no_markers(r); - - break; - } - } - - do - { - jpgd_block_t *this_coef = p + g_ZAG[k & 63]; - - if (*this_coef != 0) - { - if (pD->get_bits_no_markers(1)) - { - if ((*this_coef & p1) == 0) - { - if (*this_coef >= 0) - *this_coef = static_cast<jpgd_block_t>(*this_coef + p1); - else - *this_coef = static_cast<jpgd_block_t>(*this_coef + m1); - } - } - } - else - { - if (--r < 0) - break; - } - - k++; - - } while (k <= pD->m_spectral_end); - - if ((s) && (k < 64)) - { - p[g_ZAG[k]] = static_cast<jpgd_block_t>(s); - } - } - } - - if (pD->m_eob_run > 0) - { - for ( ; k <= pD->m_spectral_end; k++) - { - jpgd_block_t *this_coef = p + g_ZAG[k & 63]; // logical AND to shut up static code analysis - - if (*this_coef != 0) - { - if (pD->get_bits_no_markers(1)) - { - if ((*this_coef & p1) == 0) - { - if (*this_coef >= 0) - *this_coef = static_cast<jpgd_block_t>(*this_coef + p1); - else - *this_coef = static_cast<jpgd_block_t>(*this_coef + m1); - } - } - } - } - - pD->m_eob_run--; - } -} - -// Decode a scan in a progressively encoded image. -void jpeg_decoder::decode_scan(pDecode_block_func decode_block_func) -{ - int mcu_row, mcu_col, mcu_block; - int block_x_mcu[JPGD_MAX_COMPONENTS], m_block_y_mcu[JPGD_MAX_COMPONENTS]; - - memset(m_block_y_mcu, 0, sizeof(m_block_y_mcu)); - - for (mcu_col = 0; mcu_col < m_mcus_per_col; mcu_col++) - { - int component_num, component_id; - - memset(block_x_mcu, 0, sizeof(block_x_mcu)); - - for (mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++) - { - int block_x_mcu_ofs = 0, block_y_mcu_ofs = 0; - - if ((m_restart_interval) && (m_restarts_left == 0)) - process_restart(); - - for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++) - { - component_id = m_mcu_org[mcu_block]; - - decode_block_func(this, component_id, block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs); - - if (m_comps_in_scan == 1) - block_x_mcu[component_id]++; - else - { - if (++block_x_mcu_ofs == m_comp_h_samp[component_id]) - { - block_x_mcu_ofs = 0; - - if (++block_y_mcu_ofs == m_comp_v_samp[component_id]) - { - block_y_mcu_ofs = 0; - block_x_mcu[component_id] += m_comp_h_samp[component_id]; - } - } - } - } - - m_restarts_left--; - } - - if (m_comps_in_scan == 1) - m_block_y_mcu[m_comp_list[0]]++; - else - { - for (component_num = 0; component_num < m_comps_in_scan; component_num++) - { - component_id = m_comp_list[component_num]; - m_block_y_mcu[component_id] += m_comp_v_samp[component_id]; - } - } - } -} - -// Decode a progressively encoded image. -void jpeg_decoder::init_progressive() -{ - int i; - - if (m_comps_in_frame == 4) - stop_decoding(JPGD_UNSUPPORTED_COLORSPACE); - - // Allocate the coefficient buffers. - for (i = 0; i < m_comps_in_frame; i++) - { - m_dc_coeffs[i] = coeff_buf_open(m_max_mcus_per_row * m_comp_h_samp[i], m_max_mcus_per_col * m_comp_v_samp[i], 1, 1); - m_ac_coeffs[i] = coeff_buf_open(m_max_mcus_per_row * m_comp_h_samp[i], m_max_mcus_per_col * m_comp_v_samp[i], 8, 8); - } - - for ( ; ; ) - { - int dc_only_scan, refinement_scan; - pDecode_block_func decode_block_func; - - if (!init_scan()) - break; - - dc_only_scan = (m_spectral_start == 0); - refinement_scan = (m_successive_high != 0); - - if ((m_spectral_start > m_spectral_end) || (m_spectral_end > 63)) - stop_decoding(JPGD_BAD_SOS_SPECTRAL); - - if (dc_only_scan) - { - if (m_spectral_end) - stop_decoding(JPGD_BAD_SOS_SPECTRAL); - } - else if (m_comps_in_scan != 1) /* AC scans can only contain one component */ - stop_decoding(JPGD_BAD_SOS_SPECTRAL); - - if ((refinement_scan) && (m_successive_low != m_successive_high - 1)) - stop_decoding(JPGD_BAD_SOS_SUCCESSIVE); - - if (dc_only_scan) - { - if (refinement_scan) - decode_block_func = decode_block_dc_refine; - else - decode_block_func = decode_block_dc_first; - } - else - { - if (refinement_scan) - decode_block_func = decode_block_ac_refine; - else - decode_block_func = decode_block_ac_first; - } - - decode_scan(decode_block_func); - - m_bits_left = 16; - get_bits(16); - get_bits(16); - } - - m_comps_in_scan = m_comps_in_frame; - - for (i = 0; i < m_comps_in_frame; i++) - m_comp_list[i] = i; - - calc_mcu_block_order(); -} - -void jpeg_decoder::init_sequential() -{ - if (!init_scan()) - stop_decoding(JPGD_UNEXPECTED_MARKER); -} - -void jpeg_decoder::decode_start() -{ - init_frame(); - - if (m_progressive_flag) - init_progressive(); - else - init_sequential(); -} - -void jpeg_decoder::decode_init(jpeg_decoder_stream *pStream) -{ - init(pStream); - locate_sof_marker(); -} - -jpeg_decoder::jpeg_decoder(jpeg_decoder_stream *pStream) -{ - if (setjmp(m_jmp_state)) - return; - decode_init(pStream); -} - -int jpeg_decoder::begin_decoding() -{ - if (m_ready_flag) - return JPGD_SUCCESS; - - if (m_error_code) - return JPGD_FAILED; - - if (setjmp(m_jmp_state)) - return JPGD_FAILED; - - decode_start(); - - m_ready_flag = true; - - return JPGD_SUCCESS; -} - -jpeg_decoder::~jpeg_decoder() -{ - free_all_blocks(); -} - -jpeg_decoder_file_stream::jpeg_decoder_file_stream() -{ - m_pFile = NULL; - m_eof_flag = false; - m_error_flag = false; -} - -void jpeg_decoder_file_stream::close() -{ - if (m_pFile) - { - fclose(m_pFile); - m_pFile = NULL; - } - - m_eof_flag = false; - m_error_flag = false; -} - -jpeg_decoder_file_stream::~jpeg_decoder_file_stream() -{ - close(); -} - -bool jpeg_decoder_file_stream::open(const char *Pfilename) -{ - close(); - - m_eof_flag = false; - m_error_flag = false; + y += 64 * 6 - 64 * 2; + c += 64 * 6 - 8; + } + } + + uint32_t jpeg_decoder::H2V2ConvertFiltered() + { + const uint BLOCKS_PER_MCU = 6; + int y = m_image_y_size - m_total_lines_left; + int row = y & 15; + + const int half_image_y_size = (m_image_y_size >> 1) - 1; + + uint8* d0 = m_pScan_line_0; + + int c_y0 = (y - 1) >> 1; + int c_y1 = JPGD_MIN(c_y0 + 1, half_image_y_size); + + const uint8_t* p_YSamples = m_pSample_buf; + const uint8_t* p_C0Samples = m_pSample_buf; + if ((c_y0 >= 0) && (((row & 15) == 0) || ((row & 15) == 15)) && (m_total_lines_left > 1)) + { + assert(y > 0); + assert(m_sample_buf_prev_valid); + + if ((row & 15) == 15) + p_YSamples = m_pSample_buf_prev; + + p_C0Samples = m_pSample_buf_prev; + } + + const int y_sample_base_ofs = ((row & 8) ? 128 : 0) + (row & 7) * 8; + const int y0_base = (c_y0 & 7) * 8 + 256; + const int y1_base = (c_y1 & 7) * 8 + 256; + + const int half_image_x_size = (m_image_x_size >> 1) - 1; + + static const uint8_t s_muls[2][2][4] = + { + { { 1, 3, 3, 9 }, { 3, 9, 1, 3 }, }, + { { 3, 1, 9, 3 }, { 9, 3, 3, 1 } } + }; + + if (((row & 15) >= 1) && ((row & 15) <= 14)) + { + assert((row & 1) == 1); + assert(((y + 1 - 1) >> 1) == c_y0); + + assert(p_YSamples == m_pSample_buf); + assert(p_C0Samples == m_pSample_buf); + + uint8* d1 = m_pScan_line_1; + const int y_sample_base_ofs1 = (((row + 1) & 8) ? 128 : 0) + ((row + 1) & 7) * 8; + + for (int x = 0; x < m_image_x_size; x++) + { + int k = (x >> 4) * BLOCKS_PER_MCU * 64 + ((x & 8) ? 64 : 0) + (x & 7); + int y_sample0 = p_YSamples[check_sample_buf_ofs(k + y_sample_base_ofs)]; + int y_sample1 = p_YSamples[check_sample_buf_ofs(k + y_sample_base_ofs1)]; + + int c_x0 = (x - 1) >> 1; + int c_x1 = JPGD_MIN(c_x0 + 1, half_image_x_size); + c_x0 = JPGD_MAX(c_x0, 0); + + int a = (c_x0 >> 3) * BLOCKS_PER_MCU * 64 + (c_x0 & 7); + int cb00_sample = p_C0Samples[check_sample_buf_ofs(a + y0_base)]; + int cr00_sample = p_C0Samples[check_sample_buf_ofs(a + y0_base + 64)]; + + int cb01_sample = m_pSample_buf[check_sample_buf_ofs(a + y1_base)]; + int cr01_sample = m_pSample_buf[check_sample_buf_ofs(a + y1_base + 64)]; + + int b = (c_x1 >> 3) * BLOCKS_PER_MCU * 64 + (c_x1 & 7); + int cb10_sample = p_C0Samples[check_sample_buf_ofs(b + y0_base)]; + int cr10_sample = p_C0Samples[check_sample_buf_ofs(b + y0_base + 64)]; + + int cb11_sample = m_pSample_buf[check_sample_buf_ofs(b + y1_base)]; + int cr11_sample = m_pSample_buf[check_sample_buf_ofs(b + y1_base + 64)]; + + { + const uint8_t* pMuls = &s_muls[row & 1][x & 1][0]; + int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4; + int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + d0[0] = clamp(y_sample0 + rc); + d0[1] = clamp(y_sample0 + gc); + d0[2] = clamp(y_sample0 + bc); + d0[3] = 255; + + d0 += 4; + } + + { + const uint8_t* pMuls = &s_muls[(row + 1) & 1][x & 1][0]; + int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4; + int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + d1[0] = clamp(y_sample1 + rc); + d1[1] = clamp(y_sample1 + gc); + d1[2] = clamp(y_sample1 + bc); + d1[3] = 255; + + d1 += 4; + } + + if (((x & 1) == 1) && (x < m_image_x_size - 1)) + { + const int nx = x + 1; + assert(c_x0 == (nx - 1) >> 1); + + k = (nx >> 4) * BLOCKS_PER_MCU * 64 + ((nx & 8) ? 64 : 0) + (nx & 7); + y_sample0 = p_YSamples[check_sample_buf_ofs(k + y_sample_base_ofs)]; + y_sample1 = p_YSamples[check_sample_buf_ofs(k + y_sample_base_ofs1)]; + + { + const uint8_t* pMuls = &s_muls[row & 1][nx & 1][0]; + int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4; + int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + d0[0] = clamp(y_sample0 + rc); + d0[1] = clamp(y_sample0 + gc); + d0[2] = clamp(y_sample0 + bc); + d0[3] = 255; + + d0 += 4; + } + + { + const uint8_t* pMuls = &s_muls[(row + 1) & 1][nx & 1][0]; + int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4; + int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + d1[0] = clamp(y_sample1 + rc); + d1[1] = clamp(y_sample1 + gc); + d1[2] = clamp(y_sample1 + bc); + d1[3] = 255; + + d1 += 4; + } + + ++x; + } + } + + return 2; + } + else + { + for (int x = 0; x < m_image_x_size; x++) + { + int y_sample = p_YSamples[check_sample_buf_ofs((x >> 4) * BLOCKS_PER_MCU * 64 + ((x & 8) ? 64 : 0) + (x & 7) + y_sample_base_ofs)]; + + int c_x0 = (x - 1) >> 1; + int c_x1 = JPGD_MIN(c_x0 + 1, half_image_x_size); + c_x0 = JPGD_MAX(c_x0, 0); + + int a = (c_x0 >> 3) * BLOCKS_PER_MCU * 64 + (c_x0 & 7); + int cb00_sample = p_C0Samples[check_sample_buf_ofs(a + y0_base)]; + int cr00_sample = p_C0Samples[check_sample_buf_ofs(a + y0_base + 64)]; + + int cb01_sample = m_pSample_buf[check_sample_buf_ofs(a + y1_base)]; + int cr01_sample = m_pSample_buf[check_sample_buf_ofs(a + y1_base + 64)]; + + int b = (c_x1 >> 3) * BLOCKS_PER_MCU * 64 + (c_x1 & 7); + int cb10_sample = p_C0Samples[check_sample_buf_ofs(b + y0_base)]; + int cr10_sample = p_C0Samples[check_sample_buf_ofs(b + y0_base + 64)]; + + int cb11_sample = m_pSample_buf[check_sample_buf_ofs(b + y1_base)]; + int cr11_sample = m_pSample_buf[check_sample_buf_ofs(b + y1_base + 64)]; + + const uint8_t* pMuls = &s_muls[row & 1][x & 1][0]; + int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4; + int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4; + + int rc = m_crr[cr]; + int gc = ((m_crg[cr] + m_cbg[cb]) >> 16); + int bc = m_cbb[cb]; + + d0[0] = clamp(y_sample + rc); + d0[1] = clamp(y_sample + gc); + d0[2] = clamp(y_sample + bc); + d0[3] = 255; + + d0 += 4; + } + + return 1; + } + } + + // Y (1 block per MCU) to 8-bit grayscale + void jpeg_decoder::gray_convert() + { + int row = m_max_mcu_y_size - m_mcu_lines_left; + uint8* d = m_pScan_line_0; + uint8* s = m_pSample_buf + row * 8; + + for (int i = m_max_mcus_per_row; i > 0; i--) + { + *(uint*)d = *(uint*)s; + *(uint*)(&d[4]) = *(uint*)(&s[4]); + + s += 64; + d += 8; + } + } + + // Find end of image (EOI) marker, so we can return to the user the exact size of the input stream. + void jpeg_decoder::find_eoi() + { + if (!m_progressive_flag) + { + // Attempt to read the EOI marker. + //get_bits_no_markers(m_bits_left & 7); + + // Prime the bit buffer + m_bits_left = 16; + get_bits(16); + get_bits(16); + + // The next marker _should_ be EOI + process_markers(); + } + + m_total_bytes_read -= m_in_buf_left; + } + + int jpeg_decoder::decode_next_mcu_row() + { + if (::setjmp(m_jmp_state)) + return JPGD_FAILED; + + const bool chroma_y_filtering = ((m_flags & cFlagBoxChromaFiltering) == 0) && ((m_scan_type == JPGD_YH2V2) || (m_scan_type == JPGD_YH1V2)); + if (chroma_y_filtering) + { + std::swap(m_pSample_buf, m_pSample_buf_prev); + + m_sample_buf_prev_valid = true; + } + + if (m_progressive_flag) + load_next_row(); + else + decode_next_row(); + + // Find the EOI marker if that was the last row. + if (m_total_lines_left <= m_max_mcu_y_size) + find_eoi(); + + m_mcu_lines_left = m_max_mcu_y_size; + return 0; + } + + int jpeg_decoder::decode(const void** pScan_line, uint* pScan_line_len) + { + if ((m_error_code) || (!m_ready_flag)) + return JPGD_FAILED; + + if (m_total_lines_left == 0) + return JPGD_DONE; + + const bool chroma_y_filtering = ((m_flags & cFlagBoxChromaFiltering) == 0) && ((m_scan_type == JPGD_YH2V2) || (m_scan_type == JPGD_YH1V2)); + + bool get_another_mcu_row = false; + bool got_mcu_early = false; + if (chroma_y_filtering) + { + if (m_total_lines_left == m_image_y_size) + get_another_mcu_row = true; + else if ((m_mcu_lines_left == 1) && (m_total_lines_left > 1)) + { + get_another_mcu_row = true; + got_mcu_early = true; + } + } + else + { + get_another_mcu_row = (m_mcu_lines_left == 0); + } + + if (get_another_mcu_row) + { + int status = decode_next_mcu_row(); + if (status != 0) + return status; + } + + switch (m_scan_type) + { + case JPGD_YH2V2: + { + if ((m_flags & cFlagBoxChromaFiltering) == 0) + { + if (m_num_buffered_scanlines == 1) + { + *pScan_line = m_pScan_line_1; + } + else if (m_num_buffered_scanlines == 0) + { + m_num_buffered_scanlines = H2V2ConvertFiltered(); + *pScan_line = m_pScan_line_0; + } + + m_num_buffered_scanlines--; + } + else + { + if ((m_mcu_lines_left & 1) == 0) + { + H2V2Convert(); + *pScan_line = m_pScan_line_0; + } + else + *pScan_line = m_pScan_line_1; + } + + break; + } + case JPGD_YH2V1: + { + if ((m_flags & cFlagBoxChromaFiltering) == 0) + H2V1ConvertFiltered(); + else + H2V1Convert(); + *pScan_line = m_pScan_line_0; + break; + } + case JPGD_YH1V2: + { + if (chroma_y_filtering) + { + H1V2ConvertFiltered(); + *pScan_line = m_pScan_line_0; + } + else + { + if ((m_mcu_lines_left & 1) == 0) + { + H1V2Convert(); + *pScan_line = m_pScan_line_0; + } + else + *pScan_line = m_pScan_line_1; + } + + break; + } + case JPGD_YH1V1: + { + H1V1Convert(); + *pScan_line = m_pScan_line_0; + break; + } + case JPGD_GRAYSCALE: + { + gray_convert(); + *pScan_line = m_pScan_line_0; + + break; + } + } + + *pScan_line_len = m_real_dest_bytes_per_scan_line; + + if (!got_mcu_early) + { + m_mcu_lines_left--; + } + + m_total_lines_left--; + + return JPGD_SUCCESS; + } + + // Creates the tables needed for efficient Huffman decoding. + void jpeg_decoder::make_huff_table(int index, huff_tables* pH) + { + int p, i, l, si; + uint8 huffsize[258]; + uint huffcode[258]; + uint code; + uint subtree; + int code_size; + int lastp; + int nextfreeentry; + int currententry; + + pH->ac_table = m_huff_ac[index] != 0; + + p = 0; + + for (l = 1; l <= 16; l++) + { + for (i = 1; i <= m_huff_num[index][l]; i++) + { + if (p >= 257) + stop_decoding(JPGD_DECODE_ERROR); + huffsize[p++] = static_cast<uint8>(l); + } + } + + assert(p < 258); + huffsize[p] = 0; + + lastp = p; + + code = 0; + si = huffsize[0]; + p = 0; + + while (huffsize[p]) + { + while (huffsize[p] == si) + { + if (p >= 257) + stop_decoding(JPGD_DECODE_ERROR); + huffcode[p++] = code; + code++; + } + + code <<= 1; + si++; + } + + memset(pH->look_up, 0, sizeof(pH->look_up)); + memset(pH->look_up2, 0, sizeof(pH->look_up2)); + memset(pH->tree, 0, sizeof(pH->tree)); + memset(pH->code_size, 0, sizeof(pH->code_size)); + + nextfreeentry = -1; + + p = 0; + + while (p < lastp) + { + i = m_huff_val[index][p]; + + code = huffcode[p]; + code_size = huffsize[p]; + + assert(i < JPGD_HUFF_CODE_SIZE_MAX_LENGTH); + pH->code_size[i] = static_cast<uint8>(code_size); + + if (code_size <= 8) + { + code <<= (8 - code_size); + + for (l = 1 << (8 - code_size); l > 0; l--) + { + if (code >= 256) + stop_decoding(JPGD_DECODE_ERROR); + + pH->look_up[code] = i; + + bool has_extrabits = false; + int extra_bits = 0; + int num_extra_bits = i & 15; + + int bits_to_fetch = code_size; + if (num_extra_bits) + { + int total_codesize = code_size + num_extra_bits; + if (total_codesize <= 8) + { + has_extrabits = true; + extra_bits = ((1 << num_extra_bits) - 1) & (code >> (8 - total_codesize)); + + if (extra_bits > 0x7FFF) + stop_decoding(JPGD_DECODE_ERROR); + + bits_to_fetch += num_extra_bits; + } + } + + if (!has_extrabits) + pH->look_up2[code] = i | (bits_to_fetch << 8); + else + pH->look_up2[code] = i | 0x8000 | (extra_bits << 16) | (bits_to_fetch << 8); + + code++; + } + } + else + { + subtree = (code >> (code_size - 8)) & 0xFF; + + currententry = pH->look_up[subtree]; + + if (currententry == 0) + { + pH->look_up[subtree] = currententry = nextfreeentry; + pH->look_up2[subtree] = currententry = nextfreeentry; + + nextfreeentry -= 2; + } + + code <<= (16 - (code_size - 8)); + + for (l = code_size; l > 9; l--) + { + if ((code & 0x8000) == 0) + currententry--; + + unsigned int idx = -currententry - 1; + + if (idx >= JPGD_HUFF_TREE_MAX_LENGTH) + stop_decoding(JPGD_DECODE_ERROR); + + if (pH->tree[idx] == 0) + { + pH->tree[idx] = nextfreeentry; + + currententry = nextfreeentry; + + nextfreeentry -= 2; + } + else + { + currententry = pH->tree[idx]; + } + + code <<= 1; + } + + if ((code & 0x8000) == 0) + currententry--; + + if ((-currententry - 1) >= JPGD_HUFF_TREE_MAX_LENGTH) + stop_decoding(JPGD_DECODE_ERROR); + + pH->tree[-currententry - 1] = i; + } + + p++; + } + } + + // Verifies the quantization tables needed for this scan are available. + void jpeg_decoder::check_quant_tables() + { + for (int i = 0; i < m_comps_in_scan; i++) + if (m_quant[m_comp_quant[m_comp_list[i]]] == nullptr) + stop_decoding(JPGD_UNDEFINED_QUANT_TABLE); + } + + // Verifies that all the Huffman tables needed for this scan are available. + void jpeg_decoder::check_huff_tables() + { + for (int i = 0; i < m_comps_in_scan; i++) + { + if ((m_spectral_start == 0) && (m_huff_num[m_comp_dc_tab[m_comp_list[i]]] == nullptr)) + stop_decoding(JPGD_UNDEFINED_HUFF_TABLE); + + if ((m_spectral_end > 0) && (m_huff_num[m_comp_ac_tab[m_comp_list[i]]] == nullptr)) + stop_decoding(JPGD_UNDEFINED_HUFF_TABLE); + } + + for (int i = 0; i < JPGD_MAX_HUFF_TABLES; i++) + if (m_huff_num[i]) + { + if (!m_pHuff_tabs[i]) + m_pHuff_tabs[i] = (huff_tables*)alloc(sizeof(huff_tables)); + + make_huff_table(i, m_pHuff_tabs[i]); + } + } + + // Determines the component order inside each MCU. + // Also calcs how many MCU's are on each row, etc. + bool jpeg_decoder::calc_mcu_block_order() + { + int component_num, component_id; + int max_h_samp = 0, max_v_samp = 0; + + for (component_id = 0; component_id < m_comps_in_frame; component_id++) + { + if (m_comp_h_samp[component_id] > max_h_samp) + max_h_samp = m_comp_h_samp[component_id]; + + if (m_comp_v_samp[component_id] > max_v_samp) + max_v_samp = m_comp_v_samp[component_id]; + } + + for (component_id = 0; component_id < m_comps_in_frame; component_id++) + { + m_comp_h_blocks[component_id] = ((((m_image_x_size * m_comp_h_samp[component_id]) + (max_h_samp - 1)) / max_h_samp) + 7) / 8; + m_comp_v_blocks[component_id] = ((((m_image_y_size * m_comp_v_samp[component_id]) + (max_v_samp - 1)) / max_v_samp) + 7) / 8; + } + + if (m_comps_in_scan == 1) + { + m_mcus_per_row = m_comp_h_blocks[m_comp_list[0]]; + m_mcus_per_col = m_comp_v_blocks[m_comp_list[0]]; + } + else + { + m_mcus_per_row = (((m_image_x_size + 7) / 8) + (max_h_samp - 1)) / max_h_samp; + m_mcus_per_col = (((m_image_y_size + 7) / 8) + (max_v_samp - 1)) / max_v_samp; + } + + if (m_comps_in_scan == 1) + { + m_mcu_org[0] = m_comp_list[0]; + + m_blocks_per_mcu = 1; + } + else + { + m_blocks_per_mcu = 0; + + for (component_num = 0; component_num < m_comps_in_scan; component_num++) + { + int num_blocks; + + component_id = m_comp_list[component_num]; + + num_blocks = m_comp_h_samp[component_id] * m_comp_v_samp[component_id]; + + while (num_blocks--) + m_mcu_org[m_blocks_per_mcu++] = component_id; + } + } + + if (m_blocks_per_mcu > m_max_blocks_per_mcu) + return false; + + for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++) + { + int comp_id = m_mcu_org[mcu_block]; + if (comp_id >= JPGD_MAX_QUANT_TABLES) + return false; + } + + return true; + } + + // Starts a new scan. + int jpeg_decoder::init_scan() + { + if (!locate_sos_marker()) + return JPGD_FALSE; + + if (!calc_mcu_block_order()) + return JPGD_FALSE; + + check_huff_tables(); + + check_quant_tables(); + + memset(m_last_dc_val, 0, m_comps_in_frame * sizeof(uint)); + + m_eob_run = 0; + + if (m_restart_interval) + { + m_restarts_left = m_restart_interval; + m_next_restart_num = 0; + } + + fix_in_buffer(); + + return JPGD_TRUE; + } + + // Starts a frame. Determines if the number of components or sampling factors + // are supported. + void jpeg_decoder::init_frame() + { + int i; + + if (m_comps_in_frame == 1) + { + if ((m_comp_h_samp[0] != 1) || (m_comp_v_samp[0] != 1)) + stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS); + + m_scan_type = JPGD_GRAYSCALE; + m_max_blocks_per_mcu = 1; + m_max_mcu_x_size = 8; + m_max_mcu_y_size = 8; + } + else if (m_comps_in_frame == 3) + { + if (((m_comp_h_samp[1] != 1) || (m_comp_v_samp[1] != 1)) || + ((m_comp_h_samp[2] != 1) || (m_comp_v_samp[2] != 1))) + stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS); + + if ((m_comp_h_samp[0] == 1) && (m_comp_v_samp[0] == 1)) + { + m_scan_type = JPGD_YH1V1; + + m_max_blocks_per_mcu = 3; + m_max_mcu_x_size = 8; + m_max_mcu_y_size = 8; + } + else if ((m_comp_h_samp[0] == 2) && (m_comp_v_samp[0] == 1)) + { + m_scan_type = JPGD_YH2V1; + m_max_blocks_per_mcu = 4; + m_max_mcu_x_size = 16; + m_max_mcu_y_size = 8; + } + else if ((m_comp_h_samp[0] == 1) && (m_comp_v_samp[0] == 2)) + { + m_scan_type = JPGD_YH1V2; + m_max_blocks_per_mcu = 4; + m_max_mcu_x_size = 8; + m_max_mcu_y_size = 16; + } + else if ((m_comp_h_samp[0] == 2) && (m_comp_v_samp[0] == 2)) + { + m_scan_type = JPGD_YH2V2; + m_max_blocks_per_mcu = 6; + m_max_mcu_x_size = 16; + m_max_mcu_y_size = 16; + } + else + stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS); + } + else + stop_decoding(JPGD_UNSUPPORTED_COLORSPACE); + + m_max_mcus_per_row = (m_image_x_size + (m_max_mcu_x_size - 1)) / m_max_mcu_x_size; + m_max_mcus_per_col = (m_image_y_size + (m_max_mcu_y_size - 1)) / m_max_mcu_y_size; + + // These values are for the *destination* pixels: after conversion. + if (m_scan_type == JPGD_GRAYSCALE) + m_dest_bytes_per_pixel = 1; + else + m_dest_bytes_per_pixel = 4; + + m_dest_bytes_per_scan_line = ((m_image_x_size + 15) & 0xFFF0) * m_dest_bytes_per_pixel; + + m_real_dest_bytes_per_scan_line = (m_image_x_size * m_dest_bytes_per_pixel); + + // Initialize two scan line buffers. + m_pScan_line_0 = (uint8*)alloc_aligned(m_dest_bytes_per_scan_line, true); + if ((m_scan_type == JPGD_YH1V2) || (m_scan_type == JPGD_YH2V2)) + m_pScan_line_1 = (uint8*)alloc_aligned(m_dest_bytes_per_scan_line, true); + + m_max_blocks_per_row = m_max_mcus_per_row * m_max_blocks_per_mcu; + + // Should never happen + if (m_max_blocks_per_row > JPGD_MAX_BLOCKS_PER_ROW) + stop_decoding(JPGD_DECODE_ERROR); + + // Allocate the coefficient buffer, enough for one MCU + m_pMCU_coefficients = (jpgd_block_coeff_t *)alloc_aligned(m_max_blocks_per_mcu * 64 * sizeof(jpgd_block_coeff_t)); + + for (i = 0; i < m_max_blocks_per_mcu; i++) + m_mcu_block_max_zag[i] = 64; + + m_pSample_buf = (uint8*)alloc_aligned(m_max_blocks_per_row * 64); + m_pSample_buf_prev = (uint8*)alloc_aligned(m_max_blocks_per_row * 64); + + m_total_lines_left = m_image_y_size; + + m_mcu_lines_left = 0; + + create_look_ups(); + } + + // The coeff_buf series of methods originally stored the coefficients + // into a "virtual" file which was located in EMS, XMS, or a disk file. A cache + // was used to make this process more efficient. Now, we can store the entire + // thing in RAM. + jpeg_decoder::coeff_buf* jpeg_decoder::coeff_buf_open(int block_num_x, int block_num_y, int block_len_x, int block_len_y) + { + coeff_buf* cb = (coeff_buf*)alloc(sizeof(coeff_buf)); + + cb->block_num_x = block_num_x; + cb->block_num_y = block_num_y; + cb->block_len_x = block_len_x; + cb->block_len_y = block_len_y; + cb->block_size = (block_len_x * block_len_y) * sizeof(jpgd_block_coeff_t); + cb->pData = (uint8*)alloc(cb->block_size * block_num_x * block_num_y, true); + return cb; + } + + inline jpgd_block_coeff_t* jpeg_decoder::coeff_buf_getp(coeff_buf* cb, int block_x, int block_y) + { + if ((block_x >= cb->block_num_x) || (block_y >= cb->block_num_y)) + stop_decoding(JPGD_DECODE_ERROR); + + return (jpgd_block_coeff_t*)(cb->pData + block_x * cb->block_size + block_y * (cb->block_size * cb->block_num_x)); + } + + // The following methods decode the various types of m_blocks encountered + // in progressively encoded images. + void jpeg_decoder::decode_block_dc_first(jpeg_decoder* pD, int component_id, int block_x, int block_y) + { + int s, r; + jpgd_block_coeff_t* p = pD->coeff_buf_getp(pD->m_dc_coeffs[component_id], block_x, block_y); + + if ((s = pD->huff_decode(pD->m_pHuff_tabs[pD->m_comp_dc_tab[component_id]])) != 0) + { + if (s >= 16) + pD->stop_decoding(JPGD_DECODE_ERROR); + + r = pD->get_bits_no_markers(s); + s = JPGD_HUFF_EXTEND(r, s); + } + + pD->m_last_dc_val[component_id] = (s += pD->m_last_dc_val[component_id]); + + p[0] = static_cast<jpgd_block_coeff_t>(s << pD->m_successive_low); + } + + void jpeg_decoder::decode_block_dc_refine(jpeg_decoder* pD, int component_id, int block_x, int block_y) + { + if (pD->get_bits_no_markers(1)) + { + jpgd_block_coeff_t* p = pD->coeff_buf_getp(pD->m_dc_coeffs[component_id], block_x, block_y); + + p[0] |= (1 << pD->m_successive_low); + } + } + + void jpeg_decoder::decode_block_ac_first(jpeg_decoder* pD, int component_id, int block_x, int block_y) + { + int k, s, r; + + if (pD->m_eob_run) + { + pD->m_eob_run--; + return; + } + + jpgd_block_coeff_t* p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y); + + for (k = pD->m_spectral_start; k <= pD->m_spectral_end; k++) + { + unsigned int idx = pD->m_comp_ac_tab[component_id]; + if (idx >= JPGD_MAX_HUFF_TABLES) + pD->stop_decoding(JPGD_DECODE_ERROR); + + s = pD->huff_decode(pD->m_pHuff_tabs[idx]); + + r = s >> 4; + s &= 15; + + if (s) + { + if ((k += r) > 63) + pD->stop_decoding(JPGD_DECODE_ERROR); + + r = pD->get_bits_no_markers(s); + s = JPGD_HUFF_EXTEND(r, s); + + p[g_ZAG[k]] = static_cast<jpgd_block_coeff_t>(s << pD->m_successive_low); + } + else + { + if (r == 15) + { + if ((k += 15) > 63) + pD->stop_decoding(JPGD_DECODE_ERROR); + } + else + { + pD->m_eob_run = 1 << r; + + if (r) + pD->m_eob_run += pD->get_bits_no_markers(r); + + pD->m_eob_run--; + + break; + } + } + } + } + + void jpeg_decoder::decode_block_ac_refine(jpeg_decoder* pD, int component_id, int block_x, int block_y) + { + int s, k, r; + + int p1 = 1 << pD->m_successive_low; + + //int m1 = (-1) << pD->m_successive_low; + int m1 = static_cast<int>((UINT32_MAX << pD->m_successive_low)); + + jpgd_block_coeff_t* p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y); + if (pD->m_spectral_end > 63) + pD->stop_decoding(JPGD_DECODE_ERROR); + + k = pD->m_spectral_start; + + if (pD->m_eob_run == 0) + { + for (; k <= pD->m_spectral_end; k++) + { + unsigned int idx = pD->m_comp_ac_tab[component_id]; + if (idx >= JPGD_MAX_HUFF_TABLES) + pD->stop_decoding(JPGD_DECODE_ERROR); + + s = pD->huff_decode(pD->m_pHuff_tabs[idx]); + + r = s >> 4; + s &= 15; + + if (s) + { + if (s != 1) + pD->stop_decoding(JPGD_DECODE_ERROR); + + if (pD->get_bits_no_markers(1)) + s = p1; + else + s = m1; + } + else + { + if (r != 15) + { + pD->m_eob_run = 1 << r; + + if (r) + pD->m_eob_run += pD->get_bits_no_markers(r); + + break; + } + } + + do + { + jpgd_block_coeff_t* this_coef = p + g_ZAG[k & 63]; + + if (*this_coef != 0) + { + if (pD->get_bits_no_markers(1)) + { + if ((*this_coef & p1) == 0) + { + if (*this_coef >= 0) + *this_coef = static_cast<jpgd_block_coeff_t>(*this_coef + p1); + else + *this_coef = static_cast<jpgd_block_coeff_t>(*this_coef + m1); + } + } + } + else + { + if (--r < 0) + break; + } + + k++; + + } while (k <= pD->m_spectral_end); + + if ((s) && (k < 64)) + { + p[g_ZAG[k]] = static_cast<jpgd_block_coeff_t>(s); + } + } + } + + if (pD->m_eob_run > 0) + { + for (; k <= pD->m_spectral_end; k++) + { + jpgd_block_coeff_t* this_coef = p + g_ZAG[k & 63]; // logical AND to shut up static code analysis + + if (*this_coef != 0) + { + if (pD->get_bits_no_markers(1)) + { + if ((*this_coef & p1) == 0) + { + if (*this_coef >= 0) + *this_coef = static_cast<jpgd_block_coeff_t>(*this_coef + p1); + else + *this_coef = static_cast<jpgd_block_coeff_t>(*this_coef + m1); + } + } + } + } + + pD->m_eob_run--; + } + } + + // Decode a scan in a progressively encoded image. + void jpeg_decoder::decode_scan(pDecode_block_func decode_block_func) + { + int mcu_row, mcu_col, mcu_block; + int block_x_mcu[JPGD_MAX_COMPONENTS], block_y_mcu[JPGD_MAX_COMPONENTS]; + + memset(block_y_mcu, 0, sizeof(block_y_mcu)); + + for (mcu_col = 0; mcu_col < m_mcus_per_col; mcu_col++) + { + int component_num, component_id; + + memset(block_x_mcu, 0, sizeof(block_x_mcu)); + + for (mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++) + { + int block_x_mcu_ofs = 0, block_y_mcu_ofs = 0; + + if ((m_restart_interval) && (m_restarts_left == 0)) + process_restart(); + + for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++) + { + component_id = m_mcu_org[mcu_block]; + + decode_block_func(this, component_id, block_x_mcu[component_id] + block_x_mcu_ofs, block_y_mcu[component_id] + block_y_mcu_ofs); + + if (m_comps_in_scan == 1) + block_x_mcu[component_id]++; + else + { + if (++block_x_mcu_ofs == m_comp_h_samp[component_id]) + { + block_x_mcu_ofs = 0; + + if (++block_y_mcu_ofs == m_comp_v_samp[component_id]) + { + block_y_mcu_ofs = 0; + block_x_mcu[component_id] += m_comp_h_samp[component_id]; + } + } + } + } + + m_restarts_left--; + } + + if (m_comps_in_scan == 1) + block_y_mcu[m_comp_list[0]]++; + else + { + for (component_num = 0; component_num < m_comps_in_scan; component_num++) + { + component_id = m_comp_list[component_num]; + block_y_mcu[component_id] += m_comp_v_samp[component_id]; + } + } + } + } + + // Decode a progressively encoded image. + void jpeg_decoder::init_progressive() + { + int i; + + if (m_comps_in_frame == 4) + stop_decoding(JPGD_UNSUPPORTED_COLORSPACE); + + // Allocate the coefficient buffers. + for (i = 0; i < m_comps_in_frame; i++) + { + m_dc_coeffs[i] = coeff_buf_open(m_max_mcus_per_row * m_comp_h_samp[i], m_max_mcus_per_col * m_comp_v_samp[i], 1, 1); + m_ac_coeffs[i] = coeff_buf_open(m_max_mcus_per_row * m_comp_h_samp[i], m_max_mcus_per_col * m_comp_v_samp[i], 8, 8); + } + + // See https://libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf + uint32_t total_scans = 0; + const uint32_t MAX_SCANS_TO_PROCESS = 1000; + + for (; ; ) + { + int dc_only_scan, refinement_scan; + pDecode_block_func decode_block_func; + + if (!init_scan()) + break; + + dc_only_scan = (m_spectral_start == 0); + refinement_scan = (m_successive_high != 0); + + if ((m_spectral_start > m_spectral_end) || (m_spectral_end > 63)) + stop_decoding(JPGD_BAD_SOS_SPECTRAL); + + if (dc_only_scan) + { + if (m_spectral_end) + stop_decoding(JPGD_BAD_SOS_SPECTRAL); + } + else if (m_comps_in_scan != 1) /* AC scans can only contain one component */ + stop_decoding(JPGD_BAD_SOS_SPECTRAL); + + if ((refinement_scan) && (m_successive_low != m_successive_high - 1)) + stop_decoding(JPGD_BAD_SOS_SUCCESSIVE); + + if (dc_only_scan) + { + if (refinement_scan) + decode_block_func = decode_block_dc_refine; + else + decode_block_func = decode_block_dc_first; + } + else + { + if (refinement_scan) + decode_block_func = decode_block_ac_refine; + else + decode_block_func = decode_block_ac_first; + } + + decode_scan(decode_block_func); + + m_bits_left = 16; + get_bits(16); + get_bits(16); + + total_scans++; + if (total_scans > MAX_SCANS_TO_PROCESS) + stop_decoding(JPGD_TOO_MANY_SCANS); + } + + m_comps_in_scan = m_comps_in_frame; + + for (i = 0; i < m_comps_in_frame; i++) + m_comp_list[i] = i; + + if (!calc_mcu_block_order()) + stop_decoding(JPGD_DECODE_ERROR); + } + + void jpeg_decoder::init_sequential() + { + if (!init_scan()) + stop_decoding(JPGD_UNEXPECTED_MARKER); + } + + void jpeg_decoder::decode_start() + { + init_frame(); + + if (m_progressive_flag) + init_progressive(); + else + init_sequential(); + } + + void jpeg_decoder::decode_init(jpeg_decoder_stream* pStream, uint32_t flags) + { + init(pStream, flags); + locate_sof_marker(); + } + + jpeg_decoder::jpeg_decoder(jpeg_decoder_stream* pStream, uint32_t flags) + { + if (::setjmp(m_jmp_state)) + return; + decode_init(pStream, flags); + } + + int jpeg_decoder::begin_decoding() + { + if (m_ready_flag) + return JPGD_SUCCESS; + + if (m_error_code) + return JPGD_FAILED; + + if (::setjmp(m_jmp_state)) + return JPGD_FAILED; + + decode_start(); + + m_ready_flag = true; + + return JPGD_SUCCESS; + } + + jpeg_decoder::~jpeg_decoder() + { + free_all_blocks(); + } + + jpeg_decoder_file_stream::jpeg_decoder_file_stream() + { + m_pFile = nullptr; + m_eof_flag = false; + m_error_flag = false; + } + + void jpeg_decoder_file_stream::close() + { + if (m_pFile) + { + fclose(m_pFile); + m_pFile = nullptr; + } + + m_eof_flag = false; + m_error_flag = false; + } + + jpeg_decoder_file_stream::~jpeg_decoder_file_stream() + { + close(); + } + + bool jpeg_decoder_file_stream::open(const char* Pfilename) + { + close(); + + m_eof_flag = false; + m_error_flag = false; #if defined(_MSC_VER) - m_pFile = NULL; - fopen_s(&m_pFile, Pfilename, "rb"); + m_pFile = nullptr; + fopen_s(&m_pFile, Pfilename, "rb"); #else - m_pFile = fopen(Pfilename, "rb"); + m_pFile = fopen(Pfilename, "rb"); #endif - return m_pFile != NULL; -} - -int jpeg_decoder_file_stream::read(uint8 *pBuf, int max_bytes_to_read, bool *pEOF_flag) -{ - if (!m_pFile) - return -1; - - if (m_eof_flag) - { - *pEOF_flag = true; - return 0; - } - - if (m_error_flag) - return -1; - - int bytes_read = static_cast<int>(fread(pBuf, 1, max_bytes_to_read, m_pFile)); - if (bytes_read < max_bytes_to_read) - { - if (ferror(m_pFile)) - { - m_error_flag = true; - return -1; - } - - m_eof_flag = true; - *pEOF_flag = true; - } - - return bytes_read; -} - -bool jpeg_decoder_mem_stream::open(const uint8 *pSrc_data, uint size) -{ - close(); - m_pSrc_data = pSrc_data; - m_ofs = 0; - m_size = size; - return true; -} - -int jpeg_decoder_mem_stream::read(uint8 *pBuf, int max_bytes_to_read, bool *pEOF_flag) -{ - *pEOF_flag = false; - - if (!m_pSrc_data) - return -1; - - uint bytes_remaining = m_size - m_ofs; - if ((uint)max_bytes_to_read > bytes_remaining) - { - max_bytes_to_read = bytes_remaining; - *pEOF_flag = true; - } - - memcpy(pBuf, m_pSrc_data + m_ofs, max_bytes_to_read); - m_ofs += max_bytes_to_read; - - return max_bytes_to_read; -} - -unsigned char *decompress_jpeg_image_from_stream(jpeg_decoder_stream *pStream, int *width, int *height, int *actual_comps, int req_comps) -{ - if (!actual_comps) - return NULL; - *actual_comps = 0; - - if ((!pStream) || (!width) || (!height) || (!req_comps)) - return NULL; - - if ((req_comps != 1) && (req_comps != 3) && (req_comps != 4)) - return NULL; - - jpeg_decoder decoder(pStream); - if (decoder.get_error_code() != JPGD_SUCCESS) - return NULL; - - const int image_width = decoder.get_width(), image_height = decoder.get_height(); - *width = image_width; - *height = image_height; - *actual_comps = decoder.get_num_components(); - - if (decoder.begin_decoding() != JPGD_SUCCESS) - return NULL; - - const int dst_bpl = image_width * req_comps; - - uint8 *pImage_data = (uint8*)jpgd_malloc(dst_bpl * image_height); - if (!pImage_data) - return NULL; - - for (int y = 0; y < image_height; y++) - { - const uint8* pScan_line; - uint scan_line_len; - if (decoder.decode((const void**)&pScan_line, &scan_line_len) != JPGD_SUCCESS) - { - jpgd_free(pImage_data); - return NULL; - } - - uint8 *pDst = pImage_data + y * dst_bpl; - - if (((req_comps == 1) && (decoder.get_num_components() == 1)) || ((req_comps == 4) && (decoder.get_num_components() == 3))) - memcpy(pDst, pScan_line, dst_bpl); - else if (decoder.get_num_components() == 1) - { - if (req_comps == 3) - { - for (int x = 0; x < image_width; x++) - { - uint8 luma = pScan_line[x]; - pDst[0] = luma; - pDst[1] = luma; - pDst[2] = luma; - pDst += 3; - } - } - else - { - for (int x = 0; x < image_width; x++) - { - uint8 luma = pScan_line[x]; - pDst[0] = luma; - pDst[1] = luma; - pDst[2] = luma; - pDst[3] = 255; - pDst += 4; - } - } - } - else if (decoder.get_num_components() == 3) - { - if (req_comps == 1) - { - const int YR = 19595, YG = 38470, YB = 7471; - for (int x = 0; x < image_width; x++) - { - int r = pScan_line[x*4+0]; - int g = pScan_line[x*4+1]; - int b = pScan_line[x*4+2]; - *pDst++ = static_cast<uint8>((r * YR + g * YG + b * YB + 32768) >> 16); - } - } - else - { - for (int x = 0; x < image_width; x++) - { - pDst[0] = pScan_line[x*4+0]; - pDst[1] = pScan_line[x*4+1]; - pDst[2] = pScan_line[x*4+2]; - pDst += 3; - } - } - } - } - - return pImage_data; -} - -unsigned char *decompress_jpeg_image_from_memory(const unsigned char *pSrc_data, int src_data_size, int *width, int *height, int *actual_comps, int req_comps) -{ - jpgd::jpeg_decoder_mem_stream mem_stream(pSrc_data, src_data_size); - return decompress_jpeg_image_from_stream(&mem_stream, width, height, actual_comps, req_comps); -} - -unsigned char *decompress_jpeg_image_from_file(const char *pSrc_filename, int *width, int *height, int *actual_comps, int req_comps) -{ - jpgd::jpeg_decoder_file_stream file_stream; - if (!file_stream.open(pSrc_filename)) - return NULL; - return decompress_jpeg_image_from_stream(&file_stream, width, height, actual_comps, req_comps); -} - -} // namespace jpgd
\ No newline at end of file + return m_pFile != nullptr; + } + + int jpeg_decoder_file_stream::read(uint8* pBuf, int max_bytes_to_read, bool* pEOF_flag) + { + if (!m_pFile) + return -1; + + if (m_eof_flag) + { + *pEOF_flag = true; + return 0; + } + + if (m_error_flag) + return -1; + + int bytes_read = static_cast<int>(fread(pBuf, 1, max_bytes_to_read, m_pFile)); + if (bytes_read < max_bytes_to_read) + { + if (ferror(m_pFile)) + { + m_error_flag = true; + return -1; + } + + m_eof_flag = true; + *pEOF_flag = true; + } + + return bytes_read; + } + + bool jpeg_decoder_mem_stream::open(const uint8* pSrc_data, uint size) + { + close(); + m_pSrc_data = pSrc_data; + m_ofs = 0; + m_size = size; + return true; + } + + int jpeg_decoder_mem_stream::read(uint8* pBuf, int max_bytes_to_read, bool* pEOF_flag) + { + *pEOF_flag = false; + + if (!m_pSrc_data) + return -1; + + uint bytes_remaining = m_size - m_ofs; + if ((uint)max_bytes_to_read > bytes_remaining) + { + max_bytes_to_read = bytes_remaining; + *pEOF_flag = true; + } + + memcpy(pBuf, m_pSrc_data + m_ofs, max_bytes_to_read); + m_ofs += max_bytes_to_read; + + return max_bytes_to_read; + } + + unsigned char* decompress_jpeg_image_from_stream(jpeg_decoder_stream* pStream, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags) + { + if (!actual_comps) + return nullptr; + *actual_comps = 0; + + if ((!pStream) || (!width) || (!height) || (!req_comps)) + return nullptr; + + if ((req_comps != 1) && (req_comps != 3) && (req_comps != 4)) + return nullptr; + + jpeg_decoder decoder(pStream, flags); + if (decoder.get_error_code() != JPGD_SUCCESS) + return nullptr; + + const int image_width = decoder.get_width(), image_height = decoder.get_height(); + *width = image_width; + *height = image_height; + *actual_comps = decoder.get_num_components(); + + if (decoder.begin_decoding() != JPGD_SUCCESS) + return nullptr; + + const int dst_bpl = image_width * req_comps; + + uint8* pImage_data = (uint8*)jpgd_malloc(dst_bpl * image_height); + if (!pImage_data) + return nullptr; + + for (int y = 0; y < image_height; y++) + { + const uint8* pScan_line; + uint scan_line_len; + if (decoder.decode((const void**)&pScan_line, &scan_line_len) != JPGD_SUCCESS) + { + jpgd_free(pImage_data); + return nullptr; + } + + uint8* pDst = pImage_data + y * dst_bpl; + + if (((req_comps == 1) && (decoder.get_num_components() == 1)) || ((req_comps == 4) && (decoder.get_num_components() == 3))) + memcpy(pDst, pScan_line, dst_bpl); + else if (decoder.get_num_components() == 1) + { + if (req_comps == 3) + { + for (int x = 0; x < image_width; x++) + { + uint8 luma = pScan_line[x]; + pDst[0] = luma; + pDst[1] = luma; + pDst[2] = luma; + pDst += 3; + } + } + else + { + for (int x = 0; x < image_width; x++) + { + uint8 luma = pScan_line[x]; + pDst[0] = luma; + pDst[1] = luma; + pDst[2] = luma; + pDst[3] = 255; + pDst += 4; + } + } + } + else if (decoder.get_num_components() == 3) + { + if (req_comps == 1) + { + const int YR = 19595, YG = 38470, YB = 7471; + for (int x = 0; x < image_width; x++) + { + int r = pScan_line[x * 4 + 0]; + int g = pScan_line[x * 4 + 1]; + int b = pScan_line[x * 4 + 2]; + *pDst++ = static_cast<uint8>((r * YR + g * YG + b * YB + 32768) >> 16); + } + } + else + { + for (int x = 0; x < image_width; x++) + { + pDst[0] = pScan_line[x * 4 + 0]; + pDst[1] = pScan_line[x * 4 + 1]; + pDst[2] = pScan_line[x * 4 + 2]; + pDst += 3; + } + } + } + } + + return pImage_data; + } + + unsigned char* decompress_jpeg_image_from_memory(const unsigned char* pSrc_data, int src_data_size, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags) + { + jpgd::jpeg_decoder_mem_stream mem_stream(pSrc_data, src_data_size); + return decompress_jpeg_image_from_stream(&mem_stream, width, height, actual_comps, req_comps, flags); + } + + unsigned char* decompress_jpeg_image_from_file(const char* pSrc_filename, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags) + { + jpgd::jpeg_decoder_file_stream file_stream; + if (!file_stream.open(pSrc_filename)) + return nullptr; + return decompress_jpeg_image_from_stream(&file_stream, width, height, actual_comps, req_comps, flags); + } + +} // namespace jpgd diff --git a/thirdparty/jpeg-compressor/jpgd.h b/thirdparty/jpeg-compressor/jpgd.h index 150b9a0b26..39136696ba 100644 --- a/thirdparty/jpeg-compressor/jpgd.h +++ b/thirdparty/jpeg-compressor/jpgd.h @@ -1,319 +1,351 @@ // jpgd.h - C++ class for JPEG decompression. -// Public domain, Rich Geldreich <richgel99@gmail.com> +// Richard Geldreich <richgel99@gmail.com> +// See jpgd.cpp for license (Public Domain or Apache 2.0). #ifndef JPEG_DECODER_H #define JPEG_DECODER_H #include <stdlib.h> #include <stdio.h> #include <setjmp.h> +#include <assert.h> +#include <stdint.h> #ifdef _MSC_VER - #define JPGD_NORETURN __declspec(noreturn) +#define JPGD_NORETURN __declspec(noreturn) #elif defined(__GNUC__) - #define JPGD_NORETURN __attribute__ ((noreturn)) +#define JPGD_NORETURN __attribute__ ((noreturn)) #else - #define JPGD_NORETURN +#define JPGD_NORETURN #endif +#define JPGD_HUFF_TREE_MAX_LENGTH 512 +#define JPGD_HUFF_CODE_SIZE_MAX_LENGTH 256 + namespace jpgd { - typedef unsigned char uint8; - typedef signed short int16; - typedef unsigned short uint16; - typedef unsigned int uint; - typedef signed int int32; - - // Loads a JPEG image from a memory buffer or a file. - // req_comps can be 1 (grayscale), 3 (RGB), or 4 (RGBA). - // On return, width/height will be set to the image's dimensions, and actual_comps will be set to the either 1 (grayscale) or 3 (RGB). - // Notes: For more control over where and how the source data is read, see the decompress_jpeg_image_from_stream() function below, or call the jpeg_decoder class directly. - // Requesting a 8 or 32bpp image is currently a little faster than 24bpp because the jpeg_decoder class itself currently always unpacks to either 8 or 32bpp. - unsigned char *decompress_jpeg_image_from_memory(const unsigned char *pSrc_data, int src_data_size, int *width, int *height, int *actual_comps, int req_comps); - unsigned char *decompress_jpeg_image_from_file(const char *pSrc_filename, int *width, int *height, int *actual_comps, int req_comps); - - // Success/failure error codes. - enum jpgd_status - { - JPGD_SUCCESS = 0, JPGD_FAILED = -1, JPGD_DONE = 1, - JPGD_BAD_DHT_COUNTS = -256, JPGD_BAD_DHT_INDEX, JPGD_BAD_DHT_MARKER, JPGD_BAD_DQT_MARKER, JPGD_BAD_DQT_TABLE, - JPGD_BAD_PRECISION, JPGD_BAD_HEIGHT, JPGD_BAD_WIDTH, JPGD_TOO_MANY_COMPONENTS, - JPGD_BAD_SOF_LENGTH, JPGD_BAD_VARIABLE_MARKER, JPGD_BAD_DRI_LENGTH, JPGD_BAD_SOS_LENGTH, - JPGD_BAD_SOS_COMP_ID, JPGD_W_EXTRA_BYTES_BEFORE_MARKER, JPGD_NO_ARITHMITIC_SUPPORT, JPGD_UNEXPECTED_MARKER, - JPGD_NOT_JPEG, JPGD_UNSUPPORTED_MARKER, JPGD_BAD_DQT_LENGTH, JPGD_TOO_MANY_BLOCKS, - JPGD_UNDEFINED_QUANT_TABLE, JPGD_UNDEFINED_HUFF_TABLE, JPGD_NOT_SINGLE_SCAN, JPGD_UNSUPPORTED_COLORSPACE, - JPGD_UNSUPPORTED_SAMP_FACTORS, JPGD_DECODE_ERROR, JPGD_BAD_RESTART_MARKER, JPGD_ASSERTION_ERROR, - JPGD_BAD_SOS_SPECTRAL, JPGD_BAD_SOS_SUCCESSIVE, JPGD_STREAM_READ, JPGD_NOTENOUGHMEM - }; - - // Input stream interface. - // Derive from this class to read input data from sources other than files or memory. Set m_eof_flag to true when no more data is available. - // The decoder is rather greedy: it will keep on calling this method until its internal input buffer is full, or until the EOF flag is set. - // It the input stream contains data after the JPEG stream's EOI (end of image) marker it will probably be pulled into the internal buffer. - // Call the get_total_bytes_read() method to determine the actual size of the JPEG stream after successful decoding. - class jpeg_decoder_stream - { - public: - jpeg_decoder_stream() { } - virtual ~jpeg_decoder_stream() { } - - // The read() method is called when the internal input buffer is empty. - // Parameters: - // pBuf - input buffer - // max_bytes_to_read - maximum bytes that can be written to pBuf - // pEOF_flag - set this to true if at end of stream (no more bytes remaining) - // Returns -1 on error, otherwise return the number of bytes actually written to the buffer (which may be 0). - // Notes: This method will be called in a loop until you set *pEOF_flag to true or the internal buffer is full. - virtual int read(uint8 *pBuf, int max_bytes_to_read, bool *pEOF_flag) = 0; - }; - - // stdio FILE stream class. - class jpeg_decoder_file_stream : public jpeg_decoder_stream - { - jpeg_decoder_file_stream(const jpeg_decoder_file_stream &); - jpeg_decoder_file_stream &operator =(const jpeg_decoder_file_stream &); - - FILE *m_pFile; - bool m_eof_flag, m_error_flag; - - public: - jpeg_decoder_file_stream(); - virtual ~jpeg_decoder_file_stream(); - - bool open(const char *Pfilename); - void close(); - - virtual int read(uint8 *pBuf, int max_bytes_to_read, bool *pEOF_flag); - }; - - // Memory stream class. - class jpeg_decoder_mem_stream : public jpeg_decoder_stream - { - const uint8 *m_pSrc_data; - uint m_ofs, m_size; - - public: - jpeg_decoder_mem_stream() : m_pSrc_data(NULL), m_ofs(0), m_size(0) { } - jpeg_decoder_mem_stream(const uint8 *pSrc_data, uint size) : m_pSrc_data(pSrc_data), m_ofs(0), m_size(size) { } - - virtual ~jpeg_decoder_mem_stream() { } - - bool open(const uint8 *pSrc_data, uint size); - void close() { m_pSrc_data = NULL; m_ofs = 0; m_size = 0; } - - virtual int read(uint8 *pBuf, int max_bytes_to_read, bool *pEOF_flag); - }; - - // Loads JPEG file from a jpeg_decoder_stream. - unsigned char *decompress_jpeg_image_from_stream(jpeg_decoder_stream *pStream, int *width, int *height, int *actual_comps, int req_comps); - - enum - { - JPGD_IN_BUF_SIZE = 8192, JPGD_MAX_BLOCKS_PER_MCU = 10, JPGD_MAX_HUFF_TABLES = 8, JPGD_MAX_QUANT_TABLES = 4, - JPGD_MAX_COMPONENTS = 4, JPGD_MAX_COMPS_IN_SCAN = 4, JPGD_MAX_BLOCKS_PER_ROW = 8192, JPGD_MAX_HEIGHT = 16384, JPGD_MAX_WIDTH = 16384 - }; - - typedef int16 jpgd_quant_t; - typedef int16 jpgd_block_t; - - class jpeg_decoder - { - public: - // Call get_error_code() after constructing to determine if the stream is valid or not. You may call the get_width(), get_height(), etc. - // methods after the constructor is called. You may then either destruct the object, or begin decoding the image by calling begin_decoding(), then decode() on each scanline. - jpeg_decoder(jpeg_decoder_stream *pStream); - - ~jpeg_decoder(); - - // Call this method after constructing the object to begin decompression. - // If JPGD_SUCCESS is returned you may then call decode() on each scanline. - int begin_decoding(); - - // Returns the next scan line. - // For grayscale images, pScan_line will point to a buffer containing 8-bit pixels (get_bytes_per_pixel() will return 1). - // Otherwise, it will always point to a buffer containing 32-bit RGBA pixels (A will always be 255, and get_bytes_per_pixel() will return 4). - // Returns JPGD_SUCCESS if a scan line has been returned. - // Returns JPGD_DONE if all scan lines have been returned. - // Returns JPGD_FAILED if an error occurred. Call get_error_code() for a more info. - int decode(const void** pScan_line, uint* pScan_line_len); - - inline jpgd_status get_error_code() const { return m_error_code; } - - inline int get_width() const { return m_image_x_size; } - inline int get_height() const { return m_image_y_size; } - - inline int get_num_components() const { return m_comps_in_frame; } - - inline int get_bytes_per_pixel() const { return m_dest_bytes_per_pixel; } - inline int get_bytes_per_scan_line() const { return m_image_x_size * get_bytes_per_pixel(); } - - // Returns the total number of bytes actually consumed by the decoder (which should equal the actual size of the JPEG file). - inline int get_total_bytes_read() const { return m_total_bytes_read; } - - private: - jpeg_decoder(const jpeg_decoder &); - jpeg_decoder &operator =(const jpeg_decoder &); - - typedef void (*pDecode_block_func)(jpeg_decoder *, int, int, int); - - struct huff_tables - { - bool ac_table; - uint look_up[256]; - uint look_up2[256]; - uint8 code_size[256]; - uint tree[512]; - }; - - struct coeff_buf - { - uint8 *pData; - int block_num_x, block_num_y; - int block_len_x, block_len_y; - int block_size; - }; - - struct mem_block - { - mem_block *m_pNext; - size_t m_used_count; - size_t m_size; - char m_data[1]; - }; - - jmp_buf m_jmp_state; - mem_block *m_pMem_blocks; - int m_image_x_size; - int m_image_y_size; - jpeg_decoder_stream *m_pStream; - int m_progressive_flag; - uint8 m_huff_ac[JPGD_MAX_HUFF_TABLES]; - uint8* m_huff_num[JPGD_MAX_HUFF_TABLES]; // pointer to number of Huffman codes per bit size - uint8* m_huff_val[JPGD_MAX_HUFF_TABLES]; // pointer to Huffman codes per bit size - jpgd_quant_t* m_quant[JPGD_MAX_QUANT_TABLES]; // pointer to quantization tables - int m_scan_type; // Gray, Yh1v1, Yh1v2, Yh2v1, Yh2v2 (CMYK111, CMYK4114 no longer supported) - int m_comps_in_frame; // # of components in frame - int m_comp_h_samp[JPGD_MAX_COMPONENTS]; // component's horizontal sampling factor - int m_comp_v_samp[JPGD_MAX_COMPONENTS]; // component's vertical sampling factor - int m_comp_quant[JPGD_MAX_COMPONENTS]; // component's quantization table selector - int m_comp_ident[JPGD_MAX_COMPONENTS]; // component's ID - int m_comp_h_blocks[JPGD_MAX_COMPONENTS]; - int m_comp_v_blocks[JPGD_MAX_COMPONENTS]; - int m_comps_in_scan; // # of components in scan - int m_comp_list[JPGD_MAX_COMPS_IN_SCAN]; // components in this scan - int m_comp_dc_tab[JPGD_MAX_COMPONENTS]; // component's DC Huffman coding table selector - int m_comp_ac_tab[JPGD_MAX_COMPONENTS]; // component's AC Huffman coding table selector - int m_spectral_start; // spectral selection start - int m_spectral_end; // spectral selection end - int m_successive_low; // successive approximation low - int m_successive_high; // successive approximation high - int m_max_mcu_x_size; // MCU's max. X size in pixels - int m_max_mcu_y_size; // MCU's max. Y size in pixels - int m_blocks_per_mcu; - int m_max_blocks_per_row; - int m_mcus_per_row, m_mcus_per_col; - int m_mcu_org[JPGD_MAX_BLOCKS_PER_MCU]; - int m_total_lines_left; // total # lines left in image - int m_mcu_lines_left; // total # lines left in this MCU - int m_real_dest_bytes_per_scan_line; - int m_dest_bytes_per_scan_line; // rounded up - int m_dest_bytes_per_pixel; // 4 (RGB) or 1 (Y) - huff_tables* m_pHuff_tabs[JPGD_MAX_HUFF_TABLES]; - coeff_buf* m_dc_coeffs[JPGD_MAX_COMPONENTS]; - coeff_buf* m_ac_coeffs[JPGD_MAX_COMPONENTS]; - int m_eob_run; - int m_block_y_mcu[JPGD_MAX_COMPONENTS]; - uint8* m_pIn_buf_ofs; - int m_in_buf_left; - int m_tem_flag; - bool m_eof_flag; - uint8 m_in_buf_pad_start[128]; - uint8 m_in_buf[JPGD_IN_BUF_SIZE + 128]; - uint8 m_in_buf_pad_end[128]; - int m_bits_left; - uint m_bit_buf; - int m_restart_interval; - int m_restarts_left; - int m_next_restart_num; - int m_max_mcus_per_row; - int m_max_blocks_per_mcu; - int m_expanded_blocks_per_mcu; - int m_expanded_blocks_per_row; - int m_expanded_blocks_per_component; - bool m_freq_domain_chroma_upsample; - int m_max_mcus_per_col; - uint m_last_dc_val[JPGD_MAX_COMPONENTS]; - jpgd_block_t* m_pMCU_coefficients; - int m_mcu_block_max_zag[JPGD_MAX_BLOCKS_PER_MCU]; - uint8* m_pSample_buf; - int m_crr[256]; - int m_cbb[256]; - int m_crg[256]; - int m_cbg[256]; - uint8* m_pScan_line_0; - uint8* m_pScan_line_1; - jpgd_status m_error_code; - bool m_ready_flag; - int m_total_bytes_read; - - void free_all_blocks(); - JPGD_NORETURN void stop_decoding(jpgd_status status); - void *alloc(size_t n, bool zero = false); - void word_clear(void *p, uint16 c, uint n); - void prep_in_buffer(); - void read_dht_marker(); - void read_dqt_marker(); - void read_sof_marker(); - void skip_variable_marker(); - void read_dri_marker(); - void read_sos_marker(); - int next_marker(); - int process_markers(); - void locate_soi_marker(); - void locate_sof_marker(); - int locate_sos_marker(); - void init(jpeg_decoder_stream * pStream); - void create_look_ups(); - void fix_in_buffer(); - void transform_mcu(int mcu_row); - void transform_mcu_expand(int mcu_row); - coeff_buf* coeff_buf_open(int block_num_x, int block_num_y, int block_len_x, int block_len_y); - inline jpgd_block_t *coeff_buf_getp(coeff_buf *cb, int block_x, int block_y); - void load_next_row(); - void decode_next_row(); - void make_huff_table(int index, huff_tables *pH); - void check_quant_tables(); - void check_huff_tables(); - void calc_mcu_block_order(); - int init_scan(); - void init_frame(); - void process_restart(); - void decode_scan(pDecode_block_func decode_block_func); - void init_progressive(); - void init_sequential(); - void decode_start(); - void decode_init(jpeg_decoder_stream * pStream); - void H2V2Convert(); - void H2V1Convert(); - void H1V2Convert(); - void H1V1Convert(); - void gray_convert(); - void expanded_convert(); - void find_eoi(); - inline uint get_char(); - inline uint get_char(bool *pPadding_flag); - inline void stuff_char(uint8 q); - inline uint8 get_octet(); - inline uint get_bits(int num_bits); - inline uint get_bits_no_markers(int numbits); - inline int huff_decode(huff_tables *pH); - inline int huff_decode(huff_tables *pH, int& extrabits); - static inline uint8 clamp(int i); - static void decode_block_dc_first(jpeg_decoder *pD, int component_id, int block_x, int block_y); - static void decode_block_dc_refine(jpeg_decoder *pD, int component_id, int block_x, int block_y); - static void decode_block_ac_first(jpeg_decoder *pD, int component_id, int block_x, int block_y); - static void decode_block_ac_refine(jpeg_decoder *pD, int component_id, int block_x, int block_y); - }; - + typedef unsigned char uint8; + typedef signed short int16; + typedef unsigned short uint16; + typedef unsigned int uint; + typedef signed int int32; + + // Loads a JPEG image from a memory buffer or a file. + // req_comps can be 1 (grayscale), 3 (RGB), or 4 (RGBA). + // On return, width/height will be set to the image's dimensions, and actual_comps will be set to the either 1 (grayscale) or 3 (RGB). + // Notes: For more control over where and how the source data is read, see the decompress_jpeg_image_from_stream() function below, or call the jpeg_decoder class directly. + // Requesting a 8 or 32bpp image is currently a little faster than 24bpp because the jpeg_decoder class itself currently always unpacks to either 8 or 32bpp. + unsigned char* decompress_jpeg_image_from_memory(const unsigned char* pSrc_data, int src_data_size, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags = 0); + unsigned char* decompress_jpeg_image_from_file(const char* pSrc_filename, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags = 0); + + // Success/failure error codes. + enum jpgd_status + { + JPGD_SUCCESS = 0, JPGD_FAILED = -1, JPGD_DONE = 1, + JPGD_BAD_DHT_COUNTS = -256, JPGD_BAD_DHT_INDEX, JPGD_BAD_DHT_MARKER, JPGD_BAD_DQT_MARKER, JPGD_BAD_DQT_TABLE, + JPGD_BAD_PRECISION, JPGD_BAD_HEIGHT, JPGD_BAD_WIDTH, JPGD_TOO_MANY_COMPONENTS, + JPGD_BAD_SOF_LENGTH, JPGD_BAD_VARIABLE_MARKER, JPGD_BAD_DRI_LENGTH, JPGD_BAD_SOS_LENGTH, + JPGD_BAD_SOS_COMP_ID, JPGD_W_EXTRA_BYTES_BEFORE_MARKER, JPGD_NO_ARITHMITIC_SUPPORT, JPGD_UNEXPECTED_MARKER, + JPGD_NOT_JPEG, JPGD_UNSUPPORTED_MARKER, JPGD_BAD_DQT_LENGTH, JPGD_TOO_MANY_BLOCKS, + JPGD_UNDEFINED_QUANT_TABLE, JPGD_UNDEFINED_HUFF_TABLE, JPGD_NOT_SINGLE_SCAN, JPGD_UNSUPPORTED_COLORSPACE, + JPGD_UNSUPPORTED_SAMP_FACTORS, JPGD_DECODE_ERROR, JPGD_BAD_RESTART_MARKER, + JPGD_BAD_SOS_SPECTRAL, JPGD_BAD_SOS_SUCCESSIVE, JPGD_STREAM_READ, JPGD_NOTENOUGHMEM, JPGD_TOO_MANY_SCANS + }; + + // Input stream interface. + // Derive from this class to read input data from sources other than files or memory. Set m_eof_flag to true when no more data is available. + // The decoder is rather greedy: it will keep on calling this method until its internal input buffer is full, or until the EOF flag is set. + // It the input stream contains data after the JPEG stream's EOI (end of image) marker it will probably be pulled into the internal buffer. + // Call the get_total_bytes_read() method to determine the actual size of the JPEG stream after successful decoding. + class jpeg_decoder_stream + { + public: + jpeg_decoder_stream() { } + virtual ~jpeg_decoder_stream() { } + + // The read() method is called when the internal input buffer is empty. + // Parameters: + // pBuf - input buffer + // max_bytes_to_read - maximum bytes that can be written to pBuf + // pEOF_flag - set this to true if at end of stream (no more bytes remaining) + // Returns -1 on error, otherwise return the number of bytes actually written to the buffer (which may be 0). + // Notes: This method will be called in a loop until you set *pEOF_flag to true or the internal buffer is full. + virtual int read(uint8* pBuf, int max_bytes_to_read, bool* pEOF_flag) = 0; + }; + + // stdio FILE stream class. + class jpeg_decoder_file_stream : public jpeg_decoder_stream + { + jpeg_decoder_file_stream(const jpeg_decoder_file_stream&); + jpeg_decoder_file_stream& operator =(const jpeg_decoder_file_stream&); + + FILE* m_pFile; + bool m_eof_flag, m_error_flag; + + public: + jpeg_decoder_file_stream(); + virtual ~jpeg_decoder_file_stream(); + + bool open(const char* Pfilename); + void close(); + + virtual int read(uint8* pBuf, int max_bytes_to_read, bool* pEOF_flag); + }; + + // Memory stream class. + class jpeg_decoder_mem_stream : public jpeg_decoder_stream + { + const uint8* m_pSrc_data; + uint m_ofs, m_size; + + public: + jpeg_decoder_mem_stream() : m_pSrc_data(NULL), m_ofs(0), m_size(0) { } + jpeg_decoder_mem_stream(const uint8* pSrc_data, uint size) : m_pSrc_data(pSrc_data), m_ofs(0), m_size(size) { } + + virtual ~jpeg_decoder_mem_stream() { } + + bool open(const uint8* pSrc_data, uint size); + void close() { m_pSrc_data = NULL; m_ofs = 0; m_size = 0; } + + virtual int read(uint8* pBuf, int max_bytes_to_read, bool* pEOF_flag); + }; + + // Loads JPEG file from a jpeg_decoder_stream. + unsigned char* decompress_jpeg_image_from_stream(jpeg_decoder_stream* pStream, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags = 0); + + enum + { + JPGD_IN_BUF_SIZE = 8192, JPGD_MAX_BLOCKS_PER_MCU = 10, JPGD_MAX_HUFF_TABLES = 8, JPGD_MAX_QUANT_TABLES = 4, + JPGD_MAX_COMPONENTS = 4, JPGD_MAX_COMPS_IN_SCAN = 4, JPGD_MAX_BLOCKS_PER_ROW = 16384, JPGD_MAX_HEIGHT = 32768, JPGD_MAX_WIDTH = 32768 + }; + + typedef int16 jpgd_quant_t; + typedef int16 jpgd_block_coeff_t; + + class jpeg_decoder + { + public: + enum + { + cFlagBoxChromaFiltering = 1, + cFlagDisableSIMD = 2 + }; + + // Call get_error_code() after constructing to determine if the stream is valid or not. You may call the get_width(), get_height(), etc. + // methods after the constructor is called. You may then either destruct the object, or begin decoding the image by calling begin_decoding(), then decode() on each scanline. + jpeg_decoder(jpeg_decoder_stream* pStream, uint32_t flags = 0); + + ~jpeg_decoder(); + + // Call this method after constructing the object to begin decompression. + // If JPGD_SUCCESS is returned you may then call decode() on each scanline. + + int begin_decoding(); + + // Returns the next scan line. + // For grayscale images, pScan_line will point to a buffer containing 8-bit pixels (get_bytes_per_pixel() will return 1). + // Otherwise, it will always point to a buffer containing 32-bit RGBA pixels (A will always be 255, and get_bytes_per_pixel() will return 4). + // Returns JPGD_SUCCESS if a scan line has been returned. + // Returns JPGD_DONE if all scan lines have been returned. + // Returns JPGD_FAILED if an error occurred. Call get_error_code() for a more info. + int decode(const void** pScan_line, uint* pScan_line_len); + + inline jpgd_status get_error_code() const { return m_error_code; } + + inline int get_width() const { return m_image_x_size; } + inline int get_height() const { return m_image_y_size; } + + inline int get_num_components() const { return m_comps_in_frame; } + + inline int get_bytes_per_pixel() const { return m_dest_bytes_per_pixel; } + inline int get_bytes_per_scan_line() const { return m_image_x_size * get_bytes_per_pixel(); } + + // Returns the total number of bytes actually consumed by the decoder (which should equal the actual size of the JPEG file). + inline int get_total_bytes_read() const { return m_total_bytes_read; } + + private: + jpeg_decoder(const jpeg_decoder&); + jpeg_decoder& operator =(const jpeg_decoder&); + + typedef void (*pDecode_block_func)(jpeg_decoder*, int, int, int); + + struct huff_tables + { + bool ac_table; + uint look_up[256]; + uint look_up2[256]; + uint8 code_size[JPGD_HUFF_CODE_SIZE_MAX_LENGTH]; + uint tree[JPGD_HUFF_TREE_MAX_LENGTH]; + }; + + struct coeff_buf + { + uint8* pData; + int block_num_x, block_num_y; + int block_len_x, block_len_y; + int block_size; + }; + + struct mem_block + { + mem_block* m_pNext; + size_t m_used_count; + size_t m_size; + char m_data[1]; + }; + + jmp_buf m_jmp_state; + uint32_t m_flags; + mem_block* m_pMem_blocks; + int m_image_x_size; + int m_image_y_size; + jpeg_decoder_stream* m_pStream; + + int m_progressive_flag; + + uint8 m_huff_ac[JPGD_MAX_HUFF_TABLES]; + uint8* m_huff_num[JPGD_MAX_HUFF_TABLES]; // pointer to number of Huffman codes per bit size + uint8* m_huff_val[JPGD_MAX_HUFF_TABLES]; // pointer to Huffman codes per bit size + jpgd_quant_t* m_quant[JPGD_MAX_QUANT_TABLES]; // pointer to quantization tables + int m_scan_type; // Gray, Yh1v1, Yh1v2, Yh2v1, Yh2v2 (CMYK111, CMYK4114 no longer supported) + int m_comps_in_frame; // # of components in frame + int m_comp_h_samp[JPGD_MAX_COMPONENTS]; // component's horizontal sampling factor + int m_comp_v_samp[JPGD_MAX_COMPONENTS]; // component's vertical sampling factor + int m_comp_quant[JPGD_MAX_COMPONENTS]; // component's quantization table selector + int m_comp_ident[JPGD_MAX_COMPONENTS]; // component's ID + int m_comp_h_blocks[JPGD_MAX_COMPONENTS]; + int m_comp_v_blocks[JPGD_MAX_COMPONENTS]; + int m_comps_in_scan; // # of components in scan + int m_comp_list[JPGD_MAX_COMPS_IN_SCAN]; // components in this scan + int m_comp_dc_tab[JPGD_MAX_COMPONENTS]; // component's DC Huffman coding table selector + int m_comp_ac_tab[JPGD_MAX_COMPONENTS]; // component's AC Huffman coding table selector + int m_spectral_start; // spectral selection start + int m_spectral_end; // spectral selection end + int m_successive_low; // successive approximation low + int m_successive_high; // successive approximation high + int m_max_mcu_x_size; // MCU's max. X size in pixels + int m_max_mcu_y_size; // MCU's max. Y size in pixels + int m_blocks_per_mcu; + int m_max_blocks_per_row; + int m_mcus_per_row, m_mcus_per_col; + int m_mcu_org[JPGD_MAX_BLOCKS_PER_MCU]; + int m_total_lines_left; // total # lines left in image + int m_mcu_lines_left; // total # lines left in this MCU + int m_num_buffered_scanlines; + int m_real_dest_bytes_per_scan_line; + int m_dest_bytes_per_scan_line; // rounded up + int m_dest_bytes_per_pixel; // 4 (RGB) or 1 (Y) + huff_tables* m_pHuff_tabs[JPGD_MAX_HUFF_TABLES]; + coeff_buf* m_dc_coeffs[JPGD_MAX_COMPONENTS]; + coeff_buf* m_ac_coeffs[JPGD_MAX_COMPONENTS]; + int m_eob_run; + int m_block_y_mcu[JPGD_MAX_COMPONENTS]; + uint8* m_pIn_buf_ofs; + int m_in_buf_left; + int m_tem_flag; + + uint8 m_in_buf_pad_start[64]; + uint8 m_in_buf[JPGD_IN_BUF_SIZE + 128]; + uint8 m_in_buf_pad_end[64]; + + int m_bits_left; + uint m_bit_buf; + int m_restart_interval; + int m_restarts_left; + int m_next_restart_num; + int m_max_mcus_per_row; + int m_max_blocks_per_mcu; + + int m_max_mcus_per_col; + uint m_last_dc_val[JPGD_MAX_COMPONENTS]; + jpgd_block_coeff_t* m_pMCU_coefficients; + int m_mcu_block_max_zag[JPGD_MAX_BLOCKS_PER_MCU]; + uint8* m_pSample_buf; + uint8* m_pSample_buf_prev; + int m_crr[256]; + int m_cbb[256]; + int m_crg[256]; + int m_cbg[256]; + uint8* m_pScan_line_0; + uint8* m_pScan_line_1; + jpgd_status m_error_code; + int m_total_bytes_read; + + bool m_ready_flag; + bool m_eof_flag; + bool m_sample_buf_prev_valid; + bool m_has_sse2; + + inline int check_sample_buf_ofs(int ofs) const { assert(ofs >= 0); assert(ofs < m_max_blocks_per_row * 64); return ofs; } + void free_all_blocks(); + JPGD_NORETURN void stop_decoding(jpgd_status status); + void* alloc(size_t n, bool zero = false); + void* alloc_aligned(size_t nSize, uint32_t align = 16, bool zero = false); + void word_clear(void* p, uint16 c, uint n); + void prep_in_buffer(); + void read_dht_marker(); + void read_dqt_marker(); + void read_sof_marker(); + void skip_variable_marker(); + void read_dri_marker(); + void read_sos_marker(); + int next_marker(); + int process_markers(); + void locate_soi_marker(); + void locate_sof_marker(); + int locate_sos_marker(); + void init(jpeg_decoder_stream* pStream, uint32_t flags); + void create_look_ups(); + void fix_in_buffer(); + void transform_mcu(int mcu_row); + coeff_buf* coeff_buf_open(int block_num_x, int block_num_y, int block_len_x, int block_len_y); + inline jpgd_block_coeff_t* coeff_buf_getp(coeff_buf* cb, int block_x, int block_y); + void load_next_row(); + void decode_next_row(); + void make_huff_table(int index, huff_tables* pH); + void check_quant_tables(); + void check_huff_tables(); + bool calc_mcu_block_order(); + int init_scan(); + void init_frame(); + void process_restart(); + void decode_scan(pDecode_block_func decode_block_func); + void init_progressive(); + void init_sequential(); + void decode_start(); + void decode_init(jpeg_decoder_stream* pStream, uint32_t flags); + void H2V2Convert(); + uint32_t H2V2ConvertFiltered(); + void H2V1Convert(); + void H2V1ConvertFiltered(); + void H1V2Convert(); + void H1V2ConvertFiltered(); + void H1V1Convert(); + void gray_convert(); + void find_eoi(); + inline uint get_char(); + inline uint get_char(bool* pPadding_flag); + inline void stuff_char(uint8 q); + inline uint8 get_octet(); + inline uint get_bits(int num_bits); + inline uint get_bits_no_markers(int numbits); + inline int huff_decode(huff_tables* pH); + inline int huff_decode(huff_tables* pH, int& extrabits); + + // Clamps a value between 0-255. + static inline uint8 clamp(int i) + { + if (static_cast<uint>(i) > 255) + i = (((~i) >> 31) & 0xFF); + return static_cast<uint8>(i); + } + int decode_next_mcu_row(); + + static void decode_block_dc_first(jpeg_decoder* pD, int component_id, int block_x, int block_y); + static void decode_block_dc_refine(jpeg_decoder* pD, int component_id, int block_x, int block_y); + static void decode_block_ac_first(jpeg_decoder* pD, int component_id, int block_x, int block_y); + static void decode_block_ac_refine(jpeg_decoder* pD, int component_id, int block_x, int block_y); + }; + } // namespace jpgd #endif // JPEG_DECODER_H diff --git a/thirdparty/jpeg-compressor/jpgd_idct.h b/thirdparty/jpeg-compressor/jpgd_idct.h new file mode 100644 index 0000000000..876425a959 --- /dev/null +++ b/thirdparty/jpeg-compressor/jpgd_idct.h @@ -0,0 +1,462 @@ +// Copyright 2009 Intel Corporation +// All Rights Reserved +// +// Permission is granted to use, copy, distribute and prepare derivative works of this +// software for any purpose and without fee, provided, that the above copyright notice +// and this statement appear in all copies. Intel makes no representations about the +// suitability of this software for any purpose. THIS SOFTWARE IS PROVIDED "AS IS." +// INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, AND ALL LIABILITY, +// INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, FOR THE USE OF THIS SOFTWARE, +// INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY RIGHTS, AND INCLUDING THE +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Intel does not +// assume any responsibility for any errors which may appear in this software nor any +// responsibility to update it. +// +// From: +// https://software.intel.com/sites/default/files/m/d/4/1/d/8/UsingIntelAVXToImplementIDCT-r1_5.pdf +// https://software.intel.com/file/29048 +// +// Requires SSE +// +#ifdef _MSC_VER +#include <intrin.h> +#endif +#include <immintrin.h> + +#ifdef _MSC_VER + #define JPGD_SIMD_ALIGN(type, name) __declspec(align(16)) type name +#else + #define JPGD_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) +#endif + +#define BITS_INV_ACC 4 +#define SHIFT_INV_ROW 16 - BITS_INV_ACC +#define SHIFT_INV_COL 1 + BITS_INV_ACC +const short IRND_INV_ROW = 1024 * (6 - BITS_INV_ACC); //1 << (SHIFT_INV_ROW-1) +const short IRND_INV_COL = 16 * (BITS_INV_ACC - 3); // 1 << (SHIFT_INV_COL-1) +const short IRND_INV_CORR = IRND_INV_COL - 1; // correction -1.0 and round + +JPGD_SIMD_ALIGN(short, shortM128_one_corr[8]) = {1, 1, 1, 1, 1, 1, 1, 1}; +JPGD_SIMD_ALIGN(short, shortM128_round_inv_row[8]) = {IRND_INV_ROW, 0, IRND_INV_ROW, 0, IRND_INV_ROW, 0, IRND_INV_ROW, 0}; +JPGD_SIMD_ALIGN(short, shortM128_round_inv_col[8]) = {IRND_INV_COL, IRND_INV_COL, IRND_INV_COL, IRND_INV_COL, IRND_INV_COL, IRND_INV_COL, IRND_INV_COL, IRND_INV_COL}; +JPGD_SIMD_ALIGN(short, shortM128_round_inv_corr[8])= {IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR}; +JPGD_SIMD_ALIGN(short, shortM128_tg_1_16[8]) = {13036, 13036, 13036, 13036, 13036, 13036, 13036, 13036}; // tg * (2<<16) + 0.5 +JPGD_SIMD_ALIGN(short, shortM128_tg_2_16[8]) = {27146, 27146, 27146, 27146, 27146, 27146, 27146, 27146}; // tg * (2<<16) + 0.5 +JPGD_SIMD_ALIGN(short, shortM128_tg_3_16[8]) = {-21746, -21746, -21746, -21746, -21746, -21746, -21746, -21746}; // tg * (2<<16) + 0.5 +JPGD_SIMD_ALIGN(short, shortM128_cos_4_16[8]) = {-19195, -19195, -19195, -19195, -19195, -19195, -19195, -19195};// cos * (2<<16) + 0.5 + +//----------------------------------------------------------------------------- +// Table for rows 0,4 - constants are multiplied on cos_4_16 +// w15 w14 w11 w10 w07 w06 w03 w02 +// w29 w28 w25 w24 w21 w20 w17 w16 +// w31 w30 w27 w26 w23 w22 w19 w18 +//movq -> w05 w04 w01 w00 +JPGD_SIMD_ALIGN(short, shortM128_tab_i_04[]) = { + 16384, 21407, 16384, 8867, + 16384, -8867, 16384, -21407, // w13 w12 w09 w08 + 16384, 8867, -16384, -21407, // w07 w06 w03 w02 + -16384, 21407, 16384, -8867, // w15 w14 w11 w10 + 22725, 19266, 19266, -4520, // w21 w20 w17 w16 + 12873, -22725, 4520, -12873, // w29 w28 w25 w24 + 12873, 4520, -22725, -12873, // w23 w22 w19 w18 + 4520, 19266, 19266, -22725}; // w31 w30 w27 w26 + + // Table for rows 1,7 - constants are multiplied on cos_1_16 +//movq -> w05 w04 w01 w00 +JPGD_SIMD_ALIGN(short, shortM128_tab_i_17[]) = { + 22725, 29692, 22725, 12299, + 22725, -12299, 22725, -29692, // w13 w12 w09 w08 + 22725, 12299, -22725, -29692, // w07 w06 w03 w02 + -22725, 29692, 22725, -12299, // w15 w14 w11 w10 + 31521, 26722, 26722, -6270, // w21 w20 w17 w16 + 17855, -31521, 6270, -17855, // w29 w28 w25 w24 + 17855, 6270, -31521, -17855, // w23 w22 w19 w18 + 6270, 26722, 26722, -31521}; // w31 w30 w27 w26 + +// Table for rows 2,6 - constants are multiplied on cos_2_16 +//movq -> w05 w04 w01 w00 +JPGD_SIMD_ALIGN(short, shortM128_tab_i_26[]) = { + 21407, 27969, 21407, 11585, + 21407, -11585, 21407, -27969, // w13 w12 w09 w08 + 21407, 11585, -21407, -27969, // w07 w06 w03 w02 + -21407, 27969, 21407, -11585, // w15 w14 w11 w10 + 29692, 25172, 25172, -5906, // w21 w20 w17 w16 + 16819, -29692, 5906, -16819, // w29 w28 w25 w24 + 16819, 5906, -29692, -16819, // w23 w22 w19 w18 + 5906, 25172, 25172, -29692}; // w31 w30 w27 w26 +// Table for rows 3,5 - constants are multiplied on cos_3_16 +//movq -> w05 w04 w01 w00 +JPGD_SIMD_ALIGN(short, shortM128_tab_i_35[]) = { + 19266, 25172, 19266, 10426, + 19266, -10426, 19266, -25172, // w13 w12 w09 w08 + 19266, 10426, -19266, -25172, // w07 w06 w03 w02 + -19266, 25172, 19266, -10426, // w15 w14 w11 w10 + 26722, 22654, 22654, -5315, // w21 w20 w17 w16 + 15137, -26722, 5315, -15137, // w29 w28 w25 w24 + 15137, 5315, -26722, -15137, // w23 w22 w19 w18 + 5315, 22654, 22654, -26722}; // w31 w30 w27 w26 + +JPGD_SIMD_ALIGN(short, shortM128_128[8]) = { 128, 128, 128, 128, 128, 128, 128, 128 }; + +void idctSSEShortU8(const short *pInput, uint8_t * pOutputUB) +{ + __m128i r_xmm0, r_xmm4; + __m128i r_xmm1, r_xmm2, r_xmm3, r_xmm5, r_xmm6, r_xmm7; + __m128i row0, row1, row2, row3, row4, row5, row6, row7; + short * pTab_i_04 = shortM128_tab_i_04; + short * pTab_i_26 = shortM128_tab_i_26; + + //Get pointers for this input and output + pTab_i_04 = shortM128_tab_i_04; + pTab_i_26 = shortM128_tab_i_26; + + //Row 1 and Row 3 + r_xmm0 = _mm_load_si128((__m128i *) pInput); + r_xmm4 = _mm_load_si128((__m128i *) (&pInput[2*8])); + + // *** Work on the data in xmm0 + //low shuffle mask = 0xd8 = 11 01 10 00 + //get short 2 and short 0 into ls 32-bits + r_xmm0 = _mm_shufflelo_epi16(r_xmm0, 0xd8); + + // copy short 2 and short 0 to all locations + r_xmm1 = _mm_shuffle_epi32(r_xmm0, 0); + + // add to those copies + r_xmm1 = _mm_madd_epi16(r_xmm1, *((__m128i *) pTab_i_04)); + + // shuffle mask = 0x55 = 01 01 01 01 + // copy short 3 and short 1 to all locations + r_xmm3 = _mm_shuffle_epi32(r_xmm0, 0x55); + + // high shuffle mask = 0xd8 = 11 01 10 00 + // get short 6 and short 4 into bit positions 64-95 + // get short 7 and short 5 into bit positions 96-127 + r_xmm0 = _mm_shufflehi_epi16(r_xmm0, 0xd8); + + // add to short 3 and short 1 + r_xmm3 = _mm_madd_epi16(r_xmm3, *((__m128i *) &pTab_i_04[16])); + + // shuffle mask = 0xaa = 10 10 10 10 + // copy short 6 and short 4 to all locations + r_xmm2 = _mm_shuffle_epi32(r_xmm0, 0xaa); + + // shuffle mask = 0xaa = 11 11 11 11 + // copy short 7 and short 5 to all locations + r_xmm0 = _mm_shuffle_epi32(r_xmm0, 0xff); + + // add to short 6 and short 4 + r_xmm2 = _mm_madd_epi16(r_xmm2, *((__m128i *) &pTab_i_04[8])); + + // *** Work on the data in xmm4 + // high shuffle mask = 0xd8 11 01 10 00 + // get short 6 and short 4 into bit positions 64-95 + // get short 7 and short 5 into bit positions 96-127 + r_xmm4 = _mm_shufflehi_epi16(r_xmm4, 0xd8); + + // (xmm0 short 2 and short 0 plus pSi) + some constants + r_xmm1 = _mm_add_epi32(r_xmm1, *((__m128i *) shortM128_round_inv_row)); + r_xmm4 = _mm_shufflelo_epi16(r_xmm4, 0xd8); + r_xmm0 = _mm_madd_epi16(r_xmm0, *((__m128i *) &pTab_i_04[24])); + r_xmm5 = _mm_shuffle_epi32(r_xmm4, 0); + r_xmm6 = _mm_shuffle_epi32(r_xmm4, 0xaa); + r_xmm5 = _mm_madd_epi16(r_xmm5, *((__m128i *) &shortM128_tab_i_26[0])); + r_xmm1 = _mm_add_epi32(r_xmm1, r_xmm2); + r_xmm2 = r_xmm1; + r_xmm7 = _mm_shuffle_epi32(r_xmm4, 0x55); + r_xmm6 = _mm_madd_epi16(r_xmm6, *((__m128i *) &shortM128_tab_i_26[8])); + r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm3); + r_xmm4 = _mm_shuffle_epi32(r_xmm4, 0xff); + r_xmm2 = _mm_sub_epi32(r_xmm2, r_xmm0); + r_xmm7 = _mm_madd_epi16(r_xmm7, *((__m128i *) &shortM128_tab_i_26[16])); + r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm1); + r_xmm2 = _mm_srai_epi32(r_xmm2, 12); + r_xmm5 = _mm_add_epi32(r_xmm5, *((__m128i *) shortM128_round_inv_row)); + r_xmm4 = _mm_madd_epi16(r_xmm4, *((__m128i *) &shortM128_tab_i_26[24])); + r_xmm5 = _mm_add_epi32(r_xmm5, r_xmm6); + r_xmm6 = r_xmm5; + r_xmm0 = _mm_srai_epi32(r_xmm0, 12); + r_xmm2 = _mm_shuffle_epi32(r_xmm2, 0x1b); + row0 = _mm_packs_epi32(r_xmm0, r_xmm2); + r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm7); + r_xmm6 = _mm_sub_epi32(r_xmm6, r_xmm4); + r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm5); + r_xmm6 = _mm_srai_epi32(r_xmm6, 12); + r_xmm4 = _mm_srai_epi32(r_xmm4, 12); + r_xmm6 = _mm_shuffle_epi32(r_xmm6, 0x1b); + row2 = _mm_packs_epi32(r_xmm4, r_xmm6); + + //Row 5 and row 7 + r_xmm0 = _mm_load_si128((__m128i *) (&pInput[4*8])); + r_xmm4 = _mm_load_si128((__m128i *) (&pInput[6*8])); + + r_xmm0 = _mm_shufflelo_epi16(r_xmm0, 0xd8); + r_xmm1 = _mm_shuffle_epi32(r_xmm0, 0); + r_xmm1 = _mm_madd_epi16(r_xmm1, *((__m128i *) pTab_i_04)); + r_xmm3 = _mm_shuffle_epi32(r_xmm0, 0x55); + r_xmm0 = _mm_shufflehi_epi16(r_xmm0, 0xd8); + r_xmm3 = _mm_madd_epi16(r_xmm3, *((__m128i *) &pTab_i_04[16])); + r_xmm2 = _mm_shuffle_epi32(r_xmm0, 0xaa); + r_xmm0 = _mm_shuffle_epi32(r_xmm0, 0xff); + r_xmm2 = _mm_madd_epi16(r_xmm2, *((__m128i *) &pTab_i_04[8])); + r_xmm4 = _mm_shufflehi_epi16(r_xmm4, 0xd8); + r_xmm1 = _mm_add_epi32(r_xmm1, *((__m128i *) shortM128_round_inv_row)); + r_xmm4 = _mm_shufflelo_epi16(r_xmm4, 0xd8); + r_xmm0 = _mm_madd_epi16(r_xmm0, *((__m128i *) &pTab_i_04[24])); + r_xmm5 = _mm_shuffle_epi32(r_xmm4, 0); + r_xmm6 = _mm_shuffle_epi32(r_xmm4, 0xaa); + r_xmm5 = _mm_madd_epi16(r_xmm5, *((__m128i *) &shortM128_tab_i_26[0])); + r_xmm1 = _mm_add_epi32(r_xmm1, r_xmm2); + r_xmm2 = r_xmm1; + r_xmm7 = _mm_shuffle_epi32(r_xmm4, 0x55); + r_xmm6 = _mm_madd_epi16(r_xmm6, *((__m128i *) &shortM128_tab_i_26[8])); + r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm3); + r_xmm4 = _mm_shuffle_epi32(r_xmm4, 0xff); + r_xmm2 = _mm_sub_epi32(r_xmm2, r_xmm0); + r_xmm7 = _mm_madd_epi16(r_xmm7, *((__m128i *) &shortM128_tab_i_26[16])); + r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm1); + r_xmm2 = _mm_srai_epi32(r_xmm2, 12); + r_xmm5 = _mm_add_epi32(r_xmm5, *((__m128i *) shortM128_round_inv_row)); + r_xmm4 = _mm_madd_epi16(r_xmm4, *((__m128i *) &shortM128_tab_i_26[24])); + r_xmm5 = _mm_add_epi32(r_xmm5, r_xmm6); + r_xmm6 = r_xmm5; + r_xmm0 = _mm_srai_epi32(r_xmm0, 12); + r_xmm2 = _mm_shuffle_epi32(r_xmm2, 0x1b); + row4 = _mm_packs_epi32(r_xmm0, r_xmm2); + r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm7); + r_xmm6 = _mm_sub_epi32(r_xmm6, r_xmm4); + r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm5); + r_xmm6 = _mm_srai_epi32(r_xmm6, 12); + r_xmm4 = _mm_srai_epi32(r_xmm4, 12); + r_xmm6 = _mm_shuffle_epi32(r_xmm6, 0x1b); + row6 = _mm_packs_epi32(r_xmm4, r_xmm6); + + //Row 4 and row 2 + pTab_i_04 = shortM128_tab_i_35; + pTab_i_26 = shortM128_tab_i_17; + r_xmm0 = _mm_load_si128((__m128i *) (&pInput[3*8])); + r_xmm4 = _mm_load_si128((__m128i *) (&pInput[1*8])); + + r_xmm0 = _mm_shufflelo_epi16(r_xmm0, 0xd8); + r_xmm1 = _mm_shuffle_epi32(r_xmm0, 0); + r_xmm1 = _mm_madd_epi16(r_xmm1, *((__m128i *) pTab_i_04)); + r_xmm3 = _mm_shuffle_epi32(r_xmm0, 0x55); + r_xmm0 = _mm_shufflehi_epi16(r_xmm0, 0xd8); + r_xmm3 = _mm_madd_epi16(r_xmm3, *((__m128i *) &pTab_i_04[16])); + r_xmm2 = _mm_shuffle_epi32(r_xmm0, 0xaa); + r_xmm0 = _mm_shuffle_epi32(r_xmm0, 0xff); + r_xmm2 = _mm_madd_epi16(r_xmm2, *((__m128i *) &pTab_i_04[8])); + r_xmm4 = _mm_shufflehi_epi16(r_xmm4, 0xd8); + r_xmm1 = _mm_add_epi32(r_xmm1, *((__m128i *) shortM128_round_inv_row)); + r_xmm4 = _mm_shufflelo_epi16(r_xmm4, 0xd8); + r_xmm0 = _mm_madd_epi16(r_xmm0, *((__m128i *) &pTab_i_04[24])); + r_xmm5 = _mm_shuffle_epi32(r_xmm4, 0); + r_xmm6 = _mm_shuffle_epi32(r_xmm4, 0xaa); + r_xmm5 = _mm_madd_epi16(r_xmm5, *((__m128i *) &pTab_i_26[0])); + r_xmm1 = _mm_add_epi32(r_xmm1, r_xmm2); + r_xmm2 = r_xmm1; + r_xmm7 = _mm_shuffle_epi32(r_xmm4, 0x55); + r_xmm6 = _mm_madd_epi16(r_xmm6, *((__m128i *) &pTab_i_26[8])); + r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm3); + r_xmm4 = _mm_shuffle_epi32(r_xmm4, 0xff); + r_xmm2 = _mm_sub_epi32(r_xmm2, r_xmm0); + r_xmm7 = _mm_madd_epi16(r_xmm7, *((__m128i *) &pTab_i_26[16])); + r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm1); + r_xmm2 = _mm_srai_epi32(r_xmm2, 12); + r_xmm5 = _mm_add_epi32(r_xmm5, *((__m128i *) shortM128_round_inv_row)); + r_xmm4 = _mm_madd_epi16(r_xmm4, *((__m128i *) &pTab_i_26[24])); + r_xmm5 = _mm_add_epi32(r_xmm5, r_xmm6); + r_xmm6 = r_xmm5; + r_xmm0 = _mm_srai_epi32(r_xmm0, 12); + r_xmm2 = _mm_shuffle_epi32(r_xmm2, 0x1b); + row3 = _mm_packs_epi32(r_xmm0, r_xmm2); + r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm7); + r_xmm6 = _mm_sub_epi32(r_xmm6, r_xmm4); + r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm5); + r_xmm6 = _mm_srai_epi32(r_xmm6, 12); + r_xmm4 = _mm_srai_epi32(r_xmm4, 12); + r_xmm6 = _mm_shuffle_epi32(r_xmm6, 0x1b); + row1 = _mm_packs_epi32(r_xmm4, r_xmm6); + + //Row 6 and row 8 + r_xmm0 = _mm_load_si128((__m128i *) (&pInput[5*8])); + r_xmm4 = _mm_load_si128((__m128i *) (&pInput[7*8])); + + r_xmm0 = _mm_shufflelo_epi16(r_xmm0, 0xd8); + r_xmm1 = _mm_shuffle_epi32(r_xmm0, 0); + r_xmm1 = _mm_madd_epi16(r_xmm1, *((__m128i *) pTab_i_04)); + r_xmm3 = _mm_shuffle_epi32(r_xmm0, 0x55); + r_xmm0 = _mm_shufflehi_epi16(r_xmm0, 0xd8); + r_xmm3 = _mm_madd_epi16(r_xmm3, *((__m128i *) &pTab_i_04[16])); + r_xmm2 = _mm_shuffle_epi32(r_xmm0, 0xaa); + r_xmm0 = _mm_shuffle_epi32(r_xmm0, 0xff); + r_xmm2 = _mm_madd_epi16(r_xmm2, *((__m128i *) &pTab_i_04[8])); + r_xmm4 = _mm_shufflehi_epi16(r_xmm4, 0xd8); + r_xmm1 = _mm_add_epi32(r_xmm1, *((__m128i *) shortM128_round_inv_row)); + r_xmm4 = _mm_shufflelo_epi16(r_xmm4, 0xd8); + r_xmm0 = _mm_madd_epi16(r_xmm0, *((__m128i *) &pTab_i_04[24])); + r_xmm5 = _mm_shuffle_epi32(r_xmm4, 0); + r_xmm6 = _mm_shuffle_epi32(r_xmm4, 0xaa); + r_xmm5 = _mm_madd_epi16(r_xmm5, *((__m128i *) &pTab_i_26[0])); + r_xmm1 = _mm_add_epi32(r_xmm1, r_xmm2); + r_xmm2 = r_xmm1; + r_xmm7 = _mm_shuffle_epi32(r_xmm4, 0x55); + r_xmm6 = _mm_madd_epi16(r_xmm6, *((__m128i *) &pTab_i_26[8])); + r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm3); + r_xmm4 = _mm_shuffle_epi32(r_xmm4, 0xff); + r_xmm2 = _mm_sub_epi32(r_xmm2, r_xmm0); + r_xmm7 = _mm_madd_epi16(r_xmm7, *((__m128i *) &pTab_i_26[16])); + r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm1); + r_xmm2 = _mm_srai_epi32(r_xmm2, 12); + r_xmm5 = _mm_add_epi32(r_xmm5, *((__m128i *) shortM128_round_inv_row)); + r_xmm4 = _mm_madd_epi16(r_xmm4, *((__m128i *) &pTab_i_26[24])); + r_xmm5 = _mm_add_epi32(r_xmm5, r_xmm6); + r_xmm6 = r_xmm5; + r_xmm0 = _mm_srai_epi32(r_xmm0, 12); + r_xmm2 = _mm_shuffle_epi32(r_xmm2, 0x1b); + row5 = _mm_packs_epi32(r_xmm0, r_xmm2); + r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm7); + r_xmm6 = _mm_sub_epi32(r_xmm6, r_xmm4); + r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm5); + r_xmm6 = _mm_srai_epi32(r_xmm6, 12); + r_xmm4 = _mm_srai_epi32(r_xmm4, 12); + r_xmm6 = _mm_shuffle_epi32(r_xmm6, 0x1b); + row7 = _mm_packs_epi32(r_xmm4, r_xmm6); + + r_xmm1 = _mm_load_si128((__m128i *) shortM128_tg_3_16); + r_xmm2 = row5; + r_xmm3 = row3; + r_xmm0 = _mm_mulhi_epi16(row5, r_xmm1); + + r_xmm1 = _mm_mulhi_epi16(r_xmm1, r_xmm3); + r_xmm5 = _mm_load_si128((__m128i *) shortM128_tg_1_16); + r_xmm6 = row7; + r_xmm4 = _mm_mulhi_epi16(row7, r_xmm5); + + r_xmm0 = _mm_adds_epi16(r_xmm0, r_xmm2); + r_xmm5 = _mm_mulhi_epi16(r_xmm5, row1); + r_xmm1 = _mm_adds_epi16(r_xmm1, r_xmm3); + r_xmm7 = row6; + + r_xmm0 = _mm_adds_epi16(r_xmm0, r_xmm3); + r_xmm3 = _mm_load_si128((__m128i *) shortM128_tg_2_16); + r_xmm2 = _mm_subs_epi16(r_xmm2, r_xmm1); + r_xmm7 = _mm_mulhi_epi16(r_xmm7, r_xmm3); + r_xmm1 = r_xmm0; + r_xmm3 = _mm_mulhi_epi16(r_xmm3, row2); + r_xmm5 = _mm_subs_epi16(r_xmm5, r_xmm6); + r_xmm4 = _mm_adds_epi16(r_xmm4, row1); + r_xmm0 = _mm_adds_epi16(r_xmm0, r_xmm4); + r_xmm0 = _mm_adds_epi16(r_xmm0, *((__m128i *) shortM128_one_corr)); + r_xmm4 = _mm_subs_epi16(r_xmm4, r_xmm1); + r_xmm6 = r_xmm5; + r_xmm5 = _mm_subs_epi16(r_xmm5, r_xmm2); + r_xmm5 = _mm_adds_epi16(r_xmm5, *((__m128i *) shortM128_one_corr)); + r_xmm6 = _mm_adds_epi16(r_xmm6, r_xmm2); + + //Intermediate results, needed later + __m128i temp3, temp7; + temp7 = r_xmm0; + + r_xmm1 = r_xmm4; + r_xmm0 = _mm_load_si128((__m128i *) shortM128_cos_4_16); + r_xmm4 = _mm_adds_epi16(r_xmm4, r_xmm5); + r_xmm2 = _mm_load_si128((__m128i *) shortM128_cos_4_16); + r_xmm2 = _mm_mulhi_epi16(r_xmm2, r_xmm4); + + //Intermediate results, needed later + temp3 = r_xmm6; + + r_xmm1 = _mm_subs_epi16(r_xmm1, r_xmm5); + r_xmm7 = _mm_adds_epi16(r_xmm7, row2); + r_xmm3 = _mm_subs_epi16(r_xmm3, row6); + r_xmm6 = row0; + r_xmm0 = _mm_mulhi_epi16(r_xmm0, r_xmm1); + r_xmm5 = row4; + r_xmm5 = _mm_adds_epi16(r_xmm5, r_xmm6); + r_xmm6 = _mm_subs_epi16(r_xmm6, row4); + r_xmm4 = _mm_adds_epi16(r_xmm4, r_xmm2); + + r_xmm4 = _mm_or_si128(r_xmm4, *((__m128i *) shortM128_one_corr)); + r_xmm0 = _mm_adds_epi16(r_xmm0, r_xmm1); + r_xmm0 = _mm_or_si128(r_xmm0, *((__m128i *) shortM128_one_corr)); + + r_xmm2 = r_xmm5; + r_xmm5 = _mm_adds_epi16(r_xmm5, r_xmm7); + r_xmm1 = r_xmm6; + r_xmm5 = _mm_adds_epi16(r_xmm5, *((__m128i *) shortM128_round_inv_col)); + r_xmm2 = _mm_subs_epi16(r_xmm2, r_xmm7); + r_xmm7 = temp7; + r_xmm6 = _mm_adds_epi16(r_xmm6, r_xmm3); + r_xmm6 = _mm_adds_epi16(r_xmm6, *((__m128i *) shortM128_round_inv_col)); + r_xmm7 = _mm_adds_epi16(r_xmm7, r_xmm5); + r_xmm7 = _mm_srai_epi16(r_xmm7, SHIFT_INV_COL); + r_xmm1 = _mm_subs_epi16(r_xmm1, r_xmm3); + r_xmm1 = _mm_adds_epi16(r_xmm1, *((__m128i *) shortM128_round_inv_corr)); + r_xmm3 = r_xmm6; + r_xmm2 = _mm_adds_epi16(r_xmm2, *((__m128i *) shortM128_round_inv_corr)); + r_xmm6 = _mm_adds_epi16(r_xmm6, r_xmm4); + + //Store results for row 0 + //_mm_store_si128((__m128i *) pOutput, r_xmm7); + __m128i r0 = r_xmm7; + + r_xmm6 = _mm_srai_epi16(r_xmm6, SHIFT_INV_COL); + r_xmm7 = r_xmm1; + r_xmm1 = _mm_adds_epi16(r_xmm1, r_xmm0); + + //Store results for row 1 + //_mm_store_si128((__m128i *) (&pOutput[1*8]), r_xmm6); + __m128i r1 = r_xmm6; + + r_xmm1 = _mm_srai_epi16(r_xmm1, SHIFT_INV_COL); + r_xmm6 = temp3; + r_xmm7 = _mm_subs_epi16(r_xmm7, r_xmm0); + r_xmm7 = _mm_srai_epi16(r_xmm7, SHIFT_INV_COL); + + //Store results for row 2 + //_mm_store_si128((__m128i *) (&pOutput[2*8]), r_xmm1); + __m128i r2 = r_xmm1; + + r_xmm5 = _mm_subs_epi16(r_xmm5, temp7); + r_xmm5 = _mm_srai_epi16(r_xmm5, SHIFT_INV_COL); + + //Store results for row 7 + //_mm_store_si128((__m128i *) (&pOutput[7*8]), r_xmm5); + __m128i r7 = r_xmm5; + + r_xmm3 = _mm_subs_epi16(r_xmm3, r_xmm4); + r_xmm6 = _mm_adds_epi16(r_xmm6, r_xmm2); + r_xmm2 = _mm_subs_epi16(r_xmm2, temp3); + r_xmm6 = _mm_srai_epi16(r_xmm6, SHIFT_INV_COL); + r_xmm2 = _mm_srai_epi16(r_xmm2, SHIFT_INV_COL); + + //Store results for row 3 + //_mm_store_si128((__m128i *) (&pOutput[3*8]), r_xmm6); + __m128i r3 = r_xmm6; + + r_xmm3 = _mm_srai_epi16(r_xmm3, SHIFT_INV_COL); + + //Store results for rows 4, 5, and 6 + //_mm_store_si128((__m128i *) (&pOutput[4*8]), r_xmm2); + //_mm_store_si128((__m128i *) (&pOutput[5*8]), r_xmm7); + //_mm_store_si128((__m128i *) (&pOutput[6*8]), r_xmm3); + + __m128i r4 = r_xmm2; + __m128i r5 = r_xmm7; + __m128i r6 = r_xmm3; + + r0 = _mm_add_epi16(*(const __m128i *)shortM128_128, r0); + r1 = _mm_add_epi16(*(const __m128i *)shortM128_128, r1); + r2 = _mm_add_epi16(*(const __m128i *)shortM128_128, r2); + r3 = _mm_add_epi16(*(const __m128i *)shortM128_128, r3); + r4 = _mm_add_epi16(*(const __m128i *)shortM128_128, r4); + r5 = _mm_add_epi16(*(const __m128i *)shortM128_128, r5); + r6 = _mm_add_epi16(*(const __m128i *)shortM128_128, r6); + r7 = _mm_add_epi16(*(const __m128i *)shortM128_128, r7); + + ((__m128i *)pOutputUB)[0] = _mm_packus_epi16(r0, r1); + ((__m128i *)pOutputUB)[1] = _mm_packus_epi16(r2, r3); + ((__m128i *)pOutputUB)[2] = _mm_packus_epi16(r4, r5); + ((__m128i *)pOutputUB)[3] = _mm_packus_epi16(r6, r7); +} diff --git a/thirdparty/jpeg-compressor/patches/fix-msvc2017-build.patch b/thirdparty/jpeg-compressor/patches/fix-msvc2017-build.patch new file mode 100644 index 0000000000..7b338de084 --- /dev/null +++ b/thirdparty/jpeg-compressor/patches/fix-msvc2017-build.patch @@ -0,0 +1,31 @@ +diff --git a/thirdparty/jpeg-compressor/jpgd.cpp b/thirdparty/jpeg-compressor/jpgd.cpp +index a0c494db61..257d0b7574 100644 +--- a/thirdparty/jpeg-compressor/jpgd.cpp ++++ b/thirdparty/jpeg-compressor/jpgd.cpp +@@ -2126,7 +2126,7 @@ namespace jpgd { + + int jpeg_decoder::decode_next_mcu_row() + { +- if (setjmp(m_jmp_state)) ++ if (::setjmp(m_jmp_state)) + return JPGD_FAILED; + + const bool chroma_y_filtering = ((m_flags & cFlagBoxChromaFiltering) == 0) && ((m_scan_type == JPGD_YH2V2) || (m_scan_type == JPGD_YH1V2)); +@@ -3042,7 +3042,7 @@ namespace jpgd { + + jpeg_decoder::jpeg_decoder(jpeg_decoder_stream* pStream, uint32_t flags) + { +- if (setjmp(m_jmp_state)) ++ if (::setjmp(m_jmp_state)) + return; + decode_init(pStream, flags); + } +@@ -3055,7 +3055,7 @@ namespace jpgd { + if (m_error_code) + return JPGD_FAILED; + +- if (setjmp(m_jmp_state)) ++ if (::setjmp(m_jmp_state)) + return JPGD_FAILED; + + decode_start(); diff --git a/thirdparty/mbedtls/include/mbedtls/check_config.h b/thirdparty/mbedtls/include/mbedtls/check_config.h index d076c2352f..93de091c4d 100644 --- a/thirdparty/mbedtls/include/mbedtls/check_config.h +++ b/thirdparty/mbedtls/include/mbedtls/check_config.h @@ -546,6 +546,23 @@ #error "MBEDTLS_SSL_PROTO_TLS1_2 defined, but not all prerequisites" #endif +#if (defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)) && \ + !(defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) ) +#error "One or more versions of the TLS protocol are enabled " \ + "but no key exchange methods defined with MBEDTLS_KEY_EXCHANGE_xxxx" +#endif + #if defined(MBEDTLS_SSL_PROTO_DTLS) && \ !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ !defined(MBEDTLS_SSL_PROTO_TLS1_2) @@ -669,6 +686,10 @@ #error "MBEDTLS_X509_CREATE_C defined, but not all prerequisites" #endif +#if defined(MBEDTLS_CERTS_C) && !defined(MBEDTLS_X509_USE_C) +#error "MBEDTLS_CERTS_C defined, but not all prerequisites" +#endif + #if defined(MBEDTLS_X509_CRT_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) ) #error "MBEDTLS_X509_CRT_PARSE_C defined, but not all prerequisites" #endif diff --git a/thirdparty/mbedtls/include/mbedtls/version.h b/thirdparty/mbedtls/include/mbedtls/version.h index 8e2ce03c32..e0a2e7f6d6 100644 --- a/thirdparty/mbedtls/include/mbedtls/version.h +++ b/thirdparty/mbedtls/include/mbedtls/version.h @@ -40,16 +40,16 @@ */ #define MBEDTLS_VERSION_MAJOR 2 #define MBEDTLS_VERSION_MINOR 16 -#define MBEDTLS_VERSION_PATCH 5 +#define MBEDTLS_VERSION_PATCH 6 /** * The single version number has the following structure: * MMNNPP00 * Major version | Minor version | Patch version */ -#define MBEDTLS_VERSION_NUMBER 0x02100500 -#define MBEDTLS_VERSION_STRING "2.16.5" -#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.16.5" +#define MBEDTLS_VERSION_NUMBER 0x02100600 +#define MBEDTLS_VERSION_STRING "2.16.6" +#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.16.6" #if defined(MBEDTLS_VERSION_C) diff --git a/thirdparty/mbedtls/library/ecp.c b/thirdparty/mbedtls/library/ecp.c index 040c20bd38..725e176df2 100644 --- a/thirdparty/mbedtls/library/ecp.c +++ b/thirdparty/mbedtls/library/ecp.c @@ -1938,6 +1938,20 @@ static int ecp_mul_comb_after_precomp( const mbedtls_ecp_group *grp, final_norm: #endif + /* + * Knowledge of the jacobian coordinates may leak the last few bits of the + * scalar [1], and since our MPI implementation isn't constant-flow, + * inversion (used for coordinate normalization) may leak the full value + * of its input via side-channels [2]. + * + * [1] https://eprint.iacr.org/2003/191 + * [2] https://eprint.iacr.org/2020/055 + * + * Avoid the leak by randomizing coordinates before we normalize them. + */ + if( f_rng != 0 ) + MBEDTLS_MPI_CHK( ecp_randomize_jac( grp, RR, f_rng, p_rng ) ); + MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_INV ); MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, RR ) ); @@ -2308,6 +2322,20 @@ static int ecp_mul_mxz( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->Z, &RP.Z, b ) ); } + /* + * Knowledge of the projective coordinates may leak the last few bits of the + * scalar [1], and since our MPI implementation isn't constant-flow, + * inversion (used for coordinate normalization) may leak the full value + * of its input via side-channels [2]. + * + * [1] https://eprint.iacr.org/2003/191 + * [2] https://eprint.iacr.org/2020/055 + * + * Avoid the leak by randomizing coordinates before we normalize them. + */ + if( f_rng != NULL ) + MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, R, f_rng, p_rng ) ); + MBEDTLS_MPI_CHK( ecp_normalize_mxz( grp, R ) ); cleanup: diff --git a/thirdparty/mbedtls/library/ssl_cli.c b/thirdparty/mbedtls/library/ssl_cli.c index afced7a99c..c5c3af69df 100644 --- a/thirdparty/mbedtls/library/ssl_cli.c +++ b/thirdparty/mbedtls/library/ssl_cli.c @@ -1417,6 +1417,19 @@ static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse hello verify request" ) ); + /* Check that there is enough room for: + * - 2 bytes of version + * - 1 byte of cookie_len + */ + if( mbedtls_ssl_hs_hdr_len( ssl ) + 3 > ssl->in_msglen ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "incoming HelloVerifyRequest message is too short" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + /* * struct { * ProtocolVersion server_version; @@ -1445,8 +1458,6 @@ static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl ) } cookie_len = *p++; - MBEDTLS_SSL_DEBUG_BUF( 3, "cookie", p, cookie_len ); - if( ( ssl->in_msg + ssl->in_msglen ) - p < cookie_len ) { MBEDTLS_SSL_DEBUG_MSG( 1, @@ -1455,6 +1466,7 @@ static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } + MBEDTLS_SSL_DEBUG_BUF( 3, "cookie", p, cookie_len ); mbedtls_free( ssl->handshake->verify_cookie ); diff --git a/thirdparty/mbedtls/library/ssl_tls.c b/thirdparty/mbedtls/library/ssl_tls.c index b8f35fec5d..cbec74fe8c 100644 --- a/thirdparty/mbedtls/library/ssl_tls.c +++ b/thirdparty/mbedtls/library/ssl_tls.c @@ -1004,8 +1004,6 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) if( mbedtls_ssl_hw_record_init != NULL ) { - int ret = 0; - MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_init()" ) ); if( ( ret = mbedtls_ssl_hw_record_init( ssl, key1, key2, transform->keylen, @@ -2885,15 +2883,18 @@ static void ssl_dtls_replay_reset( mbedtls_ssl_context *ssl ); /* * Swap transform_out and out_ctr with the alternative ones */ -static void ssl_swap_epochs( mbedtls_ssl_context *ssl ) +static int ssl_swap_epochs( mbedtls_ssl_context *ssl ) { mbedtls_ssl_transform *tmp_transform; unsigned char tmp_out_ctr[8]; +#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) + int ret; +#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ if( ssl->transform_out == ssl->handshake->alt_transform_out ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip swap epochs" ) ); - return; + return( 0 ); } MBEDTLS_SSL_DEBUG_MSG( 3, ( "swap epochs" ) ); @@ -2920,7 +2921,9 @@ static void ssl_swap_epochs( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); } } -#endif +#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ + + return( 0 ); } /* @@ -2957,7 +2960,8 @@ int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl ) ssl->handshake->cur_msg = ssl->handshake->flight; ssl->handshake->cur_msg_p = ssl->handshake->flight->p + 12; - ssl_swap_epochs( ssl ); + if( ( ret = ssl_swap_epochs( ssl ) ) != 0 ) + return( ret ); ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_SENDING; } @@ -2980,7 +2984,8 @@ int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl ) if( is_finished && ssl->handshake->cur_msg_p == ( cur->p + 12 ) ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "swap epochs to send finished message" ) ); - ssl_swap_epochs( ssl ); + if( ( ret = ssl_swap_epochs( ssl ) ) != 0 ) + return( ret ); } ret = ssl_get_remaining_payload_in_datagram( ssl ); @@ -3017,7 +3022,10 @@ int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl ) if( ( max_frag_len < 12 ) || ( max_frag_len == 12 && hs_len != 0 ) ) { if( is_finished ) - ssl_swap_epochs( ssl ); + { + if( ( ret = ssl_swap_epochs( ssl ) ) != 0 ) + return( ret ); + } if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) return( ret ); @@ -3997,17 +4005,23 @@ static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl ) if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ) { + int send_ret; + MBEDTLS_SSL_DEBUG_MSG( 1, ( "sending HelloVerifyRequest" ) ); + MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network", + ssl->out_buf, len ); /* Don't check write errors as we can't do anything here. * If the error is permanent we'll catch it later, * if it's not, then hopefully it'll work next time. */ - (void) ssl->f_send( ssl->p_bio, ssl->out_buf, len ); + send_ret = ssl->f_send( ssl->p_bio, ssl->out_buf, len ); + MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", send_ret ); + (void) send_ret; return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ); } if( ret == 0 ) { - /* Got a valid cookie, partially reset context */ + MBEDTLS_SSL_DEBUG_MSG( 1, ( "cookie is valid, resetting context" ) ); if( ( ret = ssl_session_reset_int( ssl, 1 ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "reset", ret ); diff --git a/thirdparty/mbedtls/library/x509.c b/thirdparty/mbedtls/library/x509.c index 2e0b0e8f6c..4d25303206 100644 --- a/thirdparty/mbedtls/library/x509.c +++ b/thirdparty/mbedtls/library/x509.c @@ -1063,7 +1063,7 @@ cleanup: mbedtls_x509_crt_free( &clicert ); #else ((void) verbose); -#endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA256_C */ return( ret ); } diff --git a/thirdparty/vulkan/android/vk_mem_alloc.cpp b/thirdparty/vulkan/android/vk_mem_alloc.cpp new file mode 100644 index 0000000000..a28454cf6e --- /dev/null +++ b/thirdparty/vulkan/android/vk_mem_alloc.cpp @@ -0,0 +1,8 @@ +#define VMA_IMPLEMENTATION +#ifdef DEBUG_ENABLED +#ifndef _DEBUG +#define _DEBUG +#endif +#endif +// Include memory allocator from Android NDK +#include <vk_mem_alloc.h> |