summaryrefslogtreecommitdiff
path: root/scene/resources
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources')
-rw-r--r--scene/resources/animation.cpp44
-rw-r--r--scene/resources/audio_stream_polyphonic.cpp274
-rw-r--r--scene/resources/audio_stream_polyphonic.h119
-rw-r--r--scene/resources/camera_attributes.cpp4
-rw-r--r--scene/resources/convex_polygon_shape_2d.cpp2
-rw-r--r--scene/resources/default_theme/default_theme.cpp24
-rw-r--r--scene/resources/environment.cpp12
-rw-r--r--scene/resources/font.cpp38
-rw-r--r--scene/resources/font.h8
-rw-r--r--scene/resources/immediate_mesh.cpp37
-rw-r--r--scene/resources/importer_mesh.cpp19
-rw-r--r--scene/resources/material.cpp77
-rw-r--r--scene/resources/material.h6
-rw-r--r--scene/resources/mesh.cpp25
-rw-r--r--scene/resources/mesh.h2
-rw-r--r--scene/resources/mesh_library.cpp3
-rw-r--r--scene/resources/packed_scene.cpp22
-rw-r--r--scene/resources/packed_scene.h2
-rw-r--r--scene/resources/polygon_path_finder.cpp4
-rw-r--r--scene/resources/primitive_meshes.cpp2
-rw-r--r--scene/resources/primitive_meshes.h2
-rw-r--r--scene/resources/resource_format_text.cpp86
-rw-r--r--scene/resources/resource_format_text.h4
-rw-r--r--scene/resources/shader.cpp26
-rw-r--r--scene/resources/shader.h50
-rw-r--r--scene/resources/skeleton_modification_2d_stackholder.cpp2
-rw-r--r--scene/resources/skeleton_modification_stack_2d.cpp2
-rw-r--r--scene/resources/style_box.cpp206
-rw-r--r--scene/resources/style_box.h59
-rw-r--r--scene/resources/surface_tool.cpp74
-rw-r--r--scene/resources/surface_tool.h15
-rw-r--r--scene/resources/text_paragraph.cpp38
-rw-r--r--scene/resources/texture.cpp53
-rw-r--r--scene/resources/texture.h19
-rw-r--r--scene/resources/tile_set.cpp17
-rw-r--r--scene/resources/visual_shader.cpp7
-rw-r--r--scene/resources/visual_shader_nodes.cpp535
-rw-r--r--scene/resources/visual_shader_nodes.h30
38 files changed, 1360 insertions, 589 deletions
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index b371266c83..50f3015814 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -4754,17 +4754,17 @@ void Animation::compress(uint32_t p_page_size, uint32_t p_fps, float p_split_tol
// The frame has advanced, time to validate the previous frame
uint32_t current_page_size = base_page_size;
- for (uint32_t i = 0; i < data_tracks.size(); i++) {
- uint32_t track_size = data_tracks[i].data.size(); // track size
- track_size += data_tracks[i].get_temp_packet_size(); // Add the temporary data
+ for (const AnimationCompressionDataState &state : data_tracks) {
+ uint32_t track_size = state.data.size(); // track size
+ track_size += state.get_temp_packet_size(); // Add the temporary data
if (track_size > Compression::MAX_DATA_TRACK_SIZE) {
rollback = true; //track to large, time track can't point to keys any longer, because key offset is 12 bits
break;
}
current_page_size += track_size;
}
- for (uint32_t i = 0; i < time_tracks.size(); i++) {
- current_page_size += time_tracks[i].packets.size() * 4; // time packet is 32 bits
+ for (const AnimationCompressionTimeState &state : time_tracks) {
+ current_page_size += state.packets.size() * 4; // time packet is 32 bits
}
if (!rollback && current_page_size > p_page_size) {
@@ -4776,22 +4776,22 @@ void Animation::compress(uint32_t p_page_size, uint32_t p_fps, float p_split_tol
if (rollback) {
// Not valid any longer, so rollback and commit page
- for (uint32_t i = 0; i < data_tracks.size(); i++) {
- data_tracks[i].temp_packets.resize(data_tracks[i].validated_packet_count);
+ for (AnimationCompressionDataState &state : data_tracks) {
+ state.temp_packets.resize(state.validated_packet_count);
}
- for (uint32_t i = 0; i < time_tracks.size(); i++) {
- time_tracks[i].key_index = time_tracks[i].validated_key_index; //rollback key
- time_tracks[i].packets.resize(time_tracks[i].validated_packet_count);
+ for (AnimationCompressionTimeState &state : time_tracks) {
+ state.key_index = state.validated_key_index; //rollback key
+ state.packets.resize(state.validated_packet_count);
}
} else {
// All valid, so save rollback information
- for (uint32_t i = 0; i < data_tracks.size(); i++) {
- data_tracks[i].validated_packet_count = data_tracks[i].temp_packets.size();
+ for (AnimationCompressionDataState &state : data_tracks) {
+ state.validated_packet_count = state.temp_packets.size();
}
- for (uint32_t i = 0; i < time_tracks.size(); i++) {
- time_tracks[i].validated_key_index = time_tracks[i].key_index;
- time_tracks[i].validated_packet_count = time_tracks[i].packets.size();
+ for (AnimationCompressionTimeState &state : time_tracks) {
+ state.validated_key_index = state.key_index;
+ state.validated_packet_count = state.packets.size();
}
// Accept this frame as the frame being processed (as long as it exists)
@@ -4976,8 +4976,8 @@ void Animation::compress(uint32_t p_page_size, uint32_t p_fps, float p_split_tol
}
uint32_t new_size = 0;
- for (uint32_t i = 0; i < compression.pages.size(); i++) {
- new_size += compression.pages[i].data.size();
+ for (const Compression::Page &page : compression.pages) {
+ new_size += page.data.size();
}
print_line("Original size: " + itos(orig_size) + " - Compressed size: " + itos(new_size) + " " + String::num(float(new_size) / float(orig_size) * 100, 2) + "% pages: " + itos(compression.pages.size()));
@@ -5289,8 +5289,8 @@ int Animation::_get_compressed_key_count(uint32_t p_compressed_track) const {
int key_count = 0;
- for (uint32_t i = 0; i < compression.pages.size(); i++) {
- const uint8_t *page_data = compression.pages[i].data.ptr();
+ for (const Compression::Page &page : compression.pages) {
+ const uint8_t *page_data = page.data.ptr();
// Little endian assumed. No major big endian hardware exists any longer, but in case it does it will need to be supported.
const uint32_t *indices = (const uint32_t *)page_data;
const uint16_t *time_keys = (const uint16_t *)&page_data[indices[p_compressed_track * 3 + 0]];
@@ -5323,8 +5323,8 @@ bool Animation::_fetch_compressed_by_index(uint32_t p_compressed_track, int p_in
ERR_FAIL_COND_V(!compression.enabled, false);
ERR_FAIL_UNSIGNED_INDEX_V(p_compressed_track, compression.bounds.size(), false);
- for (uint32_t i = 0; i < compression.pages.size(); i++) {
- const uint8_t *page_data = compression.pages[i].data.ptr();
+ for (const Compression::Page &page : compression.pages) {
+ const uint8_t *page_data = page.data.ptr();
// Little endian assumed. No major big endian hardware exists any longer, but in case it does it will need to be supported.
const uint32_t *indices = (const uint32_t *)page_data;
const uint16_t *time_keys = (const uint16_t *)&page_data[indices[p_compressed_track * 3 + 0]];
@@ -5374,7 +5374,7 @@ bool Animation::_fetch_compressed_by_index(uint32_t p_compressed_track, int p_in
}
}
- r_time = compression.pages[i].time_offset + double(frame) / double(compression.fps);
+ r_time = page.time_offset + double(frame) / double(compression.fps);
for (uint32_t l = 0; l < COMPONENTS; l++) {
r_value[l] = decode[l];
}
diff --git a/scene/resources/audio_stream_polyphonic.cpp b/scene/resources/audio_stream_polyphonic.cpp
new file mode 100644
index 0000000000..f7299b0789
--- /dev/null
+++ b/scene/resources/audio_stream_polyphonic.cpp
@@ -0,0 +1,274 @@
+/**************************************************************************/
+/* audio_stream_polyphonic.cpp */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* 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 "audio_stream_polyphonic.h"
+#include "scene/main/scene_tree.h"
+
+Ref<AudioStreamPlayback> AudioStreamPolyphonic::instantiate_playback() {
+ Ref<AudioStreamPlaybackPolyphonic> playback;
+ playback.instantiate();
+ playback->streams.resize(polyphony);
+ return playback;
+}
+
+String AudioStreamPolyphonic::get_stream_name() const {
+ return "AudioStreamPolyphonic";
+}
+
+bool AudioStreamPolyphonic::is_monophonic() const {
+ return true; // This avoids stream players to instantiate more than one of these.
+}
+
+void AudioStreamPolyphonic::set_polyphony(int p_voices) {
+ ERR_FAIL_COND(p_voices < 0 || p_voices > 128);
+ polyphony = p_voices;
+}
+int AudioStreamPolyphonic::get_polyphony() const {
+ return polyphony;
+}
+
+void AudioStreamPolyphonic::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_polyphony", "voices"), &AudioStreamPolyphonic::set_polyphony);
+ ClassDB::bind_method(D_METHOD("get_polyphony"), &AudioStreamPolyphonic::get_polyphony);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "polyphony", PROPERTY_HINT_RANGE, "1,128,1"), "set_polyphony", "get_polyphony");
+}
+
+AudioStreamPolyphonic::AudioStreamPolyphonic() {
+}
+
+////////////////////////
+
+void AudioStreamPlaybackPolyphonic::start(double p_from_pos) {
+ if (active) {
+ stop();
+ }
+
+ active = true;
+}
+
+void AudioStreamPlaybackPolyphonic::stop() {
+ if (!active) {
+ return;
+ }
+
+ bool locked = false;
+ for (Stream &s : streams) {
+ if (s.active.is_set()) {
+ // Need locking because something may still be mixing.
+ locked = true;
+ AudioServer::get_singleton()->lock();
+ }
+ s.active.clear();
+ s.finish_request.clear();
+ s.stream_playback.unref();
+ s.stream.unref();
+ }
+ if (locked) {
+ AudioServer::get_singleton()->unlock();
+ }
+
+ active = false;
+}
+
+bool AudioStreamPlaybackPolyphonic::is_playing() const {
+ return active;
+}
+
+int AudioStreamPlaybackPolyphonic::get_loop_count() const {
+ return 0;
+}
+
+double AudioStreamPlaybackPolyphonic::get_playback_position() const {
+ return 0;
+}
+void AudioStreamPlaybackPolyphonic::seek(double p_time) {
+ // Ignored.
+}
+
+void AudioStreamPlaybackPolyphonic::tag_used_streams() {
+ for (Stream &s : streams) {
+ if (s.active.is_set()) {
+ s.stream_playback->tag_used_streams();
+ }
+ }
+}
+
+int AudioStreamPlaybackPolyphonic::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) {
+ if (!active) {
+ return 0;
+ }
+
+ // Pre-clear buffer.
+ for (int i = 0; i < p_frames; i++) {
+ p_buffer[i] = AudioFrame(0, 0);
+ }
+
+ for (Stream &s : streams) {
+ if (!s.active.is_set()) {
+ continue;
+ }
+
+ float volume_db = s.volume_db; // Copy because it can be overridden at any time.
+ float next_volume = Math::db_to_linear(volume_db);
+ s.prev_volume_db = volume_db;
+
+ if (s.finish_request.is_set()) {
+ if (s.pending_play.is_set()) {
+ // Did not get the chance to play, was finalized too soon.
+ s.active.clear();
+ continue;
+ }
+ next_volume = 0;
+ }
+
+ if (s.pending_play.is_set()) {
+ s.stream_playback->start(s.play_offset);
+ s.pending_play.clear();
+ }
+ float prev_volume = Math::db_to_linear(s.prev_volume_db);
+
+ float volume_inc = (next_volume - prev_volume) / float(p_frames);
+
+ int todo = p_frames;
+ int offset = 0;
+ float volume = prev_volume;
+
+ bool stream_done = false;
+
+ while (todo) {
+ int to_mix = MIN(todo, int(INTERNAL_BUFFER_LEN));
+ int mixed = s.stream_playback->mix(internal_buffer, s.pitch_scale, to_mix);
+
+ for (int i = 0; i < to_mix; i++) {
+ p_buffer[offset + i] += internal_buffer[i] * volume;
+ volume += volume_inc;
+ }
+
+ if (mixed < to_mix) {
+ // Stream is done.
+ s.active.clear();
+ stream_done = true;
+ break;
+ }
+
+ todo -= to_mix;
+ offset += to_mix;
+ }
+
+ if (stream_done) {
+ continue;
+ }
+
+ if (s.finish_request.is_set()) {
+ s.active.clear();
+ }
+ }
+
+ return p_frames;
+}
+
+AudioStreamPlaybackPolyphonic::ID AudioStreamPlaybackPolyphonic::play_stream(const Ref<AudioStream> &p_stream, float p_from_offset, float p_volume_db, float p_pitch_scale) {
+ ERR_FAIL_COND_V(p_stream.is_null(), INVALID_ID);
+ for (uint32_t i = 0; i < streams.size(); i++) {
+ if (!streams[i].active.is_set()) {
+ // Can use this stream, as it's not active.
+ streams[i].stream = p_stream;
+ streams[i].stream_playback = streams[i].stream->instantiate_playback();
+ streams[i].play_offset = p_from_offset;
+ streams[i].volume_db = p_volume_db;
+ streams[i].prev_volume_db = p_volume_db;
+ streams[i].pitch_scale = p_pitch_scale;
+ streams[i].id = id_counter++;
+ streams[i].finish_request.clear();
+ streams[i].pending_play.set();
+ streams[i].active.set();
+ return (ID(i) << INDEX_SHIFT) | ID(streams[i].id);
+ }
+ }
+
+ return INVALID_ID;
+}
+
+AudioStreamPlaybackPolyphonic::Stream *AudioStreamPlaybackPolyphonic::_find_stream(int64_t p_id) {
+ uint32_t index = p_id >> INDEX_SHIFT;
+ if (index >= streams.size()) {
+ return nullptr;
+ }
+ if (!streams[index].active.is_set()) {
+ return nullptr; // Not active, no longer exists.
+ }
+ int64_t id = p_id & ID_MASK;
+ if (streams[index].id != id) {
+ return nullptr;
+ }
+ return &streams[index];
+}
+
+void AudioStreamPlaybackPolyphonic::set_stream_volume(ID p_stream_id, float p_volume_db) {
+ Stream *s = _find_stream(p_stream_id);
+ if (!s) {
+ return;
+ }
+ s->volume_db = p_volume_db;
+}
+
+void AudioStreamPlaybackPolyphonic::set_stream_pitch_scale(ID p_stream_id, float p_pitch_scale) {
+ Stream *s = _find_stream(p_stream_id);
+ if (!s) {
+ return;
+ }
+ s->pitch_scale = p_pitch_scale;
+}
+
+bool AudioStreamPlaybackPolyphonic::is_stream_playing(ID p_stream_id) const {
+ return const_cast<AudioStreamPlaybackPolyphonic *>(this)->_find_stream(p_stream_id) != nullptr;
+}
+
+void AudioStreamPlaybackPolyphonic::stop_stream(ID p_stream_id) {
+ Stream *s = _find_stream(p_stream_id);
+ if (!s) {
+ return;
+ }
+ s->finish_request.set();
+}
+
+void AudioStreamPlaybackPolyphonic::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("play_stream", "stream", "from_offset", "volume_db", "pitch_scale"), &AudioStreamPlaybackPolyphonic::play_stream, DEFVAL(0), DEFVAL(0), DEFVAL(1.0));
+ ClassDB::bind_method(D_METHOD("set_stream_volume", "stream", "volume_db"), &AudioStreamPlaybackPolyphonic::set_stream_volume);
+ ClassDB::bind_method(D_METHOD("set_stream_pitch_scale", "stream", "pitch_scale"), &AudioStreamPlaybackPolyphonic::set_stream_pitch_scale);
+ ClassDB::bind_method(D_METHOD("is_stream_playing", "stream"), &AudioStreamPlaybackPolyphonic::is_stream_playing);
+ ClassDB::bind_method(D_METHOD("stop_stream", "stream"), &AudioStreamPlaybackPolyphonic::stop_stream);
+
+ BIND_CONSTANT(INVALID_ID);
+}
+
+AudioStreamPlaybackPolyphonic::AudioStreamPlaybackPolyphonic() {
+}
diff --git a/scene/resources/audio_stream_polyphonic.h b/scene/resources/audio_stream_polyphonic.h
new file mode 100644
index 0000000000..e414401b6f
--- /dev/null
+++ b/scene/resources/audio_stream_polyphonic.h
@@ -0,0 +1,119 @@
+/**************************************************************************/
+/* audio_stream_polyphonic.h */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* 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 AUDIO_STREAM_POLYPHONIC_H
+#define AUDIO_STREAM_POLYPHONIC_H
+
+#include "core/templates/local_vector.h"
+#include "servers/audio/audio_stream.h"
+
+class AudioStreamPolyphonic : public AudioStream {
+ GDCLASS(AudioStreamPolyphonic, AudioStream)
+ int polyphony = 32;
+
+ static void _bind_methods();
+
+public:
+ virtual Ref<AudioStreamPlayback> instantiate_playback() override;
+ virtual String get_stream_name() const override;
+ virtual bool is_monophonic() const override;
+
+ void set_polyphony(int p_voices);
+ int get_polyphony() const;
+
+ AudioStreamPolyphonic();
+};
+
+class AudioStreamPlaybackPolyphonic : public AudioStreamPlayback {
+ GDCLASS(AudioStreamPlaybackPolyphonic, AudioStreamPlayback)
+
+ enum {
+ INTERNAL_BUFFER_LEN = 128,
+ ID_MASK = 0xFFFFFFFF,
+ INDEX_SHIFT = 32
+ };
+ struct Stream {
+ SafeFlag active;
+ SafeFlag pending_play;
+ SafeFlag finish_request;
+ float play_offset = 0;
+ float pitch_scale = 1.0;
+ Ref<AudioStream> stream;
+ Ref<AudioStreamPlayback> stream_playback;
+ float prev_volume_db = 0;
+ float volume_db = 0;
+ uint32_t id = 0;
+
+ Stream() :
+ active(false), pending_play(false), finish_request(false) {}
+ };
+
+ LocalVector<Stream> streams;
+ AudioFrame internal_buffer[INTERNAL_BUFFER_LEN];
+
+ bool active = false;
+ uint32_t id_counter = 1;
+
+ _FORCE_INLINE_ Stream *_find_stream(int64_t p_id);
+
+ friend class AudioStreamPolyphonic;
+
+protected:
+ static void _bind_methods();
+
+public:
+ typedef int64_t ID;
+ enum {
+ INVALID_ID = -1
+ };
+
+ virtual void start(double p_from_pos = 0.0) override;
+ virtual void stop() override;
+ virtual bool is_playing() const override;
+
+ virtual int get_loop_count() const override; //times it looped
+
+ virtual double get_playback_position() const override;
+ virtual void seek(double p_time) override;
+
+ virtual void tag_used_streams() override;
+
+ virtual int mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) override;
+
+ ID play_stream(const Ref<AudioStream> &p_stream, float p_from_offset = 0, float p_volume_db = 0, float p_pitch_scale = 1.0);
+ void set_stream_volume(ID p_stream_id, float p_volume_db);
+ void set_stream_pitch_scale(ID p_stream_id, float p_pitch_scale);
+ bool is_stream_playing(ID p_stream_id) const;
+ void stop_stream(ID p_stream_id);
+
+ AudioStreamPlaybackPolyphonic();
+};
+
+#endif // AUDIO_STREAM_POLYPHONIC_H
diff --git a/scene/resources/camera_attributes.cpp b/scene/resources/camera_attributes.cpp
index b5e302cce5..61df56523d 100644
--- a/scene/resources/camera_attributes.cpp
+++ b/scene/resources/camera_attributes.cpp
@@ -286,10 +286,10 @@ void CameraAttributesPractical::_bind_methods() {
ADD_GROUP("DOF Blur", "dof_blur_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dof_blur_far_enabled"), "set_dof_blur_far_enabled", "is_dof_blur_far_enabled");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_far_distance", PROPERTY_HINT_RANGE, "0.01,8192,0.01,exp,suffix:m"), "set_dof_blur_far_distance", "get_dof_blur_far_distance");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_far_transition", PROPERTY_HINT_RANGE, "0.01,8192,0.01,exp"), "set_dof_blur_far_transition", "get_dof_blur_far_transition");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_far_transition", PROPERTY_HINT_RANGE, "-1,8192,0.01,exp"), "set_dof_blur_far_transition", "get_dof_blur_far_transition");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dof_blur_near_enabled"), "set_dof_blur_near_enabled", "is_dof_blur_near_enabled");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_near_distance", PROPERTY_HINT_RANGE, "0.01,8192,0.01,exp,suffix:m"), "set_dof_blur_near_distance", "get_dof_blur_near_distance");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_near_transition", PROPERTY_HINT_RANGE, "0.01,8192,0.01,exp"), "set_dof_blur_near_transition", "get_dof_blur_near_transition");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_near_transition", PROPERTY_HINT_RANGE, "-1,8192,0.01,exp"), "set_dof_blur_near_transition", "get_dof_blur_near_transition");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_dof_blur_amount", "get_dof_blur_amount");
ADD_GROUP("Auto Exposure", "auto_exposure_");
diff --git a/scene/resources/convex_polygon_shape_2d.cpp b/scene/resources/convex_polygon_shape_2d.cpp
index d92d4fa4a4..e51b48a4b1 100644
--- a/scene/resources/convex_polygon_shape_2d.cpp
+++ b/scene/resources/convex_polygon_shape_2d.cpp
@@ -82,7 +82,7 @@ void ConvexPolygonShape2D::draw(const RID &p_to_rid, const Color &p_color) {
if (is_collision_outline_enabled()) {
RenderingServer::get_singleton()->canvas_item_add_polyline(p_to_rid, points, col);
// Draw the last segment as it's not drawn by `canvas_item_add_polyline()`.
- RenderingServer::get_singleton()->canvas_item_add_line(p_to_rid, points[points.size() - 1], points[0], p_color, 1.0, true);
+ RenderingServer::get_singleton()->canvas_item_add_line(p_to_rid, points[points.size() - 1], points[0], p_color, 1.0);
}
}
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 4d3eec6333..7a865691d9 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -53,7 +53,7 @@ static const int default_corner_radius = 3;
static Ref<StyleBoxFlat> make_flat_stylebox(Color p_color, float p_margin_left = default_margin, float p_margin_top = default_margin, float p_margin_right = default_margin, float p_margin_bottom = default_margin, int p_corner_radius = default_corner_radius, bool p_draw_center = true, int p_border_width = 0) {
Ref<StyleBoxFlat> style(memnew(StyleBoxFlat));
style->set_bg_color(p_color);
- style->set_default_margin_individual(p_margin_left * scale, p_margin_top * scale, p_margin_right * scale, p_margin_bottom * scale);
+ style->set_content_margin_individual(p_margin_left * scale, p_margin_top * scale, p_margin_right * scale, p_margin_bottom * scale);
style->set_corner_radius_all(p_corner_radius);
style->set_anti_aliased(true);
@@ -67,10 +67,10 @@ static Ref<StyleBoxFlat> make_flat_stylebox(Color p_color, float p_margin_left =
}
static Ref<StyleBoxFlat> sb_expand(Ref<StyleBoxFlat> p_sbox, float p_left, float p_top, float p_right, float p_bottom) {
- p_sbox->set_expand_margin_size(SIDE_LEFT, p_left * scale);
- p_sbox->set_expand_margin_size(SIDE_TOP, p_top * scale);
- p_sbox->set_expand_margin_size(SIDE_RIGHT, p_right * scale);
- p_sbox->set_expand_margin_size(SIDE_BOTTOM, p_bottom * scale);
+ p_sbox->set_expand_margin(SIDE_LEFT, p_left * scale);
+ p_sbox->set_expand_margin(SIDE_TOP, p_top * scale);
+ p_sbox->set_expand_margin(SIDE_RIGHT, p_right * scale);
+ p_sbox->set_expand_margin(SIDE_BOTTOM, p_bottom * scale);
return p_sbox;
}
@@ -93,7 +93,7 @@ static Ref<ImageTexture> generate_icon(int p_index) {
static Ref<StyleBox> make_empty_stylebox(float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_bottom = -1) {
Ref<StyleBox> style(memnew(StyleBoxEmpty));
- style->set_default_margin_individual(p_margin_left * scale, p_margin_top * scale, p_margin_right * scale, p_margin_bottom * scale);
+ style->set_content_margin_individual(p_margin_left * scale, p_margin_top * scale, p_margin_right * scale, p_margin_bottom * scale);
return style;
}
@@ -148,7 +148,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
const Ref<StyleBoxFlat> button_disabled = make_flat_stylebox(style_disabled_color);
Ref<StyleBoxFlat> focus = make_flat_stylebox(style_focus_color, default_margin, default_margin, default_margin, default_margin, default_corner_radius, false, 2);
// Make the focus outline appear to be flush with the buttons it's focusing.
- focus->set_expand_margin_size_all(2 * scale);
+ focus->set_expand_margin_all(2 * scale);
theme->set_stylebox("normal", "Button", button_normal);
theme->set_stylebox("hover", "Button", button_hover);
@@ -279,9 +279,9 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
// CheckBox
Ref<StyleBox> cbx_empty = memnew(StyleBoxEmpty);
- cbx_empty->set_default_margin_all(4 * scale);
+ cbx_empty->set_content_margin_all(4 * scale);
Ref<StyleBox> cbx_focus = focus;
- cbx_focus->set_default_margin_all(4 * scale);
+ cbx_focus->set_content_margin_all(4 * scale);
theme->set_stylebox("normal", "CheckBox", cbx_empty);
theme->set_stylebox("pressed", "CheckBox", cbx_empty);
@@ -317,7 +317,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
// CheckButton
Ref<StyleBox> cb_empty = memnew(StyleBoxEmpty);
- cb_empty->set_default_margin_individual(6 * scale, 4 * scale, 6 * scale, 4 * scale);
+ cb_empty->set_content_margin_individual(6 * scale, 4 * scale, 6 * scale, 4 * scale);
theme->set_stylebox("normal", "CheckButton", cb_empty);
theme->set_stylebox("pressed", "CheckButton", cb_empty);
@@ -634,10 +634,10 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
Ref<StyleBoxLine> separator_horizontal = memnew(StyleBoxLine);
separator_horizontal->set_thickness(Math::round(scale));
separator_horizontal->set_color(style_separator_color);
- separator_horizontal->set_default_margin_individual(default_margin, 0, default_margin, 0);
+ separator_horizontal->set_content_margin_individual(default_margin, 0, default_margin, 0);
Ref<StyleBoxLine> separator_vertical = separator_horizontal->duplicate();
separator_vertical->set_vertical(true);
- separator_vertical->set_default_margin_individual(0, default_margin, 0, default_margin);
+ separator_vertical->set_content_margin_individual(0, default_margin, 0, default_margin);
// Always display a border for PopupMenus so they can be distinguished from their background.
Ref<StyleBoxFlat> style_popup_panel = make_flat_stylebox(style_popup_color);
diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp
index 746f2f8f9b..8b4656414d 100644
--- a/scene/resources/environment.cpp
+++ b/scene/resources/environment.cpp
@@ -1043,6 +1043,18 @@ void Environment::_validate_property(PropertyInfo &p_property) const {
}
}
+ if (p_property.name == "ambient_light_color" || p_property.name == "ambient_light_energy") {
+ if (ambient_source == AMBIENT_SOURCE_DISABLED) {
+ p_property.usage = PROPERTY_USAGE_NO_EDITOR;
+ }
+ }
+
+ if (p_property.name == "ambient_light_sky_contribution") {
+ if (ambient_source == AMBIENT_SOURCE_DISABLED || ambient_source == AMBIENT_SOURCE_COLOR) {
+ p_property.usage = PROPERTY_USAGE_NO_EDITOR;
+ }
+ }
+
if (p_property.name == "fog_aerial_perspective") {
if (bg_mode != BG_SKY) {
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp
index deee187e8e..e5a1adff20 100644
--- a/scene/resources/font.cpp
+++ b/scene/resources/font.cpp
@@ -2868,6 +2868,12 @@ void SystemFont::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_multichannel_signed_distance_field", "msdf"), &SystemFont::set_multichannel_signed_distance_field);
ClassDB::bind_method(D_METHOD("is_multichannel_signed_distance_field"), &SystemFont::is_multichannel_signed_distance_field);
+ ClassDB::bind_method(D_METHOD("set_msdf_pixel_range", "msdf_pixel_range"), &SystemFont::set_msdf_pixel_range);
+ ClassDB::bind_method(D_METHOD("get_msdf_pixel_range"), &SystemFont::get_msdf_pixel_range);
+
+ ClassDB::bind_method(D_METHOD("set_msdf_size", "msdf_size"), &SystemFont::set_msdf_size);
+ ClassDB::bind_method(D_METHOD("get_msdf_size"), &SystemFont::get_msdf_size);
+
ClassDB::bind_method(D_METHOD("set_oversampling", "oversampling"), &SystemFont::set_oversampling);
ClassDB::bind_method(D_METHOD("get_oversampling"), &SystemFont::get_oversampling);
@@ -2890,6 +2896,8 @@ void SystemFont::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal"), "set_hinting", "get_hinting");
ADD_PROPERTY(PropertyInfo(Variant::INT, "subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One Half of a Pixel,One Quarter of a Pixel"), "set_subpixel_positioning", "get_subpixel_positioning");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "multichannel_signed_distance_field"), "set_multichannel_signed_distance_field", "is_multichannel_signed_distance_field");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "msdf_pixel_range"), "set_msdf_pixel_range", "get_msdf_pixel_range");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "msdf_size"), "set_msdf_size", "get_msdf_size");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_RANGE, "0,10,0.1"), "set_oversampling", "get_oversampling");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "fallbacks", PROPERTY_HINT_ARRAY_TYPE, MAKE_RESOURCE_TYPE_HINT("Font")), "set_fallbacks", "get_fallbacks");
}
@@ -2987,6 +2995,8 @@ void SystemFont::_update_base_font() {
file->set_hinting(hinting);
file->set_subpixel_positioning(subpixel_positioning);
file->set_multichannel_signed_distance_field(msdf);
+ file->set_msdf_pixel_range(msdf_pixel_range);
+ file->set_msdf_size(msdf_size);
file->set_oversampling(oversampling);
base_font = file;
@@ -3186,6 +3196,34 @@ bool SystemFont::is_multichannel_signed_distance_field() const {
return msdf;
}
+void SystemFont::set_msdf_pixel_range(int p_msdf_pixel_range) {
+ if (msdf_pixel_range != p_msdf_pixel_range) {
+ msdf_pixel_range = p_msdf_pixel_range;
+ if (base_font.is_valid()) {
+ base_font->set_msdf_pixel_range(msdf_pixel_range);
+ }
+ emit_changed();
+ }
+}
+
+int SystemFont::get_msdf_pixel_range() const {
+ return msdf_pixel_range;
+}
+
+void SystemFont::set_msdf_size(int p_msdf_size) {
+ if (msdf_size != p_msdf_size) {
+ msdf_size = p_msdf_size;
+ if (base_font.is_valid()) {
+ base_font->set_msdf_size(msdf_size);
+ }
+ emit_changed();
+ }
+}
+
+int SystemFont::get_msdf_size() const {
+ return msdf_size;
+}
+
void SystemFont::set_oversampling(real_t p_oversampling) {
if (oversampling != p_oversampling) {
oversampling = p_oversampling;
diff --git a/scene/resources/font.h b/scene/resources/font.h
index 4d468a8841..ef79f8bd02 100644
--- a/scene/resources/font.h
+++ b/scene/resources/font.h
@@ -452,6 +452,8 @@ class SystemFont : public Font {
TextServer::SubpixelPositioning subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_AUTO;
real_t oversampling = 0.f;
bool msdf = false;
+ int msdf_pixel_range = 16;
+ int msdf_size = 48;
protected:
static void _bind_methods();
@@ -488,6 +490,12 @@ public:
virtual void set_multichannel_signed_distance_field(bool p_msdf);
virtual bool is_multichannel_signed_distance_field() const;
+ virtual void set_msdf_pixel_range(int p_msdf_pixel_range);
+ virtual int get_msdf_pixel_range() const;
+
+ virtual void set_msdf_size(int p_msdf_size);
+ virtual int get_msdf_size() const;
+
virtual void set_font_names(const PackedStringArray &p_names);
virtual PackedStringArray get_font_names() const;
diff --git a/scene/resources/immediate_mesh.cpp b/scene/resources/immediate_mesh.cpp
index 247927163b..48d609da97 100644
--- a/scene/resources/immediate_mesh.cpp
+++ b/scene/resources/immediate_mesh.cpp
@@ -41,8 +41,8 @@ void ImmediateMesh::surface_set_color(const Color &p_color) {
if (!uses_colors) {
colors.resize(vertices.size());
- for (uint32_t i = 0; i < colors.size(); i++) {
- colors[i] = p_color;
+ for (Color &color : colors) {
+ color = p_color;
}
uses_colors = true;
}
@@ -54,8 +54,8 @@ void ImmediateMesh::surface_set_normal(const Vector3 &p_normal) {
if (!uses_normals) {
normals.resize(vertices.size());
- for (uint32_t i = 0; i < normals.size(); i++) {
- normals[i] = p_normal;
+ for (Vector3 &normal : normals) {
+ normal = p_normal;
}
uses_normals = true;
}
@@ -66,8 +66,8 @@ void ImmediateMesh::surface_set_tangent(const Plane &p_tangent) {
ERR_FAIL_COND_MSG(!surface_active, "Not creating any surface. Use surface_begin() to do it.");
if (!uses_tangents) {
tangents.resize(vertices.size());
- for (uint32_t i = 0; i < tangents.size(); i++) {
- tangents[i] = p_tangent;
+ for (Plane &tangent : tangents) {
+ tangent = p_tangent;
}
uses_tangents = true;
}
@@ -78,8 +78,8 @@ void ImmediateMesh::surface_set_uv(const Vector2 &p_uv) {
ERR_FAIL_COND_MSG(!surface_active, "Not creating any surface. Use surface_begin() to do it.");
if (!uses_uvs) {
uvs.resize(vertices.size());
- for (uint32_t i = 0; i < uvs.size(); i++) {
- uvs[i] = p_uv;
+ for (Vector2 &uv : uvs) {
+ uv = p_uv;
}
uses_uvs = true;
}
@@ -90,8 +90,8 @@ void ImmediateMesh::surface_set_uv2(const Vector2 &p_uv2) {
ERR_FAIL_COND_MSG(!surface_active, "Not creating any surface. Use surface_begin() to do it.");
if (!uses_uv2s) {
uv2s.resize(vertices.size());
- for (uint32_t i = 0; i < uv2s.size(); i++) {
- uv2s[i] = p_uv2;
+ for (Vector2 &uv : uv2s) {
+ uv = p_uv2;
}
uses_uv2s = true;
}
@@ -194,25 +194,20 @@ void ImmediateMesh::surface_end() {
if (uses_normals) {
uint32_t *normal = (uint32_t *)&surface_vertex_ptr[i * vertex_stride + normal_offset];
- Vector3 n = normals[i] * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5);
+ Vector2 n = normals[i].octahedron_encode();
uint32_t value = 0;
- value |= CLAMP(int(n.x * 1023.0), 0, 1023);
- value |= CLAMP(int(n.y * 1023.0), 0, 1023) << 10;
- value |= CLAMP(int(n.z * 1023.0), 0, 1023) << 20;
+ value |= (uint16_t)CLAMP(n.x * 65535, 0, 65535);
+ value |= (uint16_t)CLAMP(n.y * 65535, 0, 65535) << 16;
*normal = value;
}
if (uses_tangents) {
uint32_t *tangent = (uint32_t *)&surface_vertex_ptr[i * vertex_stride + tangent_offset];
- Plane t = tangents[i];
+ Vector2 t = tangents[i].normal.octahedron_tangent_encode(tangents[i].d);
uint32_t value = 0;
- value |= CLAMP(int((t.normal.x * 0.5 + 0.5) * 1023.0), 0, 1023);
- value |= CLAMP(int((t.normal.y * 0.5 + 0.5) * 1023.0), 0, 1023) << 10;
- value |= CLAMP(int((t.normal.z * 0.5 + 0.5) * 1023.0), 0, 1023) << 20;
- if (t.d > 0) {
- value |= 3UL << 30;
- }
+ value |= (uint16_t)CLAMP(t.x * 65535, 0, 65535);
+ value |= (uint16_t)CLAMP(t.y * 65535, 0, 65535) << 16;
*tangent = value;
}
diff --git a/scene/resources/importer_mesh.cpp b/scene/resources/importer_mesh.cpp
index eefa5aa14a..55b633a40c 100644
--- a/scene/resources/importer_mesh.cpp
+++ b/scene/resources/importer_mesh.cpp
@@ -364,9 +364,7 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, float p_normal_spli
const LocalVector<Pair<int, int>> &close_verts = E->value;
bool found = false;
- for (unsigned int k = 0; k < close_verts.size(); k++) {
- const Pair<int, int> &idx = close_verts[k];
-
+ for (const Pair<int, int> &idx : close_verts) {
bool is_uvs_close = (!uvs_ptr || uvs_ptr[j].distance_squared_to(uvs_ptr[idx.second]) < CMP_EPSILON2);
bool is_uv2s_close = (!uv2s_ptr || uv2s_ptr[j].distance_squared_to(uv2s_ptr[idx.second]) < CMP_EPSILON2);
ERR_FAIL_INDEX(idx.second, normals.size());
@@ -599,8 +597,7 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, float p_normal_spli
const LocalVector<int> &corners = vertex_corners[j];
const Vector3 &vertex_normal = normals_ptr[j];
- for (unsigned int k = 0; k < corners.size(); k++) {
- const int &corner_idx = corners[k];
+ for (const int &corner_idx : corners) {
const Vector3 &ray_normal = ray_normals[corner_idx];
if (ray_normal.length_squared() < CMP_EPSILON2) {
@@ -635,8 +632,8 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, float p_normal_spli
split_vertex_indices.push_back(j);
split_vertex_normals.push_back(n);
int new_idx = split_vertex_count++;
- for (unsigned int l = 0; l < group_indices.size(); l++) {
- new_indices_ptr[group_indices[l]] = new_idx;
+ for (const int &index : group_indices) {
+ new_indices_ptr[index] = new_idx;
}
}
}
@@ -1241,10 +1238,10 @@ Error ImporterMesh::lightmap_unwrap_cached(const Transform3D &p_base_transform,
}
//generate surfaces
- for (unsigned int i = 0; i < surfaces_tools.size(); i++) {
- surfaces_tools[i]->index();
- Array arrays = surfaces_tools[i]->commit_to_arrays();
- add_surface(surfaces_tools[i]->get_primitive_type(), arrays, Array(), Dictionary(), surfaces_tools[i]->get_material(), surfaces_tools[i]->get_meta("name"));
+ for (Ref<SurfaceTool> &tool : surfaces_tools) {
+ tool->index();
+ Array arrays = tool->commit_to_arrays();
+ add_surface(tool->get_primitive_type(), arrays, Array(), Dictionary(), tool->get_material(), tool->get_meta("name"));
}
set_lightmap_size_hint(Size2(size_x, size_y));
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index d5c3f7730b..f4aa0637f7 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -113,6 +113,12 @@ bool Material::_can_use_render_priority() const {
return ret;
}
+Ref<Resource> Material::create_placeholder() const {
+ Ref<PlaceholderMaterial> placeholder;
+ placeholder.instantiate();
+ return placeholder;
+}
+
void Material::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_next_pass", "next_pass"), &Material::set_next_pass);
ClassDB::bind_method(D_METHOD("get_next_pass"), &Material::get_next_pass);
@@ -123,6 +129,8 @@ void Material::_bind_methods() {
ClassDB::bind_method(D_METHOD("inspect_native_shader_code"), &Material::inspect_native_shader_code);
ClassDB::set_method_flags(get_class_static(), _scs_create("inspect_native_shader_code"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
+ ClassDB::bind_method(D_METHOD("create_placeholder"), &Material::create_placeholder);
+
ADD_PROPERTY(PropertyInfo(Variant::INT, "render_priority", PROPERTY_HINT_RANGE, itos(RENDER_PRIORITY_MIN) + "," + itos(RENDER_PRIORITY_MAX) + ",1"), "set_render_priority", "get_render_priority");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "next_pass", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_next_pass", "get_next_pass");
@@ -149,11 +157,36 @@ Material::~Material() {
bool ShaderMaterial::_set(const StringName &p_name, const Variant &p_value) {
if (shader.is_valid()) {
- StringName pr = shader->remap_parameter(p_name);
- if (pr) {
- set_shader_parameter(pr, p_value);
+ const StringName *sn = remap_cache.getptr(p_name);
+ if (sn) {
+ set_shader_parameter(*sn, p_value);
+ return true;
+ }
+ String s = p_name;
+ if (s.begins_with("shader_parameter/")) {
+ String param = s.replace_first("shader_parameter/", "");
+ remap_cache[s] = param;
+ set_shader_parameter(param, p_value);
return true;
}
+#ifndef DISABLE_DEPRECATED
+ // Compatibility remaps are only needed here.
+ if (s.begins_with("param/")) {
+ s = s.replace_first("param/", "shader_parameter/");
+ } else if (s.begins_with("shader_param/")) {
+ s = s.replace_first("shader_param/", "shader_parameter/");
+ } else if (s.begins_with("shader_uniform/")) {
+ s = s.replace_first("shader_uniform/", "shader_parameter/");
+ } else {
+ return false; // Not a shader parameter.
+ }
+
+ WARN_PRINT("This material (containing shader with path: '" + shader->get_path() + "') uses an old deprecated parameter names. Consider re-saving this resource (or scene which contains it) in order for it to continue working in future versions.");
+ String param = s.replace_first("shader_parameter/", "");
+ remap_cache[s] = param;
+ set_shader_parameter(param, p_value);
+ return true;
+#endif
}
return false;
@@ -161,9 +194,10 @@ bool ShaderMaterial::_set(const StringName &p_name, const Variant &p_value) {
bool ShaderMaterial::_get(const StringName &p_name, Variant &r_ret) const {
if (shader.is_valid()) {
- StringName pr = shader->remap_parameter(p_name);
- if (pr) {
- r_ret = get_shader_parameter(pr);
+ const StringName *sn = remap_cache.getptr(p_name);
+ if (sn) {
+ // Only return a parameter if it was previously set.
+ r_ret = get_shader_parameter(*sn);
return true;
}
}
@@ -247,6 +281,12 @@ void ShaderMaterial::_get_property_list(List<PropertyInfo> *p_list) const {
PropertyInfo info = E->get();
info.name = "shader_parameter/" + info.name;
+ if (!param_cache.has(E->get().name)) {
+ // Property has never been edited, retrieve with default value.
+ Variant default_value = RenderingServer::get_singleton()->shader_get_parameter_default(shader->get_rid(), E->get().name);
+ param_cache.insert(E->get().name, default_value);
+ remap_cache.insert(info.name, E->get().name);
+ }
groups[last_group][last_subgroup].push_back(info);
}
@@ -275,11 +315,10 @@ void ShaderMaterial::_get_property_list(List<PropertyInfo> *p_list) const {
bool ShaderMaterial::_property_can_revert(const StringName &p_name) const {
if (shader.is_valid()) {
- StringName pr = shader->remap_parameter(p_name);
+ const StringName *pr = remap_cache.getptr(p_name);
if (pr) {
- Variant default_value = RenderingServer::get_singleton()->shader_get_parameter_default(shader->get_rid(), pr);
- Variant current_value;
- _get(p_name, current_value);
+ Variant default_value = RenderingServer::get_singleton()->shader_get_parameter_default(shader->get_rid(), *pr);
+ Variant current_value = get_shader_parameter(*pr);
return default_value.get_type() != Variant::NIL && default_value != current_value;
}
}
@@ -288,9 +327,9 @@ bool ShaderMaterial::_property_can_revert(const StringName &p_name) const {
bool ShaderMaterial::_property_get_revert(const StringName &p_name, Variant &r_property) const {
if (shader.is_valid()) {
- StringName pr = shader->remap_parameter(p_name);
- if (pr) {
- r_property = RenderingServer::get_singleton()->shader_get_parameter_default(shader->get_rid(), pr);
+ const StringName *pr = remap_cache.getptr(p_name);
+ if (*pr) {
+ r_property = RenderingServer::get_singleton()->shader_get_parameter_default(shader->get_rid(), *pr);
return true;
}
}
@@ -791,6 +830,14 @@ void BaseMaterial3D::_update_shader() {
code += "uniform vec4 refraction_texture_channel;\n";
}
+ if (features[FEATURE_REFRACTION]) {
+ code += "uniform sampler2D screen_texture : hint_screen_texture, repeat_disable, filter_linear_mipmap;";
+ }
+
+ if (proximity_fade_enabled) {
+ code += "uniform sampler2D depth_texture : hint_depth_texture, repeat_disable, filter_nearest;";
+ }
+
if (features[FEATURE_NORMAL_MAPPING]) {
code += "uniform sampler2D texture_normal : hint_roughness_normal," + texfilter_str + ";\n";
code += "uniform float normal_scale : hint_range(-16,16);\n";
@@ -1228,7 +1275,7 @@ void BaseMaterial3D::_update_shader() {
code += " vec2 ref_ofs = SCREEN_UV - ref_normal.xy * dot(texture(texture_refraction,base_uv),refraction_texture_channel) * refraction;\n";
}
code += " float ref_amount = 1.0 - albedo.a * albedo_tex.a;\n";
- code += " EMISSION += textureLod(SCREEN_TEXTURE,ref_ofs,ROUGHNESS * 8.0).rgb * ref_amount;\n";
+ code += " EMISSION += textureLod(screen_texture,ref_ofs,ROUGHNESS * 8.0).rgb * ref_amount;\n";
code += " ALBEDO *= 1.0 - ref_amount;\n";
code += " ALPHA = 1.0;\n";
@@ -1246,7 +1293,7 @@ void BaseMaterial3D::_update_shader() {
}
if (proximity_fade_enabled) {
- code += " float depth_tex = textureLod(DEPTH_TEXTURE,SCREEN_UV,0.0).r;\n";
+ code += " float depth_tex = textureLod(depth_texture,SCREEN_UV,0.0).r;\n";
code += " vec4 world_pos = INV_PROJECTION_MATRIX * vec4(SCREEN_UV*2.0-1.0,depth_tex,1.0);\n";
code += " world_pos.xyz/=world_pos.w;\n";
code += " ALPHA*=clamp(1.0-smoothstep(world_pos.z+proximity_fade_distance,world_pos.z,VERTEX.z),0.0,1.0);\n";
diff --git a/scene/resources/material.h b/scene/resources/material.h
index f1777d31f4..fe1448cd4c 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -74,6 +74,9 @@ public:
virtual RID get_rid() const override;
virtual RID get_shader_rid() const;
virtual Shader::Mode get_shader_mode() const;
+
+ virtual Ref<Resource> create_placeholder() const;
+
Material();
virtual ~Material();
};
@@ -82,7 +85,8 @@ class ShaderMaterial : public Material {
GDCLASS(ShaderMaterial, Material);
Ref<Shader> shader;
- HashMap<StringName, Variant> param_cache;
+ mutable HashMap<StringName, StringName> remap_cache;
+ mutable HashMap<StringName, Variant> param_cache;
protected:
bool _set(const StringName &p_name, const Variant &p_value);
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index 5e18b5df37..cf9baa2907 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -189,6 +189,7 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const {
if (primitive == PRIMITIVE_TRIANGLES) {
for (int j = 0; j < ic; j++) {
int index = ir[j];
+ ERR_FAIL_COND_V(index >= vc, Ref<TriangleMesh>());
facesw[widx++] = vr[index];
}
} else { // PRIMITIVE_TRIANGLE_STRIP
@@ -614,6 +615,13 @@ Size2i Mesh::get_lightmap_size_hint() const {
return lightmap_size_hint;
}
+Ref<Resource> Mesh::create_placeholder() const {
+ Ref<PlaceholderMesh> placeholder;
+ placeholder.instantiate();
+ placeholder->set_aabb(get_aabb());
+ return placeholder;
+}
+
void Mesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_lightmap_size_hint", "size"), &Mesh::set_lightmap_size_hint);
ClassDB::bind_method(D_METHOD("get_lightmap_size_hint"), &Mesh::get_lightmap_size_hint);
@@ -626,6 +634,7 @@ void Mesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("surface_get_blend_shape_arrays", "surf_idx"), &Mesh::surface_get_blend_shape_arrays);
ClassDB::bind_method(D_METHOD("surface_set_material", "surf_idx", "material"), &Mesh::surface_set_material);
ClassDB::bind_method(D_METHOD("surface_get_material", "surf_idx"), &Mesh::surface_get_material);
+ ClassDB::bind_method(D_METHOD("create_placeholder"), &Mesh::create_placeholder);
BIND_ENUM_CONSTANT(PRIMITIVE_POINTS);
BIND_ENUM_CONSTANT(PRIMITIVE_LINES);
@@ -687,6 +696,7 @@ void Mesh::_bind_methods() {
BIND_BITFIELD_FLAG(ARRAY_FLAG_USE_2D_VERTICES);
BIND_BITFIELD_FLAG(ARRAY_FLAG_USE_DYNAMIC_UPDATE);
BIND_BITFIELD_FLAG(ARRAY_FLAG_USE_8_BONE_WEIGHTS);
+ BIND_BITFIELD_FLAG(ARRAY_FLAG_USES_EMPTY_VERTEX_ARRAY);
BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_NORMALIZED);
BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_RELATIVE);
@@ -1120,17 +1130,6 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
}
int idx = sname.substr(8, sl - 8).to_int();
- // This is a bit of a hack to ensure compatibility with older material
- // overrides that start indexing at 1.
- // We assume that idx 0 is always read first, if its not, this won't work.
- if (idx == 0) {
- surface_index_0 = true;
- }
- if (!surface_index_0) {
- // This means the file was created when the indexing started at 1, so decrease by one.
- idx--;
- }
-
String what = sname.get_slicec('/', 1);
if (what == "material") {
surface_set_material(idx, p_value);
@@ -1555,6 +1554,7 @@ void ArrayMesh::_recompute_aabb() {
// TODO: Need to add binding to add_surface using future MeshSurfaceData object.
void ArrayMesh::add_surface(BitField<ArrayFormat> p_format, PrimitiveType p_primitive, const Vector<uint8_t> &p_array, const Vector<uint8_t> &p_attribute_array, const Vector<uint8_t> &p_skin_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<uint8_t> &p_blend_shape_data, const Vector<AABB> &p_bone_aabbs, const Vector<RS::SurfaceData::LOD> &p_lods) {
+ ERR_FAIL_COND(surfaces.size() == RS::MAX_MESH_SURFACES);
_create_if_empty();
Surface s;
@@ -1590,6 +1590,7 @@ void ArrayMesh::add_surface(BitField<ArrayFormat> p_format, PrimitiveType p_prim
}
void ArrayMesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const TypedArray<Array> &p_blend_shapes, const Dictionary &p_lods, BitField<ArrayFormat> p_flags) {
+ ERR_FAIL_COND(p_blend_shapes.size() != blend_shapes.size());
ERR_FAIL_COND(p_arrays.size() != ARRAY_MAX);
RS::SurfaceData surface;
@@ -2058,7 +2059,7 @@ void ArrayMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_blend_shape_mode", "mode"), &ArrayMesh::set_blend_shape_mode);
ClassDB::bind_method(D_METHOD("get_blend_shape_mode"), &ArrayMesh::get_blend_shape_mode);
- ClassDB::bind_method(D_METHOD("add_surface_from_arrays", "primitive", "arrays", "blend_shapes", "lods", "compress_flags"), &ArrayMesh::add_surface_from_arrays, DEFVAL(Array()), DEFVAL(Dictionary()), DEFVAL(0));
+ ClassDB::bind_method(D_METHOD("add_surface_from_arrays", "primitive", "arrays", "blend_shapes", "lods", "flags"), &ArrayMesh::add_surface_from_arrays, DEFVAL(Array()), DEFVAL(Dictionary()), DEFVAL(0));
ClassDB::bind_method(D_METHOD("clear_surfaces"), &ArrayMesh::clear_surfaces);
ClassDB::bind_method(D_METHOD("surface_update_vertex_region", "surf_idx", "offset", "data"), &ArrayMesh::surface_update_vertex_region);
ClassDB::bind_method(D_METHOD("surface_update_attribute_region", "surf_idx", "offset", "data"), &ArrayMesh::surface_update_attribute_region);
diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h
index 1baa466312..1b870d996a 100644
--- a/scene/resources/mesh.h
+++ b/scene/resources/mesh.h
@@ -220,6 +220,8 @@ public:
virtual int get_builtin_bind_pose_count() const;
virtual Transform3D get_builtin_bind_pose(int p_index) const;
+ virtual Ref<Resource> create_placeholder() const;
+
Mesh();
};
diff --git a/scene/resources/mesh_library.cpp b/scene/resources/mesh_library.cpp
index d45b8a9295..015eb0fa45 100644
--- a/scene/resources/mesh_library.cpp
+++ b/scene/resources/mesh_library.cpp
@@ -139,7 +139,6 @@ void MeshLibrary::set_item_name(int p_item, const String &p_name) {
ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
item_map[p_item].name = p_name;
emit_changed();
- notify_property_list_changed();
}
void MeshLibrary::set_item_mesh(int p_item, const Ref<Mesh> &p_mesh) {
@@ -155,7 +154,6 @@ void MeshLibrary::set_item_mesh_transform(int p_item, const Transform3D &p_trans
item_map[p_item].mesh_transform = p_transform;
notify_change_to_owners();
emit_changed();
- notify_property_list_changed();
}
void MeshLibrary::set_item_shapes(int p_item, const Vector<ShapeData> &p_shapes) {
@@ -190,7 +188,6 @@ void MeshLibrary::set_item_navigation_layers(int p_item, uint32_t p_navigation_l
notify_property_list_changed();
notify_change_to_owners();
emit_changed();
- notify_property_list_changed();
}
void MeshLibrary::set_item_preview(int p_item, const Ref<Texture2D> &p_preview) {
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index 514e7eb260..e497a628aa 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -402,8 +402,7 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const {
}
}
- for (uint32_t i = 0; i < deferred_node_paths.size(); i++) {
- const DeferredNodePathProperties &dnp = deferred_node_paths[i];
+ for (const DeferredNodePathProperties &dnp : deferred_node_paths) {
Node *other = dnp.base->get_node_or_null(dnp.path);
dnp.base->set(dnp.property, other);
}
@@ -1047,6 +1046,25 @@ Ref<SceneState> SceneState::get_base_scene_state() const {
return Ref<SceneState>();
}
+void SceneState::update_instance_resource(String p_path, Ref<PackedScene> p_packed_scene) {
+ ERR_FAIL_COND(p_packed_scene.is_null());
+
+ for (const NodeData &nd : nodes) {
+ if (nd.instance >= 0) {
+ if (!(nd.instance & FLAG_INSTANCE_IS_PLACEHOLDER)) {
+ int instance_id = nd.instance & FLAG_MASK;
+ Ref<PackedScene> original_packed_scene = variants[instance_id];
+ if (original_packed_scene.is_valid()) {
+ if (original_packed_scene->get_path() == p_path) {
+ variants.remove_at(instance_id);
+ variants.insert(instance_id, p_packed_scene);
+ }
+ }
+ }
+ }
+ }
+}
+
int SceneState::find_node_by_path(const NodePath &p_node) const {
ERR_FAIL_COND_V_MSG(node_path_cache.size() == 0, -1, "This operation requires the node cache to have been built.");
diff --git a/scene/resources/packed_scene.h b/scene/resources/packed_scene.h
index ef7363dd44..5c53ffdb45 100644
--- a/scene/resources/packed_scene.h
+++ b/scene/resources/packed_scene.h
@@ -150,6 +150,8 @@ public:
Ref<SceneState> get_base_scene_state() const;
+ void update_instance_resource(String p_path, Ref<PackedScene> p_packed_scene);
+
//unbuild API
int get_node_count() const;
diff --git a/scene/resources/polygon_path_finder.cpp b/scene/resources/polygon_path_finder.cpp
index 85106883f9..3bbd0a0b5e 100644
--- a/scene/resources/polygon_path_finder.cpp
+++ b/scene/resources/polygon_path_finder.cpp
@@ -325,7 +325,7 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
}
const Point &np = points[least_cost_point];
- //open the neighbours for search
+ //open the neighbors for search
for (const int &E : np.connections) {
Point &p = points.write[E];
@@ -339,7 +339,7 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
p.distance = distance;
}
} else {
- //add to open neighbours
+ //add to open neighbors
p.prev = least_cost_point;
p.distance = distance;
diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp
index 5ef66a22b6..86ed0001dd 100644
--- a/scene/resources/primitive_meshes.cpp
+++ b/scene/resources/primitive_meshes.cpp
@@ -2901,7 +2901,7 @@ void TextMesh::_create_mesh_array(Array &p_arr) const {
TS->shaped_text_set_spacing(text_rid, TextServer::SpacingType(i), font->get_spacing(TextServer::SpacingType(i)));
}
- Array stt;
+ TypedArray<Vector3i> stt;
if (st_parser == TextServer::STRUCTURED_TEXT_CUSTOM) {
GDVIRTUAL_CALL(_structured_text_parser, st_args, txt, stt);
} else {
diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h
index 22cd12b004..e62f26b17c 100644
--- a/scene/resources/primitive_meshes.h
+++ b/scene/resources/primitive_meshes.h
@@ -622,7 +622,7 @@ protected:
virtual void _create_mesh_array(Array &p_arr) const override;
public:
- GDVIRTUAL2RC(Array, _structured_text_parser, Array, String)
+ GDVIRTUAL2RC(TypedArray<Vector3i>, _structured_text_parser, Array, String)
TextMesh();
~TextMesh();
diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp
index 80b9ff3f38..0ba177f882 100644
--- a/scene/resources/resource_format_text.cpp
+++ b/scene/resources/resource_format_text.cpp
@@ -49,10 +49,6 @@
///
-void ResourceLoaderText::set_local_path(const String &p_local_path) {
- res_path = p_local_path;
-}
-
Ref<Resource> ResourceLoaderText::get_resource() {
return resource;
}
@@ -927,7 +923,11 @@ Error ResourceLoaderText::rename_dependencies(Ref<FileAccess> p_f, const String
if (is_scene) {
fw->store_line("[gd_scene load_steps=" + itos(resources_total) + " format=" + itos(FORMAT_VERSION) + "]\n");
} else {
- fw->store_line("[gd_resource type=\"" + res_type + "\" load_steps=" + itos(resources_total) + " format=" + itos(FORMAT_VERSION) + "]\n");
+ String script_res_text;
+ if (!script_class.is_empty()) {
+ script_res_text = "script_class=\"" + script_class + "\" ";
+ }
+ fw->store_line("[gd_resource type=\"" + res_type + "\" " + script_res_text + "load_steps=" + itos(resources_total) + " format=" + itos(FORMAT_VERSION) + "]\n");
}
}
@@ -1051,6 +1051,10 @@ void ResourceLoaderText::open(Ref<FileAccess> p_f, bool p_skip_first_tag) {
return;
}
+ if (tag.fields.has("script_class")) {
+ script_class = tag.fields["script_class"];
+ }
+
res_type = tag.fields["type"];
} else {
@@ -1497,6 +1501,44 @@ Error ResourceLoaderText::get_classes_used(HashSet<StringName> *r_classes) {
return OK;
}
+String ResourceLoaderText::recognize_script_class(Ref<FileAccess> p_f) {
+ error = OK;
+
+ lines = 1;
+ f = p_f;
+
+ stream.f = f;
+
+ ignore_resource_parsing = true;
+
+ VariantParser::Tag tag;
+ Error err = VariantParser::parse_tag(&stream, lines, error_text, tag);
+
+ if (err) {
+ _printerr();
+ return "";
+ }
+
+ if (tag.fields.has("format")) {
+ int fmt = tag.fields["format"];
+ if (fmt > FORMAT_VERSION) {
+ error_text = "Saved with newer format version";
+ _printerr();
+ return "";
+ }
+ }
+
+ if (tag.name != "gd_resource") {
+ return "";
+ }
+
+ if (tag.fields.has("script_class")) {
+ return tag.fields["script_class"];
+ }
+
+ return "";
+}
+
String ResourceLoaderText::recognize(Ref<FileAccess> p_f) {
error = OK;
@@ -1666,6 +1708,25 @@ String ResourceFormatLoaderText::get_resource_type(const String &p_path) const {
return ClassDB::get_compatibility_remapped_class(r);
}
+String ResourceFormatLoaderText::get_resource_script_class(const String &p_path) const {
+ String ext = p_path.get_extension().to_lower();
+ if (ext != "tres") {
+ return String();
+ }
+
+ // ...for anything else must test...
+
+ Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ);
+ if (f.is_null()) {
+ return ""; //could not read
+ }
+
+ ResourceLoaderText loader;
+ loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path);
+ loader.res_path = loader.local_path;
+ return loader.recognize_script_class(f);
+}
+
ResourceUID::ID ResourceFormatLoaderText::get_resource_uid(const String &p_path) const {
String ext = p_path.get_extension().to_lower();
@@ -1846,6 +1907,9 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant,
List<Variant> keys;
d.get_key_list(&keys);
for (const Variant &E : keys) {
+ // Of course keys should also be cached, after all we can't prevent users from using resources as keys, right?
+ // See also ResourceFormatSaverBinaryInstance::_find_resources (when p_variant is of type Variant::DICTIONARY)
+ _find_resources(E);
Variant v = d[E];
_find_resources(v);
}
@@ -1906,7 +1970,12 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const Ref<Reso
String title = packed_scene.is_valid() ? "[gd_scene " : "[gd_resource ";
if (packed_scene.is_null()) {
title += "type=\"" + _resource_get_class(p_resource) + "\" ";
+ Ref<Script> script = p_resource->get_script();
+ if (script.is_valid() && script->get_global_name()) {
+ title += "script_class=\"" + String(script->get_global_name()) + "\" ";
+ }
}
+
int load_steps = saved_resources.size() + external_resources.size();
if (load_steps > 1) {
@@ -2245,7 +2314,12 @@ Error ResourceLoaderText::set_uid(Ref<FileAccess> p_f, ResourceUID::ID p_uid) {
if (is_scene) {
fw->store_string("[gd_scene load_steps=" + itos(resources_total) + " format=" + itos(FORMAT_VERSION) + " uid=\"" + ResourceUID::get_singleton()->id_to_text(p_uid) + "\"]");
} else {
- fw->store_string("[gd_resource type=\"" + res_type + "\" load_steps=" + itos(resources_total) + " format=" + itos(FORMAT_VERSION) + " uid=\"" + ResourceUID::get_singleton()->id_to_text(p_uid) + "\"]");
+ String script_res_text;
+ if (!script_class.is_empty()) {
+ script_res_text = "script_class=\"" + script_class + "\" ";
+ }
+
+ fw->store_string("[gd_resource type=\"" + res_type + "\" " + script_res_text + "load_steps=" + itos(resources_total) + " format=" + itos(FORMAT_VERSION) + " uid=\"" + ResourceUID::get_singleton()->id_to_text(p_uid) + "\"]");
}
uint8_t c = f->get_8();
diff --git a/scene/resources/resource_format_text.h b/scene/resources/resource_format_text.h
index 0f95e2fbfd..25001d8023 100644
--- a/scene/resources/resource_format_text.h
+++ b/scene/resources/resource_format_text.h
@@ -64,6 +64,7 @@ class ResourceLoaderText {
int resources_total = 0;
int resource_current = 0;
String resource_type;
+ String script_class;
VariantParser::Tag next_tag;
@@ -115,7 +116,6 @@ class ResourceLoaderText {
Ref<PackedScene> _parse_node_tag(VariantParser::ResourceParser &parser);
public:
- void set_local_path(const String &p_local_path);
Ref<Resource> get_resource();
Error load();
Error set_uid(Ref<FileAccess> p_f, ResourceUID::ID p_uid);
@@ -125,6 +125,7 @@ public:
void open(Ref<FileAccess> p_f, bool p_skip_first_tag = false);
String recognize(Ref<FileAccess> p_f);
+ String recognize_script_class(Ref<FileAccess> p_f);
ResourceUID::ID get_uid(Ref<FileAccess> p_f);
void get_dependencies(Ref<FileAccess> p_f, List<String> *p_dependencies, bool p_add_types);
Error rename_dependencies(Ref<FileAccess> p_f, const String &p_path, const HashMap<String, String> &p_map);
@@ -144,6 +145,7 @@ public:
virtual void get_classes_used(const String &p_path, HashSet<StringName> *r_classes);
virtual String get_resource_type(const String &p_path) const;
+ virtual String get_resource_script_class(const String &p_path) const;
virtual ResourceUID::ID get_resource_uid(const String &p_path) const;
virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false);
virtual Error rename_dependencies(const String &p_path, const HashMap<String, String> &p_map);
diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp
index 9bb2db17ab..a09dbd50cf 100644
--- a/scene/resources/shader.cpp
+++ b/scene/resources/shader.cpp
@@ -42,10 +42,12 @@ Shader::Mode Shader::get_mode() const {
}
void Shader::_dependency_changed() {
- RenderingServer::get_singleton()->shader_set_code(shader, RenderingServer::get_singleton()->shader_get_code(shader));
- params_cache_dirty = true;
+ // Preprocess and compile the code again because a dependency has changed. It also calls emit_changed() for us.
+ _recompile();
+}
- emit_changed();
+void Shader::_recompile() {
+ set_code(get_code());
}
void Shader::set_path(const String &p_path, bool p_take_over) {
@@ -93,7 +95,6 @@ void Shader::set_code(const String &p_code) {
}
RenderingServer::get_singleton()->shader_set_code(shader, pp_code);
- params_cache_dirty = true;
emit_changed();
}
@@ -108,8 +109,6 @@ void Shader::get_shader_uniform_list(List<PropertyInfo> *p_params, bool p_get_gr
List<PropertyInfo> local;
RenderingServer::get_singleton()->get_shader_parameter_list(shader, &local);
- params_cache.clear();
- params_cache_dirty = false;
for (PropertyInfo &pi : local) {
bool is_group = pi.usage == PROPERTY_USAGE_GROUP || pi.usage == PROPERTY_USAGE_SUBGROUP;
@@ -120,7 +119,6 @@ void Shader::get_shader_uniform_list(List<PropertyInfo> *p_params, bool p_get_gr
if (default_textures.has(pi.name)) { //do not show default textures
continue;
}
- params_cache[pi.name] = pi.name;
}
if (p_params) {
//small little hack
@@ -176,11 +174,17 @@ bool Shader::is_text_shader() const {
return true;
}
-bool Shader::has_parameter(const StringName &p_name) const {
- return params_cache.has(p_name);
+void Shader::_update_shader() const {
}
-void Shader::_update_shader() const {
+Array Shader::_get_shader_uniform_list(bool p_get_groups) {
+ List<PropertyInfo> uniform_list;
+ get_shader_uniform_list(&uniform_list, p_get_groups);
+ Array ret;
+ for (const PropertyInfo &pi : uniform_list) {
+ ret.push_back(pi.operator Dictionary());
+ }
+ return ret;
}
void Shader::_bind_methods() {
@@ -192,7 +196,7 @@ void Shader::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_default_texture_parameter", "name", "texture", "index"), &Shader::set_default_texture_parameter, DEFVAL(0));
ClassDB::bind_method(D_METHOD("get_default_texture_parameter", "name", "index"), &Shader::get_default_texture_parameter, DEFVAL(0));
- ClassDB::bind_method(D_METHOD("has_parameter", "name"), &Shader::has_parameter);
+ ClassDB::bind_method(D_METHOD("get_shader_uniform_list", "get_groups"), &Shader::_get_shader_uniform_list, DEFVAL(false));
ADD_PROPERTY(PropertyInfo(Variant::STRING, "code", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_code", "get_code");
diff --git a/scene/resources/shader.h b/scene/resources/shader.h
index e579c2fca1..55608b6c11 100644
--- a/scene/resources/shader.h
+++ b/scene/resources/shader.h
@@ -57,15 +57,13 @@ private:
HashSet<Ref<ShaderInclude>> include_dependencies;
String code;
- // hack the name of performance
- // shaders keep a list of ShaderMaterial -> RenderingServer name translations, to make
- // conversion fast and save memory.
- mutable bool params_cache_dirty = true;
- mutable HashMap<StringName, StringName> params_cache; //map a shader param to a material param..
HashMap<StringName, HashMap<int, Ref<Texture2D>>> default_textures;
void _dependency_changed();
+ void _recompile();
virtual void _update_shader() const; //used for visual shader
+ Array _get_shader_uniform_list(bool p_get_groups = false);
+
protected:
static void _bind_methods();
@@ -79,7 +77,6 @@ public:
String get_code() const;
void get_shader_uniform_list(List<PropertyInfo> *p_params, bool p_get_groups = false) const;
- bool has_parameter(const StringName &p_name) const;
void set_default_texture_parameter(const StringName &p_name, const Ref<Texture2D> &p_texture, int p_index = 0);
Ref<Texture2D> get_default_texture_parameter(const StringName &p_name, int p_index = 0) const;
@@ -87,47 +84,6 @@ public:
virtual bool is_text_shader() const;
- // Finds the shader parameter name for the given property name, which should start with "shader_parameter/".
- _FORCE_INLINE_ StringName remap_parameter(const StringName &p_property) const {
- if (params_cache_dirty) {
- get_shader_uniform_list(nullptr);
- }
-
- String n = p_property;
-
- // Backwards compatibility with old shader parameter names.
- // Note: The if statements are important to make sure we are only replacing text exactly at index 0.
- if (n.find("param/") == 0) {
- n = n.replace_first("param/", "shader_parameter/");
- }
- if (n.find("shader_param/") == 0) {
- n = n.replace_first("shader_param/", "shader_parameter/");
- }
- if (n.find("shader_uniform/") == 0) {
- n = n.replace_first("shader_uniform/", "shader_parameter/");
- }
-
- {
- // Additional backwards compatibility for projects between #62972 and #64092 (about a month of v4.0 development).
- // These projects did not have any prefix for shader uniforms due to a bug.
- // This code should be removed during beta or rc of 4.0.
- const HashMap<StringName, StringName>::Iterator E = params_cache.find(n);
- if (E) {
- return E->value;
- }
- }
-
- if (n.begins_with("shader_parameter/")) {
- n = n.replace_first("shader_parameter/", "");
- const HashMap<StringName, StringName>::Iterator E = params_cache.find(n);
- if (E) {
- return E->value;
- }
- }
-
- return StringName();
- }
-
virtual RID get_rid() const override;
Shader();
diff --git a/scene/resources/skeleton_modification_2d_stackholder.cpp b/scene/resources/skeleton_modification_2d_stackholder.cpp
index 121108965b..34d31bac8a 100644
--- a/scene/resources/skeleton_modification_2d_stackholder.cpp
+++ b/scene/resources/skeleton_modification_2d_stackholder.cpp
@@ -64,7 +64,7 @@ bool SkeletonModification2DStackHolder::_get(const StringName &p_path, Variant &
}
void SkeletonModification2DStackHolder::_get_property_list(List<PropertyInfo> *p_list) const {
- p_list->push_back(PropertyInfo(Variant::OBJECT, "held_modification_stack", PROPERTY_HINT_RESOURCE_TYPE, "SkeletonModificationStack2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "held_modification_stack", PROPERTY_HINT_RESOURCE_TYPE, "SkeletonModificationStack2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_ALWAYS_DUPLICATE));
#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint()) {
diff --git a/scene/resources/skeleton_modification_stack_2d.cpp b/scene/resources/skeleton_modification_stack_2d.cpp
index 4fa287e7b6..71ddbc0898 100644
--- a/scene/resources/skeleton_modification_stack_2d.cpp
+++ b/scene/resources/skeleton_modification_stack_2d.cpp
@@ -37,7 +37,7 @@ void SkeletonModificationStack2D::_get_property_list(List<PropertyInfo> *p_list)
PropertyInfo(Variant::OBJECT, "modifications/" + itos(i),
PROPERTY_HINT_RESOURCE_TYPE,
"SkeletonModification2D",
- PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DEFERRED_SET_RESOURCE | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE));
+ PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DEFERRED_SET_RESOURCE | PROPERTY_USAGE_ALWAYS_DUPLICATE));
}
}
diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp
index 6390850b24..fbbe98d022 100644
--- a/scene/resources/style_box.cpp
+++ b/scene/resources/style_box.cpp
@@ -34,76 +34,65 @@
#include <limits.h>
-float StyleBox::get_style_margin(Side p_side) const {
- float ret = 0;
- GDVIRTUAL_REQUIRED_CALL(_get_style_margin, p_side, ret);
- return ret;
-}
+Size2 StyleBox::get_minimum_size() const {
+ Size2 min_size = Size2(get_margin(SIDE_LEFT) + get_margin(SIDE_RIGHT), get_margin(SIDE_TOP) + get_margin(SIDE_BOTTOM));
+ Size2 custom_size;
+ GDVIRTUAL_CALL(_get_minimum_size, custom_size);
-bool StyleBox::test_mask(const Point2 &p_point, const Rect2 &p_rect) const {
- bool ret = true;
- GDVIRTUAL_CALL(_test_mask, p_point, p_rect, ret);
- return ret;
-}
+ if (min_size.x < custom_size.x) {
+ min_size.x = custom_size.x;
+ }
+ if (min_size.y < custom_size.y) {
+ min_size.y = custom_size.y;
+ }
-void StyleBox::draw(RID p_canvas_item, const Rect2 &p_rect) const {
- GDVIRTUAL_REQUIRED_CALL(_draw, p_canvas_item, p_rect);
+ return min_size;
}
-void StyleBox::set_default_margin(Side p_side, float p_value) {
+void StyleBox::set_content_margin(Side p_side, float p_value) {
ERR_FAIL_INDEX((int)p_side, 4);
- margin[p_side] = p_value;
+ content_margin[p_side] = p_value;
emit_changed();
}
-void StyleBox::set_default_margin_all(float p_value) {
+void StyleBox::set_content_margin_all(float p_value) {
for (int i = 0; i < 4; i++) {
- margin[i] = p_value;
+ content_margin[i] = p_value;
}
emit_changed();
}
-void StyleBox::set_default_margin_individual(float p_left, float p_top, float p_right, float p_bottom) {
- margin[SIDE_LEFT] = p_left;
- margin[SIDE_TOP] = p_top;
- margin[SIDE_RIGHT] = p_right;
- margin[SIDE_BOTTOM] = p_bottom;
+void StyleBox::set_content_margin_individual(float p_left, float p_top, float p_right, float p_bottom) {
+ content_margin[SIDE_LEFT] = p_left;
+ content_margin[SIDE_TOP] = p_top;
+ content_margin[SIDE_RIGHT] = p_right;
+ content_margin[SIDE_BOTTOM] = p_bottom;
emit_changed();
}
-float StyleBox::get_default_margin(Side p_side) const {
+float StyleBox::get_content_margin(Side p_side) const {
ERR_FAIL_INDEX_V((int)p_side, 4, 0.0);
- return margin[p_side];
+ return content_margin[p_side];
}
float StyleBox::get_margin(Side p_side) const {
ERR_FAIL_INDEX_V((int)p_side, 4, 0.0);
- if (margin[p_side] < 0) {
+ if (content_margin[p_side] < 0) {
return get_style_margin(p_side);
} else {
- return margin[p_side];
+ return content_margin[p_side];
}
}
-CanvasItem *StyleBox::get_current_item_drawn() const {
- return CanvasItem::get_current_item_drawn();
-}
-
-Size2 StyleBox::get_minimum_size() const {
- return Size2(get_margin(SIDE_LEFT) + get_margin(SIDE_RIGHT), get_margin(SIDE_TOP) + get_margin(SIDE_BOTTOM));
-}
-
Point2 StyleBox::get_offset() const {
return Point2(get_margin(SIDE_LEFT), get_margin(SIDE_TOP));
}
-Size2 StyleBox::get_center_size() const {
- Size2 ret;
- GDVIRTUAL_CALL(_get_center_size, ret);
- return ret;
+void StyleBox::draw(RID p_canvas_item, const Rect2 &p_rect) const {
+ GDVIRTUAL_REQUIRED_CALL(_draw, p_canvas_item, p_rect);
}
Rect2 StyleBox::get_draw_rect(const Rect2 &p_rect) const {
@@ -114,37 +103,46 @@ Rect2 StyleBox::get_draw_rect(const Rect2 &p_rect) const {
return p_rect;
}
+CanvasItem *StyleBox::get_current_item_drawn() const {
+ return CanvasItem::get_current_item_drawn();
+}
+
+bool StyleBox::test_mask(const Point2 &p_point, const Rect2 &p_rect) const {
+ bool ret = true;
+ GDVIRTUAL_CALL(_test_mask, p_point, p_rect, ret);
+ return ret;
+}
+
void StyleBox::_bind_methods() {
- ClassDB::bind_method(D_METHOD("test_mask", "point", "rect"), &StyleBox::test_mask);
+ ClassDB::bind_method(D_METHOD("get_minimum_size"), &StyleBox::get_minimum_size);
- ClassDB::bind_method(D_METHOD("set_default_margin", "margin", "offset"), &StyleBox::set_default_margin);
- ClassDB::bind_method(D_METHOD("set_default_margin_all", "offset"), &StyleBox::set_default_margin_all);
- ClassDB::bind_method(D_METHOD("get_default_margin", "margin"), &StyleBox::get_default_margin);
+ ClassDB::bind_method(D_METHOD("set_content_margin", "margin", "offset"), &StyleBox::set_content_margin);
+ ClassDB::bind_method(D_METHOD("set_content_margin_all", "offset"), &StyleBox::set_content_margin_all);
+ ClassDB::bind_method(D_METHOD("get_content_margin", "margin"), &StyleBox::get_content_margin);
ClassDB::bind_method(D_METHOD("get_margin", "margin"), &StyleBox::get_margin);
- ClassDB::bind_method(D_METHOD("get_minimum_size"), &StyleBox::get_minimum_size);
- ClassDB::bind_method(D_METHOD("get_center_size"), &StyleBox::get_center_size);
ClassDB::bind_method(D_METHOD("get_offset"), &StyleBox::get_offset);
- ClassDB::bind_method(D_METHOD("get_current_item_drawn"), &StyleBox::get_current_item_drawn);
ClassDB::bind_method(D_METHOD("draw", "canvas_item", "rect"), &StyleBox::draw);
+ ClassDB::bind_method(D_METHOD("get_current_item_drawn"), &StyleBox::get_current_item_drawn);
+
+ ClassDB::bind_method(D_METHOD("test_mask", "point", "rect"), &StyleBox::test_mask);
ADD_GROUP("Content Margins", "content_margin_");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "content_margin_left", PROPERTY_HINT_RANGE, "-1,2048,1,suffix:px"), "set_default_margin", "get_default_margin", SIDE_LEFT);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "content_margin_top", PROPERTY_HINT_RANGE, "-1,2048,1,suffix:px"), "set_default_margin", "get_default_margin", SIDE_TOP);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "content_margin_right", PROPERTY_HINT_RANGE, "-1,2048,1,suffix:px"), "set_default_margin", "get_default_margin", SIDE_RIGHT);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "content_margin_bottom", PROPERTY_HINT_RANGE, "-1,2048,1,suffix:px"), "set_default_margin", "get_default_margin", SIDE_BOTTOM);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "content_margin_left", PROPERTY_HINT_RANGE, "-1,2048,1,suffix:px"), "set_content_margin", "get_content_margin", SIDE_LEFT);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "content_margin_top", PROPERTY_HINT_RANGE, "-1,2048,1,suffix:px"), "set_content_margin", "get_content_margin", SIDE_TOP);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "content_margin_right", PROPERTY_HINT_RANGE, "-1,2048,1,suffix:px"), "set_content_margin", "get_content_margin", SIDE_RIGHT);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "content_margin_bottom", PROPERTY_HINT_RANGE, "-1,2048,1,suffix:px"), "set_content_margin", "get_content_margin", SIDE_BOTTOM);
- GDVIRTUAL_BIND(_get_style_margin, "side")
- GDVIRTUAL_BIND(_test_mask, "point", "rect")
- GDVIRTUAL_BIND(_get_center_size)
- GDVIRTUAL_BIND(_get_draw_rect, "rect")
GDVIRTUAL_BIND(_draw, "to_canvas_item", "rect")
+ GDVIRTUAL_BIND(_get_draw_rect, "rect")
+ GDVIRTUAL_BIND(_get_minimum_size)
+ GDVIRTUAL_BIND(_test_mask, "point", "rect")
}
StyleBox::StyleBox() {
for (int i = 0; i < 4; i++) {
- margin[i] = -1;
+ content_margin[i] = -1;
}
}
@@ -153,11 +151,6 @@ void StyleBoxTexture::set_texture(Ref<Texture2D> p_texture) {
return;
}
texture = p_texture;
- if (p_texture.is_null()) {
- region_rect = Rect2(0, 0, 0, 0);
- } else {
- region_rect = Rect2(Point2(), texture->get_size());
- }
emit_changed();
}
@@ -165,38 +158,38 @@ Ref<Texture2D> StyleBoxTexture::get_texture() const {
return texture;
}
-void StyleBoxTexture::set_margin_size(Side p_side, float p_size) {
+void StyleBoxTexture::set_texture_margin(Side p_side, float p_size) {
ERR_FAIL_INDEX((int)p_side, 4);
- margin[p_side] = p_size;
+ texture_margin[p_side] = p_size;
emit_changed();
}
-void StyleBoxTexture::set_margin_size_all(float p_size) {
+void StyleBoxTexture::set_texture_margin_all(float p_size) {
for (int i = 0; i < 4; i++) {
- margin[i] = p_size;
+ texture_margin[i] = p_size;
}
emit_changed();
}
-void StyleBoxTexture::set_margin_size_individual(float p_left, float p_top, float p_right, float p_bottom) {
- margin[SIDE_LEFT] = p_left;
- margin[SIDE_TOP] = p_top;
- margin[SIDE_RIGHT] = p_right;
- margin[SIDE_BOTTOM] = p_bottom;
+void StyleBoxTexture::set_texture_margin_individual(float p_left, float p_top, float p_right, float p_bottom) {
+ texture_margin[SIDE_LEFT] = p_left;
+ texture_margin[SIDE_TOP] = p_top;
+ texture_margin[SIDE_RIGHT] = p_right;
+ texture_margin[SIDE_BOTTOM] = p_bottom;
emit_changed();
}
-float StyleBoxTexture::get_margin_size(Side p_side) const {
+float StyleBoxTexture::get_texture_margin(Side p_side) const {
ERR_FAIL_INDEX_V((int)p_side, 4, 0.0);
- return margin[p_side];
+ return texture_margin[p_side];
}
float StyleBoxTexture::get_style_margin(Side p_side) const {
ERR_FAIL_INDEX_V((int)p_side, 4, 0.0);
- return margin[p_side];
+ return texture_margin[p_side];
}
Rect2 StyleBoxTexture::get_draw_rect(const Rect2 &p_rect) const {
@@ -218,7 +211,10 @@ void StyleBoxTexture::draw(RID p_canvas_item, const Rect2 &p_rect) const {
rect.size.x += expand_margin[SIDE_LEFT] + expand_margin[SIDE_RIGHT];
rect.size.y += expand_margin[SIDE_TOP] + expand_margin[SIDE_BOTTOM];
- RenderingServer::get_singleton()->canvas_item_add_nine_patch(p_canvas_item, rect, src_rect, texture->get_rid(), Vector2(margin[SIDE_LEFT], margin[SIDE_TOP]), Vector2(margin[SIDE_RIGHT], margin[SIDE_BOTTOM]), RS::NinePatchAxisMode(axis_h), RS::NinePatchAxisMode(axis_v), draw_center, modulate);
+ Vector2 start_offset = Vector2(texture_margin[SIDE_LEFT], texture_margin[SIDE_TOP]);
+ Vector2 end_offset = Vector2(texture_margin[SIDE_RIGHT], texture_margin[SIDE_BOTTOM]);
+
+ RenderingServer::get_singleton()->canvas_item_add_nine_patch(p_canvas_item, rect, src_rect, texture->get_rid(), start_offset, end_offset, RS::NinePatchAxisMode(axis_h), RS::NinePatchAxisMode(axis_v), draw_center, modulate);
}
void StyleBoxTexture::set_draw_center(bool p_enabled) {
@@ -230,21 +226,13 @@ bool StyleBoxTexture::is_draw_center_enabled() const {
return draw_center;
}
-Size2 StyleBoxTexture::get_center_size() const {
- if (texture.is_null()) {
- return Size2();
- }
-
- return region_rect.size - get_minimum_size();
-}
-
-void StyleBoxTexture::set_expand_margin_size(Side p_side, float p_size) {
+void StyleBoxTexture::set_expand_margin(Side p_side, float p_size) {
ERR_FAIL_INDEX((int)p_side, 4);
expand_margin[p_side] = p_size;
emit_changed();
}
-void StyleBoxTexture::set_expand_margin_size_individual(float p_left, float p_top, float p_right, float p_bottom) {
+void StyleBoxTexture::set_expand_margin_individual(float p_left, float p_top, float p_right, float p_bottom) {
expand_margin[SIDE_LEFT] = p_left;
expand_margin[SIDE_TOP] = p_top;
expand_margin[SIDE_RIGHT] = p_right;
@@ -252,14 +240,14 @@ void StyleBoxTexture::set_expand_margin_size_individual(float p_left, float p_to
emit_changed();
}
-void StyleBoxTexture::set_expand_margin_size_all(float p_expand_margin_size) {
+void StyleBoxTexture::set_expand_margin_all(float p_expand_margin_size) {
for (int i = 0; i < 4; i++) {
expand_margin[i] = p_expand_margin_size;
}
emit_changed();
}
-float StyleBoxTexture::get_expand_margin_size(Side p_side) const {
+float StyleBoxTexture::get_expand_margin(Side p_side) const {
ERR_FAIL_INDEX_V((int)p_side, 4, 0);
return expand_margin[p_side];
}
@@ -313,13 +301,13 @@ void StyleBoxTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_texture", "texture"), &StyleBoxTexture::set_texture);
ClassDB::bind_method(D_METHOD("get_texture"), &StyleBoxTexture::get_texture);
- ClassDB::bind_method(D_METHOD("set_margin_size", "margin", "size"), &StyleBoxTexture::set_margin_size);
- ClassDB::bind_method(D_METHOD("set_margin_size_all", "size"), &StyleBoxTexture::set_margin_size_all);
- ClassDB::bind_method(D_METHOD("get_margin_size", "margin"), &StyleBoxTexture::get_margin_size);
+ ClassDB::bind_method(D_METHOD("set_texture_margin", "margin", "size"), &StyleBoxTexture::set_texture_margin);
+ ClassDB::bind_method(D_METHOD("set_texture_margin_all", "size"), &StyleBoxTexture::set_texture_margin_all);
+ ClassDB::bind_method(D_METHOD("get_texture_margin", "margin"), &StyleBoxTexture::get_texture_margin);
- ClassDB::bind_method(D_METHOD("set_expand_margin_size", "margin", "size"), &StyleBoxTexture::set_expand_margin_size);
- ClassDB::bind_method(D_METHOD("set_expand_margin_all", "size"), &StyleBoxTexture::set_expand_margin_size_all);
- ClassDB::bind_method(D_METHOD("get_expand_margin_size", "margin"), &StyleBoxTexture::get_expand_margin_size);
+ ClassDB::bind_method(D_METHOD("set_expand_margin", "margin", "size"), &StyleBoxTexture::set_expand_margin);
+ ClassDB::bind_method(D_METHOD("set_expand_margin_all", "size"), &StyleBoxTexture::set_expand_margin_all);
+ ClassDB::bind_method(D_METHOD("get_expand_margin", "margin"), &StyleBoxTexture::get_expand_margin);
ClassDB::bind_method(D_METHOD("set_region_rect", "region"), &StyleBoxTexture::set_region_rect);
ClassDB::bind_method(D_METHOD("get_region_rect"), &StyleBoxTexture::get_region_rect);
@@ -338,17 +326,17 @@ void StyleBoxTexture::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
- ADD_GROUP("Margins", "margin_");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "margin_left", PROPERTY_HINT_RANGE, "0,2048,1,suffix:px"), "set_margin_size", "get_margin_size", SIDE_LEFT);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "margin_top", PROPERTY_HINT_RANGE, "0,2048,1,suffix:px"), "set_margin_size", "get_margin_size", SIDE_TOP);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "margin_right", PROPERTY_HINT_RANGE, "0,2048,1,suffix:px"), "set_margin_size", "get_margin_size", SIDE_RIGHT);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "margin_bottom", PROPERTY_HINT_RANGE, "0,2048,1,suffix:px"), "set_margin_size", "get_margin_size", SIDE_BOTTOM);
+ ADD_GROUP("Texture Margins", "texture_margin_");
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "texture_margin_left", PROPERTY_HINT_RANGE, "0,2048,1,suffix:px"), "set_texture_margin", "get_texture_margin", SIDE_LEFT);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "texture_margin_top", PROPERTY_HINT_RANGE, "0,2048,1,suffix:px"), "set_texture_margin", "get_texture_margin", SIDE_TOP);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "texture_margin_right", PROPERTY_HINT_RANGE, "0,2048,1,suffix:px"), "set_texture_margin", "get_texture_margin", SIDE_RIGHT);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "texture_margin_bottom", PROPERTY_HINT_RANGE, "0,2048,1,suffix:px"), "set_texture_margin", "get_texture_margin", SIDE_BOTTOM);
ADD_GROUP("Expand Margins", "expand_margin_");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_left", PROPERTY_HINT_RANGE, "0,2048,1,suffix:px"), "set_expand_margin_size", "get_expand_margin_size", SIDE_LEFT);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_top", PROPERTY_HINT_RANGE, "0,2048,1,suffix:px"), "set_expand_margin_size", "get_expand_margin_size", SIDE_TOP);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_right", PROPERTY_HINT_RANGE, "0,2048,1,suffix:px"), "set_expand_margin_size", "get_expand_margin_size", SIDE_RIGHT);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_bottom", PROPERTY_HINT_RANGE, "0,2048,1,suffix:px"), "set_expand_margin_size", "get_expand_margin_size", SIDE_BOTTOM);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_left", PROPERTY_HINT_RANGE, "0,2048,1,suffix:px"), "set_expand_margin", "get_expand_margin", SIDE_LEFT);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_top", PROPERTY_HINT_RANGE, "0,2048,1,suffix:px"), "set_expand_margin", "get_expand_margin", SIDE_TOP);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_right", PROPERTY_HINT_RANGE, "0,2048,1,suffix:px"), "set_expand_margin", "get_expand_margin", SIDE_RIGHT);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_bottom", PROPERTY_HINT_RANGE, "0,2048,1,suffix:px"), "set_expand_margin", "get_expand_margin", SIDE_BOTTOM);
ADD_GROUP("Axis Stretch", "axis_stretch_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "axis_stretch_horizontal", PROPERTY_HINT_ENUM, "Stretch,Tile,Tile Fit"), "set_h_axis_stretch_mode", "get_h_axis_stretch_mode");
@@ -450,13 +438,13 @@ int StyleBoxFlat::get_corner_radius(const Corner p_corner) const {
return corner_radius[p_corner];
}
-void StyleBoxFlat::set_expand_margin_size(Side p_side, float p_size) {
+void StyleBoxFlat::set_expand_margin(Side p_side, float p_size) {
ERR_FAIL_INDEX((int)p_side, 4);
expand_margin[p_side] = p_size;
emit_changed();
}
-void StyleBoxFlat::set_expand_margin_size_individual(float p_left, float p_top, float p_right, float p_bottom) {
+void StyleBoxFlat::set_expand_margin_individual(float p_left, float p_top, float p_right, float p_bottom) {
expand_margin[SIDE_LEFT] = p_left;
expand_margin[SIDE_TOP] = p_top;
expand_margin[SIDE_RIGHT] = p_right;
@@ -464,14 +452,14 @@ void StyleBoxFlat::set_expand_margin_size_individual(float p_left, float p_top,
emit_changed();
}
-void StyleBoxFlat::set_expand_margin_size_all(float p_expand_margin_size) {
+void StyleBoxFlat::set_expand_margin_all(float p_expand_margin_size) {
for (int i = 0; i < 4; i++) {
expand_margin[i] = p_expand_margin_size;
}
emit_changed();
}
-float StyleBoxFlat::get_expand_margin_size(Side p_side) const {
+float StyleBoxFlat::get_expand_margin(Side p_side) const {
ERR_FAIL_INDEX_V((int)p_side, 4, 0.0);
return expand_margin[p_side];
}
@@ -549,10 +537,6 @@ int StyleBoxFlat::get_corner_detail() const {
return corner_detail;
}
-Size2 StyleBoxFlat::get_center_size() const {
- return Size2();
-}
-
inline void set_inner_corner_radius(const Rect2 style_rect, const Rect2 inner_rect, const real_t corner_radius[4], real_t *inner_corner_radius) {
real_t border_left = inner_rect.position.x - style_rect.position.x;
real_t border_top = inner_rect.position.y - style_rect.position.y;
@@ -891,9 +875,9 @@ void StyleBoxFlat::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_corner_radius", "corner", "radius"), &StyleBoxFlat::set_corner_radius);
ClassDB::bind_method(D_METHOD("get_corner_radius", "corner"), &StyleBoxFlat::get_corner_radius);
- ClassDB::bind_method(D_METHOD("set_expand_margin", "margin", "size"), &StyleBoxFlat::set_expand_margin_size);
- ClassDB::bind_method(D_METHOD("set_expand_margin_all", "size"), &StyleBoxFlat::set_expand_margin_size_all);
- ClassDB::bind_method(D_METHOD("get_expand_margin", "margin"), &StyleBoxFlat::get_expand_margin_size);
+ ClassDB::bind_method(D_METHOD("set_expand_margin", "margin", "size"), &StyleBoxFlat::set_expand_margin);
+ ClassDB::bind_method(D_METHOD("set_expand_margin_all", "size"), &StyleBoxFlat::set_expand_margin_all);
+ ClassDB::bind_method(D_METHOD("get_expand_margin", "margin"), &StyleBoxFlat::get_expand_margin);
ClassDB::bind_method(D_METHOD("set_draw_center", "draw_center"), &StyleBoxFlat::set_draw_center);
ClassDB::bind_method(D_METHOD("is_draw_center_enabled"), &StyleBoxFlat::is_draw_center_enabled);
@@ -1041,10 +1025,6 @@ float StyleBoxLine::get_style_margin(Side p_side) const {
return 0;
}
-Size2 StyleBoxLine::get_center_size() const {
- return Size2();
-}
-
void StyleBoxLine::draw(RID p_canvas_item, const Rect2 &p_rect) const {
RenderingServer *vs = RenderingServer::get_singleton();
Rect2i r = p_rect;
diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h
index 5a80b4d4e2..17acfd773e 100644
--- a/scene/resources/style_box.h
+++ b/scene/resources/style_box.h
@@ -41,36 +41,34 @@ class StyleBox : public Resource {
GDCLASS(StyleBox, Resource);
RES_BASE_EXTENSION("stylebox");
OBJ_SAVE_TYPE(StyleBox);
- float margin[4];
+ float content_margin[4];
protected:
- virtual float get_style_margin(Side p_side) const;
+ virtual float get_style_margin(Side p_side) const { return 0; }
static void _bind_methods();
- GDVIRTUAL1RC(float, _get_style_margin, Side)
- GDVIRTUAL2RC(bool, _test_mask, Point2, Rect2)
- GDVIRTUAL0RC(Size2, _get_center_size)
- GDVIRTUAL1RC(Rect2, _get_draw_rect, Rect2)
GDVIRTUAL2C(_draw, RID, Rect2)
+ GDVIRTUAL1RC(Rect2, _get_draw_rect, Rect2)
+ GDVIRTUAL0RC(Size2, _get_minimum_size)
+ GDVIRTUAL2RC(bool, _test_mask, Point2, Rect2)
public:
- virtual bool test_mask(const Point2 &p_point, const Rect2 &p_rect) const;
+ virtual Size2 get_minimum_size() const;
- void set_default_margin(Side p_side, float p_value);
- void set_default_margin_all(float p_value);
- void set_default_margin_individual(float p_left, float p_top, float p_right, float p_bottom);
- float get_default_margin(Side p_side) const;
+ void set_content_margin(Side p_side, float p_value);
+ void set_content_margin_all(float p_value);
+ void set_content_margin_individual(float p_left, float p_top, float p_right, float p_bottom);
+ float get_content_margin(Side p_side) const;
float get_margin(Side p_side) const;
- virtual Size2 get_center_size() const;
+ Point2 get_offset() const;
- virtual Rect2 get_draw_rect(const Rect2 &p_rect) const;
virtual void draw(RID p_canvas_item, const Rect2 &p_rect) const;
+ virtual Rect2 get_draw_rect(const Rect2 &p_rect) const;
CanvasItem *get_current_item_drawn() const;
- Size2 get_minimum_size() const;
- Point2 get_offset() const;
+ virtual bool test_mask(const Point2 &p_point, const Rect2 &p_rect) const;
StyleBox();
};
@@ -96,7 +94,7 @@ public:
private:
float expand_margin[4] = {};
- float margin[4] = {};
+ float texture_margin[4] = {};
Rect2 region_rect;
Ref<Texture2D> texture;
bool draw_center = true;
@@ -109,15 +107,15 @@ protected:
static void _bind_methods();
public:
- void set_expand_margin_size(Side p_expand_side, float p_size);
- void set_expand_margin_size_all(float p_expand_margin_size);
- void set_expand_margin_size_individual(float p_left, float p_top, float p_right, float p_bottom);
- float get_expand_margin_size(Side p_expand_side) const;
+ void set_expand_margin(Side p_expand_side, float p_size);
+ void set_expand_margin_all(float p_expand_margin_size);
+ void set_expand_margin_individual(float p_left, float p_top, float p_right, float p_bottom);
+ float get_expand_margin(Side p_expand_side) const;
- void set_margin_size(Side p_side, float p_size);
- void set_margin_size_all(float p_size);
- void set_margin_size_individual(float p_left, float p_top, float p_right, float p_bottom);
- float get_margin_size(Side p_side) const;
+ void set_texture_margin(Side p_side, float p_size);
+ void set_texture_margin_all(float p_size);
+ void set_texture_margin_individual(float p_left, float p_top, float p_right, float p_bottom);
+ float get_texture_margin(Side p_side) const;
void set_region_rect(const Rect2 &p_region_rect);
Rect2 get_region_rect() const;
@@ -127,7 +125,6 @@ public:
void set_draw_center(bool p_enabled);
bool is_draw_center_enabled() const;
- virtual Size2 get_center_size() const override;
void set_h_axis_stretch_mode(AxisStretchMode p_mode);
AxisStretchMode get_h_axis_stretch_mode() const;
@@ -198,10 +195,10 @@ public:
void set_corner_detail(const int &p_corner_detail);
int get_corner_detail() const;
- void set_expand_margin_size(Side p_expand_side, float p_size);
- void set_expand_margin_size_all(float p_expand_margin_size);
- void set_expand_margin_size_individual(float p_left, float p_top, float p_right, float p_bottom);
- float get_expand_margin_size(Side p_expand_side) const;
+ void set_expand_margin(Side p_expand_side, float p_size);
+ void set_expand_margin_all(float p_expand_margin_size);
+ void set_expand_margin_individual(float p_left, float p_top, float p_right, float p_bottom);
+ float get_expand_margin(Side p_expand_side) const;
void set_draw_center(bool p_enabled);
bool is_draw_center_enabled() const;
@@ -223,8 +220,6 @@ public:
void set_aa_size(const real_t p_aa_size);
real_t get_aa_size() const;
- virtual Size2 get_center_size() const override;
-
virtual Rect2 get_draw_rect(const Rect2 &p_rect) const override;
virtual void draw(RID p_canvas_item, const Rect2 &p_rect) const override;
@@ -261,8 +256,6 @@ public:
void set_grow_end(float p_grow);
float get_grow_end() const;
- virtual Size2 get_center_size() const override;
-
virtual void draw(RID p_canvas_item, const Rect2 &p_rect) const override;
StyleBoxLine();
diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp
index e802e1c2d9..5a2b917b9a 100644
--- a/scene/resources/surface_tool.cpp
+++ b/scene/resources/surface_tool.cpp
@@ -146,6 +146,25 @@ uint32_t SurfaceTool::VertexHasher::hash(const Vertex &p_vtx) {
return h;
}
+bool SurfaceTool::SmoothGroupVertex::operator==(const SmoothGroupVertex &p_vertex) const {
+ if (vertex != p_vertex.vertex) {
+ return false;
+ }
+
+ if (smooth_group != p_vertex.smooth_group) {
+ return false;
+ }
+
+ return true;
+}
+
+uint32_t SurfaceTool::SmoothGroupVertexHasher::hash(const SmoothGroupVertex &p_vtx) {
+ uint32_t h = hash_djb2_buffer((const uint8_t *)&p_vtx.vertex, sizeof(real_t) * 3);
+ h = hash_murmur3_one_32(p_vtx.smooth_group, h);
+ h = hash_fmix32(h);
+ return h;
+}
+
uint32_t SurfaceTool::TriangleHasher::hash(const int *p_triangle) {
int t0 = p_triangle[0];
int t1 = p_triangle[1];
@@ -732,13 +751,13 @@ void SurfaceTool::index() {
LocalVector<Vertex> old_vertex_array = vertex_array;
vertex_array.clear();
- for (uint32_t i = 0; i < old_vertex_array.size(); i++) {
- int *idxptr = indices.getptr(old_vertex_array[i]);
+ for (const Vertex &vertex : old_vertex_array) {
+ int *idxptr = indices.getptr(vertex);
int idx;
if (!idxptr) {
idx = indices.size();
- vertex_array.push_back(old_vertex_array[i]);
- indices[old_vertex_array[i]] = idx;
+ vertex_array.push_back(vertex);
+ indices[vertex] = idx;
} else {
idx = *idxptr;
}
@@ -756,9 +775,8 @@ void SurfaceTool::deindex() {
LocalVector<Vertex> old_vertex_array = vertex_array;
vertex_array.clear();
- for (uint32_t i = 0; i < index_array.size(); i++) {
- uint32_t index = index_array[i];
- ERR_FAIL_COND(index >= old_vertex_array.size());
+ for (const int &index : index_array) {
+ ERR_FAIL_COND(uint32_t(index) >= old_vertex_array.size());
vertex_array.push_back(old_vertex_array[index]);
}
format &= ~Mesh::ARRAY_FORMAT_INDEX;
@@ -1000,8 +1018,7 @@ void SurfaceTool::append_from(const Ref<Mesh> &p_existing, int p_surface, const
}
int vfrom = vertex_array.size();
- for (uint32_t vi = 0; vi < nvertices.size(); vi++) {
- Vertex v = nvertices[vi];
+ for (Vertex &v : nvertices) {
v.vertex = p_xform.xform(v.vertex);
if (nformat & RS::ARRAY_FORMAT_NORMAL) {
v.normal = p_xform.basis.xform(v.normal);
@@ -1014,8 +1031,8 @@ void SurfaceTool::append_from(const Ref<Mesh> &p_existing, int p_surface, const
vertex_array.push_back(v);
}
- for (uint32_t i = 0; i < nindices.size(); i++) {
- int dst_index = nindices[i] + vfrom;
+ for (const int &index : nindices) {
+ int dst_index = index + vfrom;
index_array.push_back(dst_index);
}
if (index_array.size() % 3) {
@@ -1132,9 +1149,9 @@ void SurfaceTool::generate_tangents() {
TangentGenerationContextUserData triangle_data;
triangle_data.vertices = &vertex_array;
- for (uint32_t i = 0; i < vertex_array.size(); i++) {
- vertex_array[i].binormal = Vector3();
- vertex_array[i].tangent = Vector3();
+ for (Vertex &vertex : vertex_array) {
+ vertex.binormal = Vector3();
+ vertex.tangent = Vector3();
}
triangle_data.indices = &index_array;
msc.m_pUserData = &triangle_data;
@@ -1154,7 +1171,7 @@ void SurfaceTool::generate_normals(bool p_flip) {
ERR_FAIL_COND((vertex_array.size() % 3) != 0);
- HashMap<Vertex, Vector3, VertexHasher> vertex_hash;
+ HashMap<SmoothGroupVertex, Vector3, SmoothGroupVertexHasher> smooth_hash;
for (uint32_t vi = 0; vi < vertex_array.size(); vi += 3) {
Vertex *v = &vertex_array[vi];
@@ -1167,21 +1184,28 @@ void SurfaceTool::generate_normals(bool p_flip) {
}
for (int i = 0; i < 3; i++) {
- Vector3 *lv = vertex_hash.getptr(v[i]);
- if (!lv) {
- vertex_hash.insert(v[i], normal);
+ // Add face normal to smooth vertex influence if vertex is member of a smoothing group
+ if (v[i].smooth_group != UINT32_MAX) {
+ Vector3 *lv = smooth_hash.getptr(v[i]);
+ if (!lv) {
+ smooth_hash.insert(v[i], normal);
+ } else {
+ (*lv) += normal;
+ }
} else {
- (*lv) += normal;
+ v[i].normal = normal;
}
}
}
- for (uint32_t vi = 0; vi < vertex_array.size(); vi++) {
- Vector3 *lv = vertex_hash.getptr(vertex_array[vi]);
- if (!lv) {
- vertex_array[vi].normal = Vector3();
- } else {
- vertex_array[vi].normal = lv->normalized();
+ for (Vertex &vertex : vertex_array) {
+ if (vertex.smooth_group != UINT32_MAX) {
+ Vector3 *lv = smooth_hash.getptr(vertex);
+ if (!lv) {
+ vertex.normal = Vector3();
+ } else {
+ vertex.normal = lv->normalized();
+ }
}
}
diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h
index 25e078d2ff..00438c4a53 100644
--- a/scene/resources/surface_tool.h
+++ b/scene/resources/surface_tool.h
@@ -97,6 +97,21 @@ private:
static _FORCE_INLINE_ uint32_t hash(const Vertex &p_vtx);
};
+ struct SmoothGroupVertex {
+ Vector3 vertex;
+ uint32_t smooth_group = 0;
+ bool operator==(const SmoothGroupVertex &p_vertex) const;
+
+ SmoothGroupVertex(const Vertex &p_vertex) {
+ vertex = p_vertex.vertex;
+ smooth_group = p_vertex.smooth_group;
+ };
+ };
+
+ struct SmoothGroupVertexHasher {
+ static _FORCE_INLINE_ uint32_t hash(const SmoothGroupVertex &p_vtx);
+ };
+
struct TriangleHasher {
static _FORCE_INLINE_ uint32_t hash(const int *p_triangle);
static _FORCE_INLINE_ bool compare(const int *p_lhs, const int *p_rhs);
diff --git a/scene/resources/text_paragraph.cpp b/scene/resources/text_paragraph.cpp
index 6d66c48b78..dfafc7d2bc 100644
--- a/scene/resources/text_paragraph.cpp
+++ b/scene/resources/text_paragraph.cpp
@@ -135,8 +135,8 @@ void TextParagraph::_bind_methods() {
void TextParagraph::_shape_lines() {
if (lines_dirty) {
- for (int i = 0; i < (int)lines_rid.size(); i++) {
- TS->free_rid(lines_rid[i]);
+ for (const RID &line_rid : lines_rid) {
+ TS->free_rid(line_rid);
}
lines_rid.clear();
@@ -234,14 +234,14 @@ void TextParagraph::_shape_lines() {
} else {
// Autowrap disabled.
- for (int i = 0; i < (int)lines_rid.size(); i++) {
+ for (const RID &line_rid : lines_rid) {
if (alignment == HORIZONTAL_ALIGNMENT_FILL) {
- TS->shaped_text_fit_to_width(lines_rid[i], width, jst_flags);
+ TS->shaped_text_fit_to_width(line_rid, width, jst_flags);
overrun_flags.set_flag(TextServer::OVERRUN_JUSTIFICATION_AWARE);
- TS->shaped_text_overrun_trim_to_width(lines_rid[i], width, overrun_flags);
- TS->shaped_text_fit_to_width(lines_rid[i], width, jst_flags | TextServer::JUSTIFICATION_CONSTRAIN_ELLIPSIS);
+ TS->shaped_text_overrun_trim_to_width(line_rid, width, overrun_flags);
+ TS->shaped_text_fit_to_width(line_rid, width, jst_flags | TextServer::JUSTIFICATION_CONSTRAIN_ELLIPSIS);
} else {
- TS->shaped_text_overrun_trim_to_width(lines_rid[i], width, overrun_flags);
+ TS->shaped_text_overrun_trim_to_width(line_rid, width, overrun_flags);
}
}
}
@@ -268,8 +268,8 @@ RID TextParagraph::get_dropcap_rid() const {
void TextParagraph::clear() {
_THREAD_SAFE_METHOD_
- for (int i = 0; i < (int)lines_rid.size(); i++) {
- TS->free_rid(lines_rid[i]);
+ for (const RID &line_rid : lines_rid) {
+ TS->free_rid(line_rid);
}
lines_rid.clear();
TS->shaped_text_clear(rid);
@@ -915,17 +915,17 @@ int TextParagraph::hit_test(const Point2 &p_coords) const {
return 0;
}
}
- for (int i = 0; i < (int)lines_rid.size(); i++) {
- if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
- if ((p_coords.y >= ofs.y) && (p_coords.y <= ofs.y + TS->shaped_text_get_size(lines_rid[i]).y)) {
- return TS->shaped_text_hit_test_position(lines_rid[i], p_coords.x);
+ for (const RID &line_rid : lines_rid) {
+ if (TS->shaped_text_get_orientation(line_rid) == TextServer::ORIENTATION_HORIZONTAL) {
+ if ((p_coords.y >= ofs.y) && (p_coords.y <= ofs.y + TS->shaped_text_get_size(line_rid).y)) {
+ return TS->shaped_text_hit_test_position(line_rid, p_coords.x);
}
- ofs.y += TS->shaped_text_get_size(lines_rid[i]).y;
+ ofs.y += TS->shaped_text_get_size(line_rid).y;
} else {
- if ((p_coords.x >= ofs.x) && (p_coords.x <= ofs.x + TS->shaped_text_get_size(lines_rid[i]).x)) {
- return TS->shaped_text_hit_test_position(lines_rid[i], p_coords.y);
+ if ((p_coords.x >= ofs.x) && (p_coords.x <= ofs.x + TS->shaped_text_get_size(line_rid).x)) {
+ return TS->shaped_text_hit_test_position(line_rid, p_coords.y);
}
- ofs.y += TS->shaped_text_get_size(lines_rid[i]).x;
+ ofs.y += TS->shaped_text_get_size(line_rid).x;
}
}
return TS->shaped_text_get_range(rid).y;
@@ -1027,8 +1027,8 @@ TextParagraph::TextParagraph() {
}
TextParagraph::~TextParagraph() {
- for (int i = 0; i < (int)lines_rid.size(); i++) {
- TS->free_rid(lines_rid[i]);
+ for (const RID &line_rid : lines_rid) {
+ TS->free_rid(line_rid);
}
lines_rid.clear();
TS->free_rid(rid);
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index f106eebff5..85e21d6056 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -94,6 +94,13 @@ bool Texture2D::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Re
return true;
}
+Ref<Resource> Texture2D::create_placeholder() const {
+ Ref<PlaceholderTexture2D> placeholder;
+ placeholder.instantiate();
+ placeholder->set_size(get_size());
+ return placeholder;
+}
+
void Texture2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_width"), &Texture2D::get_width);
ClassDB::bind_method(D_METHOD("get_height"), &Texture2D::get_height);
@@ -103,6 +110,7 @@ void Texture2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("draw_rect", "canvas_item", "rect", "tile", "modulate", "transpose"), &Texture2D::draw_rect, DEFVAL(Color(1, 1, 1)), DEFVAL(false));
ClassDB::bind_method(D_METHOD("draw_rect_region", "canvas_item", "rect", "src_rect", "modulate", "transpose", "clip_uv"), &Texture2D::draw_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(true));
ClassDB::bind_method(D_METHOD("get_image"), &Texture2D::get_image);
+ ClassDB::bind_method(D_METHOD("create_placeholder"), &Texture2D::create_placeholder);
ADD_GROUP("", "");
@@ -1137,6 +1145,7 @@ void Texture3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_depth"), &Texture3D::get_depth);
ClassDB::bind_method(D_METHOD("has_mipmaps"), &Texture3D::has_mipmaps);
ClassDB::bind_method(D_METHOD("get_data"), &Texture3D::_get_datai);
+ ClassDB::bind_method(D_METHOD("create_placeholder"), &Texture3D::create_placeholder);
GDVIRTUAL_BIND(_get_format);
GDVIRTUAL_BIND(_get_width);
@@ -1145,6 +1154,14 @@ void Texture3D::_bind_methods() {
GDVIRTUAL_BIND(_has_mipmaps);
GDVIRTUAL_BIND(_get_data);
}
+
+Ref<Resource> Texture3D::create_placeholder() const {
+ Ref<PlaceholderTexture3D> placeholder;
+ placeholder.instantiate();
+ placeholder->set_size(Vector3i(get_width(), get_height(), get_depth()));
+ return placeholder;
+}
+
//////////////////////////////////////////
Image::Format ImageTexture3D::get_format() const {
@@ -3048,6 +3065,42 @@ ImageTextureLayered::~ImageTextureLayered() {
}
}
+void Texture2DArray::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("create_placeholder"), &Texture2DArray::create_placeholder);
+}
+
+Ref<Resource> Texture2DArray::create_placeholder() const {
+ Ref<PlaceholderTexture2DArray> placeholder;
+ placeholder.instantiate();
+ placeholder->set_size(Size2i(get_width(), get_height()));
+ placeholder->set_layers(get_layers());
+ return placeholder;
+}
+
+void Cubemap::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("create_placeholder"), &Cubemap::create_placeholder);
+}
+
+Ref<Resource> Cubemap::create_placeholder() const {
+ Ref<PlaceholderCubemap> placeholder;
+ placeholder.instantiate();
+ placeholder->set_size(Size2i(get_width(), get_height()));
+ placeholder->set_layers(get_layers());
+ return placeholder;
+}
+
+void CubemapArray::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("create_placeholder"), &CubemapArray::create_placeholder);
+}
+
+Ref<Resource> CubemapArray::create_placeholder() const {
+ Ref<PlaceholderCubemapArray> placeholder;
+ placeholder.instantiate();
+ placeholder->set_size(Size2i(get_width(), get_height()));
+ placeholder->set_layers(get_layers());
+ return placeholder;
+}
+
///////////////////////////////////////////
void CompressedTextureLayered::set_path(const String &p_path, bool p_take_over) {
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index bb86910c0c..7f74ae6941 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -82,6 +82,8 @@ public:
virtual Ref<Image> get_image() const { return Ref<Image>(); }
+ virtual Ref<Resource> create_placeholder() const;
+
Texture2D();
};
@@ -450,25 +452,41 @@ public:
class Texture2DArray : public ImageTextureLayered {
GDCLASS(Texture2DArray, ImageTextureLayered)
+
+protected:
+ static void _bind_methods();
+
public:
Texture2DArray() :
ImageTextureLayered(LAYERED_TYPE_2D_ARRAY) {}
+
+ virtual Ref<Resource> create_placeholder() const;
};
class Cubemap : public ImageTextureLayered {
GDCLASS(Cubemap, ImageTextureLayered);
+protected:
+ static void _bind_methods();
+
public:
Cubemap() :
ImageTextureLayered(LAYERED_TYPE_CUBEMAP) {}
+
+ virtual Ref<Resource> create_placeholder() const;
};
class CubemapArray : public ImageTextureLayered {
GDCLASS(CubemapArray, ImageTextureLayered);
+protected:
+ static void _bind_methods();
+
public:
CubemapArray() :
ImageTextureLayered(LAYERED_TYPE_CUBEMAP_ARRAY) {}
+
+ virtual Ref<Resource> create_placeholder() const;
};
class CompressedTextureLayered : public TextureLayered {
@@ -580,6 +598,7 @@ public:
virtual int get_depth() const;
virtual bool has_mipmaps() const;
virtual Vector<Ref<Image>> get_data() const;
+ virtual Ref<Resource> create_placeholder() const;
};
class ImageTexture3D : public Texture3D {
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index 4043b73b71..b5a68ef14b 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -404,8 +404,8 @@ void TileSet::_update_terrains_cache() {
if (terrains_cache_dirty) {
// Organizes tiles into structures.
per_terrain_pattern_tiles.resize(terrain_sets.size());
- for (int i = 0; i < (int)per_terrain_pattern_tiles.size(); i++) {
- per_terrain_pattern_tiles[i].clear();
+ for (RBMap<TileSet::TerrainsPattern, RBSet<TileMapCell>> &tiles : per_terrain_pattern_tiles) {
+ tiles.clear();
}
for (const KeyValue<int, Ref<TileSetSource>> &kv : sources) {
@@ -473,6 +473,7 @@ void TileSet::_compute_next_source_id() {
int TileSet::add_source(Ref<TileSetSource> p_tile_set_source, int p_atlas_source_id_override) {
ERR_FAIL_COND_V(!p_tile_set_source.is_valid(), TileSet::INVALID_SOURCE);
ERR_FAIL_COND_V_MSG(p_atlas_source_id_override >= 0 && (sources.has(p_atlas_source_id_override)), TileSet::INVALID_SOURCE, vformat("Cannot create TileSet atlas source. Another atlas source exists with id %d.", p_atlas_source_id_override));
+ ERR_FAIL_COND_V_MSG(p_atlas_source_id_override < 0 && p_atlas_source_id_override != TileSet::INVALID_SOURCE, TileSet::INVALID_SOURCE, vformat("Provided source ID %d is not valid. Negative source IDs are not allowed.", p_atlas_source_id_override));
int new_source_id = p_atlas_source_id_override >= 0 ? p_atlas_source_id_override : next_source_id;
sources[new_source_id] = p_tile_set_source;
@@ -1341,8 +1342,8 @@ void TileSet::clear_tile_proxies() {
int TileSet::add_pattern(Ref<TileMapPattern> p_pattern, int p_index) {
ERR_FAIL_COND_V(!p_pattern.is_valid(), -1);
ERR_FAIL_COND_V_MSG(p_pattern->is_empty(), -1, "Cannot add an empty pattern to the TileSet.");
- for (unsigned int i = 0; i < patterns.size(); i++) {
- ERR_FAIL_COND_V_MSG(patterns[i] == p_pattern, -1, "TileSet has already this pattern.");
+ for (const Ref<TileMapPattern> &pattern : patterns) {
+ ERR_FAIL_COND_V_MSG(pattern == p_pattern, -1, "TileSet has already this pattern.");
}
ERR_FAIL_COND_V(p_index > (int)patterns.size(), -1);
if (p_index < 0) {
@@ -4189,8 +4190,8 @@ real_t TileSetAtlasSource::get_tile_animation_total_duration(const Vector2i p_at
ERR_FAIL_COND_V_MSG(!tiles.has(p_atlas_coords), 1, vformat("TileSetAtlasSource has no tile at %s.", Vector2i(p_atlas_coords)));
real_t sum = 0.0;
- for (int frame = 0; frame < (int)tiles[p_atlas_coords].animation_frames_durations.size(); frame++) {
- sum += tiles[p_atlas_coords].animation_frames_durations[frame];
+ for (const real_t &duration : tiles[p_atlas_coords].animation_frames_durations) {
+ sum += duration;
}
return sum;
}
@@ -4572,8 +4573,8 @@ void TileSetAtlasSource::_clear_tiles_outside_texture() {
}
}
- for (unsigned int i = 0; i < to_remove.size(); i++) {
- remove_tile(to_remove[i]);
+ for (const Vector2i &v : to_remove) {
+ remove_tile(v);
}
}
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index 4c99563a91..bfcf5cb137 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -399,7 +399,6 @@ void VisualShaderNode::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "output_port_for_preview"), "set_output_port_for_preview", "get_output_port_for_preview");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "default_input_values", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "set_default_input_values", "get_default_input_values");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "expanded_output_ports", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_output_ports_expanded", "_get_output_ports_expanded");
- ADD_SIGNAL(MethodInfo("editor_refresh_request"));
BIND_ENUM_CONSTANT(PORT_TYPE_SCALAR);
BIND_ENUM_CONSTANT(PORT_TYPE_SCALAR_INT);
@@ -1562,7 +1561,7 @@ void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const {
prop_name += "/" + itos(E.key);
if (E.key != NODE_ID_OUTPUT) {
- p_list->push_back(PropertyInfo(Variant::OBJECT, prop_name + "/node", PROPERTY_HINT_RESOURCE_TYPE, "VisualShaderNode", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, prop_name + "/node", PROPERTY_HINT_RESOURCE_TYPE, "VisualShaderNode", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_ALWAYS_DUPLICATE));
}
p_list->push_back(PropertyInfo(Variant::VECTOR2, prop_name + "/position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
@@ -2734,9 +2733,6 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "viewport_size", "VIEWPORT_SIZE" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_BOOLEAN, "output_is_srgb", "OUTPUT_IS_SRGB" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_BOOLEAN, "front_facing", "FRONT_FACING" },
- { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SAMPLER, "screen_texture", "SCREEN_TEXTURE" },
- { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SAMPLER, "normal_roughness_texture", "NORMAL_ROUGHNESS_TEXTURE" },
- { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SAMPLER, "depth_texture", "DEPTH_TEXTURE" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_index", "VIEW_INDEX" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_mono_left", "VIEW_MONO_LEFT" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_right", "VIEW_RIGHT" },
@@ -2799,7 +2795,6 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_BOOLEAN, "at_light_pass", "AT_LIGHT_PASS" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SAMPLER, "texture", "TEXTURE" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SAMPLER, "normal_texture", "NORMAL_TEXTURE" },
- { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SAMPLER, "screen_texture", "SCREEN_TEXTURE" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_4D, "specular_shininess", "SPECULAR_SHININESS" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SAMPLER, "specular_shininess_texture", "SPECULAR_SHININESS_TEXTURE" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "vertex", "VERTEX" },
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index 432d5a5b59..12be0f46a6 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -756,141 +756,157 @@ Vector<VisualShader::DefaultTextureParam> VisualShaderNodeTexture::get_default_t
}
String VisualShaderNodeTexture::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
- if (source == SOURCE_TEXTURE) {
- String u = "uniform sampler2D " + make_unique_id(p_type, p_id, "tex");
- switch (texture_type) {
- case TYPE_DATA:
- break;
- case TYPE_COLOR:
- u += " : source_color";
- break;
- case TYPE_NORMAL_MAP:
- u += " : hint_normal";
- break;
- default:
- break;
- }
- return u + ";\n";
+ String code;
+
+ switch (source) {
+ case SOURCE_TEXTURE: {
+ code += "uniform sampler2D " + make_unique_id(p_type, p_id, "tex");
+ switch (texture_type) {
+ case TYPE_DATA: {
+ } break;
+ case TYPE_COLOR: {
+ code += " : source_color";
+ } break;
+ case TYPE_NORMAL_MAP: {
+ code += " : hint_normal";
+ } break;
+ default: {
+ } break;
+ }
+ code += ";\n";
+ } break;
+ case SOURCE_SCREEN: {
+ if ((p_mode == Shader::MODE_SPATIAL || p_mode == Shader::MODE_CANVAS_ITEM) && p_type == VisualShader::TYPE_FRAGMENT) {
+ code += "uniform sampler2D " + make_unique_id(p_type, p_id, "screen_tex") + " : hint_screen_texture;\n";
+ }
+ } break;
+ case SOURCE_DEPTH:
+ case SOURCE_3D_NORMAL:
+ case SOURCE_ROUGHNESS: {
+ if (p_mode == Shader::MODE_SPATIAL && p_type == VisualShader::TYPE_FRAGMENT) {
+ String sampler_name = "";
+ String hint = " : ";
+ if (source == SOURCE_DEPTH) {
+ sampler_name = "depth_tex";
+ hint += "hint_depth_texture;\n";
+ } else {
+ sampler_name = source == SOURCE_ROUGHNESS ? "roughness_tex" : "normal_roughness_tex";
+ hint += "hint_normal_roughness_texture;\n";
+ }
+ code += "uniform sampler2D " + make_unique_id(p_type, p_id, sampler_name) + hint;
+ }
+ } break;
+ default: {
+ } break;
}
- return String();
+ return code;
}
String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
String default_uv;
if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) {
- default_uv = "UV";
+ if (source == SOURCE_SCREEN) {
+ default_uv = "SCREEN_UV";
+ } else {
+ default_uv = "UV";
+ }
} else {
default_uv = "vec2(0.0)";
}
String code;
- if (source == SOURCE_TEXTURE) {
- String id = make_unique_id(p_type, p_id, "tex");
- if (p_input_vars[0].is_empty()) { // Use UV by default.
+ String uv = p_input_vars[0].is_empty() ? default_uv : p_input_vars[0];
+
+ switch (source) {
+ case SOURCE_PORT:
+ case SOURCE_TEXTURE: {
+ String id;
+ if (source == SOURCE_PORT) {
+ id = p_input_vars[2];
+ if (id.is_empty()) {
+ break;
+ }
+ } else { // SOURCE_TEXTURE
+ id = make_unique_id(p_type, p_id, "tex");
+ }
if (p_input_vars[1].is_empty()) {
- code += " " + p_output_vars[0] + " = texture(" + id + ", " + default_uv + ");\n";
+ code += " " + p_output_vars[0] + " = texture(" + id + ", " + uv + ");\n";
} else {
- code += " " + p_output_vars[0] + " = textureLod(" + id + ", " + default_uv + ", " + p_input_vars[1] + ");\n";
+ code += " " + p_output_vars[0] + " = textureLod(" + id + ", " + uv + ", " + p_input_vars[1] + ");\n";
}
- } else if (p_input_vars[1].is_empty()) {
- //no lod
- code += " " + p_output_vars[0] + " = texture(" + id + ", " + p_input_vars[0] + ");\n";
- } else {
- code += " " + p_output_vars[0] + " = textureLod(" + id + ", " + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
- }
- return code;
- }
-
- if (source == SOURCE_PORT) {
- String id = p_input_vars[2];
- if (id.is_empty()) {
- code += " " + p_output_vars[0] + " = vec4(0.0);\n";
- } else {
- if (p_input_vars[0].is_empty()) { // Use UV by default.
+ return code;
+ } break;
+ case SOURCE_SCREEN: {
+ if ((p_mode == Shader::MODE_SPATIAL || p_mode == Shader::MODE_CANVAS_ITEM) && p_type == VisualShader::TYPE_FRAGMENT) {
+ String id = make_unique_id(p_type, p_id, "screen_tex");
if (p_input_vars[1].is_empty()) {
- code += " " + p_output_vars[0] + " = texture(" + id + ", " + default_uv + ");\n";
+ code += " " + p_output_vars[0] + " = texture(" + id + ", " + uv + ");\n";
} else {
- code += " " + p_output_vars[0] + " = textureLod(" + id + ", " + default_uv + ", " + p_input_vars[1] + ");\n";
+ code += " " + p_output_vars[0] + " = textureLod(" + id + ", " + uv + ", " + p_input_vars[1] + ");\n";
}
- } else if (p_input_vars[1].is_empty()) {
- //no lod
- code += " " + p_output_vars[0] + " = texture(" + id + ", " + p_input_vars[0] + ");\n";
- } else {
- code += " " + p_output_vars[0] + " = textureLod(" + id + ", " + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
- }
- }
- return code;
- }
-
- if (source == SOURCE_SCREEN && (p_mode == Shader::MODE_SPATIAL || p_mode == Shader::MODE_CANVAS_ITEM) && p_type == VisualShader::TYPE_FRAGMENT) {
- if (p_input_vars[0].is_empty() || p_for_preview) { // Use UV by default.
- if (p_input_vars[1].is_empty()) {
- code += " " + p_output_vars[0] + " = textureLod(SCREEN_TEXTURE, " + default_uv + ", 0.0);\n";
- } else {
- code += " " + p_output_vars[0] + " = textureLod(SCREEN_TEXTURE, " + default_uv + ", " + p_input_vars[1] + ");\n";
+ return code;
}
- } else if (p_input_vars[1].is_empty()) {
- //no lod
- code += " " + p_output_vars[0] + " = textureLod(SCREEN_TEXTURE, " + p_input_vars[0] + ", 0.0);\n";
- } else {
- code += " " + p_output_vars[0] + " = textureLod(SCREEN_TEXTURE, " + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
- }
- return code;
- }
+ } break;
+ case SOURCE_2D_NORMAL:
+ case SOURCE_2D_TEXTURE: {
+ if (p_mode == Shader::MODE_CANVAS_ITEM && p_type == VisualShader::TYPE_FRAGMENT) {
+ String id = source == SOURCE_2D_TEXTURE ? "TEXTURE" : "NORMAL_TEXTURE";
- if (source == SOURCE_2D_TEXTURE && p_mode == Shader::MODE_CANVAS_ITEM && p_type == VisualShader::TYPE_FRAGMENT) {
- if (p_input_vars[0].is_empty()) { // Use UV by default.
- if (p_input_vars[1].is_empty()) {
- code += " " + p_output_vars[0] + " = texture(TEXTURE, " + default_uv + ");\n";
- } else {
- code += " " + p_output_vars[0] + " = textureLod(TEXTURE, " + default_uv + ", " + p_input_vars[1] + ");\n";
+ if (p_input_vars[1].is_empty()) {
+ code += " " + p_output_vars[0] + " = texture(" + id + ", " + uv + ");\n";
+ } else {
+ code += " " + p_output_vars[0] + " = textureLod(" + id + ", " + uv + ", " + p_input_vars[1] + ");\n";
+ }
+ return code;
}
- } else if (p_input_vars[1].is_empty()) {
- //no lod
- code += " " + p_output_vars[0] + " = texture(TEXTURE, " + p_input_vars[0] + ");\n";
- } else {
- code += " " + p_output_vars[0] + " = textureLod(TEXTURE, " + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
- }
- return code;
- }
+ } break;
+ case SOURCE_3D_NORMAL:
+ case SOURCE_ROUGHNESS:
+ case SOURCE_DEPTH: {
+ if (!p_for_preview && p_mode == Shader::MODE_SPATIAL && p_type == VisualShader::TYPE_FRAGMENT) {
+ String var_name = "";
+ String sampler_name = "";
+
+ switch (source) {
+ case SOURCE_DEPTH: {
+ var_name = "_depth";
+ sampler_name = "depth_tex";
+ } break;
+ case SOURCE_ROUGHNESS: {
+ var_name = "_roughness";
+ sampler_name = "roughness_tex";
+ } break;
+ case SOURCE_3D_NORMAL: {
+ var_name = "_normal";
+ sampler_name = "normal_roughness_tex";
+ } break;
+ default: {
+ } break;
+ }
- if (source == SOURCE_2D_NORMAL && p_mode == Shader::MODE_CANVAS_ITEM && p_type == VisualShader::TYPE_FRAGMENT) {
- if (p_input_vars[0].is_empty()) { // Use UV by default.
- if (p_input_vars[1].is_empty()) {
- code += " " + p_output_vars[0] + " = texture(NORMAL_TEXTURE, " + default_uv + ");\n";
- } else {
- code += " " + p_output_vars[0] + " = textureLod(NORMAL_TEXTURE, " + default_uv + ", " + p_input_vars[1] + ");\n";
- }
- } else if (p_input_vars[1].is_empty()) {
- //no lod
- code += " " + p_output_vars[0] + " = texture(NORMAL_TEXTURE, " + p_input_vars[0] + ".xy);\n";
- } else {
- code += " " + p_output_vars[0] + " = textureLod(NORMAL_TEXTURE, " + p_input_vars[0] + ".xy, " + p_input_vars[1] + ");\n";
- }
- return code;
- }
+ String id = make_unique_id(p_type, p_id, sampler_name);
+ String type = source == SOURCE_3D_NORMAL ? "vec3" : "float";
+ String components = source == SOURCE_3D_NORMAL ? "rgb" : "r";
- if (source == SOURCE_DEPTH) {
- if (!p_for_preview && p_mode == Shader::MODE_SPATIAL && p_type == VisualShader::TYPE_FRAGMENT) {
- code += " {\n";
- if (p_input_vars[0].is_empty()) { // Use UV by default.
+ code += " {\n";
if (p_input_vars[1].is_empty()) {
- code += " float _depth = texture(DEPTH_TEXTURE, " + default_uv + ").r;\n";
+ code += " " + type + " " + var_name + " = texture(" + id + ", " + uv + ")." + components + ";\n";
} else {
- code += " float _depth = textureLod(DEPTH_TEXTURE, " + default_uv + ", " + p_input_vars[1] + ").r;\n";
+ code += " " + type + " " + var_name + " = textureLod(" + id + ", " + uv + ", " + p_input_vars[1] + ")." + components + ";\n";
}
- } else if (p_input_vars[1].is_empty()) {
- //no lod
- code += " float _depth = texture(DEPTH_TEXTURE, " + p_input_vars[0] + ".xy).r;\n";
- } else {
- code += " float _depth = textureLod(DEPTH_TEXTURE, " + p_input_vars[0] + ".xy, " + p_input_vars[1] + ").r;\n";
- }
+ if (source == SOURCE_3D_NORMAL) {
+ code += " " + p_output_vars[0] + " = vec4(" + var_name + ", 1.0);\n";
+ } else {
+ code += " " + p_output_vars[0] + " = vec4(" + var_name + ", " + var_name + ", " + var_name + ", 1.0);\n";
+ }
+ code += " }\n";
- code += " " + p_output_vars[0] + " = vec4(_depth, _depth, _depth, 1.0);\n";
- code += " }\n";
- return code;
- }
+ return code;
+ }
+ } break;
+ default: {
+ } break;
}
code += " " + p_output_vars[0] + " = vec4(0.0);\n";
@@ -921,12 +937,17 @@ void VisualShaderNodeTexture::set_source(Source p_source) {
case SOURCE_PORT:
simple_decl = false;
break;
+ case SOURCE_3D_NORMAL:
+ simple_decl = false;
+ break;
+ case SOURCE_ROUGHNESS:
+ simple_decl = false;
+ break;
default:
break;
}
source = p_source;
emit_changed();
- emit_signal(SNAME("editor_refresh_request"));
}
VisualShaderNodeTexture::Source VisualShaderNodeTexture::get_source() const {
@@ -970,31 +991,34 @@ String VisualShaderNodeTexture::get_warning(Shader::Mode p_mode, VisualShader::T
return RTR("The sampler port is connected but not used. Consider changing the source to 'SamplerPort'.");
}
- if (source == SOURCE_TEXTURE) {
- return String(); // all good
- }
-
- if (source == SOURCE_PORT) {
- return String(); // all good
- }
-
- if (source == SOURCE_SCREEN && (p_mode == Shader::MODE_SPATIAL || p_mode == Shader::MODE_CANVAS_ITEM) && p_type == VisualShader::TYPE_FRAGMENT) {
- return String(); // all good
- }
-
- if (source == SOURCE_2D_TEXTURE && p_mode == Shader::MODE_CANVAS_ITEM && p_type == VisualShader::TYPE_FRAGMENT) {
- return String(); // all good
- }
-
- if (source == SOURCE_2D_NORMAL && p_mode == Shader::MODE_CANVAS_ITEM) {
- return String(); // all good
- }
-
- if (source == SOURCE_DEPTH && p_mode == Shader::MODE_SPATIAL && p_type == VisualShader::TYPE_FRAGMENT) {
- if (get_output_port_for_preview() == 0) { // DEPTH_TEXTURE is not supported in preview(canvas_item) shader
- return RTR("Invalid source for preview.");
- }
- return String(); // all good
+ switch (source) {
+ case SOURCE_TEXTURE:
+ case SOURCE_PORT: {
+ return String(); // All good.
+ } break;
+ case SOURCE_SCREEN: {
+ if ((p_mode == Shader::MODE_SPATIAL || p_mode == Shader::MODE_CANVAS_ITEM) && p_type == VisualShader::TYPE_FRAGMENT) {
+ return String(); // All good.
+ }
+ } break;
+ case SOURCE_2D_NORMAL:
+ case SOURCE_2D_TEXTURE: {
+ if (p_mode == Shader::MODE_CANVAS_ITEM && p_type == VisualShader::TYPE_FRAGMENT) {
+ return String(); // All good.
+ }
+ } break;
+ case SOURCE_3D_NORMAL:
+ case SOURCE_ROUGHNESS:
+ case SOURCE_DEPTH: {
+ if (p_mode == Shader::MODE_SPATIAL && p_type == VisualShader::TYPE_FRAGMENT) {
+ if (get_output_port_for_preview() == 0) { // Not supported in preview(canvas_item) shader.
+ return RTR("Invalid source for preview.");
+ }
+ return String(); // All good.
+ }
+ } break;
+ default: {
+ } break;
}
return RTR("Invalid source for shader.");
@@ -1010,7 +1034,7 @@ void VisualShaderNodeTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_texture_type", "value"), &VisualShaderNodeTexture::set_texture_type);
ClassDB::bind_method(D_METHOD("get_texture_type"), &VisualShaderNodeTexture::get_texture_type);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "source", PROPERTY_HINT_ENUM, "Texture,Screen,Texture2D,NormalMap2D,Depth,SamplerPort"), "set_source", "get_source");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "source", PROPERTY_HINT_ENUM, "Texture,Screen,Texture2D,NormalMap2D,Depth,SamplerPort,Normal3D,Roughness"), "set_source", "get_source");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normal Map"), "set_texture_type", "get_texture_type");
@@ -1020,6 +1044,8 @@ void VisualShaderNodeTexture::_bind_methods() {
BIND_ENUM_CONSTANT(SOURCE_2D_NORMAL);
BIND_ENUM_CONSTANT(SOURCE_DEPTH);
BIND_ENUM_CONSTANT(SOURCE_PORT);
+ BIND_ENUM_CONSTANT(SOURCE_3D_NORMAL);
+ BIND_ENUM_CONSTANT(SOURCE_ROUGHNESS);
BIND_ENUM_CONSTANT(SOURCE_MAX);
BIND_ENUM_CONSTANT(TYPE_DATA);
@@ -1260,6 +1286,17 @@ bool VisualShaderNodeSample3D::is_input_port_default(int p_port, Shader::Mode p_
}
String VisualShaderNodeSample3D::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+ String code;
+ String id;
+ if (source == SOURCE_TEXTURE) {
+ id = make_unique_id(p_type, p_id, "tex3d");
+ } else { // SOURCE_PORT
+ id = p_input_vars[2];
+ if (id.is_empty()) {
+ code += " " + p_output_vars[0] + " = vec4(0.0);\n";
+ return code;
+ }
+ }
String default_uv;
if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) {
default_uv = "vec3(UV, 0.0)";
@@ -1267,33 +1304,12 @@ String VisualShaderNodeSample3D::generate_code(Shader::Mode p_mode, VisualShader
default_uv = "vec3(0.0)";
}
- String code;
- if (source == SOURCE_TEXTURE || source == SOURCE_PORT) {
- String id;
- if (source == SOURCE_TEXTURE) {
- id = make_unique_id(p_type, p_id, "tex3d");
- } else {
- id = p_input_vars[2];
- }
- if (!id.is_empty()) {
- if (p_input_vars[0].is_empty()) { // Use UV by default.
- if (p_input_vars[1].is_empty()) {
- code += " " + p_output_vars[0] + " = texture(" + id + ", " + default_uv + ");\n";
- } else {
- code += " " + p_output_vars[0] + " = textureLod(" + id + ", " + default_uv + ", " + p_input_vars[1] + ");\n";
- }
- } else if (p_input_vars[1].is_empty()) {
- //no lod
- code += " " + p_output_vars[0] + " = texture(" + id + ", " + p_input_vars[0] + ");\n";
- } else {
- code += " " + p_output_vars[0] + " = textureLod(" + id + ", " + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
- }
- } else {
- code += " " + p_output_vars[0] + " = vec4(0.0);\n";
- }
- return code;
+ String uv = p_input_vars[0].is_empty() ? default_uv : p_input_vars[0];
+ if (p_input_vars[1].is_empty()) {
+ code += " " + p_output_vars[0] + " = texture(" + id + ", " + uv + ");\n";
+ } else {
+ code += " " + p_output_vars[0] + " = textureLod(" + id + ", " + uv + ", " + p_input_vars[1] + ");\n";
}
- code += " " + p_output_vars[0] + " = vec4(0.0);\n";
return code;
}
@@ -1304,7 +1320,6 @@ void VisualShaderNodeSample3D::set_source(Source p_source) {
}
source = p_source;
emit_changed();
- emit_signal(SNAME("editor_refresh_request"));
}
VisualShaderNodeSample3D::Source VisualShaderNodeSample3D::get_source() const {
@@ -1326,14 +1341,7 @@ String VisualShaderNodeSample3D::get_warning(Shader::Mode p_mode, VisualShader::
if (is_input_port_connected(2) && source != SOURCE_PORT) {
return RTR("The sampler port is connected but not used. Consider changing the source to 'SamplerPort'.");
}
-
- if (source == SOURCE_TEXTURE) {
- return String(); // all good
- }
- if (source == SOURCE_PORT) {
- return String(); // all good
- }
- return RTR("Invalid source for shader.");
+ return String();
}
VisualShaderNodeSample3D::VisualShaderNodeSample3D() {
@@ -1539,42 +1547,33 @@ String VisualShaderNodeCubemap::generate_global(Shader::Mode p_mode, VisualShade
}
String VisualShaderNodeCubemap::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
- String default_uv;
- if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) {
- default_uv = "vec3(UV, 0.0)";
- } else {
- default_uv = "vec3(0.0)";
- }
-
String code;
String id;
+
if (source == SOURCE_TEXTURE) {
id = make_unique_id(p_type, p_id, "cube");
- } else if (source == SOURCE_PORT) {
+ } else { // SOURCE_PORT
id = p_input_vars[2];
- } else {
- return code;
+ if (id.is_empty()) {
+ code += " " + p_output_vars[0] + " = vec4(0.0);\n";
+ return code;
+ }
}
- if (id.is_empty()) {
- code += " " + p_output_vars[0] + " = vec4(0.0);\n";
- return code;
+ String default_uv;
+ if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) {
+ default_uv = "vec3(UV, 0.0)";
+ } else {
+ default_uv = "vec3(0.0)";
}
- if (p_input_vars[0].is_empty()) { // Use UV by default.
-
- if (p_input_vars[1].is_empty()) {
- code += " " + p_output_vars[0] + " = texture(" + id + ", " + default_uv + ");\n";
- } else {
- code += " " + p_output_vars[0] + " = textureLod(" + id + ", " + default_uv + ", " + p_input_vars[1] + ");\n";
- }
-
- } else if (p_input_vars[1].is_empty()) {
- //no lod
- code += " " + p_output_vars[0] + " = texture(" + id + ", " + p_input_vars[0] + ");\n";
+ String uv = p_input_vars[0].is_empty() ? default_uv : p_input_vars[0];
+ if (p_input_vars[1].is_empty()) {
+ code += " " + p_output_vars[0] + " = texture(" + id + ", " + uv + ");\n";
} else {
- code += " " + p_output_vars[0] + " = textureLod(" + id + ", " + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ code += " " + p_output_vars[0] + " = textureLod(" + id + ", " + uv + ", " + p_input_vars[1] + ");\n";
}
+
return code;
}
@@ -1594,7 +1593,6 @@ void VisualShaderNodeCubemap::set_source(Source p_source) {
}
source = p_source;
emit_changed();
- emit_signal(SNAME("editor_refresh_request"));
}
VisualShaderNodeCubemap::Source VisualShaderNodeCubemap::get_source() const {
@@ -1702,11 +1700,15 @@ bool VisualShaderNodeLinearSceneDepth::has_output_port_preview(int p_port) const
return false;
}
+String VisualShaderNodeLinearSceneDepth::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+ return "uniform sampler2D " + make_unique_id(p_type, p_id, "depth_tex") + " : hint_depth_texture;\n";
+}
+
String VisualShaderNodeLinearSceneDepth::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
String code;
code += " {\n";
- code += " float __log_depth = textureLod(DEPTH_TEXTURE, SCREEN_UV, 0.0).x;\n";
+ code += " float __log_depth = textureLod(" + make_unique_id(p_type, p_id, "depth_tex") + ", SCREEN_UV, 0.0).x;\n";
code += " vec3 __depth_ndc = vec3(SCREEN_UV * 2.0 - 1.0, __log_depth);\n";
code += " vec4 __depth_view = INV_PROJECTION_MATRIX * vec4(__depth_ndc, 1.0);\n";
code += " __depth_view.xyz /= __depth_view.w;\n";
@@ -3688,16 +3690,47 @@ String VisualShaderNodeDerivativeFunc::get_output_port_name(int p_port) const {
String VisualShaderNodeDerivativeFunc::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
static const char *functions[FUNC_MAX] = {
- "fwidth($)",
- "dFdx($)",
- "dFdy($)"
+ "fwidth$($)",
+ "dFdx$($)",
+ "dFdy$($)"
+ };
+
+ static const char *precisions[PRECISION_MAX] = {
+ "",
+ "Coarse",
+ "Fine"
};
String code;
- code += " " + p_output_vars[0] + " = " + String(functions[func]).replace("$", p_input_vars[0]) + ";\n";
+ if (OS::get_singleton()->get_current_rendering_method() == "gl_compatibility") {
+ code += " " + p_output_vars[0] + " = " + String(functions[func]).replace_first("$", "").replace_first("$", p_input_vars[0]) + ";\n";
+ return code;
+ }
+
+ code += " " + p_output_vars[0] + " = " + String(functions[func]).replace_first("$", String(precisions[precision])).replace_first("$", p_input_vars[0]) + ";\n";
return code;
}
+String VisualShaderNodeDerivativeFunc::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const {
+ if (precision != PRECISION_NONE && OS::get_singleton()->get_current_rendering_method() == "gl_compatibility") {
+ String precision_str;
+ switch (precision) {
+ case PRECISION_COARSE: {
+ precision_str = "Coarse";
+ } break;
+ case PRECISION_FINE: {
+ precision_str = "Fine";
+ } break;
+ default: {
+ } break;
+ }
+
+ return vformat(RTR("`%s` precision mode is not available for `gl_compatibility` profile.\nReverted to `None` precision."), precision_str);
+ }
+
+ return String();
+}
+
void VisualShaderNodeDerivativeFunc::set_op_type(OpType p_op_type) {
ERR_FAIL_INDEX((int)p_op_type, int(OP_TYPE_MAX));
if (op_type == p_op_type) {
@@ -3740,10 +3773,24 @@ VisualShaderNodeDerivativeFunc::Function VisualShaderNodeDerivativeFunc::get_fun
return func;
}
+void VisualShaderNodeDerivativeFunc::set_precision(Precision p_precision) {
+ ERR_FAIL_INDEX(int(p_precision), int(PRECISION_MAX));
+ if (precision == p_precision) {
+ return;
+ }
+ precision = p_precision;
+ emit_changed();
+}
+
+VisualShaderNodeDerivativeFunc::Precision VisualShaderNodeDerivativeFunc::get_precision() const {
+ return precision;
+}
+
Vector<StringName> VisualShaderNodeDerivativeFunc::get_editable_properties() const {
Vector<StringName> props;
props.push_back("op_type");
props.push_back("function");
+ props.push_back("precision");
return props;
}
@@ -3754,8 +3801,12 @@ void VisualShaderNodeDerivativeFunc::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeDerivativeFunc::set_function);
ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeDerivativeFunc::get_function);
+ ClassDB::bind_method(D_METHOD("set_precision", "precision"), &VisualShaderNodeDerivativeFunc::set_precision);
+ ClassDB::bind_method(D_METHOD("get_precision"), &VisualShaderNodeDerivativeFunc::get_precision);
+
ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector2,Vector3,Vector4"), "set_op_type", "get_op_type");
ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Sum,X,Y"), "set_function", "get_function");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "precision", PROPERTY_HINT_ENUM, "None,Coarse,Fine"), "set_precision", "get_precision");
BIND_ENUM_CONSTANT(OP_TYPE_SCALAR);
BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D);
@@ -3767,6 +3818,11 @@ void VisualShaderNodeDerivativeFunc::_bind_methods() {
BIND_ENUM_CONSTANT(FUNC_X);
BIND_ENUM_CONSTANT(FUNC_Y);
BIND_ENUM_CONSTANT(FUNC_MAX);
+
+ BIND_ENUM_CONSTANT(PRECISION_NONE);
+ BIND_ENUM_CONSTANT(PRECISION_COARSE);
+ BIND_ENUM_CONSTANT(PRECISION_FINE);
+ BIND_ENUM_CONSTANT(PRECISION_MAX);
}
VisualShaderNodeDerivativeFunc::VisualShaderNodeDerivativeFunc() {
@@ -6101,7 +6157,7 @@ VisualShaderNodeTransformParameter::VisualShaderNodeTransformParameter() {
//////////////
-String get_sampler_hint(VisualShaderNodeTextureParameter::TextureType p_texture_type, VisualShaderNodeTextureParameter::ColorDefault p_color_default, VisualShaderNodeTextureParameter::TextureFilter p_texture_filter, VisualShaderNodeTextureParameter::TextureRepeat p_texture_repeat) {
+String get_sampler_hint(VisualShaderNodeTextureParameter::TextureType p_texture_type, VisualShaderNodeTextureParameter::ColorDefault p_color_default, VisualShaderNodeTextureParameter::TextureFilter p_texture_filter, VisualShaderNodeTextureParameter::TextureRepeat p_texture_repeat, VisualShaderNodeTextureParameter::TextureSource p_texture_source) {
String code;
bool has_colon = false;
@@ -6204,6 +6260,33 @@ String get_sampler_hint(VisualShaderNodeTextureParameter::TextureType p_texture_
}
}
+ {
+ String source_code;
+
+ switch (p_texture_source) {
+ case VisualShaderNodeTextureParameter::SOURCE_SCREEN:
+ source_code = "hint_screen_texture";
+ break;
+ case VisualShaderNodeTextureParameter::SOURCE_DEPTH:
+ source_code = "hint_depth_texture";
+ break;
+ case VisualShaderNodeTextureParameter::SOURCE_NORMAL_ROUGHNESS:
+ source_code = "hint_normal_roughness_texture";
+ break;
+ default:
+ break;
+ }
+
+ if (!source_code.is_empty()) {
+ if (!has_colon) {
+ code += " : ";
+ } else {
+ code += ", ";
+ }
+ code += source_code;
+ }
+ }
+
return code;
}
@@ -6290,6 +6373,19 @@ VisualShaderNodeTextureParameter::TextureRepeat VisualShaderNodeTextureParameter
return texture_repeat;
}
+void VisualShaderNodeTextureParameter::set_texture_source(TextureSource p_source) {
+ ERR_FAIL_INDEX(int(p_source), int(SOURCE_MAX));
+ if (texture_source == p_source) {
+ return;
+ }
+ texture_source = p_source;
+ emit_changed();
+}
+
+VisualShaderNodeTextureParameter::TextureSource VisualShaderNodeTextureParameter::get_texture_source() const {
+ return texture_source;
+}
+
Vector<StringName> VisualShaderNodeTextureParameter::get_editable_properties() const {
Vector<StringName> props = VisualShaderNodeParameter::get_editable_properties();
props.push_back("texture_type");
@@ -6298,6 +6394,7 @@ Vector<StringName> VisualShaderNodeTextureParameter::get_editable_properties() c
}
props.push_back("texture_filter");
props.push_back("texture_repeat");
+ props.push_back("texture_source");
return props;
}
@@ -6311,6 +6408,7 @@ HashMap<StringName, String> VisualShaderNodeTextureParameter::get_editable_prope
names.insert("color_default", RTR("Default Color"));
names.insert("texture_filter", RTR("Filter"));
names.insert("texture_repeat", RTR("Repeat"));
+ names.insert("texture_source", RTR("Source"));
return names;
}
@@ -6318,19 +6416,23 @@ void VisualShaderNodeTextureParameter::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_texture_type", "type"), &VisualShaderNodeTextureParameter::set_texture_type);
ClassDB::bind_method(D_METHOD("get_texture_type"), &VisualShaderNodeTextureParameter::get_texture_type);
- ClassDB::bind_method(D_METHOD("set_color_default", "type"), &VisualShaderNodeTextureParameter::set_color_default);
+ ClassDB::bind_method(D_METHOD("set_color_default", "color"), &VisualShaderNodeTextureParameter::set_color_default);
ClassDB::bind_method(D_METHOD("get_color_default"), &VisualShaderNodeTextureParameter::get_color_default);
ClassDB::bind_method(D_METHOD("set_texture_filter", "filter"), &VisualShaderNodeTextureParameter::set_texture_filter);
ClassDB::bind_method(D_METHOD("get_texture_filter"), &VisualShaderNodeTextureParameter::get_texture_filter);
- ClassDB::bind_method(D_METHOD("set_texture_repeat", "type"), &VisualShaderNodeTextureParameter::set_texture_repeat);
+ ClassDB::bind_method(D_METHOD("set_texture_repeat", "repeat"), &VisualShaderNodeTextureParameter::set_texture_repeat);
ClassDB::bind_method(D_METHOD("get_texture_repeat"), &VisualShaderNodeTextureParameter::get_texture_repeat);
+ ClassDB::bind_method(D_METHOD("set_texture_source", "source"), &VisualShaderNodeTextureParameter::set_texture_source);
+ ClassDB::bind_method(D_METHOD("get_texture_source"), &VisualShaderNodeTextureParameter::get_texture_source);
+
ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normal Map,Anisotropic"), "set_texture_type", "get_texture_type");
ADD_PROPERTY(PropertyInfo(Variant::INT, "color_default", PROPERTY_HINT_ENUM, "White,Black,Transparent"), "set_color_default", "get_color_default");
ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_filter", PROPERTY_HINT_ENUM, "Default,Nearest,Linear,Nearest Mipmap,Linear Mipmap,Nearest Mipmap Anisotropic,Linear Mipmap Anisotropic"), "set_texture_filter", "get_texture_filter");
ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_repeat", PROPERTY_HINT_ENUM, "Default,Enabled,Disabled"), "set_texture_repeat", "get_texture_repeat");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_source", PROPERTY_HINT_ENUM, "None,Screen,Depth,NormalRoughness"), "set_texture_source", "get_texture_source");
BIND_ENUM_CONSTANT(TYPE_DATA);
BIND_ENUM_CONSTANT(TYPE_COLOR);
@@ -6356,6 +6458,12 @@ void VisualShaderNodeTextureParameter::_bind_methods() {
BIND_ENUM_CONSTANT(REPEAT_ENABLED);
BIND_ENUM_CONSTANT(REPEAT_DISABLED);
BIND_ENUM_CONSTANT(REPEAT_MAX);
+
+ BIND_ENUM_CONSTANT(SOURCE_NONE);
+ BIND_ENUM_CONSTANT(SOURCE_SCREEN);
+ BIND_ENUM_CONSTANT(SOURCE_DEPTH);
+ BIND_ENUM_CONSTANT(SOURCE_NORMAL_ROUGHNESS);
+ BIND_ENUM_CONSTANT(SOURCE_MAX);
}
bool VisualShaderNodeTextureParameter::is_qualifier_supported(Qualifier p_qual) const {
@@ -6396,7 +6504,7 @@ String VisualShaderNodeTexture2DParameter::get_output_port_name(int p_port) cons
String VisualShaderNodeTexture2DParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
String code = _get_qual_str() + "uniform sampler2D " + get_parameter_name();
- code += get_sampler_hint(texture_type, color_default, texture_filter, texture_repeat);
+ code += get_sampler_hint(texture_type, color_default, texture_filter, texture_repeat, texture_source);
code += ";\n";
return code;
}
@@ -6407,7 +6515,7 @@ VisualShaderNodeTexture2DParameter::VisualShaderNodeTexture2DParameter() {
////////////// Texture Parameter (Triplanar)
String VisualShaderNodeTextureParameterTriplanar::get_caption() const {
- return "TextureUniformTriplanar";
+ return "TextureParameterTriplanar";
}
int VisualShaderNodeTextureParameterTriplanar::get_input_port_count() const {
@@ -6496,7 +6604,7 @@ String VisualShaderNodeTextureParameterTriplanar::generate_global_per_func(Shade
String VisualShaderNodeTextureParameterTriplanar::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
String code = _get_qual_str() + "uniform sampler2D " + get_parameter_name();
- code += get_sampler_hint(texture_type, color_default, texture_filter, texture_repeat);
+ code += get_sampler_hint(texture_type, color_default, texture_filter, texture_repeat, texture_source);
code += ";\n";
return code;
}
@@ -6542,7 +6650,7 @@ String VisualShaderNodeTexture2DArrayParameter::get_output_port_name(int p_port)
String VisualShaderNodeTexture2DArrayParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
String code = _get_qual_str() + "uniform sampler2DArray " + get_parameter_name();
- code += get_sampler_hint(texture_type, color_default, texture_filter, texture_repeat);
+ code += get_sampler_hint(texture_type, color_default, texture_filter, texture_repeat, texture_source);
code += ";\n";
return code;
}
@@ -6562,7 +6670,7 @@ String VisualShaderNodeTexture3DParameter::get_output_port_name(int p_port) cons
String VisualShaderNodeTexture3DParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
String code = _get_qual_str() + "uniform sampler3D " + get_parameter_name();
- code += get_sampler_hint(texture_type, color_default, texture_filter, texture_repeat);
+ code += get_sampler_hint(texture_type, color_default, texture_filter, texture_repeat, texture_source);
code += ";\n";
return code;
}
@@ -6582,7 +6690,7 @@ String VisualShaderNodeCubemapParameter::get_output_port_name(int p_port) const
String VisualShaderNodeCubemapParameter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
String code = _get_qual_str() + "uniform samplerCube " + get_parameter_name();
- code += get_sampler_hint(texture_type, color_default, texture_filter, texture_repeat);
+ code += get_sampler_hint(texture_type, color_default, texture_filter, texture_repeat, texture_source);
code += ";\n";
return code;
}
@@ -7640,12 +7748,15 @@ bool VisualShaderNodeProximityFade::has_output_port_preview(int p_port) const {
return false;
}
+String VisualShaderNodeProximityFade::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+ return "uniform sampler2D " + make_unique_id(p_type, p_id, "depth_tex") + " : hint_depth_texture;\n";
+}
+
String VisualShaderNodeProximityFade::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
String code;
code += " {\n";
- String proximity_fade_distance = vformat("%s", p_input_vars[0]);
- code += " float __depth_tex = textureLod(DEPTH_TEXTURE, SCREEN_UV, 0.0).r;\n";
+ code += " float __depth_tex = texture(" + make_unique_id(p_type, p_id, "depth_tex") + ", SCREEN_UV).r;\n";
if (!RenderingServer::get_singleton()->is_low_end()) {
code += " vec4 __depth_world_pos = INV_PROJECTION_MATRIX * vec4(SCREEN_UV * 2.0 - 1.0, __depth_tex, 1.0);\n";
} else {
diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h
index 07843c0264..fa6b134526 100644
--- a/scene/resources/visual_shader_nodes.h
+++ b/scene/resources/visual_shader_nodes.h
@@ -385,6 +385,8 @@ public:
SOURCE_2D_NORMAL,
SOURCE_DEPTH,
SOURCE_PORT,
+ SOURCE_3D_NORMAL,
+ SOURCE_ROUGHNESS,
SOURCE_MAX,
};
@@ -668,6 +670,7 @@ public:
virtual String get_output_port_name(int p_port) const override;
virtual bool has_output_port_preview(int p_port) const override;
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
VisualShaderNodeLinearSceneDepth();
@@ -1533,9 +1536,17 @@ public:
FUNC_MAX,
};
+ enum Precision {
+ PRECISION_NONE,
+ PRECISION_COARSE,
+ PRECISION_FINE,
+ PRECISION_MAX,
+ };
+
protected:
OpType op_type = OP_TYPE_SCALAR;
Function func = FUNC_SUM;
+ Precision precision = PRECISION_NONE;
protected:
static void _bind_methods();
@@ -1552,6 +1563,7 @@ public:
virtual String get_output_port_name(int p_port) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const override;
void set_op_type(OpType p_op_type);
OpType get_op_type() const;
@@ -1559,6 +1571,9 @@ public:
void set_function(Function p_func);
Function get_function() const;
+ void set_precision(Precision p_precision);
+ Precision get_precision() const;
+
virtual Vector<StringName> get_editable_properties() const override;
VisualShaderNodeDerivativeFunc();
@@ -1566,6 +1581,7 @@ public:
VARIANT_ENUM_CAST(VisualShaderNodeDerivativeFunc::OpType)
VARIANT_ENUM_CAST(VisualShaderNodeDerivativeFunc::Function)
+VARIANT_ENUM_CAST(VisualShaderNodeDerivativeFunc::Precision)
///////////////////////////////////////
/// FACEFORWARD
@@ -2362,11 +2378,20 @@ public:
REPEAT_MAX,
};
+ enum TextureSource {
+ SOURCE_NONE,
+ SOURCE_SCREEN,
+ SOURCE_DEPTH,
+ SOURCE_NORMAL_ROUGHNESS,
+ SOURCE_MAX,
+ };
+
protected:
TextureType texture_type = TYPE_DATA;
ColorDefault color_default = COLOR_DEFAULT_WHITE;
TextureFilter texture_filter = FILTER_DEFAULT;
TextureRepeat texture_repeat = REPEAT_DEFAULT;
+ TextureSource texture_source = SOURCE_NONE;
protected:
static void _bind_methods();
@@ -2398,6 +2423,9 @@ public:
void set_texture_repeat(TextureRepeat p_repeat);
TextureRepeat get_texture_repeat() const;
+ void set_texture_source(TextureSource p_source);
+ TextureSource get_texture_source() const;
+
bool is_qualifier_supported(Qualifier p_qual) const override;
bool is_convertible_to_constant() const override;
@@ -2408,6 +2436,7 @@ VARIANT_ENUM_CAST(VisualShaderNodeTextureParameter::TextureType)
VARIANT_ENUM_CAST(VisualShaderNodeTextureParameter::ColorDefault)
VARIANT_ENUM_CAST(VisualShaderNodeTextureParameter::TextureFilter)
VARIANT_ENUM_CAST(VisualShaderNodeTextureParameter::TextureRepeat)
+VARIANT_ENUM_CAST(VisualShaderNodeTextureParameter::TextureSource)
///////////////////////////////////////
@@ -2833,6 +2862,7 @@ public:
virtual String get_output_port_name(int p_port) const override;
virtual bool has_output_port_preview(int p_port) const override;
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
VisualShaderNodeProximityFade();