diff options
67 files changed, 424 insertions, 164 deletions
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 2c2a963a26..690e74855f 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -53,4 +53,4 @@ body: label: Minimal reproduction project description: | A small Godot project which reproduces the issue. Highly recommended to speed up troubleshooting. - Drag and drop a ZIP archive to upload it. + Drag and drop a ZIP archive to upload it. Be sure to not include the ".godot" folder in the archive. diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml index 3a92b8ffb4..95d216deb3 100644 --- a/.github/workflows/linux_builds.yml +++ b/.github/workflows/linux_builds.yml @@ -102,6 +102,9 @@ jobs: with: dotnet-version: '6.0.x' + - name: Setup GCC problem matcher + uses: ammaraskar/gcc-problem-matcher@master + - name: Compilation uses: ./.github/actions/godot-build with: diff --git a/.github/workflows/windows_builds.yml b/.github/workflows/windows_builds.yml index 31661e3f90..7f04c3475e 100644 --- a/.github/workflows/windows_builds.yml +++ b/.github/workflows/windows_builds.yml @@ -45,10 +45,12 @@ jobs: cache-name: ${{ matrix.cache-name }} continue-on-error: true - - name: Setup python and scons uses: ./.github/actions/godot-deps + - name: Setup MSVC problem matcher + uses: ammaraskar/msvc-problem-matcher@master + - name: Compilation uses: ./.github/actions/godot-build with: diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index c6cc4cc4ac..2ba389fc4d 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -1460,15 +1460,25 @@ String String::num(double p_num, int p_decimals) { fmt[5] = 'f'; fmt[6] = 0; } - char buf[256]; + // if we want to convert a double with as much decimal places as as + // DBL_MAX or DBL_MIN then we would theoretically need a buffer of at least + // DBL_MAX_10_EXP + 2 for DBL_MAX and DBL_MAX_10_EXP + 4 for DBL_MIN. + // BUT those values where still giving me exceptions, so I tested from + // DBL_MAX_10_EXP + 10 incrementing one by one and DBL_MAX_10_EXP + 17 (325) + // was the first buffer size not to throw an exception + char buf[325]; #if defined(__GNUC__) || defined(_MSC_VER) - snprintf(buf, 256, fmt, p_num); + // PLEASE NOTE that, albeit vcrt online reference states that snprintf + // should safely truncate the output to the given buffer size, we have + // found a case where this is not true, so we should create a buffer + // as big as needed + snprintf(buf, 325, fmt, p_num); #else sprintf(buf, fmt, p_num); #endif - buf[255] = 0; + buf[324] = 0; //destroy trailing zeroes { bool period = false; diff --git a/doc/classes/CompressedCubemap.xml b/doc/classes/CompressedCubemap.xml index fbb0879fdc..10ee266897 100644 --- a/doc/classes/CompressedCubemap.xml +++ b/doc/classes/CompressedCubemap.xml @@ -1,8 +1,17 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="CompressedCubemap" inherits="CompressedTextureLayered" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> + 6-sided texture typically used in 3D rendering, optionally compressed. </brief_description> <description> + A cubemap that is loaded from a [code].ccube[/code] file. This file format is internal to Godot; it is created by importing other image formats with the import system. [CompressedCubemap] can use one of 4 compresson methods: + - Uncompressed (uncompressed on the GPU) + - Lossless (WebP or PNG, uncompressed on the GPU) + - Lossy (WebP, uncompressed on the GPU) + - VRAM Compressed (compressed on the GPU) + Only [b]VRAM Compressed[/b] actually reduces the memory usage on the GPU. The [b]Lossless[/b] and [b]Lossy[/b] compression methods will reduce the required storage on disk, but they will not reduce memory usage on the GPU as the texture is sent to the GPU uncompressed. + Using [b]VRAM Compressed[/b] also improves loading times, as VRAM-compressed textures are faster to load compared to textures using lossless or lossy compression. VRAM compression can exhibit noticeable artifacts and is intended to be used for 3D rendering, not 2D. + See [Cubemap] for a general description of cubemaps. </description> <tutorials> </tutorials> diff --git a/doc/classes/CompressedCubemapArray.xml b/doc/classes/CompressedCubemapArray.xml index ff096cea47..4221241910 100644 --- a/doc/classes/CompressedCubemapArray.xml +++ b/doc/classes/CompressedCubemapArray.xml @@ -1,8 +1,17 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="CompressedCubemapArray" inherits="CompressedTextureLayered" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> + Array of 6-sided textures typically used in 3D rendering, optionally compressed. </brief_description> <description> + A cubemap array that is loaded from a [code].ccubearray[/code] file. This file format is internal to Godot; it is created by importing other image formats with the import system. [CompressedCubemapArray] can use one of 4 compresson methods: + - Uncompressed (uncompressed on the GPU) + - Lossless (WebP or PNG, uncompressed on the GPU) + - Lossy (WebP, uncompressed on the GPU) + - VRAM Compressed (compressed on the GPU) + Only [b]VRAM Compressed[/b] actually reduces the memory usage on the GPU. The [b]Lossless[/b] and [b]Lossy[/b] compression methods will reduce the required storage on disk, but they will not reduce memory usage on the GPU as the texture is sent to the GPU uncompressed. + Using [b]VRAM Compressed[/b] also improves loading times, as VRAM-compressed textures are faster to load compared to textures using lossless or lossy compression. VRAM compression can exhibit noticeable artifacts and is intended to be used for 3D rendering, not 2D. + See [CubemapArray] for a general description of cubemap arrays. </description> <tutorials> </tutorials> diff --git a/doc/classes/CompressedTexture2D.xml b/doc/classes/CompressedTexture2D.xml index f7464d8951..660062af7b 100644 --- a/doc/classes/CompressedTexture2D.xml +++ b/doc/classes/CompressedTexture2D.xml @@ -1,10 +1,16 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="CompressedTexture2D" inherits="Texture2D" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> - A [code].ctex[/code] texture. + Texture with 2 dimensions, optionally compressed. </brief_description> <description> - A texture that is loaded from a [code].ctex[/code] file. + A texture that is loaded from a [code].ctex[/code] file. This file format is internal to Godot; it is created by importing other image formats with the import system. [CompressedTexture2D] can use one of 4 compression methods (including a lack of any compression): + - Uncompressed (uncompressed on the GPU) + - Lossless (WebP or PNG, uncompressed on the GPU) + - Lossy (WebP, uncompressed on the GPU) + - VRAM Compressed (compressed on the GPU) + Only [b]VRAM Compressed[/b] actually reduces the memory usage on the GPU. The [b]Lossless[/b] and [b]Lossy[/b] compression methods will reduce the required storage on disk, but they will not reduce memory usage on the GPU as the texture is sent to the GPU uncompressed. + Using [b]VRAM Compressed[/b] also improves loading times, as VRAM-compressed textures are faster to load compared to textures using lossless or lossy compression. VRAM compression can exhibit noticeable artifacts and is intended to be used for 3D rendering, not 2D. </description> <tutorials> </tutorials> @@ -13,13 +19,13 @@ <return type="int" enum="Error" /> <param index="0" name="path" type="String" /> <description> - Loads the texture from the given path. + Loads the texture from the specified [param path]. </description> </method> </methods> <members> <member name="load_path" type="String" setter="load" getter="get_load_path" default=""""> - The CompressedTexture's file path to a [code].ctex[/code] file. + The [CompressedTexture2D]'s file path to a [code].ctex[/code] file. </member> <member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" overrides="Resource" default="false" /> </members> diff --git a/doc/classes/CompressedTexture2DArray.xml b/doc/classes/CompressedTexture2DArray.xml index 0c751759af..0bd894a2da 100644 --- a/doc/classes/CompressedTexture2DArray.xml +++ b/doc/classes/CompressedTexture2DArray.xml @@ -1,8 +1,17 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="CompressedTexture2DArray" inherits="CompressedTextureLayered" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> + Array of 2-dimensional textures, optionally compressed. </brief_description> <description> + A texture array that is loaded from a [code].ctexarray[/code] file. This file format is internal to Godot; it is created by importing other image formats with the import system. [CompressedTexture2DArray] can use one of 4 compresson methods: + - Uncompressed (uncompressed on the GPU) + - Lossless (WebP or PNG, uncompressed on the GPU) + - Lossy (WebP, uncompressed on the GPU) + - VRAM Compressed (compressed on the GPU) + Only [b]VRAM Compressed[/b] actually reduces the memory usage on the GPU. The [b]Lossless[/b] and [b]Lossy[/b] compression methods will reduce the required storage on disk, but they will not reduce memory usage on the GPU as the texture is sent to the GPU uncompressed. + Using [b]VRAM Compressed[/b] also improves loading times, as VRAM-compressed textures are faster to load compared to textures using lossless or lossy compression. VRAM compression can exhibit noticeable artifacts and is intended to be used for 3D rendering, not 2D. + See [Texture2DArray] for a general description of texture arrays. </description> <tutorials> </tutorials> diff --git a/doc/classes/CompressedTexture3D.xml b/doc/classes/CompressedTexture3D.xml index 50bd025861..b11583b684 100644 --- a/doc/classes/CompressedTexture3D.xml +++ b/doc/classes/CompressedTexture3D.xml @@ -1,8 +1,12 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="CompressedTexture3D" inherits="Texture3D" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> + Texture with 3 dimensions, optionally compressed. </brief_description> <description> + [CompressedTexture3D] is the VRAM-compressed counterpart of [ImageTexture3D]. The file extension for [CompressedTexture3D] files is [code].ctex3d[/code]. This file format is internal to Godot; it is created by importing other image formats with the import system. + [CompressedTexture3D] uses VRAM compression, which allows to reduce memory usage on the GPU when rendering the texture. This also improves loading times, as VRAM-compressed textures are faster to load compared to textures using lossless compression. VRAM compression can exhibit noticeable artifacts and is intended to be used for 3D rendering, not 2D. + See [Texture3D] for a general description of 3D textures. </description> <tutorials> </tutorials> @@ -11,11 +15,13 @@ <return type="int" enum="Error" /> <param index="0" name="path" type="String" /> <description> + Loads the texture from the specified [param path]. </description> </method> </methods> <members> <member name="load_path" type="String" setter="load" getter="get_load_path" default=""""> + The [CompressedTexture3D]'s file path to a [code].ctex3d[/code] file. </member> </members> </class> diff --git a/doc/classes/CompressedTextureLayered.xml b/doc/classes/CompressedTextureLayered.xml index 547679c0f0..376483ae5c 100644 --- a/doc/classes/CompressedTextureLayered.xml +++ b/doc/classes/CompressedTextureLayered.xml @@ -1,8 +1,16 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="CompressedTextureLayered" inherits="TextureLayered" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> + Base class for texture arrays that can optionally be compressed. </brief_description> <description> + A texture array that is loaded from a [code].ctexarray[/code] file. This file format is internal to Godot; it is created by importing other image formats with the import system. [CompressedTexture2D] can use one of 4 compresson methods: + - Uncompressed (uncompressed on the GPU) + - Lossless (WebP or PNG, uncompressed on the GPU) + - Lossy (WebP, uncompressed on the GPU) + - VRAM Compressed (compressed on the GPU) + Only [b]VRAM Compressed[/b] actually reduces the memory usage on the GPU. The [b]Lossless[/b] and [b]Lossy[/b] compression methods will reduce the required storage on disk, but they will not reduce memory usage on the GPU as the texture is sent to the GPU uncompressed. + Using [b]VRAM Compressed[/b] also improves loading times, as VRAM-compressed textures are faster to load compared to textures using lossless or lossy compression. VRAM compression can exhibit noticeable artifacts and is intended to be used for 3D rendering, not 2D. </description> <tutorials> </tutorials> @@ -11,11 +19,13 @@ <return type="int" enum="Error" /> <param index="0" name="path" type="String" /> <description> + Loads the texture at [param path]. </description> </method> </methods> <members> <member name="load_path" type="String" setter="load" getter="get_load_path" default=""""> + The path the texture should be loaded from. </member> </members> </class> diff --git a/doc/classes/Cubemap.xml b/doc/classes/Cubemap.xml index 0cdebeda95..46ddede9b1 100644 --- a/doc/classes/Cubemap.xml +++ b/doc/classes/Cubemap.xml @@ -4,8 +4,9 @@ 6-sided texture typically used in 3D rendering. </brief_description> <description> - A cubemap is made of 6 textures organized in layers. They are typically used for faking reflections (see [ReflectionProbe]) in 3D rendering. It can be used to make an object look as if it's reflecting its surroundings. This usually delivers much better performance than other reflection methods. - This resource is typically used as a uniform in custom shaders. Few core Godot methods make use of Cubemap resources. + A cubemap is made of 6 textures organized in layers. They are typically used for faking reflections in 3D rendering (see [ReflectionProbe]). It can be used to make an object look as if it's reflecting its surroundings. This usually delivers much better performance than other reflection methods. + This resource is typically used as a uniform in custom shaders. Few core Godot methods make use of [Cubemap] resources. + To create such a texture file yourself, reimport your image files using the Godot Editor import presets. [b]Note:[/b] Godot doesn't support using cubemaps in a [PanoramaSkyMaterial]. You can use [url=https://danilw.github.io/GLSL-howto/cubemap_to_panorama_js/cubemap_to_panorama.html]this tool[/url] to convert a cubemap to an equirectangular sky map. </description> <tutorials> diff --git a/doc/classes/CubemapArray.xml b/doc/classes/CubemapArray.xml index 07e401a13d..2fd55b66c6 100644 --- a/doc/classes/CubemapArray.xml +++ b/doc/classes/CubemapArray.xml @@ -5,8 +5,9 @@ </brief_description> <description> [CubemapArray]s are made of an array of [Cubemap]s. Accordingly, like [Cubemap]s they are made of multiple textures the amount of which must be divisible by 6 (one image for each face of the cube). The primary benefit of [CubemapArray]s is that they can be accessed in shader code using a single texture reference. In other words, you can pass multiple [Cubemap]s into a shader using a single [CubemapArray]. - Generally, [CubemapArray]s provide a more efficient way for storing multiple [Cubemap]s, than storing multiple [Cubemap]s themselves in an array. - Internally Godot, uses [CubemapArray]s for many effects including the [Sky], if you set [member ProjectSettings.rendering/reflections/sky_reflections/texture_array_reflections] to [code]true[/code]. + Generally, [CubemapArray]s provide a more efficient way for storing multiple [Cubemap]s compared to storing multiple [Cubemap]s themselves in an array. + Internally, Godot uses [CubemapArray]s for many effects including the [Sky], if you set [member ProjectSettings.rendering/reflections/sky_reflections/texture_array_reflections] to [code]true[/code]. + To create such a texture file yourself, reimport your image files using the Godot Editor import presets. [b]Note:[/b] [CubemapArray] is not supported in the OpenGL 3 rendering backend. </description> <tutorials> diff --git a/doc/classes/Image.xml b/doc/classes/Image.xml index bbd633819b..be66b8a7b9 100644 --- a/doc/classes/Image.xml +++ b/doc/classes/Image.xml @@ -118,7 +118,7 @@ <param index="2" name="use_mipmaps" type="bool" /> <param index="3" name="format" type="int" enum="Image.Format" /> <description> - Creates an empty image of given size and format. See [enum Format] constants. If [param use_mipmaps] is [code]true[/code] then generate mipmaps for this image. See the [method generate_mipmaps]. + Creates an empty image of given size and format. See [enum Format] constants. If [param use_mipmaps] is [code]true[/code], then generate mipmaps for this image. See the [method generate_mipmaps]. </description> </method> <method name="create_from_data" qualifiers="static"> diff --git a/doc/classes/ImageTexture3D.xml b/doc/classes/ImageTexture3D.xml index 958c5f90f1..ee26a959aa 100644 --- a/doc/classes/ImageTexture3D.xml +++ b/doc/classes/ImageTexture3D.xml @@ -1,8 +1,11 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="ImageTexture3D" inherits="Texture3D" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> + Texture with 3 dimensions. </brief_description> <description> + [ImageTexture3D] is a 3-dimensional [ImageTexture] that has a width, height, and depth. See also [ImageTextureLayered]. + 3D textures are typically used to store density maps for [FogMaterial], color correction LUTs for [Environment], vector fields for [GPUParticlesAttractorVectorField3D] and collision maps for [GPUParticlesCollisionSDF3D]. 3D textures can also be used in custom shaders. </description> <tutorials> </tutorials> @@ -16,12 +19,14 @@ <param index="4" name="use_mipmaps" type="bool" /> <param index="5" name="data" type="Image[]" /> <description> + Creates the [ImageTexture3D] with specified [param width], [param height], and [param depth]. See [enum Image.Format] for [param format] options. If [param use_mipmaps] is [code]true[/code], then generate mipmaps for the [ImageTexture3D]. </description> </method> <method name="update"> <return type="void" /> <param index="0" name="data" type="Image[]" /> <description> + Replaces the texture's existing data with the layers specified in [code]data[/code]. The size of [code]data[/code] must match the parameters that were used for [method create]. In other words, the texture cannot be resized or have its format changed by calling [method update]. </description> </method> </methods> diff --git a/doc/classes/ImageTextureLayered.xml b/doc/classes/ImageTextureLayered.xml index f5786f070a..0aa1d65d5a 100644 --- a/doc/classes/ImageTextureLayered.xml +++ b/doc/classes/ImageTextureLayered.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="ImageTextureLayered" inherits="TextureLayered" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> + Base class for texture types which contain the data of multiple [ImageTexture]s. Each image is of the same size and format. </brief_description> <description> + Base class for [Texture2DArray], [Cubemap] and [CubemapArray]. Cannot be used directly, but contains all the functions necessary for accessing the derived resource types. See also [Texture3D]. </description> <tutorials> </tutorials> @@ -11,7 +13,7 @@ <return type="int" enum="Error" /> <param index="0" name="images" type="Image[]" /> <description> - Creates an [ImageTextureLayered] from an array of [Image]s. The first image decides the width, height, image format and mipmapping setting. The other images must have the same width, height, image format and mipmapping setting. + Creates an [ImageTextureLayered] from an array of [Image]s. See [method Image.create] for the expected data format. The first image decides the width, height, image format and mipmapping setting. The other images [i]must[/i] have the same width, height, image format and mipmapping setting. Each [Image] represents one [code]layer[/code]. </description> </method> @@ -23,7 +25,7 @@ Replaces the existing [Image] data at the given [code]layer[/code] with this new image. The given [Image] must have the same width, height, image format and mipmapping setting (a [code]bool[/code] value) as the rest of the referenced images. If the image format is unsupported, it will be decompressed and converted to a similar and supported [enum Image.Format]. - The update is immediate: synced with the draw. + The update is immediate: it's synchronized with drawing. </description> </method> </methods> diff --git a/doc/classes/PlaceholderCubemap.xml b/doc/classes/PlaceholderCubemap.xml index 3617c6ac2c..0892b023a2 100644 --- a/doc/classes/PlaceholderCubemap.xml +++ b/doc/classes/PlaceholderCubemap.xml @@ -1,8 +1,12 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="PlaceholderCubemap" inherits="PlaceholderTextureLayered" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> + Placeholder class for a cubemap texture. </brief_description> <description> + This class is used when loading a project that uses a [Cubemap] subclass in 2 conditions: + - When running the project exported in dedicated server mode, only the texture's dimensions are kept (as they may be relied upon for gameplay purposes or positioning of other elements). This allows reducing the exported PCK's size significantly. + - When this subclass is missing due to using a different engine version or build (e.g. modules disabled). </description> <tutorials> </tutorials> diff --git a/doc/classes/PlaceholderCubemapArray.xml b/doc/classes/PlaceholderCubemapArray.xml index 1fcf1e7795..c7a7e9154c 100644 --- a/doc/classes/PlaceholderCubemapArray.xml +++ b/doc/classes/PlaceholderCubemapArray.xml @@ -1,8 +1,12 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="PlaceholderCubemapArray" inherits="PlaceholderTextureLayered" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> + Placeholder class for a cubemap texture array. </brief_description> <description> + This class is used when loading a project that uses a [CubemapArray] subclass in 2 conditions: + - When running the project exported in dedicated server mode, only the texture's dimensions are kept (as they may be relied upon for gameplay purposes or positioning of other elements). This allows reducing the exported PCK's size significantly. + - When this subclass is missing due to using a different engine version or build (e.g. modules disabled). </description> <tutorials> </tutorials> diff --git a/doc/classes/PlaceholderMaterial.xml b/doc/classes/PlaceholderMaterial.xml index c66641d81c..7febdc7a07 100644 --- a/doc/classes/PlaceholderMaterial.xml +++ b/doc/classes/PlaceholderMaterial.xml @@ -1,8 +1,12 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="PlaceholderMaterial" inherits="Material" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> + Placeholder class for a material. </brief_description> <description> + This class is used when loading a project that uses a [Material] subclass in 2 conditions: + - When running the project exported in dedicated server mode, only the texture's dimensions are kept (as they may be relied upon for gameplay purposes or positioning of other elements). This allows reducing the exported PCK's size significantly. + - When this subclass is missing due to using a different engine version or build (e.g. modules disabled). </description> <tutorials> </tutorials> diff --git a/doc/classes/PlaceholderMesh.xml b/doc/classes/PlaceholderMesh.xml index cc688816b6..8021a57878 100644 --- a/doc/classes/PlaceholderMesh.xml +++ b/doc/classes/PlaceholderMesh.xml @@ -1,13 +1,18 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="PlaceholderMesh" inherits="Mesh" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> + Placeholder class for a mesh. </brief_description> <description> + This class is used when loading a project that uses a [Mesh] subclass in 2 conditions: + - When running the project exported in dedicated server mode, only the texture's dimensions are kept (as they may be relied upon for gameplay purposes or positioning of other elements). This allows reducing the exported PCK's size significantly. + - When this subclass is missing due to using a different engine version or build (e.g. modules disabled). </description> <tutorials> </tutorials> <members> <member name="aabb" type="AABB" setter="set_aabb" getter="get_aabb" default="AABB(0, 0, 0, 0, 0, 0)"> + The smallest [AABB] enclosing this mesh in local space. </member> </members> </class> diff --git a/doc/classes/PlaceholderTexture2D.xml b/doc/classes/PlaceholderTexture2D.xml index 5d8509ec77..c889055e4d 100644 --- a/doc/classes/PlaceholderTexture2D.xml +++ b/doc/classes/PlaceholderTexture2D.xml @@ -1,14 +1,19 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="PlaceholderTexture2D" inherits="Texture2D" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> + Placeholder class for a 2-dimensional texture. </brief_description> <description> + This class is used when loading a project that uses a [Texture2D] subclass in 2 conditions: + - When running the project exported in dedicated server mode, only the texture's dimensions are kept (as they may be relied upon for gameplay purposes or positioning of other elements). This allows reducing the exported PCK's size significantly. + - When this subclass is missing due to using a different engine version or build (e.g. modules disabled). </description> <tutorials> </tutorials> <members> <member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" overrides="Resource" default="false" /> <member name="size" type="Vector2" setter="set_size" getter="get_size" default="Vector2(1, 1)"> + The texture's size (in pixels). </member> </members> </class> diff --git a/doc/classes/PlaceholderTexture2DArray.xml b/doc/classes/PlaceholderTexture2DArray.xml index a502e5d334..a749e8c039 100644 --- a/doc/classes/PlaceholderTexture2DArray.xml +++ b/doc/classes/PlaceholderTexture2DArray.xml @@ -1,8 +1,12 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="PlaceholderTexture2DArray" inherits="PlaceholderTextureLayered" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> + Placeholder class for a 2-dimensional texture array. </brief_description> <description> + This class is used when loading a project that uses a [Texture2D] subclass in 2 conditions: + - When running the project exported in dedicated server mode, only the texture's dimensions are kept (as they may be relied upon for gameplay purposes or positioning of other elements). This allows reducing the exported PCK's size significantly. + - When this subclass is missing due to using a different engine version or build (e.g. modules disabled). </description> <tutorials> </tutorials> diff --git a/doc/classes/PlaceholderTexture3D.xml b/doc/classes/PlaceholderTexture3D.xml index d31e538307..ccd3c94fc2 100644 --- a/doc/classes/PlaceholderTexture3D.xml +++ b/doc/classes/PlaceholderTexture3D.xml @@ -1,13 +1,18 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="PlaceholderTexture3D" inherits="Texture3D" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> + Placeholder class for a 3-dimensional texture. </brief_description> <description> + This class is used when loading a project that uses a [Texture3D] subclass in 2 conditions: + - When running the project exported in dedicated server mode, only the texture's dimensions are kept (as they may be relied upon for gameplay purposes or positioning of other elements). This allows reducing the exported PCK's size significantly. + - When this subclass is missing due to using a different engine version or build (e.g. modules disabled). </description> <tutorials> </tutorials> <members> <member name="size" type="Vector3i" setter="set_size" getter="get_size" default="Vector3i(1, 1, 1)"> + The texture's size (in pixels). </member> </members> </class> diff --git a/doc/classes/PlaceholderTextureLayered.xml b/doc/classes/PlaceholderTextureLayered.xml index 39af08473a..8cc6dd606a 100644 --- a/doc/classes/PlaceholderTextureLayered.xml +++ b/doc/classes/PlaceholderTextureLayered.xml @@ -1,15 +1,21 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="PlaceholderTextureLayered" inherits="TextureLayered" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> + Placeholder class for a 2-dimensional texture array. </brief_description> <description> + This class is used when loading a project that uses a [TextureLayered] subclass in 2 conditions: + - When running the project exported in dedicated server mode, only the texture's dimensions are kept (as they may be relied upon for gameplay purposes or positioning of other elements). This allows reducing the exported PCK's size significantly. + - When this subclass is missing due to using a different engine version or build (e.g. modules disabled). </description> <tutorials> </tutorials> <members> <member name="layers" type="int" setter="set_layers" getter="get_layers" default="1"> + The number of layers in the texture array. </member> <member name="size" type="Vector2i" setter="set_size" getter="get_size" default="Vector2i(1, 1)"> + The size of each texture layer (in pixels). </member> </members> </class> diff --git a/doc/classes/RenderingDevice.xml b/doc/classes/RenderingDevice.xml index cb13697cc2..2de812f5fc 100644 --- a/doc/classes/RenderingDevice.xml +++ b/doc/classes/RenderingDevice.xml @@ -643,6 +643,15 @@ <description> </description> </method> + <method name="vertex_array_create"> + <return type="RID" /> + <param index="0" name="vertex_count" type="int" /> + <param index="1" name="vertex_format" type="int" /> + <param index="2" name="src_buffers" type="RID[]" /> + <description> + Creates a vertex array based on the specified buffers. + </description> + </method> <method name="vertex_buffer_create"> <return type="RID" /> <param index="0" name="size_bytes" type="int" /> diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index 1c02d58299..13e5470a56 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -3024,6 +3024,14 @@ <description> </description> </method> + <method name="texture_get_rd_texture" qualifiers="const"> + <return type="RID" /> + <param index="0" name="texture" type="RID" /> + <param index="1" name="srgb" type="bool" default="false" /> + <description> + Returns a texture [RID] that can be used with [RenderingDevice]. + </description> + </method> <method name="texture_proxy_create"> <return type="RID" /> <param index="0" name="base" type="RID" /> diff --git a/doc/classes/Texture.xml b/doc/classes/Texture.xml index df6e0433dc..86c9026fd1 100644 --- a/doc/classes/Texture.xml +++ b/doc/classes/Texture.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="Texture" inherits="Resource" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> + Base class for all texture types. </brief_description> <description> + [Texture] is the base class for all texture types. Common texture types are [Texture2D] and [ImageTexture]. See also [Image]. </description> <tutorials> </tutorials> diff --git a/doc/classes/Texture2D.xml b/doc/classes/Texture2D.xml index 3dd8c339b2..aac197090a 100644 --- a/doc/classes/Texture2D.xml +++ b/doc/classes/Texture2D.xml @@ -19,6 +19,8 @@ <param index="2" name="modulate" type="Color" /> <param index="3" name="transpose" type="bool" /> <description> + Called when the entire [Texture2D] is requested to be drawn over a [CanvasItem], with the top-left offset specified in [param pos]. [param modulate] specifies a multiplier for the colors being drawn, while [param transpose] specifies whether drawing should be performed in column-major order instead of row-major order (resulting in 90-degree clockwise rotation). + [b]Note:[/b] This is only used in 2D rendering, not 3D. </description> </method> <method name="_draw_rect" qualifiers="virtual const"> @@ -29,6 +31,8 @@ <param index="3" name="modulate" type="Color" /> <param index="4" name="transpose" type="bool" /> <description> + Called when the [Texture2D] is requested to be drawn onto [CanvasItem]'s specified [param rect]. [param modulate] specifies a multiplier for the colors being drawn, while [param transpose] specifies whether drawing should be performed in column-major order instead of row-major order (resulting in 90-degree clockwise rotation). + [b]Note:[/b] This is only used in 2D rendering, not 3D. </description> </method> <method name="_draw_rect_region" qualifiers="virtual const"> @@ -40,21 +44,26 @@ <param index="4" name="transpose" type="bool" /> <param index="5" name="clip_uv" type="bool" /> <description> + Called when a part of the [Texture2D] specified by [param src_rect]'s coordinates is requested to be drawn onto [CanvasItem]'s specified [param rect]. [param modulate] specifies a multiplier for the colors being drawn, while [param transpose] specifies whether drawing should be performed in column-major order instead of row-major order (resulting in 90-degree clockwise rotation). + [b]Note:[/b] This is only used in 2D rendering, not 3D. </description> </method> <method name="_get_height" qualifiers="virtual const"> <return type="int" /> <description> + Called when the [Texture2D]'s height is queried. </description> </method> <method name="_get_width" qualifiers="virtual const"> <return type="int" /> <description> + Called when the [Texture2D]'s width is queried. </description> </method> <method name="_has_alpha" qualifiers="virtual const"> <return type="bool" /> <description> + Called when the presence of an alpha channel in the [Texture2D] is queried. </description> </method> <method name="_is_pixel_opaque" qualifiers="virtual const"> @@ -62,6 +71,7 @@ <param index="0" name="x" type="int" /> <param index="1" name="y" type="int" /> <description> + Called when a pixel's opaque state in the [Texture2D] is queried at the specified [code](x, y)[/code] position. </description> </method> <method name="draw" qualifiers="const"> @@ -100,7 +110,7 @@ <method name="get_height" qualifiers="const"> <return type="int" /> <description> - Returns the texture height. + Returns the texture height in pixels. </description> </method> <method name="get_image" qualifiers="const"> @@ -113,13 +123,13 @@ <method name="get_size" qualifiers="const"> <return type="Vector2" /> <description> - Returns the texture size. + Returns the texture size in pixels. </description> </method> <method name="get_width" qualifiers="const"> <return type="int" /> <description> - Returns the texture width. + Returns the texture width in pixels. </description> </method> <method name="has_alpha" qualifiers="const"> diff --git a/doc/classes/Texture2DArray.xml b/doc/classes/Texture2DArray.xml index 113f37f974..ec00198db1 100644 --- a/doc/classes/Texture2DArray.xml +++ b/doc/classes/Texture2DArray.xml @@ -4,8 +4,9 @@ A single texture resource which consists of multiple, separate images. Each image has the same dimensions and number of mipmap levels. </brief_description> <description> - A Texture2DArray is different from a Texture3D: The Texture2DArray does not support trilinear interpolation between the [Image]s, i.e. no blending. + A Texture2DArray is different from a Texture3D: The Texture2DArray does not support trilinear interpolation between the [Image]s, i.e. no blending. See also [Cubemap] and [CubemapArray], which are texture arrays with specialized cubemap functions. A Texture2DArray is also different from an [AtlasTexture]: In a Texture2DArray, all images are treated separately. In an atlas, the regions (i.e. the single images) can be of different sizes. Furthermore, you usually need to add a padding around the regions, to prevent accidental UV mapping to more than one region. The same goes for mipmapping: Mipmap chains are handled separately for each layer. In an atlas, the slicing has to be done manually in the fragment shader. + To create such a texture file yourself, reimport your image files using the Godot Editor import presets. </description> <tutorials> </tutorials> diff --git a/doc/classes/Texture3D.xml b/doc/classes/Texture3D.xml index 4968f46fe8..1a66932d62 100644 --- a/doc/classes/Texture3D.xml +++ b/doc/classes/Texture3D.xml @@ -1,8 +1,12 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="Texture3D" inherits="Texture" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> + Base class for 3-dimensionnal textures. </brief_description> <description> + Base class for [ImageTexture3D] and [CompressedTexture3D]. Cannot be used directly, but contains all the functions necessary for accessing the derived resource types. [Texture3D] is the base class for all 3-dimensional texture types. See also [TextureLayered]. + All images need to have the same width, height and number of mipmap levels. + To create such a texture file yourself, reimport your image files using the Godot Editor import presets. </description> <tutorials> </tutorials> @@ -10,61 +14,73 @@ <method name="_get_data" qualifiers="virtual const"> <return type="Image[]" /> <description> + Called when the [Texture3D]'s data is queried. </description> </method> <method name="_get_depth" qualifiers="virtual const"> <return type="int" /> <description> + Called when the [Texture3D]'s depth is queried. </description> </method> <method name="_get_format" qualifiers="virtual const"> <return type="int" enum="Image.Format" /> <description> + Called when the [Texture3D]'s format is queried. </description> </method> <method name="_get_height" qualifiers="virtual const"> <return type="int" /> <description> + Called when the [Texture3D]'s height is queried. </description> </method> <method name="_get_width" qualifiers="virtual const"> <return type="int" /> <description> + Called when the [Texture3D]'s width is queried. </description> </method> <method name="_has_mipmaps" qualifiers="virtual const"> <return type="bool" /> <description> + Called when the presence of mipmaps in the [Texture3D] is queried. </description> </method> <method name="get_data" qualifiers="const"> <return type="Image[]" /> <description> + Returns the [Texture3D]'s data as an array of [Image]s. Each [Image] represents a [i]slice[/i] of the [Texture3D], with different slices mapping to different depth (Z axis) levels. </description> </method> <method name="get_depth" qualifiers="const"> <return type="int" /> <description> + Returns the [Texture3D]'s depth in pixels. Depth is typically represented by the Z axis (a dimension not present in [Texture2D]). </description> </method> <method name="get_format" qualifiers="const"> <return type="int" enum="Image.Format" /> <description> + Returns the current format being used by this texture. See [enum Image.Format] for details. </description> </method> <method name="get_height" qualifiers="const"> <return type="int" /> <description> + Returns the [Texture3D]'s height in pixels. Width is typically represented by the Y axis. </description> </method> <method name="get_width" qualifiers="const"> <return type="int" /> <description> + Returns the [Texture3D]'s width in pixels. Width is typically represented by the X axis. </description> </method> <method name="has_mipmaps" qualifiers="const"> <return type="bool" /> <description> + Returns [code]true[/code] if the [Texture3D] has generated mipmaps. </description> </method> </methods> diff --git a/doc/classes/TextureLayered.xml b/doc/classes/TextureLayered.xml index 5e6afcbc5c..8f6dff7acf 100644 --- a/doc/classes/TextureLayered.xml +++ b/doc/classes/TextureLayered.xml @@ -4,12 +4,11 @@ Base class for texture types which contain the data of multiple [Image]s. Each image is of the same size and format. </brief_description> <description> - Base class for [Texture2DArray], [Cubemap] and [CubemapArray]. Cannot be used directly, but contains all the functions necessary for accessing the derived resource types. + Base class for [ImageTextureLayered]. Cannot be used directly, but contains all the functions necessary for accessing the derived resource types. See also [Texture3D]. Data is set on a per-layer basis. For [Texture2DArray]s, the layer specifies the array layer. All images need to have the same width, height and number of mipmap levels. - A [TextureLayered] can be loaded with [code]method ResourceFormatLoader.load[/code]. - To create such a texture file yourself, re-import your image files using the Godot Editor import presets. - Internally, Godot maps these files to their respective counterparts in the target rendering driver (GLES3, Vulkan). + A [TextureLayered] can be loaded with [method ResourceLoader.load]. + Internally, Godot maps these files to their respective counterparts in the target rendering driver (Vulkan, GLES3). </description> <tutorials> </tutorials> @@ -17,37 +16,44 @@ <method name="_get_format" qualifiers="virtual const"> <return type="int" enum="Image.Format" /> <description> + Called when the [TextureLayered]'s format is queried. </description> </method> <method name="_get_height" qualifiers="virtual const"> <return type="int" /> <description> + Called when the the [TextureLayered]'s height is queried. </description> </method> <method name="_get_layer_data" qualifiers="virtual const"> <return type="Image" /> <param index="0" name="layer_index" type="int" /> <description> + Called when the data for a layer in the [TextureLayered] is queried. </description> </method> <method name="_get_layered_type" qualifiers="virtual const"> <return type="int" /> <description> + Called when the layers' type in the [TextureLayered] is queried. </description> </method> <method name="_get_layers" qualifiers="virtual const"> <return type="int" /> <description> + Called when the number of layers in the [TextureLayered] is queried. </description> </method> <method name="_get_width" qualifiers="virtual const"> <return type="int" /> <description> + Called when the [TextureLayered]'s width queried. </description> </method> <method name="_has_mipmaps" qualifiers="virtual const"> <return type="bool" /> <description> + Called when the presence of mipmaps in the [TextureLayered] is queried. </description> </method> <method name="get_format" qualifiers="const"> @@ -59,7 +65,7 @@ <method name="get_height" qualifiers="const"> <return type="int" /> <description> - Returns the height of the texture. Height is typically represented by the Y-axis. + Returns the height of the texture in pixels. Height is typically represented by the Y axis. </description> </method> <method name="get_layer_data" qualifiers="const"> @@ -72,6 +78,7 @@ <method name="get_layered_type" qualifiers="const"> <return type="int" enum="TextureLayered.LayeredType" /> <description> + Returns the [TextureLayered]'s type. The type determines how the data is accessed, with cubemaps having special types. </description> </method> <method name="get_layers" qualifiers="const"> @@ -83,7 +90,7 @@ <method name="get_width" qualifiers="const"> <return type="int" /> <description> - Returns the width of the texture. Width is typically represented by the X-axis. + Returns the width of the texture in pixels. Width is typically represented by the X axis. </description> </method> <method name="has_mipmaps" qualifiers="const"> @@ -95,10 +102,13 @@ </methods> <constants> <constant name="LAYERED_TYPE_2D_ARRAY" value="0" enum="LayeredType"> + Texture is a generic [Texture2DArray]. </constant> <constant name="LAYERED_TYPE_CUBEMAP" value="1" enum="LayeredType"> + Texture is a [Cubemap], with each side in its own layer (6 in total). </constant> <constant name="LAYERED_TYPE_CUBEMAP_ARRAY" value="2" enum="LayeredType"> + Texture is a [CubemapArray], with each cubemap being made of 6 layers. </constant> </constants> </class> diff --git a/doc/classes/XRInterface.xml b/doc/classes/XRInterface.xml index cc483dbd02..05d5eb6673 100644 --- a/doc/classes/XRInterface.xml +++ b/doc/classes/XRInterface.xml @@ -35,6 +35,16 @@ Returns an array of vectors that denotes the physical play area mapped to the virtual space around the [XROrigin3D] point. The points form a convex polygon that can be used to react to or visualize the play area. This returns an empty array if this feature is not supported or if the information is not yet available. </description> </method> + <method name="get_projection_for_view"> + <return type="Projection" /> + <param index="0" name="view" type="int" /> + <param index="1" name="aspect" type="float" /> + <param index="2" name="near" type="float" /> + <param index="3" name="far" type="float" /> + <description> + Returns the projection matrix for a view/eye. + </description> + </method> <method name="get_render_target_size"> <return type="Vector2" /> <description> @@ -47,6 +57,16 @@ 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. </description> </method> + <method name="get_transform_for_view"> + <return type="Transform3D" /> + <param index="0" name="view" type="int" /> + <param index="1" name="cam_transform" type="Transform3D" /> + <description> + Returns the transform for a view/eye. + [param view] is the view/eye index. + [param cam_transform] is the transform that maps device coordinates to scene coordinates, typically the global_transform of the current XROrigin3D. + </description> + </method> <method name="get_view_count"> <return type="int" /> <description> diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index b05817cd8e..0a64cda787 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -1006,13 +1006,15 @@ void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, const Tran if (primitive->point_count != state.canvas_instance_batches[state.current_batch_index].primitive_points || state.canvas_instance_batches[state.current_batch_index].command_type != Item::Command::TYPE_PRIMITIVE) { _new_batch(r_batch_broken, r_index); - state.canvas_instance_batches[state.current_batch_index].tex = RID(); + state.canvas_instance_batches[state.current_batch_index].tex = primitive->texture; state.canvas_instance_batches[state.current_batch_index].primitive_points = primitive->point_count; state.canvas_instance_batches[state.current_batch_index].command_type = Item::Command::TYPE_PRIMITIVE; state.canvas_instance_batches[state.current_batch_index].command = c; state.canvas_instance_batches[state.current_batch_index].shader_variant = CanvasShaderGLES3::MODE_PRIMITIVE; } + _prepare_canvas_texture(state.canvas_instance_batches[state.current_batch_index].tex, state.canvas_instance_batches[state.current_batch_index].filter, state.canvas_instance_batches[state.current_batch_index].repeat, r_index, texpixel_size); + for (uint32_t j = 0; j < MIN(3u, primitive->point_count); j++) { state.instance_data_array[r_index].points[j * 2 + 0] = primitive->points[j].x; state.instance_data_array[r_index].points[j * 2 + 1] = primitive->points[j].y; diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp index e0457a8d28..51e22fe779 100644 --- a/drivers/gles3/storage/texture_storage.cpp +++ b/drivers/gles3/storage/texture_storage.cpp @@ -721,6 +721,26 @@ void TextureStorage::texture_2d_update(RID p_texture, const Ref<Image> &p_image, } void TextureStorage::texture_proxy_update(RID p_texture, RID p_proxy_to) { + Texture *tex = texture_owner.get_or_null(p_texture); + ERR_FAIL_COND(!tex); + ERR_FAIL_COND(!tex->is_proxy); + Texture *proxy_to = texture_owner.get_or_null(p_proxy_to); + ERR_FAIL_COND(!proxy_to); + ERR_FAIL_COND(proxy_to->is_proxy); + + if (tex->proxy_to.is_valid()) { + Texture *prev_tex = texture_owner.get_or_null(tex->proxy_to); + ERR_FAIL_COND(!prev_tex); + prev_tex->proxies.erase(p_texture); + } + + *tex = *proxy_to; + + tex->proxy_to = p_proxy_to; + tex->is_render_target = false; + tex->is_proxy = true; + tex->proxies.clear(); + proxy_to->proxies.push_back(p_texture); } void TextureStorage::texture_2d_placeholder_initialize(RID p_texture) { @@ -1022,6 +1042,10 @@ Size2 TextureStorage::texture_size_with_proxy(RID p_texture) { } } +RID TextureStorage::texture_get_rd_texture_rid(RID p_texture, bool p_srgb) const { + return RID(); +} + void TextureStorage::texture_set_data(RID p_texture, const Ref<Image> &p_image, int p_layer) { Texture *texture = texture_owner.get_or_null(p_texture); diff --git a/drivers/gles3/storage/texture_storage.h b/drivers/gles3/storage/texture_storage.h index 5dff768bd7..7714e72f62 100644 --- a/drivers/gles3/storage/texture_storage.h +++ b/drivers/gles3/storage/texture_storage.h @@ -504,6 +504,8 @@ public: virtual Size2 texture_size_with_proxy(RID p_proxy) override; + virtual RID texture_get_rd_texture_rid(RID p_texture, bool p_srgb = false) const override; + void texture_set_data(RID p_texture, const Ref<Image> &p_image, int p_layer = 0); void texture_set_data_partial(RID p_texture, const Ref<Image> &p_image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int p_dst_mip, int p_layer = 0); //Ref<Image> texture_get_data(RID p_texture, int p_layer = 0) const; diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp index d6636606d2..f196530e51 100644 --- a/drivers/wasapi/audio_driver_wasapi.cpp +++ b/drivers/wasapi/audio_driver_wasapi.cpp @@ -127,11 +127,6 @@ static bool default_capture_device_changed = false; #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" #endif -#if defined(__GNUC__) -// Workaround GCC warning from -Wcast-function-type. -#define GetProcAddress (void *)GetProcAddress -#endif - class CMMNotificationClient : public IMMNotificationClient { LONG _cRef = 1; IMMDeviceEnumerator *_pEnumerator = nullptr; @@ -206,21 +201,7 @@ public: static CMMNotificationClient notif_client; -typedef const char *(CDECL *PWineGetVersionPtr)(void); - -bool AudioDriverWASAPI::is_running_on_wine() { - HMODULE nt_lib = LoadLibraryW(L"ntdll.dll"); - if (!nt_lib) { - return false; - } - - PWineGetVersionPtr wine_get_version = (PWineGetVersionPtr)GetProcAddress(nt_lib, "wine_get_version"); - FreeLibrary(nt_lib); - - return (bool)wine_get_version; -} - -Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_capture, bool reinit) { +Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_capture, bool p_reinit, bool p_no_audio_client_3) { WAVEFORMATEX *pwfex; IMMDeviceEnumerator *enumerator = nullptr; IMMDevice *device = nullptr; @@ -286,7 +267,7 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_c } } - if (reinit) { + if (p_reinit) { // In case we're trying to re-initialize the device prevent throwing this error on the console, // otherwise if there is currently no device available this will spam the console. if (hr != S_OK) { @@ -304,10 +285,11 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_c } using_audio_client_3 = !p_capture; // IID_IAudioClient3 is only used for adjustable output latency (not input) - if (using_audio_client_3 && is_running_on_wine()) { + + if (p_no_audio_client_3) { using_audio_client_3 = false; - print_verbose("WASAPI: Wine detected, falling back to IAudioClient interface"); } + if (using_audio_client_3) { hr = device->Activate(IID_IAudioClient3, CLSCTX_ALL, nullptr, (void **)&p_device->audio_client); if (hr != S_OK) { @@ -325,7 +307,7 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_c SAFE_RELEASE(device) - if (reinit) { + if (p_reinit) { if (hr != S_OK) { return ERR_CANT_OPEN; } @@ -436,7 +418,12 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_c &fundamental_period_frames, &min_period_frames, &max_period_frames); - ERR_FAIL_COND_V_MSG(hr != S_OK, ERR_CANT_OPEN, "WASAPI: GetSharedModeEnginePeriod failed with error 0x" + String::num_uint64(hr, 16) + "."); + if (hr != S_OK) { + print_verbose("WASAPI: GetSharedModeEnginePeriod failed with error 0x" + String::num_uint64(hr, 16) + ", falling back to IAudioClient."); + CoTaskMemFree(pwfex); + SAFE_RELEASE(device) + return audio_device_init(p_device, p_capture, p_reinit, true); + } // Period frames must be an integral multiple of fundamental_period_frames or IAudioClient3 initialization will fail, // so we need to select the closest multiple to the user-specified latency. @@ -453,12 +440,25 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_c buffer_frames = period_frames; hr = device_audio_client_3->InitializeSharedAudioStream(0, period_frames, pwfex, nullptr); - ERR_FAIL_COND_V_MSG(hr != S_OK, ERR_CANT_OPEN, "WASAPI: InitializeSharedAudioStream failed with error 0x" + String::num_uint64(hr, 16) + "."); - uint32_t output_latency_in_frames; - WAVEFORMATEX *current_pwfex; - device_audio_client_3->GetCurrentSharedModeEnginePeriod(¤t_pwfex, &output_latency_in_frames); - real_latency = (float)output_latency_in_frames / (float)current_pwfex->nSamplesPerSec; - CoTaskMemFree(current_pwfex); + if (hr != S_OK) { + print_verbose("WASAPI: InitializeSharedAudioStream failed with error 0x" + String::num_uint64(hr, 16) + ", falling back to IAudioClient."); + CoTaskMemFree(pwfex); + SAFE_RELEASE(device); + return audio_device_init(p_device, p_capture, p_reinit, true); + } else { + uint32_t output_latency_in_frames; + WAVEFORMATEX *current_pwfex; + hr = device_audio_client_3->GetCurrentSharedModeEnginePeriod(¤t_pwfex, &output_latency_in_frames); + if (hr == OK) { + real_latency = (float)output_latency_in_frames / (float)current_pwfex->nSamplesPerSec; + CoTaskMemFree(current_pwfex); + } else { + print_verbose("WASAPI: GetCurrentSharedModeEnginePeriod failed with error 0x" + String::num_uint64(hr, 16) + ", falling back to IAudioClient."); + CoTaskMemFree(pwfex); + SAFE_RELEASE(device); + return audio_device_init(p_device, p_capture, p_reinit, true); + } + } } if (p_capture) { @@ -475,8 +475,8 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_c return OK; } -Error AudioDriverWASAPI::init_render_device(bool reinit) { - Error err = audio_device_init(&audio_output, false, reinit); +Error AudioDriverWASAPI::init_render_device(bool p_reinit) { + Error err = audio_device_init(&audio_output, false, p_reinit); if (err != OK) { return err; } @@ -507,8 +507,8 @@ Error AudioDriverWASAPI::init_render_device(bool reinit) { return OK; } -Error AudioDriverWASAPI::init_capture_device(bool reinit) { - Error err = audio_device_init(&audio_input, true, reinit); +Error AudioDriverWASAPI::init_capture_device(bool p_reinit) { + Error err = audio_device_init(&audio_input, true, p_reinit); if (err != OK) { return err; } diff --git a/drivers/wasapi/audio_driver_wasapi.h b/drivers/wasapi/audio_driver_wasapi.h index e9f2794e97..fb6a55734d 100644 --- a/drivers/wasapi/audio_driver_wasapi.h +++ b/drivers/wasapi/audio_driver_wasapi.h @@ -79,19 +79,17 @@ class AudioDriverWASAPI : public AudioDriver { SafeFlag exit_thread; - static bool is_running_on_wine(); - static _FORCE_INLINE_ void write_sample(WORD format_tag, int bits_per_sample, BYTE *buffer, int i, int32_t sample); static _FORCE_INLINE_ int32_t read_sample(WORD format_tag, int bits_per_sample, BYTE *buffer, int i); static void thread_func(void *p_udata); - Error init_render_device(bool reinit = false); - Error init_capture_device(bool reinit = false); + Error init_render_device(bool p_reinit = false); + Error init_capture_device(bool p_reinit = false); Error finish_render_device(); Error finish_capture_device(); - Error audio_device_init(AudioDeviceWASAPI *p_device, bool p_capture, bool reinit); + Error audio_device_init(AudioDeviceWASAPI *p_device, bool p_capture, bool p_reinit, bool p_no_audio_client_3 = false); Error audio_device_finish(AudioDeviceWASAPI *p_device); PackedStringArray audio_device_get_list(bool p_capture); diff --git a/editor/debugger/editor_performance_profiler.cpp b/editor/debugger/editor_performance_profiler.cpp index e2fd462f3a..071eb583c0 100644 --- a/editor/debugger/editor_performance_profiler.cpp +++ b/editor/debugger/editor_performance_profiler.cpp @@ -234,6 +234,7 @@ TreeItem *EditorPerformanceProfiler::_get_monitor_base(const StringName &p_base_ base->set_editable(0, false); base->set_selectable(0, false); base->set_expand_right(0, true); + base->set_custom_font(0, get_theme_font(SNAME("bold"), SNAME("EditorFonts"))); base_map.insert(p_base_name, base); return base; } diff --git a/editor/editor_settings_dialog.cpp b/editor/editor_settings_dialog.cpp index a72c545b2f..77a0d9f85c 100644 --- a/editor/editor_settings_dialog.cpp +++ b/editor/editor_settings_dialog.cpp @@ -487,6 +487,7 @@ void EditorSettingsDialog::_update_shortcuts() { TreeItem *section = E.value; if (section->get_first_child() == nullptr) { root->remove_child(section); + memdelete(section); } } } diff --git a/modules/openxr/extensions/openxr_opengl_extension.cpp b/modules/openxr/extensions/openxr_opengl_extension.cpp index a25727f885..ee69144123 100644 --- a/modules/openxr/extensions/openxr_opengl_extension.cpp +++ b/modules/openxr/extensions/openxr_opengl_extension.cpp @@ -151,19 +151,6 @@ void *OpenXROpenGLExtension::set_session_create_and_get_next_pointer(void *p_nex graphics_binding_gl.glxContext = (GLXContext)glxcontext_handle; graphics_binding_gl.glxDrawable = (GLXDrawable)glxdrawable_handle; - if (graphics_binding_gl.xDisplay == nullptr) { - print_line("OpenXR Failed to get xDisplay from Godot, using XOpenDisplay(nullptr)"); - graphics_binding_gl.xDisplay = XOpenDisplay(nullptr); - } - if (graphics_binding_gl.glxContext == nullptr) { - print_line("OpenXR Failed to get glxContext from Godot, using glXGetCurrentContext()"); - graphics_binding_gl.glxContext = glXGetCurrentContext(); - } - if (graphics_binding_gl.glxDrawable == 0) { - print_line("OpenXR Failed to get glxDrawable from Godot, using glXGetCurrentDrawable()"); - graphics_binding_gl.glxDrawable = glXGetCurrentDrawable(); - } - // spec says to use proper values but runtimes don't care graphics_binding_gl.visualid = 0; graphics_binding_gl.glxFBConfig = 0; diff --git a/modules/openxr/openxr_interface.cpp b/modules/openxr/openxr_interface.cpp index be6b7e4411..1db8f5e665 100644 --- a/modules/openxr/openxr_interface.cpp +++ b/modules/openxr/openxr_interface.cpp @@ -666,6 +666,7 @@ Transform3D OpenXRInterface::get_camera_transform() { Transform3D OpenXRInterface::get_transform_for_view(uint32_t p_view, const Transform3D &p_cam_transform) { XRServer *xr_server = XRServer::get_singleton(); ERR_FAIL_NULL_V(xr_server, Transform3D()); + ERR_FAIL_INDEX_V_MSG(p_view, get_view_count(), Transform3D(), "View index outside bounds."); Transform3D t; if (openxr_api && openxr_api->get_view_transform(p_view, t)) { @@ -685,6 +686,7 @@ Transform3D OpenXRInterface::get_transform_for_view(uint32_t p_view, const Trans Projection OpenXRInterface::get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) { Projection cm; + ERR_FAIL_INDEX_V_MSG(p_view, get_view_count(), cm, "View index outside bounds."); if (openxr_api) { if (openxr_api->get_view_projection(p_view, p_z_near, p_z_far, cm)) { diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle index 0346625e4b..e1d9dc4cde 100644 --- a/platform/android/java/app/config.gradle +++ b/platform/android/java/app/config.gradle @@ -1,10 +1,10 @@ ext.versions = [ - androidGradlePlugin: '7.0.3', + androidGradlePlugin: '7.2.1', compileSdk : 32, - minSdk : 19, // Also update 'platform/android/java/lib/AndroidManifest.xml#minSdkVersion' & 'platform/android/export/export_plugin.cpp#DEFAULT_MIN_SDK_VERSION' - targetSdk : 32, // Also update 'platform/android/java/lib/AndroidManifest.xml#targetSdkVersion' & 'platform/android/export/export_plugin.cpp#DEFAULT_TARGET_SDK_VERSION' + minSdk : 19, // Also update 'platform/android/export/export_plugin.cpp#DEFAULT_MIN_SDK_VERSION' + targetSdk : 32, // Also update 'platform/android/export/export_plugin.cpp#DEFAULT_TARGET_SDK_VERSION' buildTools : '32.0.0', - kotlinVersion : '1.6.21', + kotlinVersion : '1.7.0', fragmentVersion : '1.3.6', nexusPublishVersion: '1.1.0', javaVersion : 11, diff --git a/platform/android/java/gradle/wrapper/gradle-wrapper.properties b/platform/android/java/gradle/wrapper/gradle-wrapper.properties index ffed3a254e..41dfb87909 100644 --- a/platform/android/java/gradle/wrapper/gradle-wrapper.properties +++ b/platform/android/java/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/platform/android/java/lib/AndroidManifest.xml b/platform/android/java/lib/AndroidManifest.xml index 79b5aadf2a..1f77e2fc34 100644 --- a/platform/android/java/lib/AndroidManifest.xml +++ b/platform/android/java/lib/AndroidManifest.xml @@ -4,9 +4,6 @@ android:versionCode="1" android:versionName="1.0"> - <!-- Should match the mindSdk and targetSdk values in platform/android/java/app/config.gradle --> - <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="32" /> - <application> <!-- Records the version of the Godot library --> diff --git a/platform/android/java/lib/build.gradle b/platform/android/java/lib/build.gradle index c9e2a5d7d2..841656a240 100644 --- a/platform/android/java/lib/build.gradle +++ b/platform/android/java/lib/build.gradle @@ -176,11 +176,10 @@ android { } } - // TODO: Enable when issues with AGP 7.1+ are resolved (https://github.com/GodotVR/godot_openxr/issues/187). -// publishing { -// singleVariant("templateRelease") { -// withSourcesJar() -// withJavadocJar() -// } -// } + publishing { + singleVariant("templateRelease") { + withSourcesJar() + withJavadocJar() + } + } } diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index c3a86c69e1..2e60ad8f45 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -376,10 +376,18 @@ void DisplayServerX11::mouse_set_mode(MouseMode p_mode) { } // The only modes that show a cursor are VISIBLE and CONFINED - bool showCursor = (p_mode == MOUSE_MODE_VISIBLE || p_mode == MOUSE_MODE_CONFINED); + bool show_cursor = (p_mode == MOUSE_MODE_VISIBLE || p_mode == MOUSE_MODE_CONFINED); + bool previously_shown = (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED); + + if (show_cursor && !previously_shown) { + WindowID window_id = get_window_at_screen_position(mouse_get_position()); + if (window_id != INVALID_WINDOW_ID) { + _send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_ENTER); + } + } for (const KeyValue<WindowID, WindowData> &E : windows) { - if (showCursor) { + if (show_cursor) { XDefineCursor(x11_display, E.value.x11_window, cursors[current_cursor]); // show cursor } else { XDefineCursor(x11_display, E.value.x11_window, null_cursor); // hide cursor diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index 33d8a8dd14..8b596379a0 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -1843,11 +1843,22 @@ void DisplayServerMacOS::mouse_set_mode(MouseMode p_mode) { window_id = MAIN_WINDOW_ID; } WindowData &wd = windows[window_id]; + + bool show_cursor = (p_mode == MOUSE_MODE_VISIBLE || p_mode == MOUSE_MODE_CONFINED); + bool previously_shown = (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED); + + if (show_cursor && !previously_shown) { + WindowID window_id = get_window_at_screen_position(mouse_get_position()); + if (window_id != INVALID_WINDOW_ID) { + send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_ENTER); + } + } + if (p_mode == MOUSE_MODE_CAPTURED) { // Apple Docs state that the display parameter is not used. // "This parameter is not used. By default, you may pass kCGDirectMainDisplay." // https://developer.apple.com/library/mac/documentation/graphicsimaging/reference/Quartz_Services_Ref/Reference/reference.html - if (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED) { + if (previously_shown) { CGDisplayHideCursor(kCGDirectMainDisplay); } CGAssociateMouseAndMouseCursorPosition(false); @@ -1858,7 +1869,7 @@ void DisplayServerMacOS::mouse_set_mode(MouseMode p_mode) { CGPoint lMouseWarpPos = { pointOnScreen.x, CGDisplayBounds(CGMainDisplayID()).size.height - pointOnScreen.y }; CGWarpMouseCursorPosition(lMouseWarpPos); } else if (p_mode == MOUSE_MODE_HIDDEN) { - if (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED) { + if (previously_shown) { CGDisplayHideCursor(kCGDirectMainDisplay); } [wd.window_object setMovable:YES]; @@ -1868,7 +1879,7 @@ void DisplayServerMacOS::mouse_set_mode(MouseMode p_mode) { [wd.window_object setMovable:NO]; CGAssociateMouseAndMouseCursorPosition(false); } else if (p_mode == MOUSE_MODE_CONFINED_HIDDEN) { - if (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED) { + if (previously_shown) { CGDisplayHideCursor(kCGDirectMainDisplay); } [wd.window_object setMovable:NO]; @@ -1884,7 +1895,7 @@ void DisplayServerMacOS::mouse_set_mode(MouseMode p_mode) { warp_events.clear(); mouse_mode = p_mode; - if (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED) { + if (show_cursor) { cursor_update_shape(); } } diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index fb5ab9f923..8a77c39487 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -960,17 +960,30 @@ void LineEdit::_notification(int p_what) { if (ime_text.length() == 0) { // Normal caret. CaretInfo caret = TS->shaped_text_get_carets(text_rid, caret_column); - - if (caret.l_caret == Rect2() && caret.t_caret == Rect2()) { + if (using_placeholder || (caret.l_caret == Rect2() && caret.t_caret == Rect2())) { // No carets, add one at the start. int h = theme_cache.font->get_height(theme_cache.font_size); int y = style->get_offset().y + (y_area - h) / 2; - if (rtl) { - caret.l_dir = TextServer::DIRECTION_RTL; - caret.l_caret = Rect2(Vector2(ofs_max, y), Size2(caret_width, h)); - } else { - caret.l_dir = TextServer::DIRECTION_LTR; - caret.l_caret = Rect2(Vector2(x_ofs, y), Size2(caret_width, h)); + caret.l_dir = (rtl) ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR; + switch (alignment) { + case HORIZONTAL_ALIGNMENT_FILL: + case HORIZONTAL_ALIGNMENT_LEFT: { + if (rtl) { + caret.l_caret = Rect2(Vector2(ofs_max, y), Size2(caret_width, h)); + } else { + caret.l_caret = Rect2(Vector2(style->get_offset().x, y), Size2(caret_width, h)); + } + } break; + case HORIZONTAL_ALIGNMENT_CENTER: { + caret.l_caret = Rect2(Vector2(size.x / 2, y), Size2(caret_width, h)); + } break; + case HORIZONTAL_ALIGNMENT_RIGHT: { + if (rtl) { + caret.l_caret = Rect2(Vector2(style->get_offset().x, y), Size2(caret_width, h)); + } else { + caret.l_caret = Rect2(Vector2(ofs_max, y), Size2(caret_width, h)); + } + } break; } RenderingServer::get_singleton()->canvas_item_add_rect(ci, caret.l_caret, caret_color); } else { diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index f8b0a66a71..43a2c9473e 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1561,44 +1561,15 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { set_input_as_handled(); } - if (gui.drag_data.get_type() != Variant::NIL && mb->get_button_index() == MouseButton::LEFT) { + if (gui.dragging && mb->get_button_index() == MouseButton::LEFT) { // Alternate drop use (when using force_drag(), as proposed by #5342). - gui.drag_successful = false; - if (gui.mouse_focus) { - gui.drag_successful = _gui_drop(gui.mouse_focus, pos, false); - } - - gui.drag_data = Variant(); - gui.dragging = false; - - Control *drag_preview = _gui_get_drag_preview(); - if (drag_preview) { - memdelete(drag_preview); - gui.drag_preview_id = ObjectID(); - } - _propagate_viewport_notification(this, NOTIFICATION_DRAG_END); - get_base_window()->update_mouse_cursor_shape(); + _perform_drop(gui.mouse_focus, pos); } _gui_cancel_tooltip(); } else { - if (gui.drag_data.get_type() != Variant::NIL && mb->get_button_index() == MouseButton::LEFT) { - gui.drag_successful = false; - if (gui.drag_mouse_over) { - gui.drag_successful = _gui_drop(gui.drag_mouse_over, gui.drag_mouse_over_pos, false); - } - - Control *drag_preview = _gui_get_drag_preview(); - if (drag_preview) { - memdelete(drag_preview); - gui.drag_preview_id = ObjectID(); - } - - gui.drag_data = Variant(); - gui.dragging = false; - gui.drag_mouse_over = nullptr; - _propagate_viewport_notification(this, NOTIFICATION_DRAG_END); - get_base_window()->update_mouse_cursor_shape(); + if (gui.dragging && mb->get_button_index() == MouseButton::LEFT) { + _perform_drop(gui.drag_mouse_over, gui.drag_mouse_over_pos); } gui.mouse_focus_mask &= ~mouse_button_to_mask(mb->get_button_index()); // Remove from mask. @@ -1682,7 +1653,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { } gui.drag_attempted = true; - if (gui.drag_data.get_type() != Variant::NIL) { + if (gui.dragging) { _propagate_viewport_notification(this, NOTIFICATION_DRAG_BEGIN); } } @@ -1795,7 +1766,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { } } - if (gui.drag_data.get_type() != Variant::NIL) { + if (gui.dragging) { // Handle drag & drop. Control *drag_preview = _gui_get_drag_preview(); @@ -1997,6 +1968,12 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { } if (mm.is_null() && mb.is_null() && p_event->is_action_type()) { + if (gui.dragging && p_event->is_action_pressed("ui_cancel") && Input::get_singleton()->is_action_just_pressed("ui_cancel")) { + _perform_drop(); + set_input_as_handled(); + return; + } + if (gui.key_focus && !gui.key_focus->is_visible_in_tree()) { gui.key_focus->release_focus(); } @@ -2078,6 +2055,27 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { } } +void Viewport::_perform_drop(Control *p_control, Point2 p_pos) { + // Without any arguments, simply cancel Drag and Drop. + if (p_control) { + gui.drag_successful = _gui_drop(p_control, p_pos, false); + } else { + gui.drag_successful = false; + } + + Control *drag_preview = _gui_get_drag_preview(); + if (drag_preview) { + memdelete(drag_preview); + gui.drag_preview_id = ObjectID(); + } + + gui.drag_data = Variant(); + gui.dragging = false; + gui.drag_mouse_over = nullptr; + _propagate_viewport_notification(this, NOTIFICATION_DRAG_END); + get_base_window()->update_mouse_cursor_shape(); +} + void Viewport::_gui_cleanup_internal_state(Ref<InputEvent> p_event) { ERR_FAIL_COND(p_event.is_null()); @@ -4231,6 +4229,8 @@ void SubViewport::_bind_methods() { BIND_ENUM_CONSTANT(UPDATE_ALWAYS); } -SubViewport::SubViewport() {} +SubViewport::SubViewport() { + RS::get_singleton()->viewport_set_size(get_viewport_rid(), get_size().width, get_size().height); +} SubViewport::~SubViewport() {} diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 8911aea335..dc69ec24d8 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -405,6 +405,7 @@ private: Control *_gui_find_control_at_pos(CanvasItem *p_node, const Point2 &p_global, const Transform2D &p_xform, Transform2D &r_inv_xform); void _gui_input_event(Ref<InputEvent> p_event); + void _perform_drop(Control *p_control = nullptr, Point2 p_pos = Point2()); void _gui_cleanup_internal_state(Ref<InputEvent> p_event); _FORCE_INLINE_ Transform2D _get_input_pre_xform() const; diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 706db3af16..d1e300e057 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -940,7 +940,7 @@ void _fix_array_compatibility(const Vector<uint8_t> &p_src, uint32_t p_old_forma dst[0] = (int16_t)CLAMP(src[0] / 127.0f * 32767, -32768, 32767); dst[1] = (int16_t)CLAMP(src[1] / 127.0f * 32767, -32768, 32767); } - src_offset += sizeof(int16_t) * 2; + src_offset += sizeof(int8_t) * 2; } else { for (uint32_t i = 0; i < p_elements; i++) { const int16_t *src = (const int16_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; @@ -962,7 +962,7 @@ void _fix_array_compatibility(const Vector<uint8_t> &p_src, uint32_t p_old_forma dst[0] = (uint16_t)CLAMP(res.x * 65535, 0, 65535); dst[1] = (uint16_t)CLAMP(res.y * 65535, 0, 65535); } - src_offset += sizeof(uint16_t) * 2; + src_offset += sizeof(uint8_t) * 4; // 1 byte padding } else { for (uint32_t i = 0; i < p_elements; i++) { const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; @@ -973,7 +973,7 @@ void _fix_array_compatibility(const Vector<uint8_t> &p_src, uint32_t p_old_forma dst[0] = (uint16_t)CLAMP(res.x * 65535, 0, 65535); dst[1] = (uint16_t)CLAMP(res.y * 65535, 0, 65535); } - src_offset += sizeof(uint16_t) * 2; + src_offset += sizeof(float) * 3; } } @@ -988,7 +988,7 @@ void _fix_array_compatibility(const Vector<uint8_t> &p_src, uint32_t p_old_forma dst[0] = (uint16_t)CLAMP((src[0] / 127.0f * .5f + .5f) * 65535, 0, 65535); dst[1] = (uint16_t)CLAMP((src[1] / 127.0f * .5f + .5f) * 65535, 0, 65535); } - src_offset += sizeof(uint16_t) * 2; + src_offset += sizeof(uint8_t) * 2; } else { // int16 SNORM -> uint16 UNORM for (uint32_t i = 0; i < p_elements; i++) { const int16_t *src = (const int16_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; @@ -1010,7 +1010,7 @@ void _fix_array_compatibility(const Vector<uint8_t> &p_src, uint32_t p_old_forma dst[0] = (uint16_t)CLAMP(res.x * 65535, 0, 65535); dst[1] = (uint16_t)CLAMP(res.y * 65535, 0, 65535); } - src_offset += sizeof(uint16_t) * 2; + src_offset += sizeof(uint8_t) * 4; } else { for (uint32_t i = 0; i < p_elements; i++) { const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; @@ -1021,7 +1021,7 @@ void _fix_array_compatibility(const Vector<uint8_t> &p_src, uint32_t p_old_forma dst[0] = (uint16_t)CLAMP(res.x * 65535, 0, 65535); dst[1] = (uint16_t)CLAMP(res.y * 65535, 0, 65535); } - src_offset += sizeof(uint16_t) * 2; + src_offset += sizeof(float) * 4; } } } break; diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index 4d566178a5..3a671edeea 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -177,7 +177,7 @@ bool Shader::is_text_shader() const { } bool Shader::has_parameter(const StringName &p_name) const { - return params_cache.has("shader_parameter/" + p_name); + return params_cache.has(p_name); } void Shader::_update_shader() const { diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index 04637983b5..03abac1b3e 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -3108,9 +3108,9 @@ void VisualShaderNodeUVFunc::set_function(VisualShaderNodeUVFunc::Function p_fun return; } if (p_func == FUNC_PANNING) { - set_input_port_default_value(2, Vector2()); // offset + set_input_port_default_value(2, Vector2(), get_input_port_default_value(2)); // offset } else { // FUNC_SCALING - set_input_port_default_value(2, Vector2(0.5, 0.5)); // pivot + set_input_port_default_value(2, Vector2(0.5, 0.5), get_input_port_default_value(2)); // pivot } func = p_func; emit_changed(); diff --git a/servers/rendering/dummy/storage/texture_storage.h b/servers/rendering/dummy/storage/texture_storage.h index ad28dd68c3..a17d734e10 100644 --- a/servers/rendering/dummy/storage/texture_storage.h +++ b/servers/rendering/dummy/storage/texture_storage.h @@ -126,6 +126,8 @@ public: virtual Size2 texture_size_with_proxy(RID p_proxy) override { return Size2(); }; + virtual RID texture_get_rd_texture_rid(RID p_texture, bool p_srgb = false) const override { return RID(); }; + /* DECAL API */ virtual RID decal_allocate() override { return RID(); } virtual void decal_initialize(RID p_rid) override {} diff --git a/servers/rendering/renderer_rd/effects/copy_effects.cpp b/servers/rendering/renderer_rd/effects/copy_effects.cpp index a14228eb3d..27f977a80b 100644 --- a/servers/rendering/renderer_rd/effects/copy_effects.cpp +++ b/servers/rendering/renderer_rd/effects/copy_effects.cpp @@ -1122,8 +1122,8 @@ void CopyEffects::cubemap_roughness_raster(RID p_source_rd_texture, RID p_dest_f roughness.push_constant.use_direct_write = p_roughness == 0.0; roughness.push_constant.face_size = p_size; - // setup our uniforms - RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + // Setup our uniforms. + RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture })); diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index ceed287184..0e4a223f69 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -3349,7 +3349,7 @@ void RenderForwardClustered::_geometry_instance_add_surface_with_material(Geomet SceneShaderForwardClustered::MaterialData *material_shadow = nullptr; void *surface_shadow = nullptr; - if (!p_material->shader_data->uses_particle_trails && !p_material->shader_data->writes_modelview_or_projection && !p_material->shader_data->uses_vertex && !p_material->shader_data->uses_position && !p_material->shader_data->uses_discard && !p_material->shader_data->uses_depth_pre_pass && !p_material->shader_data->uses_alpha_clip && p_material->shader_data->cull_mode == SceneShaderForwardClustered::ShaderData::CULL_BACK) { + if (!p_material->shader_data->uses_particle_trails && !p_material->shader_data->writes_modelview_or_projection && !p_material->shader_data->uses_vertex && !p_material->shader_data->uses_position && !p_material->shader_data->uses_discard && !p_material->shader_data->uses_depth_pre_pass && !p_material->shader_data->uses_alpha_clip && p_material->shader_data->cull_mode == SceneShaderForwardClustered::ShaderData::CULL_BACK && !p_material->shader_data->uses_point_size) { flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_SHARED_SHADOW_MATERIAL; material_shadow = static_cast<SceneShaderForwardClustered::MaterialData *>(RendererRD::MaterialStorage::get_singleton()->material_get_data(scene_shader.default_material, RendererRD::MaterialStorage::SHADER_TYPE_3D)); diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index cbc5cc337c..7e0070f8b7 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -706,7 +706,7 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend //bind textures - _bind_canvas_texture(p_draw_list, RID(), current_filter, current_repeat, last_texture, push_constant, texpixel_size); + _bind_canvas_texture(p_draw_list, primitive->texture, current_filter, current_repeat, last_texture, push_constant, texpixel_size); RD::get_singleton()->draw_list_bind_index_array(p_draw_list, primitive_arrays.index_array[MIN(3u, primitive->point_count) - 1]); diff --git a/servers/rendering/renderer_rd/shaders/cluster_render.glsl b/servers/rendering/renderer_rd/shaders/cluster_render.glsl index 932312de82..8c26a67926 100644 --- a/servers/rendering/renderer_rd/shaders/cluster_render.glsl +++ b/servers/rendering/renderer_rd/shaders/cluster_render.glsl @@ -142,7 +142,11 @@ void main() { } } #else - if (!gl_HelperInvocation) { +// MoltenVK/Metal fails to compile shaders using gl_HelperInvocation for some GPUs +#ifndef MOLTENVK_USED + if (!gl_HelperInvocation) +#endif + { atomicOr(cluster_render.data[usage_write_offset], usage_write_bit); } #endif @@ -162,7 +166,11 @@ void main() { } } #else - if (!gl_HelperInvocation) { +// MoltenVK/Metal fails to compile shaders using gl_HelperInvocation for some GPUs +#ifndef MOLTENVK_USED + if (!gl_HelperInvocation) +#endif + { atomicOr(cluster_render.data[z_write_offset], z_write_bit); } #endif diff --git a/servers/rendering/renderer_rd/shaders/particles.glsl b/servers/rendering/renderer_rd/shaders/particles.glsl index 3a6dd579b9..9f6aa7adc0 100644 --- a/servers/rendering/renderer_rd/shaders/particles.glsl +++ b/servers/rendering/renderer_rd/shaders/particles.glsl @@ -462,7 +462,7 @@ void main() { if (any(lessThan(uvw_pos, vec3(0.0))) || any(greaterThan(uvw_pos, vec3(1.0)))) { continue; } - vec3 s = texture(sampler3D(sdf_vec_textures[FRAME.attractors[i].texture_index], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos).xyz * 2.0 - 1.0; + vec3 s = texture(sampler3D(sdf_vec_textures[FRAME.attractors[i].texture_index], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos).xyz * -2.0 + 1.0; dir = mat3(FRAME.attractors[i].transform) * safe_normalize(s); //revert direction amount = length(s); diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.h b/servers/rendering/renderer_rd/storage_rd/particles_storage.h index 6478e2b5dc..a9cc98abb9 100644 --- a/servers/rendering/renderer_rd/storage_rd/particles_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.h @@ -97,7 +97,7 @@ private: uint32_t type; uint32_t texture_index; //texture index for vector field - real_t scale; + float scale; uint32_t pad[2]; }; @@ -106,8 +106,8 @@ private: float prev_system_phase; uint32_t cycle; - real_t explosiveness; - real_t randomness; + float explosiveness; + float randomness; float time; float delta; diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp index 3785c3899b..077fde58b8 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp @@ -1336,6 +1336,13 @@ Size2 TextureStorage::texture_size_with_proxy(RID p_proxy) { return texture_2d_get_size(p_proxy); } +RID TextureStorage::texture_get_rd_texture_rid(RID p_texture, bool p_srgb) const { + Texture *tex = texture_owner.get_or_null(p_texture); + ERR_FAIL_COND_V(!tex, RID()); + + return (p_srgb && tex->rd_texture_srgb.is_valid()) ? tex->rd_texture_srgb : tex->rd_texture; +} + Ref<Image> TextureStorage::_validate_texture_format(const Ref<Image> &p_image, TextureToRDFormat &r_format) { Ref<Image> image = p_image->duplicate(); diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.h b/servers/rendering/renderer_rd/storage_rd/texture_storage.h index 72d4c90159..f4737eb63d 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.h @@ -491,6 +491,8 @@ public: virtual Size2 texture_size_with_proxy(RID p_proxy) override; + virtual RID texture_get_rd_texture_rid(RID p_texture, bool p_srgb = false) const override; + //internal usage _FORCE_INLINE_ TextureType texture_get_type(RID p_texture) { RendererRD::TextureStorage::Texture *tex = texture_owner.get_or_null(p_texture); diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index 93118f39e7..bb4c41df52 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -393,6 +393,7 @@ void RenderingDevice::_bind_methods() { ClassDB::bind_method(D_METHOD("vertex_buffer_create", "size_bytes", "data", "use_as_storage"), &RenderingDevice::vertex_buffer_create, DEFVAL(Vector<uint8_t>()), DEFVAL(false)); ClassDB::bind_method(D_METHOD("vertex_format_create", "vertex_descriptions"), &RenderingDevice::_vertex_format_create); + ClassDB::bind_method(D_METHOD("vertex_array_create", "vertex_count", "vertex_format", "src_buffers"), &RenderingDevice::_vertex_array_create); ClassDB::bind_method(D_METHOD("index_buffer_create", "size_indices", "format", "data", "use_restart_indices"), &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); diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index 6d2d0d9906..b77b95bb62 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -212,6 +212,7 @@ public: FUNC1(texture_debug_usage, List<TextureInfo> *) FUNC2(texture_set_force_redraw_if_visible, RID, bool) + FUNC2RC(RID, texture_get_rd_texture_rid, RID, bool) /* SHADER API */ diff --git a/servers/rendering/storage/texture_storage.h b/servers/rendering/storage/texture_storage.h index 3207181471..31fb5e8791 100644 --- a/servers/rendering/storage/texture_storage.h +++ b/servers/rendering/storage/texture_storage.h @@ -100,6 +100,8 @@ public: virtual Size2 texture_size_with_proxy(RID p_proxy) = 0; + virtual RID texture_get_rd_texture_rid(RID p_texture, bool p_srgb = false) const = 0; + /* Decal API */ virtual RID decal_allocate() = 0; virtual void decal_initialize(RID p_rid) = 0; diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 0c4d641a6f..7691bede07 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -1691,6 +1691,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("texture_get_path", "texture"), &RenderingServer::texture_get_path); ClassDB::bind_method(D_METHOD("texture_set_force_redraw_if_visible", "texture", "enable"), &RenderingServer::texture_set_force_redraw_if_visible); + ClassDB::bind_method(D_METHOD("texture_get_rd_texture", "texture", "srgb"), &RenderingServer::texture_get_rd_texture_rid, DEFVAL(false)); BIND_ENUM_CONSTANT(TEXTURE_LAYERED_2D_ARRAY); BIND_ENUM_CONSTANT(TEXTURE_LAYERED_CUBEMAP); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 97fafd1b14..1d364dfcff 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -157,6 +157,8 @@ public: virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) = 0; + virtual RID texture_get_rd_texture_rid(RID p_texture, bool p_srgb = false) const = 0; + /* SHADER API */ enum ShaderMode { diff --git a/servers/xr/xr_interface.cpp b/servers/xr/xr_interface.cpp index a5ee1d5726..4d58d24405 100644 --- a/servers/xr/xr_interface.cpp +++ b/servers/xr/xr_interface.cpp @@ -72,6 +72,8 @@ void XRInterface::_bind_methods() { ClassDB::bind_method(D_METHOD("is_passthrough_enabled"), &XRInterface::is_passthrough_enabled); ClassDB::bind_method(D_METHOD("start_passthrough"), &XRInterface::start_passthrough); ClassDB::bind_method(D_METHOD("stop_passthrough"), &XRInterface::stop_passthrough); + ClassDB::bind_method(D_METHOD("get_transform_for_view", "view", "cam_transform"), &XRInterface::get_transform_for_view); + ClassDB::bind_method(D_METHOD("get_projection_for_view", "view", "aspect", "near", "far"), &XRInterface::get_projection_for_view); ADD_GROUP("AR", "ar_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ar_is_anchor_detection_enabled"), "set_anchor_detection_is_enabled", "get_anchor_detection_is_enabled"); |