summaryrefslogtreecommitdiff
path: root/scene/resources
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources')
-rw-r--r--scene/resources/animation.cpp4
-rw-r--r--scene/resources/default_theme/default_theme.cpp37
-rw-r--r--scene/resources/default_theme/default_theme.h2
-rw-r--r--scene/resources/font.cpp42
-rw-r--r--scene/resources/font.h8
-rw-r--r--scene/resources/material.cpp36
-rw-r--r--scene/resources/material.h13
-rw-r--r--scene/resources/mesh.cpp131
-rw-r--r--scene/resources/mesh.h63
-rw-r--r--scene/resources/packed_scene.cpp2
-rw-r--r--scene/resources/packed_scene.h2
-rw-r--r--scene/resources/primitive_meshes.cpp12
-rw-r--r--scene/resources/primitive_meshes.h3
-rw-r--r--scene/resources/resource_format_text.cpp3
-rw-r--r--scene/resources/sky_material.cpp33
-rw-r--r--scene/resources/sky_material.h8
-rw-r--r--scene/resources/style_box.cpp33
-rw-r--r--scene/resources/style_box.h10
-rw-r--r--scene/resources/texture.cpp440
-rw-r--r--scene/resources/texture.h120
-rw-r--r--scene/resources/visual_shader.cpp619
-rw-r--r--scene/resources/visual_shader.h170
-rw-r--r--scene/resources/visual_shader_nodes.cpp6
23 files changed, 1525 insertions, 272 deletions
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index 312a557602..f6e0df0265 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -4347,7 +4347,7 @@ struct AnimationCompressionDataState {
if (temp_packets.size() == 0) {
return; //nohing to do
}
-#define DEBUG_PACKET_PUSH
+//#define DEBUG_PACKET_PUSH
#ifdef DEBUG_PACKET_PUSH
#ifndef _MSC_VER
#warning Debugging packet push, disable this code in production to gain a bit more import performance.
@@ -4378,7 +4378,7 @@ struct AnimationCompressionDataState {
header_bytes += 2;
}
- while (header_bytes % 4 != 0) {
+ while (header_bytes < 8 && header_bytes % 4 != 0) { // First cond needed to silence wrong GCC warning.
header[header_bytes++] = 0;
}
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 61114333fb..da37228ed9 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -103,7 +103,7 @@ static Ref<StyleBox> make_empty_stylebox(float p_margin_left = -1, float p_margi
return style;
}
-void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, Ref<Texture2D> &default_icon, Ref<StyleBox> &default_style, float p_scale) {
+void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const Ref<Font> &bold_font, const Ref<Font> &bold_italics_font, const Ref<Font> &italics_font, Ref<Texture2D> &default_icon, Ref<StyleBox> &default_style, float p_scale) {
scale = p_scale;
// Font colors
@@ -924,9 +924,9 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, Ref<Te
theme->set_stylebox("normal", "RichTextLabel", make_empty_stylebox(0, 0, 0, 0));
theme->set_font("normal_font", "RichTextLabel", Ref<Font>());
- theme->set_font("bold_font", "RichTextLabel", Ref<Font>());
- theme->set_font("italics_font", "RichTextLabel", Ref<Font>());
- theme->set_font("bold_italics_font", "RichTextLabel", Ref<Font>());
+ theme->set_font("bold_font", "RichTextLabel", bold_font);
+ theme->set_font("italics_font", "RichTextLabel", italics_font);
+ theme->set_font("bold_italics_font", "RichTextLabel", bold_italics_font);
theme->set_font("mono_font", "RichTextLabel", Ref<Font>());
theme->set_font_size("normal_font_size", "RichTextLabel", -1);
@@ -1025,6 +1025,9 @@ void make_default_theme(float p_scale, Ref<Font> p_font, TextServer::SubpixelPos
Ref<StyleBox> default_style;
Ref<Texture2D> default_icon;
Ref<Font> default_font;
+ Ref<Font> bold_font;
+ Ref<Font> bold_italics_font;
+ Ref<Font> italics_font;
float default_scale = CLAMP(p_scale, 0.5, 8.0);
if (p_font.is_valid()) {
@@ -1048,7 +1051,31 @@ void make_default_theme(float p_scale, Ref<Font> p_font, TextServer::SubpixelPos
default_font = dynamic_font;
}
- fill_default_theme(t, default_font, default_icon, default_style, default_scale);
+ if (default_font.is_valid()) {
+ bold_font.instantiate();
+ for (int i = 0; i < default_font->get_data_count(); i++) {
+ Ref<FontData> data = default_font->get_data(i)->duplicate();
+ data->set_embolden(1.2);
+ bold_font->add_data(data);
+ }
+
+ bold_italics_font.instantiate();
+ for (int i = 0; i < default_font->get_data_count(); i++) {
+ Ref<FontData> data = default_font->get_data(i)->duplicate();
+ data->set_embolden(1.2);
+ data->set_transform(Transform2D(1.0, 0.4, 0.0, 1.0, 0.0, 0.0));
+ bold_italics_font->add_data(data);
+ }
+
+ italics_font.instantiate();
+ for (int i = 0; i < default_font->get_data_count(); i++) {
+ Ref<FontData> data = default_font->get_data(i)->duplicate();
+ data->set_transform(Transform2D(1.0, 0.4, 0.0, 1.0, 0.0, 0.0));
+ italics_font->add_data(data);
+ }
+ }
+
+ fill_default_theme(t, default_font, bold_font, bold_italics_font, italics_font, default_icon, default_style, default_scale);
Theme::set_default(t);
Theme::set_fallback_base_scale(default_scale);
diff --git a/scene/resources/default_theme/default_theme.h b/scene/resources/default_theme/default_theme.h
index 28afd5f5e1..a9e21dda3f 100644
--- a/scene/resources/default_theme/default_theme.h
+++ b/scene/resources/default_theme/default_theme.h
@@ -35,7 +35,7 @@
const int default_font_size = 16;
-void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, Ref<Texture2D> &default_icon, Ref<StyleBox> &default_style, float p_scale);
+void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const Ref<Font> &bold_font, const Ref<Font> &bold_italics_font, const Ref<Font> &italics_font, Ref<Texture2D> &default_icon, Ref<StyleBox> &default_style, float p_scale);
void make_default_theme(float p_scale, Ref<Font> p_font, TextServer::SubpixelPositioning p_subpixel, TextServer::Hinting p_hinting, bool p_aa);
void clear_default_theme();
diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp
index 5b57e93950..ce2a675854 100644
--- a/scene/resources/font.cpp
+++ b/scene/resources/font.cpp
@@ -61,6 +61,8 @@ _FORCE_INLINE_ void FontData::_ensure_rid(int p_cache_index) const {
TS->font_set_force_autohinter(cache[p_cache_index], force_autohinter);
TS->font_set_hinting(cache[p_cache_index], hinting);
TS->font_set_subpixel_positioning(cache[p_cache_index], subpixel_positioning);
+ TS->font_set_embolden(cache[p_cache_index], embolden);
+ TS->font_set_transform(cache[p_cache_index], transform);
TS->font_set_oversampling(cache[p_cache_index], oversampling);
}
}
@@ -105,6 +107,12 @@ void FontData::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_subpixel_positioning", "subpixel_positioning"), &FontData::set_subpixel_positioning);
ClassDB::bind_method(D_METHOD("get_subpixel_positioning"), &FontData::get_subpixel_positioning);
+ ClassDB::bind_method(D_METHOD("set_embolden", "strength"), &FontData::set_embolden);
+ ClassDB::bind_method(D_METHOD("get_embolden"), &FontData::get_embolden);
+
+ ClassDB::bind_method(D_METHOD("set_transform", "transform"), &FontData::set_transform);
+ ClassDB::bind_method(D_METHOD("get_transform"), &FontData::get_transform);
+
ClassDB::bind_method(D_METHOD("set_oversampling", "oversampling"), &FontData::set_oversampling);
ClassDB::bind_method(D_METHOD("get_oversampling"), &FontData::get_oversampling);
@@ -209,6 +217,8 @@ void FontData::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::STRING, "style_name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_font_style_name", "get_font_style_name");
ADD_PROPERTY(PropertyInfo(Variant::INT, "font_style", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_font_style", "get_font_style");
ADD_PROPERTY(PropertyInfo(Variant::INT, "subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One half of a pixel,One quarter of a pixel", PROPERTY_USAGE_STORAGE), "set_subpixel_positioning", "get_subpixel_positioning");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "embolden", PROPERTY_HINT_RANGE, "-2,2,0.01", PROPERTY_USAGE_STORAGE), "set_embolden", "get_embolden");
+ ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_transform", "get_transform");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "multichannel_signed_distance_field", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_multichannel_signed_distance_field", "is_multichannel_signed_distance_field");
ADD_PROPERTY(PropertyInfo(Variant::INT, "msdf_pixel_range", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_msdf_pixel_range", "get_msdf_pixel_range");
ADD_PROPERTY(PropertyInfo(Variant::INT, "msdf_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_msdf_size", "get_msdf_size");
@@ -439,6 +449,8 @@ void FontData::reset_state() {
msdf_pixel_range = 14;
msdf_size = 128;
fixed_size = 0;
+ embolden = 0.f;
+ transform = Transform2D();
oversampling = 0.f;
}
@@ -1385,6 +1397,36 @@ TextServer::SubpixelPositioning FontData::get_subpixel_positioning() const {
return subpixel_positioning;
}
+void FontData::set_embolden(float p_strength) {
+ if (embolden != p_strength) {
+ embolden = p_strength;
+ for (int i = 0; i < cache.size(); i++) {
+ _ensure_rid(i);
+ TS->font_set_embolden(cache[i], embolden);
+ }
+ emit_changed();
+ }
+}
+
+float FontData::get_embolden() const {
+ return embolden;
+}
+
+void FontData::set_transform(Transform2D p_transform) {
+ if (transform != p_transform) {
+ transform = p_transform;
+ for (int i = 0; i < cache.size(); i++) {
+ _ensure_rid(i);
+ TS->font_set_transform(cache[i], transform);
+ }
+ emit_changed();
+ }
+}
+
+Transform2D FontData::get_transform() const {
+ return transform;
+}
+
void FontData::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 aaf0a7fe7b..0185b019f1 100644
--- a/scene/resources/font.h
+++ b/scene/resources/font.h
@@ -57,6 +57,8 @@ class FontData : public Resource {
TextServer::Hinting hinting = TextServer::HINTING_LIGHT;
TextServer::SubpixelPositioning subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_AUTO;
real_t oversampling = 0.f;
+ real_t embolden = 0.f;
+ Transform2D transform;
// Cache.
mutable Vector<RID> cache;
@@ -122,6 +124,12 @@ public:
virtual void set_subpixel_positioning(TextServer::SubpixelPositioning p_subpixel);
virtual TextServer::SubpixelPositioning get_subpixel_positioning() const;
+ virtual void set_embolden(float p_strength);
+ virtual float get_embolden() const;
+
+ virtual void set_transform(Transform2D p_transform);
+ virtual Transform2D get_transform() const;
+
virtual void set_oversampling(real_t p_oversampling);
virtual real_t get_oversampling() const;
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 6fb0c0468d..a0e6cc28ce 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -88,6 +88,37 @@ void Material::inspect_native_shader_code() {
}
}
+RID Material::get_shader_rid() const {
+ RID ret;
+ if (GDVIRTUAL_REQUIRED_CALL(_get_shader_rid, ret)) {
+ return ret;
+ }
+ return RID();
+}
+Shader::Mode Material::get_shader_mode() const {
+ Shader::Mode ret;
+ if (GDVIRTUAL_REQUIRED_CALL(_get_shader_mode, ret)) {
+ return ret;
+ }
+
+ return Shader::MODE_MAX;
+}
+
+bool Material::_can_do_next_pass() const {
+ bool ret;
+ if (GDVIRTUAL_CALL(_can_do_next_pass, ret)) {
+ return ret;
+ }
+ return false;
+}
+bool Material::_can_use_render_priority() const {
+ bool ret;
+ if (GDVIRTUAL_CALL(_can_use_render_priority, ret)) {
+ return ret;
+ }
+ return false;
+}
+
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);
@@ -103,6 +134,11 @@ void Material::_bind_methods() {
BIND_CONSTANT(RENDER_PRIORITY_MAX);
BIND_CONSTANT(RENDER_PRIORITY_MIN);
+
+ GDVIRTUAL_BIND(_get_shader_rid)
+ GDVIRTUAL_BIND(_get_shader_mode)
+ GDVIRTUAL_BIND(_can_do_next_pass)
+ GDVIRTUAL_BIND(_can_use_render_priority)
}
Material::Material() {
diff --git a/scene/resources/material.h b/scene/resources/material.h
index a79f072f9a..07227c037c 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -51,11 +51,15 @@ class Material : public Resource {
protected:
_FORCE_INLINE_ RID _get_material() const { return material; }
static void _bind_methods();
- virtual bool _can_do_next_pass() const { return false; }
- virtual bool _can_use_render_priority() const { return false; }
+ virtual bool _can_do_next_pass() const;
+ virtual bool _can_use_render_priority() const;
void _validate_property(PropertyInfo &property) const override;
+ GDVIRTUAL0RC(RID, _get_shader_rid)
+ GDVIRTUAL0RC(Shader::Mode, _get_shader_mode)
+ GDVIRTUAL0RC(bool, _can_do_next_pass)
+ GDVIRTUAL0RC(bool, _can_use_render_priority)
public:
enum {
RENDER_PRIORITY_MAX = RS::MATERIAL_RENDER_PRIORITY_MAX,
@@ -68,9 +72,8 @@ public:
int get_render_priority() const;
virtual RID get_rid() const override;
- virtual RID get_shader_rid() const = 0;
-
- virtual Shader::Mode get_shader_mode() const = 0;
+ virtual RID get_shader_rid() const;
+ virtual Shader::Mode get_shader_mode() const;
Material();
virtual ~Material();
};
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index 6b44b05e02..3c67a20f50 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -40,6 +40,122 @@
Mesh::ConvexDecompositionFunc Mesh::convex_decomposition_function = nullptr;
+int Mesh::get_surface_count() const {
+ int ret;
+ if (GDVIRTUAL_REQUIRED_CALL(_get_surface_count, ret)) {
+ return ret;
+ }
+ return 0;
+}
+
+int Mesh::surface_get_array_len(int p_idx) const {
+ int ret;
+ if (GDVIRTUAL_REQUIRED_CALL(_surface_get_array_len, p_idx, ret)) {
+ return ret;
+ }
+ return 0;
+}
+
+int Mesh::surface_get_array_index_len(int p_idx) const {
+ int ret;
+ if (GDVIRTUAL_REQUIRED_CALL(_surface_get_array_index_len, p_idx, ret)) {
+ return ret;
+ }
+ return 0;
+}
+
+Array Mesh::surface_get_arrays(int p_surface) const {
+ Array ret;
+ if (GDVIRTUAL_REQUIRED_CALL(_surface_get_arrays, p_surface, ret)) {
+ return ret;
+ }
+ return Array();
+}
+
+Array Mesh::surface_get_blend_shape_arrays(int p_surface) const {
+ Array ret;
+ if (GDVIRTUAL_REQUIRED_CALL(_surface_get_blend_shape_arrays, p_surface, ret)) {
+ return ret;
+ }
+
+ return Array();
+}
+
+Dictionary Mesh::surface_get_lods(int p_surface) const {
+ Dictionary ret;
+ if (GDVIRTUAL_REQUIRED_CALL(_surface_get_lods, p_surface, ret)) {
+ return ret;
+ }
+
+ return Dictionary();
+}
+
+uint32_t Mesh::surface_get_format(int p_idx) const {
+ uint32_t ret;
+ if (GDVIRTUAL_REQUIRED_CALL(_surface_get_format, p_idx, ret)) {
+ return ret;
+ }
+
+ return 0;
+}
+
+Mesh::PrimitiveType Mesh::surface_get_primitive_type(int p_idx) const {
+ uint32_t ret;
+ if (GDVIRTUAL_REQUIRED_CALL(_surface_get_primitive_type, p_idx, ret)) {
+ return (Mesh::PrimitiveType)ret;
+ }
+
+ return PRIMITIVE_MAX;
+}
+
+void Mesh::surface_set_material(int p_idx, const Ref<Material> &p_material) {
+ if (GDVIRTUAL_REQUIRED_CALL(_surface_set_material, p_idx, p_material)) {
+ return;
+ }
+}
+
+Ref<Material> Mesh::surface_get_material(int p_idx) const {
+ Ref<Material> ret;
+ if (GDVIRTUAL_REQUIRED_CALL(_surface_get_material, p_idx, ret)) {
+ return ret;
+ }
+
+ return Ref<Material>();
+}
+
+int Mesh::get_blend_shape_count() const {
+ int ret;
+ if (GDVIRTUAL_REQUIRED_CALL(_get_blend_shape_count, ret)) {
+ return ret;
+ }
+
+ return 0;
+}
+
+StringName Mesh::get_blend_shape_name(int p_index) const {
+ StringName ret;
+ if (GDVIRTUAL_REQUIRED_CALL(_get_blend_shape_name, p_index, ret)) {
+ return ret;
+ }
+
+ return StringName();
+}
+
+void Mesh::set_blend_shape_name(int p_index, const StringName &p_name) {
+ if (GDVIRTUAL_REQUIRED_CALL(_set_blend_shape_name, p_index, p_name)) {
+ return;
+ }
+}
+
+AABB Mesh::get_aabb() const {
+ AABB ret;
+ if (GDVIRTUAL_REQUIRED_CALL(_get_aabb, ret)) {
+ return ret;
+ }
+
+ return AABB();
+}
+
Ref<TriangleMesh> Mesh::generate_triangle_mesh() const {
if (triangle_mesh.is_valid()) {
return triangle_mesh;
@@ -502,6 +618,21 @@ void Mesh::_bind_methods() {
BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_NORMALIZED);
BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_RELATIVE);
+
+ GDVIRTUAL_BIND(_get_surface_count)
+ GDVIRTUAL_BIND(_surface_get_array_len, "index")
+ GDVIRTUAL_BIND(_surface_get_array_index_len, "index")
+ GDVIRTUAL_BIND(_surface_get_arrays, "index")
+ GDVIRTUAL_BIND(_surface_get_blend_shape_arrays, "index")
+ GDVIRTUAL_BIND(_surface_get_lods, "index")
+ GDVIRTUAL_BIND(_surface_get_format, "index")
+ GDVIRTUAL_BIND(_surface_get_primitive_type, "index")
+ GDVIRTUAL_BIND(_surface_set_material, "index", "material")
+ GDVIRTUAL_BIND(_surface_get_material, "index")
+ GDVIRTUAL_BIND(_get_blend_shape_count)
+ GDVIRTUAL_BIND(_get_blend_shape_name, "index")
+ GDVIRTUAL_BIND(_set_blend_shape_name, "index", "name")
+ GDVIRTUAL_BIND(_get_aabb)
}
void Mesh::clear_cache() const {
diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h
index 08d834bdb9..652c045a24 100644
--- a/scene/resources/mesh.h
+++ b/scene/resources/mesh.h
@@ -45,9 +45,34 @@ class Mesh : public Resource {
mutable Vector<Vector3> debug_lines;
Size2i lightmap_size_hint;
+public:
+ enum PrimitiveType {
+ PRIMITIVE_POINTS = RenderingServer::PRIMITIVE_POINTS,
+ PRIMITIVE_LINES = RenderingServer::PRIMITIVE_LINES,
+ PRIMITIVE_LINE_STRIP = RenderingServer::PRIMITIVE_LINE_STRIP,
+ PRIMITIVE_TRIANGLES = RenderingServer::PRIMITIVE_TRIANGLES,
+ PRIMITIVE_TRIANGLE_STRIP = RenderingServer::PRIMITIVE_TRIANGLE_STRIP,
+ PRIMITIVE_MAX = RenderingServer::PRIMITIVE_MAX,
+ };
+
protected:
static void _bind_methods();
+ GDVIRTUAL0RC(int, _get_surface_count)
+ GDVIRTUAL1RC(int, _surface_get_array_len, int)
+ GDVIRTUAL1RC(int, _surface_get_array_index_len, int)
+ GDVIRTUAL1RC(Array, _surface_get_arrays, int)
+ GDVIRTUAL1RC(Array, _surface_get_blend_shape_arrays, int)
+ GDVIRTUAL1RC(Dictionary, _surface_get_lods, int)
+ GDVIRTUAL1RC(uint32_t, _surface_get_format, int)
+ GDVIRTUAL1RC(uint32_t, _surface_get_primitive_type, int)
+ GDVIRTUAL2(_surface_set_material, int, Ref<Material>)
+ GDVIRTUAL1RC(Ref<Material>, _surface_get_material, int)
+ GDVIRTUAL0RC(int, _get_blend_shape_count)
+ GDVIRTUAL1RC(StringName, _get_blend_shape_name, int)
+ GDVIRTUAL2(_set_blend_shape_name, int, StringName)
+ GDVIRTUAL0RC(AABB, _get_aabb)
+
public:
enum {
NO_INDEX_ARRAY = RenderingServer::NO_INDEX_ARRAY,
@@ -120,28 +145,20 @@ public:
};
- enum PrimitiveType {
- PRIMITIVE_POINTS = RenderingServer::PRIMITIVE_POINTS,
- PRIMITIVE_LINES = RenderingServer::PRIMITIVE_LINES,
- PRIMITIVE_LINE_STRIP = RenderingServer::PRIMITIVE_LINE_STRIP,
- PRIMITIVE_TRIANGLES = RenderingServer::PRIMITIVE_TRIANGLES,
- PRIMITIVE_TRIANGLE_STRIP = RenderingServer::PRIMITIVE_TRIANGLE_STRIP,
- PRIMITIVE_MAX = RenderingServer::PRIMITIVE_MAX,
- };
-
- virtual int get_surface_count() const = 0;
- virtual int surface_get_array_len(int p_idx) const = 0;
- virtual int surface_get_array_index_len(int p_idx) const = 0;
- virtual Array surface_get_arrays(int p_surface) const = 0;
- virtual Array surface_get_blend_shape_arrays(int p_surface) const = 0;
- virtual Dictionary surface_get_lods(int p_surface) const = 0;
- virtual uint32_t surface_get_format(int p_idx) const = 0;
- virtual PrimitiveType surface_get_primitive_type(int p_idx) const = 0;
- virtual void surface_set_material(int p_idx, const Ref<Material> &p_material) = 0;
- virtual Ref<Material> surface_get_material(int p_idx) const = 0;
- virtual int get_blend_shape_count() const = 0;
- virtual StringName get_blend_shape_name(int p_index) const = 0;
- virtual void set_blend_shape_name(int p_index, const StringName &p_name) = 0;
+ virtual int get_surface_count() const;
+ virtual int surface_get_array_len(int p_idx) const;
+ virtual int surface_get_array_index_len(int p_idx) const;
+ virtual Array surface_get_arrays(int p_surface) const;
+ virtual Array surface_get_blend_shape_arrays(int p_surface) const;
+ virtual Dictionary surface_get_lods(int p_surface) const;
+ virtual uint32_t surface_get_format(int p_idx) const;
+ virtual PrimitiveType surface_get_primitive_type(int p_idx) const;
+ virtual void surface_set_material(int p_idx, const Ref<Material> &p_material);
+ virtual Ref<Material> surface_get_material(int p_idx) const;
+ virtual int get_blend_shape_count() const;
+ virtual StringName get_blend_shape_name(int p_index) const;
+ virtual void set_blend_shape_name(int p_index, const StringName &p_name);
+ virtual AABB get_aabb() const;
Vector<Face3> get_faces() const;
Ref<TriangleMesh> generate_triangle_mesh() const;
@@ -153,8 +170,6 @@ public:
Ref<Mesh> create_outline(float p_margin) const;
- virtual AABB get_aabb() const = 0;
-
void set_lightmap_size_hint(const Size2i &p_size);
Size2i get_lightmap_size_hint() const;
void clear_cache() const;
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index 9d388d465d..2f1ac7a83a 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -1653,7 +1653,7 @@ void PackedScene::recreate_state() {
#endif
}
-Ref<SceneState> PackedScene::get_state() {
+Ref<SceneState> PackedScene::get_state() const {
return state;
}
diff --git a/scene/resources/packed_scene.h b/scene/resources/packed_scene.h
index 81b38840d9..96222937d0 100644
--- a/scene/resources/packed_scene.h
+++ b/scene/resources/packed_scene.h
@@ -228,7 +228,7 @@ public:
virtual void set_last_modified_time(uint64_t p_time) override { state->set_last_modified_time(p_time); }
#endif
- Ref<SceneState> get_state();
+ Ref<SceneState> get_state() const;
PackedScene();
};
diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp
index 38acd0af0a..781e219f1f 100644
--- a/scene/resources/primitive_meshes.cpp
+++ b/scene/resources/primitive_meshes.cpp
@@ -36,11 +36,17 @@
*/
void PrimitiveMesh::_update() const {
Array arr;
- arr.resize(RS::ARRAY_MAX);
- _create_mesh_array(arr);
+ if (GDVIRTUAL_CALL(_create_mesh_array, arr)) {
+ ERR_FAIL_COND_MSG(arr.size() != RS::ARRAY_MAX, "_create_mesh_array must return an array of Mesh.ARRAY_MAX elements.");
+ } else {
+ arr.resize(RS::ARRAY_MAX);
+ _create_mesh_array(arr);
+ }
Vector<Vector3> points = arr[RS::ARRAY_VERTEX];
+ ERR_FAIL_COND_MSG(points.size() == 0, "_create_mesh_array must return at least a vertex array.");
+
aabb = AABB();
int pc = points.size();
@@ -210,6 +216,8 @@ void PrimitiveMesh::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "BaseMaterial3D,ShaderMaterial"), "set_material", "get_material");
ADD_PROPERTY(PropertyInfo(Variant::AABB, "custom_aabb", PROPERTY_HINT_NONE, ""), "set_custom_aabb", "get_custom_aabb");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_faces"), "set_flip_faces", "get_flip_faces");
+
+ GDVIRTUAL_BIND(_create_mesh_array);
}
void PrimitiveMesh::set_material(const Ref<Material> &p_material) {
diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h
index 3fc5fd4a16..eef5eb3f7d 100644
--- a/scene/resources/primitive_meshes.h
+++ b/scene/resources/primitive_meshes.h
@@ -64,8 +64,9 @@ protected:
static void _bind_methods();
- virtual void _create_mesh_array(Array &p_arr) const = 0;
+ virtual void _create_mesh_array(Array &p_arr) const {}
void _request_update();
+ GDVIRTUAL0RC(Array, _create_mesh_array)
public:
virtual int get_surface_count() const override;
diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp
index d9ac967699..fd6f018651 100644
--- a/scene/resources/resource_format_text.cpp
+++ b/scene/resources/resource_format_text.cpp
@@ -908,10 +908,9 @@ Error ResourceLoaderText::rename_dependencies(FileAccess *p_f, const String &p_p
return ERR_CANT_CREATE;
}
- DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+ DirAccessRef da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
da->remove(p_path);
da->rename(p_path + ".depren", p_path);
- memdelete(da);
return OK;
}
diff --git a/scene/resources/sky_material.cpp b/scene/resources/sky_material.cpp
index 8e633a4075..54543782f6 100644
--- a/scene/resources/sky_material.cpp
+++ b/scene/resources/sky_material.cpp
@@ -71,6 +71,25 @@ float ProceduralSkyMaterial::get_sky_energy() const {
return sky_energy;
}
+void ProceduralSkyMaterial::set_sky_cover(const Ref<Texture2D> &p_sky_cover) {
+ sky_cover = p_sky_cover;
+ RID tex_rid = p_sky_cover.is_valid() ? p_sky_cover->get_rid() : RID();
+ RS::get_singleton()->material_set_param(_get_material(), "sky_cover", tex_rid);
+}
+
+Ref<Texture2D> ProceduralSkyMaterial::get_sky_cover() const {
+ return sky_cover;
+}
+
+void ProceduralSkyMaterial::set_sky_cover_modulate(const Color &p_sky_cover_modulate) {
+ sky_cover_modulate = p_sky_cover_modulate;
+ RS::get_singleton()->material_set_param(_get_material(), "sky_cover_modulate", sky_cover_modulate);
+}
+
+Color ProceduralSkyMaterial::get_sky_cover_modulate() const {
+ return sky_cover_modulate;
+}
+
void ProceduralSkyMaterial::set_ground_bottom_color(const Color &p_ground_bottom) {
ground_bottom_color = p_ground_bottom;
RS::get_singleton()->material_set_param(_get_material(), "ground_bottom_color", ground_bottom_color);
@@ -156,6 +175,12 @@ void ProceduralSkyMaterial::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_sky_energy", "energy"), &ProceduralSkyMaterial::set_sky_energy);
ClassDB::bind_method(D_METHOD("get_sky_energy"), &ProceduralSkyMaterial::get_sky_energy);
+ ClassDB::bind_method(D_METHOD("set_sky_cover", "sky_cover"), &ProceduralSkyMaterial::set_sky_cover);
+ ClassDB::bind_method(D_METHOD("get_sky_cover"), &ProceduralSkyMaterial::get_sky_cover);
+
+ ClassDB::bind_method(D_METHOD("set_sky_cover_modulate", "color"), &ProceduralSkyMaterial::set_sky_cover_modulate);
+ ClassDB::bind_method(D_METHOD("get_sky_cover_modulate"), &ProceduralSkyMaterial::get_sky_cover_modulate);
+
ClassDB::bind_method(D_METHOD("set_ground_bottom_color", "color"), &ProceduralSkyMaterial::set_ground_bottom_color);
ClassDB::bind_method(D_METHOD("get_ground_bottom_color"), &ProceduralSkyMaterial::get_ground_bottom_color);
@@ -179,6 +204,8 @@ void ProceduralSkyMaterial::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sky_horizon_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_sky_horizon_color", "get_sky_horizon_color");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sky_curve", PROPERTY_HINT_EXP_EASING), "set_sky_curve", "get_sky_curve");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sky_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_sky_energy", "get_sky_energy");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "sky_cover", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_sky_cover", "get_sky_cover");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sky_cover_modulate"), "set_sky_cover_modulate", "get_sky_cover_modulate");
ADD_GROUP("Ground", "ground_");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ground_bottom_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_ground_bottom_color", "get_ground_bottom_color");
@@ -212,6 +239,8 @@ uniform vec4 sky_top_color : hint_color = vec4(0.385, 0.454, 0.55, 1.0);
uniform vec4 sky_horizon_color : hint_color = vec4(0.646, 0.656, 0.67, 1.0);
uniform float sky_curve : hint_range(0, 1) = 0.15;
uniform float sky_energy = 1.0;
+uniform sampler2D sky_cover : hint_black_albedo;
+uniform vec4 sky_cover_modulate : hint_color = vec4(1.0, 1.0, 1.0, 1.0);
uniform vec4 ground_bottom_color : hint_color = vec4(0.2, 0.169, 0.133, 1.0);
uniform vec4 ground_horizon_color : hint_color = vec4(0.646, 0.656, 0.67, 1.0);
uniform float ground_curve : hint_range(0, 1) = 0.02;
@@ -265,6 +294,9 @@ void sky() {
}
}
+ vec4 sky_cover_texture = texture(sky_cover, SKY_COORDS);
+ sky += (sky_cover_texture.rgb * sky_cover_modulate.rgb) * sky_cover_texture.a * sky_cover_modulate.a * sky_energy;
+
c = (v_angle - (PI * 0.5)) / (PI * 0.5);
vec3 ground = mix(ground_horizon_color.rgb, ground_bottom_color.rgb, clamp(1.0 - pow(1.0 - c, 1.0 / ground_curve), 0.0, 1.0));
ground *= ground_energy;
@@ -281,6 +313,7 @@ ProceduralSkyMaterial::ProceduralSkyMaterial() {
set_sky_horizon_color(Color(0.6463, 0.6558, 0.6708));
set_sky_curve(0.15);
set_sky_energy(1.0);
+ set_sky_cover_modulate(Color(1, 1, 1));
set_ground_bottom_color(Color(0.2, 0.169, 0.133));
set_ground_horizon_color(Color(0.6463, 0.6558, 0.6708));
diff --git a/scene/resources/sky_material.h b/scene/resources/sky_material.h
index 7f421beb8d..5c791a185a 100644
--- a/scene/resources/sky_material.h
+++ b/scene/resources/sky_material.h
@@ -42,6 +42,8 @@ private:
Color sky_horizon_color;
float sky_curve;
float sky_energy;
+ Ref<Texture2D> sky_cover;
+ Color sky_cover_modulate;
Color ground_bottom_color;
Color ground_horizon_color;
@@ -72,6 +74,12 @@ public:
void set_sky_energy(float p_energy);
float get_sky_energy() const;
+ void set_sky_cover(const Ref<Texture2D> &p_sky_cover);
+ Ref<Texture2D> get_sky_cover() const;
+
+ void set_sky_cover_modulate(const Color &p_sky_cover_modulate);
+ Color get_sky_cover_modulate() const;
+
void set_ground_bottom_color(const Color &p_ground_bottom);
Color get_ground_bottom_color() const;
diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp
index 5afd424e03..fe52761482 100644
--- a/scene/resources/style_box.cpp
+++ b/scene/resources/style_box.cpp
@@ -34,10 +34,28 @@
#include <limits.h>
+float StyleBox::get_style_margin(Side p_side) const {
+ float ret;
+ if (GDVIRTUAL_REQUIRED_CALL(_get_style_margin, p_side, ret)) {
+ return ret;
+ }
+ return 0;
+}
bool StyleBox::test_mask(const Point2 &p_point, const Rect2 &p_rect) const {
+ bool ret;
+ if (GDVIRTUAL_CALL(_test_mask, p_point, p_rect, ret)) {
+ return ret;
+ }
+
return true;
}
+void StyleBox::draw(RID p_canvas_item, const Rect2 &p_rect) const {
+ if (GDVIRTUAL_REQUIRED_CALL(_draw, p_canvas_item, p_rect)) {
+ return;
+ }
+}
+
void StyleBox::set_default_margin(Side p_side, float p_value) {
ERR_FAIL_INDEX((int)p_side, 4);
@@ -74,10 +92,19 @@ Point2 StyleBox::get_offset() const {
}
Size2 StyleBox::get_center_size() const {
+ Size2 ret;
+ if (GDVIRTUAL_CALL(_get_center_size, ret)) {
+ return ret;
+ }
+
return Size2();
}
Rect2 StyleBox::get_draw_rect(const Rect2 &p_rect) const {
+ Rect2 ret;
+ if (GDVIRTUAL_CALL(_get_draw_rect, p_rect, ret)) {
+ return ret;
+ }
return p_rect;
}
@@ -100,6 +127,12 @@ void StyleBox::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "content_margin_right", PROPERTY_HINT_RANGE, "-1,2048,1"), "set_default_margin", "get_default_margin", SIDE_RIGHT);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "content_margin_top", PROPERTY_HINT_RANGE, "-1,2048,1"), "set_default_margin", "get_default_margin", SIDE_TOP);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "content_margin_bottom", PROPERTY_HINT_RANGE, "-1,2048,1"), "set_default_margin", "get_default_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")
}
StyleBox::StyleBox() {
diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h
index 4c41f42293..68ad41b69c 100644
--- a/scene/resources/style_box.h
+++ b/scene/resources/style_box.h
@@ -44,9 +44,15 @@ class StyleBox : public Resource {
float margin[4];
protected:
- virtual float get_style_margin(Side p_side) const = 0;
+ virtual float get_style_margin(Side p_side) const;
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)
+
public:
virtual bool test_mask(const Point2 &p_point, const Rect2 &p_rect) const;
@@ -56,7 +62,7 @@ public:
virtual Size2 get_center_size() const;
virtual Rect2 get_draw_rect(const Rect2 &p_rect) const;
- virtual void draw(RID p_canvas_item, const Rect2 &p_rect) const = 0;
+ virtual void draw(RID p_canvas_item, const Rect2 &p_rect) const;
CanvasItem *get_current_item_drawn() const;
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 0ee0e4b33e..1930fa2682 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -38,23 +38,61 @@
#include "scene/resources/bit_map.h"
#include "servers/camera/camera_feed.h"
+int Texture2D::get_width() const {
+ int ret;
+ if (GDVIRTUAL_REQUIRED_CALL(_get_width, ret)) {
+ return ret;
+ }
+ return 0;
+}
+
+int Texture2D::get_height() const {
+ int ret;
+ if (GDVIRTUAL_REQUIRED_CALL(_get_height, ret)) {
+ return ret;
+ }
+ return 0;
+}
+
Size2 Texture2D::get_size() const {
return Size2(get_width(), get_height());
}
bool Texture2D::is_pixel_opaque(int p_x, int p_y) const {
+ bool ret;
+ if (GDVIRTUAL_CALL(_is_pixel_opaque, p_x, p_y, ret)) {
+ return ret;
+ }
+
+ return true;
+}
+bool Texture2D::has_alpha() const {
+ bool ret;
+ if (GDVIRTUAL_CALL(_has_alpha, ret)) {
+ return ret;
+ }
+
return true;
}
void Texture2D::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose) const {
+ if (GDVIRTUAL_CALL(_draw, p_canvas_item, p_pos, p_modulate, p_transpose)) {
+ return;
+ }
RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, get_size()), get_rid(), false, p_modulate, p_transpose);
}
void Texture2D::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const {
+ if (GDVIRTUAL_CALL(_draw_rect, p_canvas_item, p_rect, p_tile, p_modulate, p_transpose)) {
+ return;
+ }
RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, get_rid(), p_tile, p_modulate, p_transpose);
}
void Texture2D::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, bool p_clip_uv) const {
+ if (GDVIRTUAL_CALL(_draw_rect_region, p_canvas_item, p_rect, p_src_rect, p_modulate, p_transpose, p_clip_uv)) {
+ return;
+ }
RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, get_rid(), p_src_rect, p_modulate, p_transpose, p_clip_uv);
}
@@ -75,6 +113,15 @@ void Texture2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_image"), &Texture2D::get_image);
ADD_GROUP("", "");
+
+ GDVIRTUAL_BIND(_get_width);
+ GDVIRTUAL_BIND(_get_height);
+ GDVIRTUAL_BIND(_is_pixel_opaque, "x", "y");
+ GDVIRTUAL_BIND(_has_alpha);
+
+ GDVIRTUAL_BIND(_draw, "to_canvas_item", "pos", "modulate", "transpose")
+ GDVIRTUAL_BIND(_draw_rect, "to_canvas_item", "rect", "tile", "modulate", "transpose")
+ GDVIRTUAL_BIND(_draw_rect_region, "tp_canvas_item", "rect", "src_rect", "modulate", "transpose", "clip_uv");
}
Texture2D::Texture2D() {
@@ -293,7 +340,7 @@ ImageTexture::~ImageTexture() {
//////////////////////////////////////////
-Ref<Image> StreamTexture2D::load_image_from_file(FileAccess *f, int p_size_limit) {
+Ref<Image> CompressedTexture2D::load_image_from_file(FileAccess *f, int p_size_limit) {
uint32_t data_format = f->get_32();
uint32_t w = f->get_16();
uint32_t h = f->get_16();
@@ -426,7 +473,7 @@ Ref<Image> StreamTexture2D::load_image_from_file(FileAccess *f, int p_size_limit
return Ref<Image>();
}
-void StreamTexture2D::set_path(const String &p_path, bool p_take_over) {
+void CompressedTexture2D::set_path(const String &p_path, bool p_take_over) {
if (texture.is_valid()) {
RenderingServer::get_singleton()->texture_set_path(texture, p_path);
}
@@ -434,36 +481,36 @@ void StreamTexture2D::set_path(const String &p_path, bool p_take_over) {
Resource::set_path(p_path, p_take_over);
}
-void StreamTexture2D::_requested_3d(void *p_ud) {
- StreamTexture2D *st = (StreamTexture2D *)p_ud;
- Ref<StreamTexture2D> stex(st);
+void CompressedTexture2D::_requested_3d(void *p_ud) {
+ CompressedTexture2D *ct = (CompressedTexture2D *)p_ud;
+ Ref<CompressedTexture2D> ctex(ct);
ERR_FAIL_COND(!request_3d_callback);
- request_3d_callback(stex);
+ request_3d_callback(ctex);
}
-void StreamTexture2D::_requested_roughness(void *p_ud, const String &p_normal_path, RS::TextureDetectRoughnessChannel p_roughness_channel) {
- StreamTexture2D *st = (StreamTexture2D *)p_ud;
- Ref<StreamTexture2D> stex(st);
+void CompressedTexture2D::_requested_roughness(void *p_ud, const String &p_normal_path, RS::TextureDetectRoughnessChannel p_roughness_channel) {
+ CompressedTexture2D *ct = (CompressedTexture2D *)p_ud;
+ Ref<CompressedTexture2D> ctex(ct);
ERR_FAIL_COND(!request_roughness_callback);
- request_roughness_callback(stex, p_normal_path, p_roughness_channel);
+ request_roughness_callback(ctex, p_normal_path, p_roughness_channel);
}
-void StreamTexture2D::_requested_normal(void *p_ud) {
- StreamTexture2D *st = (StreamTexture2D *)p_ud;
- Ref<StreamTexture2D> stex(st);
+void CompressedTexture2D::_requested_normal(void *p_ud) {
+ CompressedTexture2D *ct = (CompressedTexture2D *)p_ud;
+ Ref<CompressedTexture2D> ctex(ct);
ERR_FAIL_COND(!request_normal_callback);
- request_normal_callback(stex);
+ request_normal_callback(ctex);
}
-StreamTexture2D::TextureFormatRequestCallback StreamTexture2D::request_3d_callback = nullptr;
-StreamTexture2D::TextureFormatRoughnessRequestCallback StreamTexture2D::request_roughness_callback = nullptr;
-StreamTexture2D::TextureFormatRequestCallback StreamTexture2D::request_normal_callback = nullptr;
+CompressedTexture2D::TextureFormatRequestCallback CompressedTexture2D::request_3d_callback = nullptr;
+CompressedTexture2D::TextureFormatRoughnessRequestCallback CompressedTexture2D::request_roughness_callback = nullptr;
+CompressedTexture2D::TextureFormatRequestCallback CompressedTexture2D::request_normal_callback = nullptr;
-Image::Format StreamTexture2D::get_format() const {
+Image::Format CompressedTexture2D::get_format() const {
return format;
}
-Error StreamTexture2D::_load_data(const String &p_path, int &r_width, int &r_height, Ref<Image> &image, bool &r_request_3d, bool &r_request_normal, bool &r_request_roughness, int &mipmap_limit, int p_size_limit) {
+Error CompressedTexture2D::_load_data(const String &p_path, int &r_width, int &r_height, Ref<Image> &image, bool &r_request_3d, bool &r_request_normal, bool &r_request_roughness, int &mipmap_limit, int p_size_limit) {
alpha_cache.unref();
ERR_FAIL_COND_V(image.is_null(), ERR_INVALID_PARAMETER);
@@ -475,14 +522,14 @@ Error StreamTexture2D::_load_data(const String &p_path, int &r_width, int &r_hei
f->get_buffer(header, 4);
if (header[0] != 'G' || header[1] != 'S' || header[2] != 'T' || header[3] != '2') {
memdelete(f);
- ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Stream texture file is corrupt (Bad header).");
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Compressed texture file is corrupt (Bad header).");
}
uint32_t version = f->get_32();
if (version > FORMAT_VERSION) {
memdelete(f);
- ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Stream texture file is too new.");
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Compressed texture file is too new.");
}
r_width = f->get_32();
r_height = f->get_32();
@@ -523,7 +570,7 @@ Error StreamTexture2D::_load_data(const String &p_path, int &r_width, int &r_hei
return OK;
}
-Error StreamTexture2D::load(const String &p_path) {
+Error CompressedTexture2D::load(const String &p_path) {
int lw, lh;
Ref<Image> image;
image.instantiate();
@@ -590,51 +637,51 @@ Error StreamTexture2D::load(const String &p_path) {
return OK;
}
-String StreamTexture2D::get_load_path() const {
+String CompressedTexture2D::get_load_path() const {
return path_to_file;
}
-int StreamTexture2D::get_width() const {
+int CompressedTexture2D::get_width() const {
return w;
}
-int StreamTexture2D::get_height() const {
+int CompressedTexture2D::get_height() const {
return h;
}
-RID StreamTexture2D::get_rid() const {
+RID CompressedTexture2D::get_rid() const {
if (!texture.is_valid()) {
texture = RS::get_singleton()->texture_2d_placeholder_create();
}
return texture;
}
-void StreamTexture2D::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose) const {
+void CompressedTexture2D::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose) const {
if ((w | h) == 0) {
return;
}
RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, Size2(w, h)), texture, false, p_modulate, p_transpose);
}
-void StreamTexture2D::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const {
+void CompressedTexture2D::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const {
if ((w | h) == 0) {
return;
}
RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose);
}
-void StreamTexture2D::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, bool p_clip_uv) const {
+void CompressedTexture2D::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, bool p_clip_uv) const {
if ((w | h) == 0) {
return;
}
RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, p_clip_uv);
}
-bool StreamTexture2D::has_alpha() const {
+bool CompressedTexture2D::has_alpha() const {
return false;
}
-Ref<Image> StreamTexture2D::get_image() const {
+Ref<Image> CompressedTexture2D::get_image() const {
if (texture.is_valid()) {
return RS::get_singleton()->texture_2d_get(texture);
} else {
@@ -642,7 +689,7 @@ Ref<Image> StreamTexture2D::get_image() const {
}
}
-bool StreamTexture2D::is_pixel_opaque(int p_x, int p_y) const {
+bool CompressedTexture2D::is_pixel_opaque(int p_x, int p_y) const {
if (!alpha_cache.is_valid()) {
Ref<Image> img = get_image();
if (img.is_valid()) {
@@ -676,7 +723,7 @@ bool StreamTexture2D::is_pixel_opaque(int p_x, int p_y) const {
return true;
}
-void StreamTexture2D::reload_from_file() {
+void CompressedTexture2D::reload_from_file() {
String path = get_path();
if (!path.is_resource_file()) {
return;
@@ -691,26 +738,26 @@ void StreamTexture2D::reload_from_file() {
load(path);
}
-void StreamTexture2D::_validate_property(PropertyInfo &property) const {
+void CompressedTexture2D::_validate_property(PropertyInfo &property) const {
}
-void StreamTexture2D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("load", "path"), &StreamTexture2D::load);
- ClassDB::bind_method(D_METHOD("get_load_path"), &StreamTexture2D::get_load_path);
+void CompressedTexture2D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("load", "path"), &CompressedTexture2D::load);
+ ClassDB::bind_method(D_METHOD("get_load_path"), &CompressedTexture2D::get_load_path);
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "load_path", PROPERTY_HINT_FILE, "*.stex"), "load", "get_load_path");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "load_path", PROPERTY_HINT_FILE, "*.ctex"), "load", "get_load_path");
}
-StreamTexture2D::StreamTexture2D() {}
+CompressedTexture2D::CompressedTexture2D() {}
-StreamTexture2D::~StreamTexture2D() {
+CompressedTexture2D::~CompressedTexture2D() {
if (texture.is_valid()) {
RS::get_singleton()->free(texture);
}
}
-RES ResourceFormatLoaderStreamTexture2D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
- Ref<StreamTexture2D> st;
+RES ResourceFormatLoaderCompressedTexture2D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
+ Ref<CompressedTexture2D> st;
st.instantiate();
Error err = st->load(p_path);
if (r_error) {
@@ -723,24 +770,24 @@ RES ResourceFormatLoaderStreamTexture2D::load(const String &p_path, const String
return st;
}
-void ResourceFormatLoaderStreamTexture2D::get_recognized_extensions(List<String> *p_extensions) const {
- p_extensions->push_back("stex");
+void ResourceFormatLoaderCompressedTexture2D::get_recognized_extensions(List<String> *p_extensions) const {
+ p_extensions->push_back("ctex");
}
-bool ResourceFormatLoaderStreamTexture2D::handles_type(const String &p_type) const {
- return p_type == "StreamTexture2D";
+bool ResourceFormatLoaderCompressedTexture2D::handles_type(const String &p_type) const {
+ return p_type == "CompressedTexture2D";
}
-String ResourceFormatLoaderStreamTexture2D::get_resource_type(const String &p_path) const {
- if (p_path.get_extension().to_lower() == "stex") {
- return "StreamTexture2D";
+String ResourceFormatLoaderCompressedTexture2D::get_resource_type(const String &p_path) const {
+ if (p_path.get_extension().to_lower() == "ctex") {
+ return "CompressedTexture2D";
}
return "";
}
////////////////////////////////////
-TypedArray<Image> Texture3D::_get_data() const {
+TypedArray<Image> Texture3D::_get_datai() const {
Vector<Ref<Image>> data = get_data();
TypedArray<Image> ret;
@@ -751,13 +798,73 @@ TypedArray<Image> Texture3D::_get_data() const {
return ret;
}
+Image::Format Texture3D::get_format() const {
+ Image::Format ret;
+ if (GDVIRTUAL_REQUIRED_CALL(_get_format, ret)) {
+ return ret;
+ }
+ return Image::FORMAT_MAX;
+}
+
+int Texture3D::get_width() const {
+ int ret;
+ if (GDVIRTUAL_REQUIRED_CALL(_get_width, ret)) {
+ return ret;
+ }
+ return 0;
+}
+
+int Texture3D::get_height() const {
+ int ret;
+ if (GDVIRTUAL_REQUIRED_CALL(_get_height, ret)) {
+ return ret;
+ }
+ return 0;
+}
+
+int Texture3D::get_depth() const {
+ int ret;
+ if (GDVIRTUAL_REQUIRED_CALL(_get_depth, ret)) {
+ return ret;
+ }
+
+ return 0;
+}
+
+bool Texture3D::has_mipmaps() const {
+ bool ret;
+ if (GDVIRTUAL_REQUIRED_CALL(_has_mipmaps, ret)) {
+ return ret;
+ }
+ return 0;
+}
+
+Vector<Ref<Image>> Texture3D::get_data() const {
+ TypedArray<Image> ret;
+ if (GDVIRTUAL_REQUIRED_CALL(_get_data, ret)) {
+ Vector<Ref<Image>> data;
+ data.resize(ret.size());
+ for (int i = 0; i < data.size(); i++) {
+ data.write[i] = ret[i];
+ }
+ return data;
+ }
+ return Vector<Ref<Image>>();
+}
void Texture3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_format"), &Texture3D::get_format);
ClassDB::bind_method(D_METHOD("get_width"), &Texture3D::get_width);
ClassDB::bind_method(D_METHOD("get_height"), &Texture3D::get_height);
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_data);
+ ClassDB::bind_method(D_METHOD("get_data"), &Texture3D::_get_datai);
+
+ GDVIRTUAL_BIND(_get_format);
+ GDVIRTUAL_BIND(_get_width);
+ GDVIRTUAL_BIND(_get_height);
+ GDVIRTUAL_BIND(_get_depth);
+ GDVIRTUAL_BIND(_has_mipmaps);
+ GDVIRTUAL_BIND(_get_data);
}
//////////////////////////////////////////
@@ -846,7 +953,7 @@ ImageTexture3D::~ImageTexture3D() {
////////////////////////////////////////////
-void StreamTexture3D::set_path(const String &p_path, bool p_take_over) {
+void CompressedTexture3D::set_path(const String &p_path, bool p_take_over) {
if (texture.is_valid()) {
RenderingServer::get_singleton()->texture_set_path(texture, p_path);
}
@@ -854,11 +961,11 @@ void StreamTexture3D::set_path(const String &p_path, bool p_take_over) {
Resource::set_path(p_path, p_take_over);
}
-Image::Format StreamTexture3D::get_format() const {
+Image::Format CompressedTexture3D::get_format() const {
return format;
}
-Error StreamTexture3D::_load_data(const String &p_path, Vector<Ref<Image>> &r_data, Image::Format &r_format, int &r_width, int &r_height, int &r_depth, bool &r_mipmaps) {
+Error CompressedTexture3D::_load_data(const String &p_path, Vector<Ref<Image>> &r_data, Image::Format &r_format, int &r_width, int &r_height, int &r_depth, bool &r_mipmaps) {
FileAccessRef f = FileAccess::open(p_path, FileAccess::READ);
ERR_FAIL_COND_V_MSG(!f, ERR_CANT_OPEN, vformat("Unable to open file: %s.", p_path));
@@ -866,11 +973,11 @@ Error StreamTexture3D::_load_data(const String &p_path, Vector<Ref<Image>> &r_da
f->get_buffer(header, 4);
ERR_FAIL_COND_V(header[0] != 'G' || header[1] != 'S' || header[2] != 'T' || header[3] != 'L', ERR_FILE_UNRECOGNIZED);
- //stored as stream textures (used for lossless and lossy compression)
+ //stored as compressed textures (used for lossless and lossy compression)
uint32_t version = f->get_32();
if (version > FORMAT_VERSION) {
- ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Stream texture file is too new.");
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Compressed texture file is too new.");
}
r_depth = f->get_32(); //depth
@@ -887,7 +994,7 @@ Error StreamTexture3D::_load_data(const String &p_path, Vector<Ref<Image>> &r_da
r_data.clear();
for (int i = 0; i < (r_depth + mipmaps); i++) {
- Ref<Image> image = StreamTexture2D::load_image_from_file(f, 0);
+ Ref<Image> image = CompressedTexture2D::load_image_from_file(f, 0);
ERR_FAIL_COND_V(image.is_null() || image->is_empty(), ERR_CANT_OPEN);
if (i == 0) {
r_format = image->get_format();
@@ -900,7 +1007,7 @@ Error StreamTexture3D::_load_data(const String &p_path, Vector<Ref<Image>> &r_da
return OK;
}
-Error StreamTexture3D::load(const String &p_path) {
+Error CompressedTexture3D::load(const String &p_path) {
Vector<Ref<Image>> data;
int tw, th, td;
@@ -937,34 +1044,34 @@ Error StreamTexture3D::load(const String &p_path) {
return OK;
}
-String StreamTexture3D::get_load_path() const {
+String CompressedTexture3D::get_load_path() const {
return path_to_file;
}
-int StreamTexture3D::get_width() const {
+int CompressedTexture3D::get_width() const {
return w;
}
-int StreamTexture3D::get_height() const {
+int CompressedTexture3D::get_height() const {
return h;
}
-int StreamTexture3D::get_depth() const {
+int CompressedTexture3D::get_depth() const {
return d;
}
-bool StreamTexture3D::has_mipmaps() const {
+bool CompressedTexture3D::has_mipmaps() const {
return mipmaps;
}
-RID StreamTexture3D::get_rid() const {
+RID CompressedTexture3D::get_rid() const {
if (!texture.is_valid()) {
texture = RS::get_singleton()->texture_3d_placeholder_create();
}
return texture;
}
-Vector<Ref<Image>> StreamTexture3D::get_data() const {
+Vector<Ref<Image>> CompressedTexture3D::get_data() const {
if (texture.is_valid()) {
return RS::get_singleton()->texture_3d_get(texture);
} else {
@@ -972,7 +1079,7 @@ Vector<Ref<Image>> StreamTexture3D::get_data() const {
}
}
-void StreamTexture3D::reload_from_file() {
+void CompressedTexture3D::reload_from_file() {
String path = get_path();
if (!path.is_resource_file()) {
return;
@@ -987,19 +1094,19 @@ void StreamTexture3D::reload_from_file() {
load(path);
}
-void StreamTexture3D::_validate_property(PropertyInfo &property) const {
+void CompressedTexture3D::_validate_property(PropertyInfo &property) const {
}
-void StreamTexture3D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("load", "path"), &StreamTexture3D::load);
- ClassDB::bind_method(D_METHOD("get_load_path"), &StreamTexture3D::get_load_path);
+void CompressedTexture3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("load", "path"), &CompressedTexture3D::load);
+ ClassDB::bind_method(D_METHOD("get_load_path"), &CompressedTexture3D::get_load_path);
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "load_path", PROPERTY_HINT_FILE, "*.stex"), "load", "get_load_path");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "load_path", PROPERTY_HINT_FILE, "*.ctex"), "load", "get_load_path");
}
-StreamTexture3D::StreamTexture3D() {}
+CompressedTexture3D::CompressedTexture3D() {}
-StreamTexture3D::~StreamTexture3D() {
+CompressedTexture3D::~CompressedTexture3D() {
if (texture.is_valid()) {
RS::get_singleton()->free(texture);
}
@@ -1007,8 +1114,8 @@ StreamTexture3D::~StreamTexture3D() {
/////////////////////////////
-RES ResourceFormatLoaderStreamTexture3D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
- Ref<StreamTexture3D> st;
+RES ResourceFormatLoaderCompressedTexture3D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
+ Ref<CompressedTexture3D> st;
st.instantiate();
Error err = st->load(p_path);
if (r_error) {
@@ -1021,17 +1128,17 @@ RES ResourceFormatLoaderStreamTexture3D::load(const String &p_path, const String
return st;
}
-void ResourceFormatLoaderStreamTexture3D::get_recognized_extensions(List<String> *p_extensions) const {
- p_extensions->push_back("stex3d");
+void ResourceFormatLoaderCompressedTexture3D::get_recognized_extensions(List<String> *p_extensions) const {
+ p_extensions->push_back("ctex3d");
}
-bool ResourceFormatLoaderStreamTexture3D::handles_type(const String &p_type) const {
- return p_type == "StreamTexture3D";
+bool ResourceFormatLoaderCompressedTexture3D::handles_type(const String &p_type) const {
+ return p_type == "CompressedTexture3D";
}
-String ResourceFormatLoaderStreamTexture3D::get_resource_type(const String &p_path) const {
- if (p_path.get_extension().to_lower() == "stex3d") {
- return "StreamTexture3D";
+String ResourceFormatLoaderCompressedTexture3D::get_resource_type(const String &p_path) const {
+ if (p_path.get_extension().to_lower() == "ctex3d") {
+ return "CompressedTexture3D";
}
return "";
}
@@ -2446,6 +2553,63 @@ AnimatedTexture::~AnimatedTexture() {
///////////////////////////////
+Image::Format TextureLayered::get_format() const {
+ Image::Format ret;
+ if (GDVIRTUAL_REQUIRED_CALL(_get_format, ret)) {
+ return ret;
+ }
+ return Image::FORMAT_MAX;
+}
+
+TextureLayered::LayeredType TextureLayered::get_layered_type() const {
+ uint32_t ret;
+ if (GDVIRTUAL_REQUIRED_CALL(_get_layered_type, ret)) {
+ return (LayeredType)ret;
+ }
+ return LAYERED_TYPE_2D_ARRAY;
+}
+
+int TextureLayered::get_width() const {
+ int ret;
+ if (GDVIRTUAL_REQUIRED_CALL(_get_width, ret)) {
+ return ret;
+ }
+ return 0;
+}
+
+int TextureLayered::get_height() const {
+ int ret;
+ if (GDVIRTUAL_REQUIRED_CALL(_get_height, ret)) {
+ return ret;
+ }
+ return 0;
+}
+
+int TextureLayered::get_layers() const {
+ int ret;
+ if (GDVIRTUAL_REQUIRED_CALL(_get_layers, ret)) {
+ return ret;
+ }
+
+ return 0;
+}
+
+bool TextureLayered::has_mipmaps() const {
+ bool ret;
+ if (GDVIRTUAL_REQUIRED_CALL(_has_mipmaps, ret)) {
+ return ret;
+ }
+ return false;
+}
+
+Ref<Image> TextureLayered::get_layer_data(int p_layer) const {
+ Ref<Image> ret;
+ if (GDVIRTUAL_REQUIRED_CALL(_get_layer_data, p_layer, ret)) {
+ return ret;
+ }
+ return Ref<Image>();
+}
+
void TextureLayered::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_format"), &TextureLayered::get_format);
ClassDB::bind_method(D_METHOD("get_layered_type"), &TextureLayered::get_layered_type);
@@ -2458,6 +2622,14 @@ void TextureLayered::_bind_methods() {
BIND_ENUM_CONSTANT(LAYERED_TYPE_2D_ARRAY);
BIND_ENUM_CONSTANT(LAYERED_TYPE_CUBEMAP);
BIND_ENUM_CONSTANT(LAYERED_TYPE_CUBEMAP_ARRAY);
+
+ GDVIRTUAL_BIND(_get_format);
+ GDVIRTUAL_BIND(_get_layered_type);
+ GDVIRTUAL_BIND(_get_width);
+ GDVIRTUAL_BIND(_get_height);
+ GDVIRTUAL_BIND(_get_layers);
+ GDVIRTUAL_BIND(_has_mipmaps);
+ GDVIRTUAL_BIND(_get_layer_data, "layer_index");
}
///////////////////////////////
@@ -2599,7 +2771,7 @@ ImageTextureLayered::~ImageTextureLayered() {
///////////////////////////////////////////
-void StreamTextureLayered::set_path(const String &p_path, bool p_take_over) {
+void CompressedTextureLayered::set_path(const String &p_path, bool p_take_over) {
if (texture.is_valid()) {
RenderingServer::get_singleton()->texture_set_path(texture, p_path);
}
@@ -2607,11 +2779,11 @@ void StreamTextureLayered::set_path(const String &p_path, bool p_take_over) {
Resource::set_path(p_path, p_take_over);
}
-Image::Format StreamTextureLayered::get_format() const {
+Image::Format CompressedTextureLayered::get_format() const {
return format;
}
-Error StreamTextureLayered::_load_data(const String &p_path, Vector<Ref<Image>> &images, int &mipmap_limit, int p_size_limit) {
+Error CompressedTextureLayered::_load_data(const String &p_path, Vector<Ref<Image>> &images, int &mipmap_limit, int p_size_limit) {
ERR_FAIL_COND_V(images.size() != 0, ERR_INVALID_PARAMETER);
FileAccessRef f = FileAccess::open(p_path, FileAccess::READ);
@@ -2620,13 +2792,13 @@ Error StreamTextureLayered::_load_data(const String &p_path, Vector<Ref<Image>>
uint8_t header[4];
f->get_buffer(header, 4);
if (header[0] != 'G' || header[1] != 'S' || header[2] != 'T' || header[3] != 'L') {
- ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Stream texture layered file is corrupt (Bad header).");
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Compressed texture layered file is corrupt (Bad header).");
}
uint32_t version = f->get_32();
if (version > FORMAT_VERSION) {
- ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Stream texture file is too new.");
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Compressed texture file is too new.");
}
uint32_t layer_count = f->get_32(); //layer count
@@ -2647,7 +2819,7 @@ Error StreamTextureLayered::_load_data(const String &p_path, Vector<Ref<Image>>
images.resize(layer_count);
for (uint32_t i = 0; i < layer_count; i++) {
- Ref<Image> image = StreamTexture2D::load_image_from_file(f, p_size_limit);
+ Ref<Image> image = CompressedTexture2D::load_image_from_file(f, p_size_limit);
ERR_FAIL_COND_V(image.is_null() || image->is_empty(), ERR_CANT_OPEN);
images.write[i] = image;
}
@@ -2655,7 +2827,7 @@ Error StreamTextureLayered::_load_data(const String &p_path, Vector<Ref<Image>>
return OK;
}
-Error StreamTextureLayered::load(const String &p_path) {
+Error CompressedTextureLayered::load(const String &p_path) {
Vector<Ref<Image>> images;
int mipmap_limit;
@@ -2690,38 +2862,38 @@ Error StreamTextureLayered::load(const String &p_path) {
return OK;
}
-String StreamTextureLayered::get_load_path() const {
+String CompressedTextureLayered::get_load_path() const {
return path_to_file;
}
-int StreamTextureLayered::get_width() const {
+int CompressedTextureLayered::get_width() const {
return w;
}
-int StreamTextureLayered::get_height() const {
+int CompressedTextureLayered::get_height() const {
return h;
}
-int StreamTextureLayered::get_layers() const {
+int CompressedTextureLayered::get_layers() const {
return layers;
}
-bool StreamTextureLayered::has_mipmaps() const {
+bool CompressedTextureLayered::has_mipmaps() const {
return mipmaps;
}
-TextureLayered::LayeredType StreamTextureLayered::get_layered_type() const {
+TextureLayered::LayeredType CompressedTextureLayered::get_layered_type() const {
return layered_type;
}
-RID StreamTextureLayered::get_rid() const {
+RID CompressedTextureLayered::get_rid() const {
if (!texture.is_valid()) {
texture = RS::get_singleton()->texture_2d_layered_placeholder_create(RS::TextureLayeredType(layered_type));
}
return texture;
}
-Ref<Image> StreamTextureLayered::get_layer_data(int p_layer) const {
+Ref<Image> CompressedTextureLayered::get_layer_data(int p_layer) const {
if (texture.is_valid()) {
return RS::get_singleton()->texture_2d_layer_get(texture, p_layer);
} else {
@@ -2729,7 +2901,7 @@ Ref<Image> StreamTextureLayered::get_layer_data(int p_layer) const {
}
}
-void StreamTextureLayered::reload_from_file() {
+void CompressedTextureLayered::reload_from_file() {
String path = get_path();
if (!path.is_resource_file()) {
return;
@@ -2744,21 +2916,21 @@ void StreamTextureLayered::reload_from_file() {
load(path);
}
-void StreamTextureLayered::_validate_property(PropertyInfo &property) const {
+void CompressedTextureLayered::_validate_property(PropertyInfo &property) const {
}
-void StreamTextureLayered::_bind_methods() {
- ClassDB::bind_method(D_METHOD("load", "path"), &StreamTextureLayered::load);
- ClassDB::bind_method(D_METHOD("get_load_path"), &StreamTextureLayered::get_load_path);
+void CompressedTextureLayered::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("load", "path"), &CompressedTextureLayered::load);
+ ClassDB::bind_method(D_METHOD("get_load_path"), &CompressedTextureLayered::get_load_path);
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "load_path", PROPERTY_HINT_FILE, "*.stex"), "load", "get_load_path");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "load_path", PROPERTY_HINT_FILE, "*.ctex"), "load", "get_load_path");
}
-StreamTextureLayered::StreamTextureLayered(LayeredType p_type) {
+CompressedTextureLayered::CompressedTextureLayered(LayeredType p_type) {
layered_type = p_type;
}
-StreamTextureLayered::~StreamTextureLayered() {
+CompressedTextureLayered::~CompressedTextureLayered() {
if (texture.is_valid()) {
RS::get_singleton()->free(texture);
}
@@ -2766,27 +2938,27 @@ StreamTextureLayered::~StreamTextureLayered() {
/////////////////////////////////////////////////
-RES ResourceFormatLoaderStreamTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
- Ref<StreamTextureLayered> st;
- if (p_path.get_extension().to_lower() == "stexarray") {
- Ref<StreamTexture2DArray> s;
- s.instantiate();
- st = s;
- } else if (p_path.get_extension().to_lower() == "scube") {
- Ref<StreamCubemap> s;
- s.instantiate();
- st = s;
- } else if (p_path.get_extension().to_lower() == "scubearray") {
- Ref<StreamCubemapArray> s;
- s.instantiate();
- st = s;
+RES ResourceFormatLoaderCompressedTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
+ Ref<CompressedTextureLayered> ct;
+ if (p_path.get_extension().to_lower() == "ctexarray") {
+ Ref<CompressedTexture2DArray> c;
+ c.instantiate();
+ ct = c;
+ } else if (p_path.get_extension().to_lower() == "ccube") {
+ Ref<CompressedCubemap> c;
+ c.instantiate();
+ ct = c;
+ } else if (p_path.get_extension().to_lower() == "ccubearray") {
+ Ref<CompressedCubemapArray> c;
+ c.instantiate();
+ ct = c;
} else {
if (r_error) {
*r_error = ERR_FILE_UNRECOGNIZED;
}
return RES();
}
- Error err = st->load(p_path);
+ Error err = ct->load(p_path);
if (r_error) {
*r_error = err;
}
@@ -2794,28 +2966,28 @@ RES ResourceFormatLoaderStreamTextureLayered::load(const String &p_path, const S
return RES();
}
- return st;
+ return ct;
}
-void ResourceFormatLoaderStreamTextureLayered::get_recognized_extensions(List<String> *p_extensions) const {
- p_extensions->push_back("stexarray");
- p_extensions->push_back("scube");
- p_extensions->push_back("scubearray");
+void ResourceFormatLoaderCompressedTextureLayered::get_recognized_extensions(List<String> *p_extensions) const {
+ p_extensions->push_back("ctexarray");
+ p_extensions->push_back("ccube");
+ p_extensions->push_back("ccubearray");
}
-bool ResourceFormatLoaderStreamTextureLayered::handles_type(const String &p_type) const {
- return p_type == "StreamTexture2DArray" || p_type == "StreamCubemap" || p_type == "StreamCubemapArray";
+bool ResourceFormatLoaderCompressedTextureLayered::handles_type(const String &p_type) const {
+ return p_type == "CompressedTexture2DArray" || p_type == "CompressedCubemap" || p_type == "CompressedCubemapArray";
}
-String ResourceFormatLoaderStreamTextureLayered::get_resource_type(const String &p_path) const {
- if (p_path.get_extension().to_lower() == "stexarray") {
- return "StreamTexture2DArray";
+String ResourceFormatLoaderCompressedTextureLayered::get_resource_type(const String &p_path) const {
+ if (p_path.get_extension().to_lower() == "ctexarray") {
+ return "CompressedTexture2DArray";
}
- if (p_path.get_extension().to_lower() == "scube") {
- return "StreamCubemap";
+ if (p_path.get_extension().to_lower() == "ccube") {
+ return "CompressedCubemap";
}
- if (p_path.get_extension().to_lower() == "scubearray") {
- return "StreamCubemapArray";
+ if (p_path.get_extension().to_lower() == "ccubearray") {
+ return "CompressedCubemapArray";
}
return "";
}
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index 8075497c42..1e07b83547 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -57,14 +57,23 @@ class Texture2D : public Texture {
protected:
static void _bind_methods();
+ GDVIRTUAL0RC(int, _get_width)
+ GDVIRTUAL0RC(int, _get_height)
+ GDVIRTUAL2RC(bool, _is_pixel_opaque, int, int)
+ GDVIRTUAL0RC(bool, _has_alpha)
+
+ GDVIRTUAL4C(_draw, RID, Point2, Color, bool)
+ GDVIRTUAL5C(_draw_rect, RID, Rect2, bool, Color, bool)
+ GDVIRTUAL6C(_draw_rect_region, RID, Rect2, Rect2, Color, bool, bool)
+
public:
- virtual int get_width() const = 0;
- virtual int get_height() const = 0;
+ virtual int get_width() const;
+ virtual int get_height() const;
virtual Size2 get_size() const;
virtual bool is_pixel_opaque(int p_x, int p_y) const;
- virtual bool has_alpha() const = 0;
+ virtual bool has_alpha() const;
virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const;
virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const;
@@ -128,8 +137,8 @@ public:
~ImageTexture();
};
-class StreamTexture2D : public Texture2D {
- GDCLASS(StreamTexture2D, Texture2D);
+class CompressedTexture2D : public Texture2D {
+ GDCLASS(CompressedTexture2D, Texture2D);
public:
enum DataFormat {
@@ -174,8 +183,8 @@ protected:
public:
static Ref<Image> load_image_from_file(FileAccess *p_file, int p_size_limit);
- typedef void (*TextureFormatRequestCallback)(const Ref<StreamTexture2D> &);
- typedef void (*TextureFormatRoughnessRequestCallback)(const Ref<StreamTexture2D> &, const String &p_normal_path, RS::TextureDetectRoughnessChannel p_roughness_channel);
+ typedef void (*TextureFormatRequestCallback)(const Ref<CompressedTexture2D> &);
+ typedef void (*TextureFormatRoughnessRequestCallback)(const Ref<CompressedTexture2D> &, const String &p_normal_path, RS::TextureDetectRoughnessChannel p_roughness_channel);
static TextureFormatRequestCallback request_3d_callback;
static TextureFormatRoughnessRequestCallback request_roughness_callback;
@@ -200,11 +209,11 @@ public:
virtual Ref<Image> get_image() const override;
- StreamTexture2D();
- ~StreamTexture2D();
+ CompressedTexture2D();
+ ~CompressedTexture2D();
};
-class ResourceFormatLoaderStreamTexture2D : public ResourceFormatLoader {
+class ResourceFormatLoaderCompressedTexture2D : public ResourceFormatLoader {
public:
virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
@@ -300,6 +309,13 @@ class TextureLayered : public Texture {
protected:
static void _bind_methods();
+ GDVIRTUAL0RC(Image::Format, _get_format)
+ GDVIRTUAL0RC(uint32_t, _get_layered_type)
+ GDVIRTUAL0RC(int, _get_width)
+ GDVIRTUAL0RC(int, _get_height)
+ GDVIRTUAL0RC(int, _get_layers)
+ GDVIRTUAL0RC(bool, _has_mipmaps)
+ GDVIRTUAL1RC(Ref<Image>, _get_layer_data, int)
public:
enum LayeredType {
LAYERED_TYPE_2D_ARRAY,
@@ -307,13 +323,15 @@ public:
LAYERED_TYPE_CUBEMAP_ARRAY
};
- virtual Image::Format get_format() const = 0;
- virtual LayeredType get_layered_type() const = 0;
- virtual int get_width() const = 0;
- virtual int get_height() const = 0;
- virtual int get_layers() const = 0;
- virtual bool has_mipmaps() const = 0;
- virtual Ref<Image> get_layer_data(int p_layer) const = 0;
+ virtual Image::Format get_format() const;
+ virtual LayeredType get_layered_type() const;
+ virtual int get_width() const;
+ virtual int get_height() const;
+ virtual int get_layers() const;
+ virtual bool has_mipmaps() const;
+ virtual Ref<Image> get_layer_data(int p_layer) const;
+
+ TextureLayered() {}
};
VARIANT_ENUM_CAST(TextureLayered::LayeredType)
@@ -380,8 +398,8 @@ public:
ImageTextureLayered(LAYERED_TYPE_CUBEMAP_ARRAY) {}
};
-class StreamTextureLayered : public TextureLayered {
- GDCLASS(StreamTextureLayered, TextureLayered);
+class CompressedTextureLayered : public TextureLayered {
+ GDCLASS(CompressedTextureLayered, TextureLayered);
public:
enum DataFormat {
@@ -433,34 +451,34 @@ public:
virtual Ref<Image> get_layer_data(int p_layer) const override;
- StreamTextureLayered(LayeredType p_layered_type);
- ~StreamTextureLayered();
+ CompressedTextureLayered(LayeredType p_layered_type);
+ ~CompressedTextureLayered();
};
-class StreamTexture2DArray : public StreamTextureLayered {
- GDCLASS(StreamTexture2DArray, StreamTextureLayered)
+class CompressedTexture2DArray : public CompressedTextureLayered {
+ GDCLASS(CompressedTexture2DArray, CompressedTextureLayered)
public:
- StreamTexture2DArray() :
- StreamTextureLayered(LAYERED_TYPE_2D_ARRAY) {}
+ CompressedTexture2DArray() :
+ CompressedTextureLayered(LAYERED_TYPE_2D_ARRAY) {}
};
-class StreamCubemap : public StreamTextureLayered {
- GDCLASS(StreamCubemap, StreamTextureLayered);
+class CompressedCubemap : public CompressedTextureLayered {
+ GDCLASS(CompressedCubemap, CompressedTextureLayered);
public:
- StreamCubemap() :
- StreamTextureLayered(LAYERED_TYPE_CUBEMAP) {}
+ CompressedCubemap() :
+ CompressedTextureLayered(LAYERED_TYPE_CUBEMAP) {}
};
-class StreamCubemapArray : public StreamTextureLayered {
- GDCLASS(StreamCubemapArray, StreamTextureLayered);
+class CompressedCubemapArray : public CompressedTextureLayered {
+ GDCLASS(CompressedCubemapArray, CompressedTextureLayered);
public:
- StreamCubemapArray() :
- StreamTextureLayered(LAYERED_TYPE_CUBEMAP_ARRAY) {}
+ CompressedCubemapArray() :
+ CompressedTextureLayered(LAYERED_TYPE_CUBEMAP_ARRAY) {}
};
-class ResourceFormatLoaderStreamTextureLayered : public ResourceFormatLoader {
+class ResourceFormatLoaderCompressedTextureLayered : public ResourceFormatLoader {
public:
virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
@@ -474,15 +492,21 @@ class Texture3D : public Texture {
protected:
static void _bind_methods();
- TypedArray<Image> _get_data() const;
-
-public:
- virtual Image::Format get_format() const = 0;
- virtual int get_width() const = 0;
- virtual int get_height() const = 0;
- virtual int get_depth() const = 0;
- virtual bool has_mipmaps() const = 0;
- virtual Vector<Ref<Image>> get_data() const = 0;
+ TypedArray<Image> _get_datai() const;
+
+ GDVIRTUAL0RC(Image::Format, _get_format)
+ GDVIRTUAL0RC(int, _get_width)
+ GDVIRTUAL0RC(int, _get_height)
+ GDVIRTUAL0RC(int, _get_depth)
+ GDVIRTUAL0RC(bool, _has_mipmaps)
+ GDVIRTUAL0RC(TypedArray<Image>, _get_data)
+public:
+ virtual Image::Format get_format() const;
+ virtual int get_width() const;
+ virtual int get_height() const;
+ virtual int get_depth() const;
+ virtual bool has_mipmaps() const;
+ virtual Vector<Ref<Image>> get_data() const;
};
class ImageTexture3D : public Texture3D {
@@ -520,8 +544,8 @@ public:
~ImageTexture3D();
};
-class StreamTexture3D : public Texture3D {
- GDCLASS(StreamTexture3D, Texture3D);
+class CompressedTexture3D : public Texture3D {
+ GDCLASS(CompressedTexture3D, Texture3D);
public:
enum DataFormat {
@@ -571,11 +595,11 @@ public:
virtual Vector<Ref<Image>> get_data() const override;
- StreamTexture3D();
- ~StreamTexture3D();
+ CompressedTexture3D();
+ ~CompressedTexture3D();
};
-class ResourceFormatLoaderStreamTexture3D : public ResourceFormatLoader {
+class ResourceFormatLoaderCompressedTexture3D : public ResourceFormatLoader {
public:
virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index 47ca643029..d3e61dbc84 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -455,32 +455,69 @@ String VisualShaderNodeCustom::generate_code(Shader::Mode p_mode, VisualShader::
for (int i = 0; i < get_output_port_count(); i++) {
output_vars.push_back(p_output_vars[i]);
}
- String code = " {\n";
+
String _code;
GDVIRTUAL_CALL(_get_code, input_vars, output_vars, p_mode, p_type, _code);
- bool nend = _code.ends_with("\n");
- _code = _code.insert(0, " ");
- _code = _code.replace("\n", "\n ");
- code += _code;
- if (!nend) {
- code += "\n }";
- } else {
- code.remove_at(code.size() - 1);
- code += "}";
+ if (_is_valid_code(_code)) {
+ String code = " {\n";
+ bool nend = _code.ends_with("\n");
+ _code = _code.insert(0, " ");
+ _code = _code.replace("\n", "\n ");
+ code += _code;
+ if (!nend) {
+ code += "\n }";
+ } else {
+ code.remove_at(code.size() - 1);
+ code += "}";
+ }
+ code += "\n";
+ return code;
}
- code += "\n";
- return code;
+ return String();
}
String VisualShaderNodeCustom::generate_global_per_node(Shader::Mode p_mode, int p_id) const {
- String ret;
- if (GDVIRTUAL_CALL(_get_global_code, p_mode, ret)) {
- String code = "// " + get_caption() + "\n";
- code += ret;
- code += "\n";
- return code;
+ String _code;
+ if (GDVIRTUAL_CALL(_get_global_code, p_mode, _code)) {
+ if (_is_valid_code(_code)) {
+ String code = "// " + get_caption() + "\n";
+ code += _code;
+ code += "\n";
+ return code;
+ }
}
- return "";
+ return String();
+}
+
+String VisualShaderNodeCustom::generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+ String _code;
+ if (GDVIRTUAL_CALL(_get_func_code, p_mode, p_type, _code)) {
+ if (_is_valid_code(_code)) {
+ bool nend = _code.ends_with("\n");
+ String code = "// " + get_caption() + "\n";
+ code += " {\n";
+ _code = _code.insert(0, " ");
+ _code = _code.replace("\n", "\n ");
+ code += _code;
+ if (!nend) {
+ code += "\n }";
+ } else {
+ code.remove_at(code.size() - 1);
+ code += "}";
+ }
+ code += "\n";
+ return code;
+ }
+ }
+ return String();
+}
+
+bool VisualShaderNodeCustom::is_available(Shader::Mode p_mode, VisualShader::Type p_type) const {
+ bool ret;
+ if (GDVIRTUAL_CALL(_is_available, p_mode, p_type, ret)) {
+ return ret;
+ }
+ return true;
}
void VisualShaderNodeCustom::set_input_port_default_value(int p_port, const Variant &p_value, const Variant &p_prev_value) {
@@ -511,6 +548,13 @@ void VisualShaderNodeCustom::_set_input_port_default_value(int p_port, const Var
VisualShaderNode::set_input_port_default_value(p_port, p_value);
}
+bool VisualShaderNodeCustom::_is_valid_code(const String &p_code) const {
+ if (p_code.is_empty() || p_code == "null") {
+ return false;
+ }
+ return true;
+}
+
bool VisualShaderNodeCustom::_is_initialized() {
return is_initialized;
}
@@ -531,8 +575,10 @@ void VisualShaderNodeCustom::_bind_methods() {
GDVIRTUAL_BIND(_get_output_port_type, "port");
GDVIRTUAL_BIND(_get_output_port_name, "port");
GDVIRTUAL_BIND(_get_code, "input_vars", "output_vars", "mode", "type");
+ GDVIRTUAL_BIND(_get_func_code, "mode", "type");
GDVIRTUAL_BIND(_get_global_code, "mode");
GDVIRTUAL_BIND(_is_highend);
+ GDVIRTUAL_BIND(_is_available, "mode", "type");
ClassDB::bind_method(D_METHOD("_set_initialized", "enabled"), &VisualShaderNodeCustom::_set_initialized);
ClassDB::bind_method(D_METHOD("_is_initialized"), &VisualShaderNodeCustom::_is_initialized);
@@ -555,6 +601,72 @@ VisualShader::Type VisualShader::get_shader_type() const {
return current_type;
}
+void VisualShader::add_varying(const String &p_name, VaryingMode p_mode, VaryingType p_type) {
+ ERR_FAIL_COND(!p_name.is_valid_identifier());
+ ERR_FAIL_INDEX((int)p_mode, (int)VARYING_MODE_MAX);
+ ERR_FAIL_INDEX((int)p_type, (int)VARYING_TYPE_MAX);
+ ERR_FAIL_COND(varyings.has(p_name));
+ Varying var = Varying(p_name, p_mode, p_type);
+ varyings[p_name] = var;
+ varyings_list.push_back(var);
+ _queue_update();
+}
+
+void VisualShader::remove_varying(const String &p_name) {
+ ERR_FAIL_COND(!varyings.has(p_name));
+ varyings.erase(p_name);
+ for (List<Varying>::Element *E = varyings_list.front(); E; E = E->next()) {
+ if (E->get().name == p_name) {
+ varyings_list.erase(E);
+ break;
+ }
+ }
+ _queue_update();
+}
+
+bool VisualShader::has_varying(const String &p_name) const {
+ return varyings.has(p_name);
+}
+
+int VisualShader::get_varyings_count() const {
+ return varyings_list.size();
+}
+
+const VisualShader::Varying *VisualShader::get_varying_by_index(int p_idx) const {
+ ERR_FAIL_INDEX_V(p_idx, varyings_list.size(), nullptr);
+ return &varyings_list[p_idx];
+}
+
+void VisualShader::set_varying_mode(const String &p_name, VaryingMode p_mode) {
+ ERR_FAIL_INDEX((int)p_mode, (int)VARYING_MODE_MAX);
+ ERR_FAIL_COND(!varyings.has(p_name));
+ if (varyings[p_name].mode == p_mode) {
+ return;
+ }
+ varyings[p_name].mode = p_mode;
+ _queue_update();
+}
+
+VisualShader::VaryingMode VisualShader::get_varying_mode(const String &p_name) {
+ ERR_FAIL_COND_V(!varyings.has(p_name), VARYING_MODE_MAX);
+ return varyings[p_name].mode;
+}
+
+void VisualShader::set_varying_type(const String &p_name, VaryingType p_type) {
+ ERR_FAIL_INDEX((int)p_type, (int)VARYING_TYPE_MAX);
+ ERR_FAIL_COND(!varyings.has(p_name));
+ if (varyings[p_name].type == p_type) {
+ return;
+ }
+ varyings[p_name].type = p_type;
+ _queue_update();
+}
+
+VisualShader::VaryingType VisualShader::get_varying_type(const String &p_name) {
+ ERR_FAIL_COND_V(!varyings.has(p_name), VARYING_TYPE_MAX);
+ return varyings[p_name].type;
+}
+
void VisualShader::set_engine_version(const Dictionary &p_engine_version) {
ERR_FAIL_COND(!p_engine_version.has("major"));
ERR_FAIL_COND(!p_engine_version.has("minor"));
@@ -1072,7 +1184,7 @@ String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port
code += "\nvoid fragment() {\n";
Set<int> processed;
- Error err = _write_node(p_type, global_code, global_code_per_node, global_code_per_func, code, default_tex_params, input_connections, output_connections, p_node, processed, true, classes);
+ Error err = _write_node(p_type, &global_code, &global_code_per_node, &global_code_per_func, code, default_tex_params, input_connections, output_connections, p_node, processed, true, classes);
ERR_FAIL_COND_V(err != OK, String());
switch (node->get_output_port_type(p_port)) {
@@ -1253,6 +1365,16 @@ bool VisualShader::_set(const StringName &p_name, const Variant &p_value) {
}
_queue_update();
return true;
+ } else if (name.begins_with("varyings/")) {
+ String var_name = name.get_slicec('/', 1);
+ Varying value = Varying();
+ value.name = var_name;
+ if (value.from_string(p_value) && !varyings.has(var_name)) {
+ varyings[var_name] = value;
+ varyings_list.push_back(value);
+ }
+ _queue_update();
+ return true;
} else if (name.begins_with("nodes/")) {
String typestr = name.get_slicec('/', 1);
Type type = TYPE_VERTEX;
@@ -1317,6 +1439,14 @@ bool VisualShader::_get(const StringName &p_name, Variant &r_ret) const {
r_ret = 0;
}
return true;
+ } else if (name.begins_with("varyings/")) {
+ String var_name = name.get_slicec('/', 1);
+ if (varyings.has(var_name)) {
+ r_ret = varyings[var_name].to_string();
+ } else {
+ r_ret = String();
+ }
+ return true;
} else if (name.begins_with("nodes/")) {
String typestr = name.get_slicec('/', 1);
Type type = TYPE_VERTEX;
@@ -1411,6 +1541,10 @@ void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::BOOL, "flags/" + E->get()));
}
+ for (const KeyValue<String, Varying> &E : varyings) {
+ p_list->push_back(PropertyInfo(Variant::STRING, "varyings/" + E.key));
+ }
+
for (int i = 0; i < TYPE_MAX; i++) {
for (const KeyValue<int, Node> &E : graph[i].nodes) {
String prop_name = "nodes/";
@@ -1435,7 +1569,7 @@ void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const {
}
}
-Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBuilder &global_code_per_node, Map<Type, StringBuilder> &global_code_per_func, StringBuilder &code, Vector<VisualShader::DefaultTextureParam> &def_tex_params, const VMap<ConnectionKey, const List<Connection>::Element *> &input_connections, const VMap<ConnectionKey, const List<Connection>::Element *> &output_connections, int node, Set<int> &processed, bool for_preview, Set<StringName> &r_classes) const {
+Error VisualShader::_write_node(Type type, StringBuilder *global_code, StringBuilder *global_code_per_node, Map<Type, StringBuilder> *global_code_per_func, StringBuilder &code, Vector<VisualShader::DefaultTextureParam> &def_tex_params, const VMap<ConnectionKey, const List<Connection>::Element *> &input_connections, const VMap<ConnectionKey, const List<Connection>::Element *> &output_connections, int node, Set<int> &processed, bool for_preview, Set<StringName> &r_classes) const {
const Ref<VisualShaderNode> vsnode = graph[type].nodes[node].node;
if (vsnode->is_disabled()) {
@@ -1477,7 +1611,9 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
if (!skip_global) {
Ref<VisualShaderNodeUniform> uniform = vsnode;
if (!uniform.is_valid() || !uniform->is_global_code_generated()) {
- global_code += vsnode->generate_global(get_mode(), type, node);
+ if (global_code) {
+ *global_code += vsnode->generate_global(get_mode(), type, node);
+ }
}
String class_name = vsnode->get_class_name();
@@ -1485,9 +1621,13 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
class_name = vsnode->get_script_instance()->get_script()->get_path();
}
if (!r_classes.has(class_name)) {
- global_code_per_node += vsnode->generate_global_per_node(get_mode(), node);
+ if (global_code_per_node) {
+ *global_code_per_node += vsnode->generate_global_per_node(get_mode(), node);
+ }
for (int i = 0; i < TYPE_MAX; i++) {
- global_code_per_func[Type(i)] += vsnode->generate_global_per_func(get_mode(), Type(i), node);
+ if (global_code_per_func) {
+ (*global_code_per_func)[Type(i)] += vsnode->generate_global_per_func(get_mode(), Type(i), node);
+ }
}
r_classes.insert(class_name);
}
@@ -1940,6 +2080,7 @@ void VisualShader::_update_shader() const {
Set<String> used_uniform_names;
List<VisualShaderNodeUniform *> uniforms;
Map<int, List<int>> emitters;
+ Map<int, List<int>> varying_setters;
for (int i = 0, index = 0; i < TYPE_MAX; i++) {
if (!has_func_name(RenderingServer::ShaderMode(shader_mode), func_name[i])) {
@@ -1964,18 +2105,19 @@ void VisualShader::_update_shader() const {
if (uniform.is_valid()) {
uniforms.push_back(uniform.ptr());
}
+ Ref<VisualShaderNodeVaryingSetter> varying_setter = Object::cast_to<VisualShaderNodeVaryingSetter>(E->get().node.ptr());
+ if (varying_setter.is_valid() && varying_setter->is_input_port_connected(0)) {
+ if (!varying_setters.has(i)) {
+ varying_setters.insert(i, List<int>());
+ }
+ varying_setters[i].push_back(E->key());
+ }
Ref<VisualShaderNodeParticleEmit> emit_particle = Object::cast_to<VisualShaderNodeParticleEmit>(E->get().node.ptr());
if (emit_particle.is_valid()) {
if (!emitters.has(i)) {
emitters.insert(i, List<int>());
}
-
- for (const KeyValue<int, Node> &M : graph[i].nodes) {
- if (M.value.node == emit_particle.ptr()) {
- emitters[i].push_back(M.key);
- break;
- }
- }
+ emitters[i].push_back(E->key());
}
}
}
@@ -1990,6 +2132,36 @@ void VisualShader::_update_shader() const {
}
}
+ if (!varyings.is_empty()) {
+ global_code += "\n// Varyings\n";
+
+ for (const KeyValue<String, Varying> &E : varyings) {
+ global_code += "varying ";
+ switch (E.value.type) {
+ case VaryingType::VARYING_TYPE_FLOAT:
+ global_code += "float ";
+ break;
+ case VaryingType::VARYING_TYPE_VECTOR_2D:
+ global_code += "vec2 ";
+ break;
+ case VaryingType::VARYING_TYPE_VECTOR_3D:
+ global_code += "vec3 ";
+ break;
+ case VaryingType::VARYING_TYPE_COLOR:
+ global_code += "vec4 ";
+ break;
+ case VaryingType::VARYING_TYPE_TRANSFORM:
+ global_code += "mat4 ";
+ break;
+ default:
+ break;
+ }
+ global_code += E.key + ";\n";
+ }
+
+ global_code += "\n";
+ }
+
Map<int, String> code_map;
Set<int> empty_funcs;
@@ -2003,12 +2175,54 @@ void VisualShader::_update_shader() const {
VMap<ConnectionKey, const List<Connection>::Element *> output_connections;
StringBuilder func_code;
+ Set<int> processed;
bool is_empty_func = false;
if (shader_mode != Shader::MODE_PARTICLES && shader_mode != Shader::MODE_SKY && shader_mode != Shader::MODE_FOG) {
is_empty_func = true;
}
+ String varying_code;
+ if (shader_mode == Shader::MODE_SPATIAL || shader_mode == Shader::MODE_CANVAS_ITEM) {
+ for (const KeyValue<String, Varying> &E : varyings) {
+ if ((E.value.mode == VARYING_MODE_VERTEX_TO_FRAG_LIGHT && i == TYPE_VERTEX) || (E.value.mode == VARYING_MODE_FRAG_TO_LIGHT && i == TYPE_FRAGMENT)) {
+ bool found = false;
+ for (int key : varying_setters[i]) {
+ Ref<VisualShaderNodeVaryingSetter> setter = Object::cast_to<VisualShaderNodeVaryingSetter>(const_cast<VisualShaderNode *>(graph[i].nodes[key].node.ptr()));
+ if (setter.is_valid() && E.value.name == setter->get_varying_name()) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ String code2;
+ switch (E.value.type) {
+ case VaryingType::VARYING_TYPE_FLOAT:
+ code2 += "0.0";
+ break;
+ case VaryingType::VARYING_TYPE_VECTOR_2D:
+ code2 += "vec2(0.0)";
+ break;
+ case VaryingType::VARYING_TYPE_VECTOR_3D:
+ code2 += "vec3(0.0)";
+ break;
+ case VaryingType::VARYING_TYPE_COLOR:
+ code2 += "vec4(0.0)";
+ break;
+ case VaryingType::VARYING_TYPE_TRANSFORM:
+ code2 += "mat4(1.0)";
+ break;
+ default:
+ break;
+ }
+ varying_code += vformat(" %s = %s;\n", E.key, code2);
+ }
+ is_empty_func = false;
+ }
+ }
+ }
+
for (const List<Connection>::Element *E = graph[i].connections.front(); E; E = E->next()) {
ConnectionKey from_key;
from_key.node = E->get().from_node;
@@ -2037,13 +2251,19 @@ void VisualShader::_update_shader() const {
}
insertion_pos.insert(i, code.get_string_length() + func_code.get_string_length());
- Set<int> processed;
- Error err = _write_node(Type(i), global_code, global_code_per_node, global_code_per_func, func_code, default_tex_params, input_connections, output_connections, NODE_ID_OUTPUT, processed, false, classes);
+ Error err = _write_node(Type(i), &global_code, &global_code_per_node, &global_code_per_func, func_code, default_tex_params, input_connections, output_connections, NODE_ID_OUTPUT, processed, false, classes);
ERR_FAIL_COND(err != OK);
+ if (varying_setters.has(i)) {
+ for (int &E : varying_setters[i]) {
+ err = _write_node(Type(i), nullptr, nullptr, nullptr, func_code, default_tex_params, input_connections, output_connections, E, processed, false, classes);
+ ERR_FAIL_COND(err != OK);
+ }
+ }
+
if (emitters.has(i)) {
for (int &E : emitters[i]) {
- err = _write_node(Type(i), global_code, global_code_per_node, global_code_per_func, func_code, default_tex_params, input_connections, output_connections, E, processed, false, classes);
+ err = _write_node(Type(i), &global_code, &global_code_per_node, &global_code_per_func, func_code, default_tex_params, input_connections, output_connections, E, processed, false, classes);
ERR_FAIL_COND(err != OK);
}
}
@@ -2051,6 +2271,7 @@ void VisualShader::_update_shader() const {
if (shader_mode == Shader::MODE_PARTICLES) {
code_map.insert(i, func_code);
} else {
+ func_code += varying_code;
func_code += "}\n";
code += func_code;
}
@@ -2276,6 +2497,10 @@ void VisualShader::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_graph_offset", "offset"), &VisualShader::set_graph_offset);
ClassDB::bind_method(D_METHOD("get_graph_offset"), &VisualShader::get_graph_offset);
+ ClassDB::bind_method(D_METHOD("add_varying", "name", "mode", "type"), &VisualShader::add_varying);
+ ClassDB::bind_method(D_METHOD("remove_varying", "name"), &VisualShader::remove_varying);
+ ClassDB::bind_method(D_METHOD("has_varying", "name"), &VisualShader::has_varying);
+
ClassDB::bind_method(D_METHOD("_update_shader"), &VisualShader::_update_shader);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "graph_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_graph_offset", "get_graph_offset");
@@ -2295,6 +2520,17 @@ void VisualShader::_bind_methods() {
BIND_ENUM_CONSTANT(TYPE_FOG);
BIND_ENUM_CONSTANT(TYPE_MAX);
+ BIND_ENUM_CONSTANT(VARYING_MODE_VERTEX_TO_FRAG_LIGHT);
+ BIND_ENUM_CONSTANT(VARYING_MODE_FRAG_TO_LIGHT);
+ BIND_ENUM_CONSTANT(VARYING_MODE_MAX);
+
+ BIND_ENUM_CONSTANT(VARYING_TYPE_FLOAT);
+ BIND_ENUM_CONSTANT(VARYING_TYPE_VECTOR_2D);
+ BIND_ENUM_CONSTANT(VARYING_TYPE_VECTOR_3D);
+ BIND_ENUM_CONSTANT(VARYING_TYPE_COLOR);
+ BIND_ENUM_CONSTANT(VARYING_TYPE_TRANSFORM);
+ BIND_ENUM_CONSTANT(VARYING_TYPE_MAX);
+
BIND_CONSTANT(NODE_ID_INVALID);
BIND_CONSTANT(NODE_ID_OUTPUT);
}
@@ -2327,6 +2563,7 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
// Node3D, Vertex
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "vertex", "VERTEX" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "vertex_id", "VERTEX_ID" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "normal", "NORMAL" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "tangent", "TANGENT" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "binormal", "BINORMAL" },
@@ -2348,6 +2585,9 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_2D, "viewport_size", "VIEWPORT_SIZE" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_BOOLEAN, "output_is_srgb", "OUTPUT_IS_SRGB" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_index", "VIEW_INDEX" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_mono_left", "VIEW_MONO_LEFT" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_right", "VIEW_RIGHT" },
// Node3D, Fragment
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "fragcoord", "FRAGCOORD.xyz" },
@@ -2374,6 +2614,9 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
{ 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" },
// Node3D, Light
{ Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "fragcoord", "FRAGCOORD.xyz" },
@@ -2384,6 +2627,7 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
{ Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "light", "LIGHT" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "light_color", "LIGHT_COLOR" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "attenuation", "ATTENUATION" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "shadow_attenuation", "SHADOW_ATTENUATION" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "albedo", "ALBEDO" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "backlight", "BACKLIGHT" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "diffuse", "DIFFUSE_LIGHT" },
@@ -2415,6 +2659,8 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_BOOLEAN, "at_light_pass", "AT_LIGHT_PASS" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "instance_custom", "INSTANCE_CUSTOM.rgb" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "instance_custom_alpha", "INSTANCE_CUSTOM.a" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "instance_id", "INSTANCE_ID" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "vertex_id", "VERTEX_ID" },
// Canvas Item, Fragment
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "fragcoord", "FRAGCOORD.xyz" },
@@ -3144,6 +3390,7 @@ const VisualShaderNodeOutput::Port VisualShaderNodeOutput::ports[] = {
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "color", "COLOR.rgb" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "roughness", "ROUGHNESS" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "point_size", "POINT_SIZE" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "model_view_matrix", "MODELVIEW_MATRIX" },
////////////////////////////////////////////////////////////////////////
// Node3D, Fragment.
@@ -3155,6 +3402,7 @@ const VisualShaderNodeOutput::Port VisualShaderNodeOutput::ports[] = {
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "specular", "SPECULAR" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "emission", "EMISSION" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "ao", "AO" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "ao_light_affect", "AO_LIGHT_AFFECT" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "normal", "NORMAL" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "normal_map", "NORMAL_MAP" },
@@ -3170,7 +3418,10 @@ const VisualShaderNodeOutput::Port VisualShaderNodeOutput::ports[] = {
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "backlight", "BACKLIGHT" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha_scissor_threshold", "ALPHA_SCISSOR_THRESHOLD" },
- { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "ao_light_affect", "AO_LIGHT_AFFECT" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha_hash_scale", "ALPHA_HASH_SCALE" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha_aa_edge", "ALPHA_ANTIALIASING_EDGE" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "alpha_uv", "ALPHA_TEXTURE_COORDINATE" },
+
////////////////////////////////////////////////////////////////////////
// Node3D, Light.
////////////////////////////////////////////////////////////////////////
@@ -3294,7 +3545,7 @@ bool VisualShaderNodeOutput::is_port_separator(int p_index) const {
}
if (shader_mode == Shader::MODE_SPATIAL && shader_type == VisualShader::TYPE_FRAGMENT) {
String name = get_input_port_name(p_index);
- return bool(name == "Normal" || name == "Rim" || name == "Alpha Scissor Threshold");
+ return bool(name == "Ao" || name == "Normal" || name == "Rim" || name == "Clearcoat" || name == "Anisotropy" || name == "Subsurf Scatter" || name == "Alpha Scissor Threshold");
}
return false;
}
@@ -4199,3 +4450,299 @@ String VisualShaderNodeGlobalExpression::generate_global(Shader::Mode p_mode, Vi
VisualShaderNodeGlobalExpression::VisualShaderNodeGlobalExpression() {
set_editable(false);
}
+
+////////////// Varying
+
+List<VisualShaderNodeVarying::Varying> varyings;
+
+void VisualShaderNodeVarying::add_varying(const String &p_name, VisualShader::VaryingMode p_mode, VisualShader::VaryingType p_type) { // static
+ varyings.push_back({ p_name, p_mode, p_type });
+}
+
+void VisualShaderNodeVarying::clear_varyings() { // static
+ varyings.clear();
+}
+
+bool VisualShaderNodeVarying::has_varying(const String &p_name) { // static
+ for (const VisualShaderNodeVarying::Varying &E : varyings) {
+ if (E.name == p_name) {
+ return true;
+ }
+ }
+ return false;
+}
+
+int VisualShaderNodeVarying::get_varyings_count() const {
+ return varyings.size();
+}
+
+String VisualShaderNodeVarying::get_varying_name_by_index(int p_idx) const {
+ if (p_idx >= 0 && p_idx < varyings.size()) {
+ return varyings[p_idx].name;
+ }
+ return "";
+}
+
+VisualShader::VaryingType VisualShaderNodeVarying::get_varying_type_by_name(const String &p_name) const {
+ for (int i = 0; i < varyings.size(); i++) {
+ if (varyings[i].name == p_name) {
+ return varyings[i].type;
+ }
+ }
+ return VisualShader::VARYING_TYPE_FLOAT;
+}
+
+VisualShader::VaryingType VisualShaderNodeVarying::get_varying_type_by_index(int p_idx) const {
+ if (p_idx >= 0 && p_idx < varyings.size()) {
+ return varyings[p_idx].type;
+ }
+ return VisualShader::VARYING_TYPE_FLOAT;
+}
+
+VisualShader::VaryingMode VisualShaderNodeVarying::get_varying_mode_by_name(const String &p_name) const {
+ for (int i = 0; i < varyings.size(); i++) {
+ if (varyings[i].name == p_name) {
+ return varyings[i].mode;
+ }
+ }
+ return VisualShader::VARYING_MODE_VERTEX_TO_FRAG_LIGHT;
+}
+
+VisualShader::VaryingMode VisualShaderNodeVarying::get_varying_mode_by_index(int p_idx) const {
+ if (p_idx >= 0 && p_idx < varyings.size()) {
+ return varyings[p_idx].mode;
+ }
+ return VisualShader::VARYING_MODE_VERTEX_TO_FRAG_LIGHT;
+}
+
+VisualShaderNodeVarying::PortType VisualShaderNodeVarying::get_port_type_by_index(int p_idx) const {
+ if (p_idx >= 0 && p_idx < varyings.size()) {
+ return get_port_type(varyings[p_idx].type, 0);
+ }
+ return PORT_TYPE_SCALAR;
+}
+
+//////////////
+
+void VisualShaderNodeVarying::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_varying_name", "name"), &VisualShaderNodeVarying::set_varying_name);
+ ClassDB::bind_method(D_METHOD("get_varying_name"), &VisualShaderNodeVarying::get_varying_name);
+
+ ClassDB::bind_method(D_METHOD("set_varying_type", "type"), &VisualShaderNodeVarying::set_varying_type);
+ ClassDB::bind_method(D_METHOD("get_varying_type"), &VisualShaderNodeVarying::get_varying_type);
+
+ ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "varying_name"), "set_varying_name", "get_varying_name");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "varying_type", PROPERTY_HINT_ENUM, "Float,Vector,Transform"), "set_varying_type", "get_varying_type");
+}
+
+String VisualShaderNodeVarying::get_type_str() const {
+ switch (varying_type) {
+ case VisualShader::VARYING_TYPE_FLOAT:
+ return "float";
+ case VisualShader::VARYING_TYPE_VECTOR_2D:
+ return "vec2";
+ case VisualShader::VARYING_TYPE_VECTOR_3D:
+ return "vec3";
+ case VisualShader::VARYING_TYPE_COLOR:
+ return "vec4";
+ case VisualShader::VARYING_TYPE_TRANSFORM:
+ return "mat4";
+ default:
+ break;
+ }
+ return "";
+}
+
+VisualShaderNodeVarying::PortType VisualShaderNodeVarying::get_port_type(VisualShader::VaryingType p_type, int p_port) const {
+ switch (p_type) {
+ case VisualShader::VARYING_TYPE_VECTOR_2D:
+ return PORT_TYPE_VECTOR_2D;
+ case VisualShader::VARYING_TYPE_VECTOR_3D:
+ return PORT_TYPE_VECTOR_3D;
+ case VisualShader::VARYING_TYPE_COLOR:
+ if (p_port == 1) {
+ break; // scalar
+ }
+ return PORT_TYPE_VECTOR_3D;
+ case VisualShader::VARYING_TYPE_TRANSFORM:
+ return PORT_TYPE_TRANSFORM;
+ default:
+ break;
+ }
+ return PORT_TYPE_SCALAR;
+}
+
+void VisualShaderNodeVarying::set_varying_name(String p_varying_name) {
+ if (varying_name == p_varying_name) {
+ return;
+ }
+ varying_name = p_varying_name;
+ emit_changed();
+}
+
+String VisualShaderNodeVarying::get_varying_name() const {
+ return varying_name;
+}
+
+void VisualShaderNodeVarying::set_varying_type(VisualShader::VaryingType p_varying_type) {
+ ERR_FAIL_INDEX(p_varying_type, VisualShader::VARYING_TYPE_MAX);
+ if (varying_type == p_varying_type) {
+ return;
+ }
+ varying_type = p_varying_type;
+ emit_changed();
+}
+
+VisualShader::VaryingType VisualShaderNodeVarying::get_varying_type() const {
+ return varying_type;
+}
+
+VisualShaderNodeVarying::VisualShaderNodeVarying() {
+}
+
+////////////// Varying Setter
+
+String VisualShaderNodeVaryingSetter::get_caption() const {
+ return vformat("VaryingSetter");
+}
+
+int VisualShaderNodeVaryingSetter::get_input_port_count() const {
+ if (varying_type == VisualShader::VARYING_TYPE_COLOR) {
+ return 2;
+ }
+ return 1;
+}
+
+VisualShaderNodeVaryingSetter::PortType VisualShaderNodeVaryingSetter::get_input_port_type(int p_port) const {
+ return get_port_type(varying_type, p_port);
+}
+
+String VisualShaderNodeVaryingSetter::get_input_port_name(int p_port) const {
+ if (varying_type == VisualShader::VARYING_TYPE_COLOR) {
+ if (p_port == 0) {
+ return "color";
+ } else {
+ return "alpha";
+ }
+ }
+ return "";
+}
+
+int VisualShaderNodeVaryingSetter::get_output_port_count() const {
+ return 0;
+}
+
+VisualShaderNodeVaryingSetter::PortType VisualShaderNodeVaryingSetter::get_output_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR;
+}
+
+String VisualShaderNodeVaryingSetter::get_output_port_name(int p_port) const {
+ return "";
+}
+
+String VisualShaderNodeVaryingSetter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+ return vformat("varying %s %s;\n", get_type_str(), varying_name);
+}
+
+String VisualShaderNodeVaryingSetter::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;
+ if (varying_name == "[None]") {
+ return code;
+ }
+ if (varying_type == VisualShader::VARYING_TYPE_COLOR) {
+ code += vformat(" %s = vec4(%s, %s);\n", varying_name, p_input_vars[0], p_input_vars[1]);
+ } else {
+ code += vformat(" %s = %s;\n", varying_name, p_input_vars[0]);
+ }
+ return code;
+}
+
+VisualShaderNodeVaryingSetter::VisualShaderNodeVaryingSetter() {
+}
+
+////////////// Varying Getter
+
+String VisualShaderNodeVaryingGetter::get_caption() const {
+ return vformat("VaryingGetter");
+}
+
+int VisualShaderNodeVaryingGetter::get_input_port_count() const {
+ return 0;
+}
+
+VisualShaderNodeVaryingGetter::PortType VisualShaderNodeVaryingGetter::get_input_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR;
+}
+
+String VisualShaderNodeVaryingGetter::get_input_port_name(int p_port) const {
+ return "";
+}
+
+int VisualShaderNodeVaryingGetter::get_output_port_count() const {
+ if (varying_type == VisualShader::VARYING_TYPE_COLOR) {
+ return 2;
+ }
+ return 1;
+}
+
+VisualShaderNodeVaryingGetter::PortType VisualShaderNodeVaryingGetter::get_output_port_type(int p_port) const {
+ return get_port_type(varying_type, p_port);
+}
+
+String VisualShaderNodeVaryingGetter::get_output_port_name(int p_port) const {
+ if (varying_type == VisualShader::VARYING_TYPE_COLOR) {
+ if (p_port == 0) {
+ return "color";
+ } else {
+ return "alpha";
+ }
+ }
+ return "";
+}
+
+bool VisualShaderNodeVaryingGetter::has_output_port_preview(int p_port) const {
+ return false;
+}
+
+String VisualShaderNodeVaryingGetter::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 from = varying_name;
+ String from2;
+
+ if (varying_name == "[None]") {
+ switch (varying_type) {
+ case VisualShader::VARYING_TYPE_FLOAT:
+ from = "0.0";
+ break;
+ case VisualShader::VARYING_TYPE_VECTOR_2D:
+ from = "vec2(0.0)";
+ break;
+ case VisualShader::VARYING_TYPE_VECTOR_3D:
+ from = "vec3(0.0)";
+ break;
+ case VisualShader::VARYING_TYPE_COLOR:
+ from = "vec3(0.0)";
+ from2 = "0.0";
+ break;
+ case VisualShader::VARYING_TYPE_TRANSFORM:
+ from = "mat4(1.0)";
+ break;
+ default:
+ break;
+ }
+ } else if (varying_type == VisualShader::VARYING_TYPE_COLOR) {
+ from = varying_name + ".rgb";
+ from2 = varying_name + ".a";
+ }
+
+ if (varying_type == VisualShader::VARYING_TYPE_COLOR) {
+ String code;
+ code += vformat(" %s = %s;\n", p_output_vars[0], from);
+ code += vformat(" %s = %s;\n", p_output_vars[1], from2);
+ return code;
+ }
+ return vformat(" %s = %s;\n", p_output_vars[0], from);
+}
+
+VisualShaderNodeVaryingGetter::VisualShaderNodeVaryingGetter() {
+ varying_name = "[None]";
+}
diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h
index d3b5365893..2d4b2852e9 100644
--- a/scene/resources/visual_shader.h
+++ b/scene/resources/visual_shader.h
@@ -73,6 +73,49 @@ public:
List<Ref<Texture2D>> params;
};
+ enum VaryingMode {
+ VARYING_MODE_VERTEX_TO_FRAG_LIGHT,
+ VARYING_MODE_FRAG_TO_LIGHT,
+ VARYING_MODE_MAX,
+ };
+
+ enum VaryingType {
+ VARYING_TYPE_FLOAT,
+ VARYING_TYPE_VECTOR_2D,
+ VARYING_TYPE_VECTOR_3D,
+ VARYING_TYPE_COLOR,
+ VARYING_TYPE_TRANSFORM,
+ VARYING_TYPE_MAX,
+ };
+
+ struct Varying {
+ String name;
+ VaryingMode mode;
+ VaryingType type;
+
+ Varying() {
+ }
+
+ Varying(String p_name, VaryingMode p_mode, VaryingType p_type) :
+ name(p_name), mode(p_mode), type(p_type) {}
+
+ bool from_string(const String &p_str) {
+ Vector<String> arr = p_str.split(",");
+ if (arr.size() != 2) {
+ return false;
+ }
+
+ mode = (VaryingMode)arr[0].to_int();
+ type = (VaryingType)arr[1].to_int();
+
+ return true;
+ }
+
+ String to_string() const {
+ return vformat("%s,%s", itos((int)mode), itos((int)type));
+ }
+ };
+
private:
Type current_type;
@@ -94,14 +137,12 @@ private:
Vector2 graph_offset;
- struct RenderModeEnums {
- Shader::Mode mode = Shader::Mode::MODE_MAX;
- const char *string;
- };
-
HashMap<String, int> modes;
Set<StringName> flags;
+ Map<String, Varying> varyings;
+ List<Varying> varyings_list;
+
mutable SafeFlag dirty;
void _queue_update();
@@ -116,7 +157,7 @@ private:
}
};
- Error _write_node(Type p_type, StringBuilder &global_code, StringBuilder &global_code_per_node, Map<Type, StringBuilder> &global_code_per_func, StringBuilder &code, Vector<DefaultTextureParam> &def_tex_params, const VMap<ConnectionKey, const List<Connection>::Element *> &input_connections, const VMap<ConnectionKey, const List<Connection>::Element *> &output_connections, int node, Set<int> &processed, bool for_preview, Set<StringName> &r_classes) const;
+ Error _write_node(Type p_type, StringBuilder *global_code, StringBuilder *global_code_per_node, Map<Type, StringBuilder> *global_code_per_func, StringBuilder &code, Vector<DefaultTextureParam> &def_tex_params, const VMap<ConnectionKey, const List<Connection>::Element *> &input_connections, const VMap<ConnectionKey, const List<Connection>::Element *> &output_connections, int node, Set<int> &processed, bool for_preview, Set<StringName> &r_classes) const;
void _input_type_changed(Type p_type, int p_id);
bool has_func_name(RenderingServer::ShaderMode p_mode, const String &p_func_name) const;
@@ -151,6 +192,18 @@ public:
void add_node(Type p_type, const Ref<VisualShaderNode> &p_node, const Vector2 &p_position, int p_id);
void set_node_position(Type p_type, int p_id, const Vector2 &p_position);
+ void add_varying(const String &p_name, VaryingMode p_mode, VaryingType p_type);
+ void remove_varying(const String &p_name);
+ bool has_varying(const String &p_name) const;
+ int get_varyings_count() const;
+ const Varying *get_varying_by_index(int p_idx) const;
+
+ void set_varying_mode(const String &p_name, VaryingMode p_mode);
+ VaryingMode get_varying_mode(const String &p_name);
+
+ void set_varying_type(const String &p_name, VaryingType p_type);
+ VaryingType get_varying_type(const String &p_name);
+
Vector2 get_node_position(Type p_type, int p_id) const;
Ref<VisualShaderNode> get_node(Type p_type, int p_id) const;
@@ -190,6 +243,8 @@ public:
};
VARIANT_ENUM_CAST(VisualShader::Type)
+VARIANT_ENUM_CAST(VisualShader::VaryingMode)
+VARIANT_ENUM_CAST(VisualShader::VaryingType)
///
///
///
@@ -328,14 +383,20 @@ protected:
GDVIRTUAL1RC(int, _get_output_port_type, int)
GDVIRTUAL1RC(String, _get_output_port_name, int)
GDVIRTUAL4RC(String, _get_code, TypedArray<String>, TypedArray<String>, Shader::Mode, VisualShader::Type)
+ GDVIRTUAL2RC(String, _get_func_code, Shader::Mode, VisualShader::Type)
GDVIRTUAL1RC(String, _get_global_code, Shader::Mode)
GDVIRTUAL0RC(bool, _is_highend)
+ GDVIRTUAL2RC(bool, _is_available, Shader::Mode, VisualShader::Type)
+
+ bool _is_valid_code(const String &p_code) const;
protected:
void _set_input_port_default_value(int p_port, const Variant &p_value);
+ bool is_available(Shader::Mode p_mode, VisualShader::Type p_type) const;
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 generate_global_per_node(Shader::Mode p_mode, int p_id) const override;
+ virtual String generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
static void _bind_methods();
@@ -697,6 +758,103 @@ public:
VisualShaderNodeGlobalExpression();
};
+class VisualShaderNodeVarying : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeVarying, VisualShaderNode);
+
+public:
+ struct Varying {
+ String name;
+ VisualShader::VaryingMode mode;
+ VisualShader::VaryingType type;
+ bool assigned = false;
+ };
+
+protected:
+ VisualShader::VaryingType varying_type = VisualShader::VARYING_TYPE_FLOAT;
+ String varying_name = "[None]";
+
+public: // internal
+ static void add_varying(const String &p_name, VisualShader::VaryingMode p_mode, VisualShader::VaryingType p_type);
+ static void clear_varyings();
+ static bool has_varying(const String &p_name);
+
+ int get_varyings_count() const;
+ String get_varying_name_by_index(int p_idx) const;
+ VisualShader::VaryingMode get_varying_mode_by_name(const String &p_name) const;
+ VisualShader::VaryingMode get_varying_mode_by_index(int p_idx) const;
+ VisualShader::VaryingType get_varying_type_by_name(const String &p_name) const;
+ VisualShader::VaryingType get_varying_type_by_index(int p_idx) const;
+ PortType get_port_type_by_index(int p_idx) const;
+
+protected:
+ static void _bind_methods();
+
+protected:
+ String get_type_str() const;
+ PortType get_port_type(VisualShader::VaryingType p_type, int p_port) const;
+
+public:
+ virtual String get_caption() const override = 0;
+
+ virtual int get_input_port_count() const override = 0;
+ virtual PortType get_input_port_type(int p_port) const override = 0;
+ virtual String get_input_port_name(int p_port) const override = 0;
+
+ virtual int get_output_port_count() const override = 0;
+ virtual PortType get_output_port_type(int p_port) const override = 0;
+ virtual String get_output_port_name(int p_port) const override = 0;
+
+ 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 = 0;
+
+ void set_varying_name(String p_varying_name);
+ String get_varying_name() const;
+
+ void set_varying_type(VisualShader::VaryingType p_varying_type);
+ VisualShader::VaryingType get_varying_type() const;
+
+ VisualShaderNodeVarying();
+};
+
+class VisualShaderNodeVaryingSetter : public VisualShaderNodeVarying {
+ GDCLASS(VisualShaderNodeVaryingSetter, VisualShaderNodeVarying);
+
+public:
+ virtual String get_caption() const override;
+
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
+
+ virtual String 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;
+
+ VisualShaderNodeVaryingSetter();
+};
+
+class VisualShaderNodeVaryingGetter : public VisualShaderNodeVarying {
+ GDCLASS(VisualShaderNodeVaryingGetter, VisualShaderNodeVarying);
+
+public:
+ virtual String get_caption() const override;
+
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
+ virtual bool has_output_port_preview(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;
+
+ VisualShaderNodeVaryingGetter();
+};
+
extern String make_unique_id(VisualShader::Type p_type, int p_id, const String &p_name);
#endif // VISUAL_SHADER_H
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index a6aa6d8c49..7b4d7e66d4 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -5696,7 +5696,7 @@ String VisualShaderNodeTextureUniformTriplanar::get_input_port_name(int p_port)
String VisualShaderNodeTextureUniformTriplanar::generate_global_per_node(Shader::Mode p_mode, int p_id) const {
String code;
- code += "// TRIPLANAR FUNCTION GLOBAL CODE\n";
+ code += "// " + get_caption() + "\n";
code += " vec4 triplanar_texture(sampler2D p_sampler, vec3 p_weights, vec3 p_triplanar_pos) {\n";
code += " vec4 samp = vec4(0.0);\n";
code += " samp += texture(p_sampler, p_triplanar_pos.xy) * p_weights.z;\n";
@@ -5719,11 +5719,13 @@ String VisualShaderNodeTextureUniformTriplanar::generate_global_per_func(Shader:
String code;
if (p_type == VisualShader::TYPE_VERTEX) {
- code += " // TRIPLANAR FUNCTION VERTEX CODE\n";
+ code += "// " + get_caption() + "\n";
+ code += " {\n";
code += " triplanar_power_normal = pow(abs(NORMAL), vec3(triplanar_sharpness));\n";
code += " triplanar_power_normal /= dot(triplanar_power_normal, vec3(1.0));\n";
code += " triplanar_pos = VERTEX * triplanar_scale + triplanar_offset;\n";
code += " triplanar_pos *= vec3(1.0, -1.0, 1.0);\n";
+ code += " }\n";
}
return code;