From 2bb1638b0a34f4f298e2db18354ea3aec3d63f61 Mon Sep 17 00:00:00 2001 From: Marc Gilleron Date: Sat, 24 Jun 2017 21:28:22 +0200 Subject: [PATCH] GradientTexture now uses a Gradient - Added gradient property - Deleted duplicate code --- editor/editor_node.cpp | 2 - editor/plugins/gradient_editor_plugin.cpp | 3 +- editor/plugins/gradient_editor_plugin.h | 1 - .../gradient_texture_editor_plugin.cpp | 539 ------------------ .../plugins/gradient_texture_editor_plugin.h | 98 ---- scene/resources/texture.cpp | 166 +----- scene/resources/texture.h | 69 +-- 7 files changed, 36 insertions(+), 842 deletions(-) delete mode 100644 editor/plugins/gradient_texture_editor_plugin.cpp delete mode 100644 editor/plugins/gradient_texture_editor_plugin.h diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 2b29e4b08a2..04257b8cd14 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -77,7 +77,6 @@ #include "plugins/curve_editor_plugin.h" #include "plugins/gi_probe_editor_plugin.h" #include "plugins/gradient_editor_plugin.h" -#include "plugins/gradient_texture_editor_plugin.h" #include "plugins/item_list_editor_plugin.h" #include "plugins/light_occluder_2d_editor_plugin.h" #include "plugins/line_2d_editor_plugin.h" @@ -6112,7 +6111,6 @@ EditorNode::EditorNode() { add_editor_plugin(memnew(LightOccluder2DEditorPlugin(this))); add_editor_plugin(memnew(NavigationPolygonEditorPlugin(this))); add_editor_plugin(memnew(GradientEditorPlugin(this))); - add_editor_plugin(memnew(GradientTextureEditorPlugin(this))); add_editor_plugin(memnew(CollisionShape2DEditorPlugin(this))); add_editor_plugin(memnew(CurveEditorPlugin(this))); add_editor_plugin(memnew(TextureEditorPlugin(this))); diff --git a/editor/plugins/gradient_editor_plugin.cpp b/editor/plugins/gradient_editor_plugin.cpp index 9884db934b6..4aaa155cfdf 100644 --- a/editor/plugins/gradient_editor_plugin.cpp +++ b/editor/plugins/gradient_editor_plugin.cpp @@ -91,8 +91,7 @@ void GradientEditorPlugin::_ramp_changed() { } } -void GradientEditorPlugin::_undo_redo_gradient(const Vector &offsets, - const Vector &colors) { +void GradientEditorPlugin::_undo_redo_gradient(const Vector &offsets, const Vector &colors) { gradient_ref->set_offsets(offsets); gradient_ref->set_colors(colors); diff --git a/editor/plugins/gradient_editor_plugin.h b/editor/plugins/gradient_editor_plugin.h index 843e98a9170..c319a13a017 100644 --- a/editor/plugins/gradient_editor_plugin.h +++ b/editor/plugins/gradient_editor_plugin.h @@ -38,7 +38,6 @@ class GradientEditorPlugin : public EditorPlugin { GDCLASS(GradientEditorPlugin, EditorPlugin); - bool _2d; Ref gradient_ref; GradientEdit *ramp_editor; EditorNode *editor; diff --git a/editor/plugins/gradient_texture_editor_plugin.cpp b/editor/plugins/gradient_texture_editor_plugin.cpp deleted file mode 100644 index bc985dcdf71..00000000000 --- a/editor/plugins/gradient_texture_editor_plugin.cpp +++ /dev/null @@ -1,539 +0,0 @@ -/*************************************************************************/ -/* gradient_texture_editor_plugin.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include "gradient_texture_editor_plugin.h" - -#include "canvas_item_editor_plugin.h" -#include "os/keyboard.h" -#include "scene/resources/default_theme/theme_data.h" -#include "spatial_editor_plugin.h" - -#define POINT_WIDTH 8 - -GradientTextureEdit::GradientTextureEdit() { - grabbed = -1; - grabbing = false; - set_focus_mode(FOCUS_ALL); - - popup = memnew(PopupPanel); - picker = memnew(ColorPicker); - popup->add_child(picker); - - add_child(popup); - - checker = Ref(memnew(ImageTexture)); - Ref checker_bg = memnew(Image(checker_bg_png)); - checker->create_from_image(checker_bg, ImageTexture::FLAG_REPEAT); -} - -int GradientTextureEdit::_get_point_from_pos(int x) { - int result = -1; - int total_w = get_size().width - get_size().height - 3; - for (int i = 0; i < points.size(); i++) { - //Check if we clicked at point - if (ABS(x - points[i].offset * total_w + 1) < (POINT_WIDTH / 2 + 1)) { - result = i; - } - } - return result; -} - -void GradientTextureEdit::_show_color_picker() { - if (grabbed == -1) - return; - Size2 ms = Size2(350, picker->get_combined_minimum_size().height + 10); - picker->set_pick_color(points[grabbed].color); - popup->set_position(get_global_position() - Vector2(ms.width - get_size().width, ms.height)); - popup->set_size(ms); - popup->popup(); -} - -GradientTextureEdit::~GradientTextureEdit() { -} - -void GradientTextureEdit::_gui_input(const Ref &p_event) { - - Ref k = p_event; - - if (k.is_valid() && k->is_pressed() && k->get_scancode() == KEY_DELETE && grabbed != -1) { - - points.remove(grabbed); - grabbed = -1; - grabbing = false; - update(); - emit_signal("ramp_changed"); - accept_event(); - } - - Ref mb = p_event; - //Show color picker on double click. - if (mb.is_valid() && mb->get_button_index() == 1 && mb->is_doubleclick() && mb->is_pressed()) { - grabbed = _get_point_from_pos(mb->get_position().x); - _show_color_picker(); - accept_event(); - } - - //Delete point on right click - if (mb.is_valid() && mb->get_button_index() == 2 && mb->is_pressed()) { - grabbed = _get_point_from_pos(mb->get_position().x); - if (grabbed != -1) { - points.remove(grabbed); - grabbed = -1; - grabbing = false; - update(); - emit_signal("ramp_changed"); - accept_event(); - } - } - - //Hold alt key to duplicate selected color - if (mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed() && mb->get_alt()) { - - int x = mb->get_position().x; - grabbed = _get_point_from_pos(x); - - if (grabbed != -1) { - int total_w = get_size().width - get_size().height - 3; - GradientTexture::Point newPoint = points[grabbed]; - newPoint.offset = CLAMP(x / float(total_w), 0, 1); - - points.push_back(newPoint); - points.sort(); - for (int i = 0; i < points.size(); ++i) { - if (points[i].offset == newPoint.offset) { - grabbed = i; - break; - } - } - - emit_signal("ramp_changed"); - update(); - } - } - - if (mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) { - - update(); - int x = mb->get_position().x; - int total_w = get_size().width - get_size().height - 3; - - //Check if color selector was clicked. - if (x > total_w + 3) { - _show_color_picker(); - return; - } - - grabbing = true; - - grabbed = _get_point_from_pos(x); - //grab or select - if (grabbed != -1) { - return; - } - - //insert - GradientTexture::Point newPoint; - newPoint.offset = CLAMP(x / float(total_w), 0, 1); - - GradientTexture::Point prev; - GradientTexture::Point next; - - int pos = -1; - for (int i = 0; i < points.size(); i++) { - if (points[i].offset < newPoint.offset) - pos = i; - } - - if (pos == -1) { - - prev.color = Color(0, 0, 0); - prev.offset = 0; - if (points.size()) { - next = points[0]; - } else { - next.color = Color(1, 1, 1); - next.offset = 1.0; - } - } else { - - if (pos == points.size() - 1) { - next.color = Color(1, 1, 1); - next.offset = 1.0; - } else { - next = points[pos + 1]; - } - prev = points[pos]; - } - - newPoint.color = prev.color.linear_interpolate(next.color, (newPoint.offset - prev.offset) / (next.offset - prev.offset)); - - points.push_back(newPoint); - points.sort(); - for (int i = 0; i < points.size(); i++) { - if (points[i].offset == newPoint.offset) { - grabbed = i; - break; - } - } - - emit_signal("ramp_changed"); - } - - if (mb.is_valid() && mb->get_button_index() == 1 && !mb->is_pressed()) { - - if (grabbing) { - grabbing = false; - emit_signal("ramp_changed"); - } - update(); - } - - Ref mm = p_event; - - if (mm.is_valid() && grabbing) { - - int total_w = get_size().width - get_size().height - 3; - - int x = mm->get_position().x; - float newofs = CLAMP(x / float(total_w), 0, 1); - - //Snap to nearest point if holding shift - if (mm->get_shift()) { - float snap_treshhold = 0.03; - float smallest_ofs = snap_treshhold; - bool founded = false; - int nearest_point; - for (int i = 0; i < points.size(); ++i) { - if (i != grabbed) { - float temp_ofs = ABS(points[i].offset - newofs); - if (temp_ofs < smallest_ofs) { - smallest_ofs = temp_ofs; - nearest_point = i; - if (founded) - break; - founded = true; - } - } - } - if (founded) { - if (points[nearest_point].offset < newofs) - newofs = points[nearest_point].offset + 0.00001; - else - newofs = points[nearest_point].offset - 0.00001; - newofs = CLAMP(newofs, 0, 1); - } - } - - bool valid = true; - for (int i = 0; i < points.size(); i++) { - - if (points[i].offset == newofs && i != grabbed) { - valid = false; - } - } - - if (!valid) - return; - - points[grabbed].offset = newofs; - - points.sort(); - for (int i = 0; i < points.size(); i++) { - if (points[i].offset == newofs) { - grabbed = i; - break; - } - } - - emit_signal("ramp_changed"); - - update(); - } -} - -void GradientTextureEdit::_notification(int p_what) { - - if (p_what == NOTIFICATION_ENTER_TREE) { - if (!picker->is_connected("color_changed", this, "_color_changed")) { - picker->connect("color_changed", this, "_color_changed"); - } - } - if (p_what == NOTIFICATION_DRAW) { - - int w = get_size().x; - int h = get_size().y; - - if (w == 0 || h == 0) - return; //Safety check. We have division by 'h'. And in any case there is nothing to draw with such size - - int total_w = get_size().width - get_size().height - 3; - - //Draw checker pattern for ramp - _draw_checker(0, 0, total_w, h); - - //Draw color ramp - GradientTexture::Point prev; - prev.offset = 0; - if (points.size() == 0) - prev.color = Color(0, 0, 0); //Draw black rectangle if we have no points - else - prev.color = points[0].color; //Extend color of first point to the beginning. - - for (int i = -1; i < points.size(); i++) { - - GradientTexture::Point next; - //If there is no next point - if (i + 1 == points.size()) { - if (points.size() == 0) - next.color = Color(0, 0, 0); //Draw black rectangle if we have no points - else - next.color = points[i].color; //Extend color of last point to the end. - next.offset = 1; - } else { - next = points[i + 1]; - } - - if (prev.offset == next.offset) { - prev = next; - continue; - } - - Vector points; - Vector colors; - points.push_back(Vector2(prev.offset * total_w, h)); - points.push_back(Vector2(prev.offset * total_w, 0)); - points.push_back(Vector2(next.offset * total_w, 0)); - points.push_back(Vector2(next.offset * total_w, h)); - colors.push_back(prev.color); - colors.push_back(prev.color); - colors.push_back(next.color); - colors.push_back(next.color); - draw_primitive(points, colors, Vector()); - prev = next; - } - - //Draw point markers - for (int i = 0; i < points.size(); i++) { - - Color col = i == grabbed ? Color(1, 0.0, 0.0, 0.9) : points[i].color.contrasted(); - col.a = 0.9; - - draw_line(Vector2(points[i].offset * total_w, 0), Vector2(points[i].offset * total_w, h / 2), col); - draw_rect(Rect2(points[i].offset * total_w - POINT_WIDTH / 2, h / 2, POINT_WIDTH, h / 2), Color(0.6, 0.6, 0.6, i == grabbed ? 0.9 : 0.4)); - draw_line(Vector2(points[i].offset * total_w - POINT_WIDTH / 2, h / 2), Vector2(points[i].offset * total_w - POINT_WIDTH / 2, h - 1), col); - draw_line(Vector2(points[i].offset * total_w + POINT_WIDTH / 2, h / 2), Vector2(points[i].offset * total_w + POINT_WIDTH / 2, h - 1), col); - draw_line(Vector2(points[i].offset * total_w - POINT_WIDTH / 2, h / 2), Vector2(points[i].offset * total_w + POINT_WIDTH / 2, h / 2), col); - draw_line(Vector2(points[i].offset * total_w - POINT_WIDTH / 2, h - 1), Vector2(points[i].offset * total_w + POINT_WIDTH / 2, h - 1), col); - } - - //Draw "button" for color selector - _draw_checker(total_w + 3, 0, h, h); - if (grabbed != -1) { - //Draw with selection color - draw_rect(Rect2(total_w + 3, 0, h, h), points[grabbed].color); - } else { - //if no color selected draw grey color with 'X' on top. - draw_rect(Rect2(total_w + 3, 0, h, h), Color(0.5, 0.5, 0.5, 1)); - draw_line(Vector2(total_w + 3, 0), Vector2(total_w + 3 + h, h), Color(1, 1, 1, 0.6)); - draw_line(Vector2(total_w + 3, h), Vector2(total_w + 3 + h, 0), Color(1, 1, 1, 0.6)); - } - - //Draw borders around color ramp if in focus - if (has_focus()) { - - draw_line(Vector2(-1, -1), Vector2(total_w + 1, -1), Color(1, 1, 1, 0.6)); - draw_line(Vector2(total_w + 1, -1), Vector2(total_w + 1, h + 1), Color(1, 1, 1, 0.6)); - draw_line(Vector2(total_w + 1, h + 1), Vector2(-1, h + 1), Color(1, 1, 1, 0.6)); - draw_line(Vector2(-1, -1), Vector2(-1, h + 1), Color(1, 1, 1, 0.6)); - } - } -} - -void GradientTextureEdit::_draw_checker(int x, int y, int w, int h) { - //Draw it with polygon to insert UVs for scale - Vector backPoints; - backPoints.push_back(Vector2(x, y)); - backPoints.push_back(Vector2(x, y + h)); - backPoints.push_back(Vector2(x + w, y + h)); - backPoints.push_back(Vector2(x + w, y)); - Vector colorPoints; - colorPoints.push_back(Color(1, 1, 1, 1)); - colorPoints.push_back(Color(1, 1, 1, 1)); - colorPoints.push_back(Color(1, 1, 1, 1)); - colorPoints.push_back(Color(1, 1, 1, 1)); - Vector uvPoints; - //Draw checker pattern pixel-perfect and scale it by 2. - uvPoints.push_back(Vector2(x, y)); - uvPoints.push_back(Vector2(x, y + h * .5f / checker->get_height())); - uvPoints.push_back(Vector2(x + w * .5f / checker->get_width(), y + h * .5f / checker->get_height())); - uvPoints.push_back(Vector2(x + w * .5f / checker->get_width(), y)); - draw_polygon(backPoints, colorPoints, uvPoints, checker); -} - -Size2 GradientTextureEdit::get_minimum_size() const { - - return Vector2(0, 16); -} - -void GradientTextureEdit::_color_changed(const Color &p_color) { - - if (grabbed == -1) - return; - points[grabbed].color = p_color; - update(); - emit_signal("ramp_changed"); -} - -void GradientTextureEdit::set_ramp(const Vector &p_offsets, const Vector &p_colors) { - - ERR_FAIL_COND(p_offsets.size() != p_colors.size()); - points.clear(); - for (int i = 0; i < p_offsets.size(); i++) { - GradientTexture::Point p; - p.offset = p_offsets[i]; - p.color = p_colors[i]; - points.push_back(p); - } - - points.sort(); - update(); -} - -Vector GradientTextureEdit::get_offsets() const { - Vector ret; - for (int i = 0; i < points.size(); i++) - ret.push_back(points[i].offset); - return ret; -} - -Vector GradientTextureEdit::get_colors() const { - Vector ret; - for (int i = 0; i < points.size(); i++) - ret.push_back(points[i].color); - return ret; -} - -void GradientTextureEdit::set_points(Vector &p_points) { - if (points.size() != p_points.size()) - grabbed = -1; - points.clear(); - points = p_points; -} - -Vector &GradientTextureEdit::get_points() { - return points; -} - -void GradientTextureEdit::_bind_methods() { - ClassDB::bind_method(D_METHOD("_gui_input"), &GradientTextureEdit::_gui_input); - ClassDB::bind_method(D_METHOD("_color_changed"), &GradientTextureEdit::_color_changed); - ADD_SIGNAL(MethodInfo("ramp_changed")); -} - -GradientTextureEditorPlugin::GradientTextureEditorPlugin(EditorNode *p_node) { - - editor = p_node; - ramp_editor = memnew(GradientTextureEdit); - - gradient_button = editor->add_bottom_panel_item("GradientTexture", ramp_editor); - - gradient_button->hide(); - ramp_editor->set_custom_minimum_size(Size2(100, 100 * EDSCALE)); - ramp_editor->hide(); - ramp_editor->connect("ramp_changed", this, "ramp_changed"); -} - -void GradientTextureEditorPlugin::edit(Object *p_object) { - - GradientTexture *gradient_texture = p_object->cast_to(); - if (!gradient_texture) - return; - gradient_texture_ref = Ref(gradient_texture); - ramp_editor->set_points(gradient_texture_ref->get_points()); -} - -bool GradientTextureEditorPlugin::handles(Object *p_object) const { - - return p_object->is_class("GradientTexture"); -} - -void GradientTextureEditorPlugin::make_visible(bool p_visible) { - - if (p_visible) { - gradient_button->show(); - editor->make_bottom_panel_item_visible(ramp_editor); - - } else { - - gradient_button->hide(); - if (ramp_editor->is_visible_in_tree()) - editor->hide_bottom_panel(); - } -} - -void GradientTextureEditorPlugin::_ramp_changed() { - - if (gradient_texture_ref.is_valid()) { - - UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); - - //Not sure if I should convert this data to PoolVector - Vector new_offsets = ramp_editor->get_offsets(); - Vector new_colors = ramp_editor->get_colors(); - Vector old_offsets = gradient_texture_ref->get_offsets(); - Vector old_colors = gradient_texture_ref->get_colors(); - - if (old_offsets.size() != new_offsets.size()) - ur->create_action(TTR("Add/Remove Color Ramp Point")); - else - ur->create_action(TTR("Modify Color Ramp"), UndoRedo::MERGE_ENDS); - ur->add_do_method(this, "undo_redo_gradient_texture", new_offsets, new_colors); - ur->add_undo_method(this, "undo_redo_gradient_texture", old_offsets, old_colors); - ur->commit_action(); - - //gradient_texture_ref->set_points(ramp_editor->get_points()); - } -} - -void GradientTextureEditorPlugin::_undo_redo_gradient_texture(const Vector &offsets, - const Vector &colors) { - - gradient_texture_ref->set_offsets(offsets); - gradient_texture_ref->set_colors(colors); - ramp_editor->set_points(gradient_texture_ref->get_points()); - ramp_editor->update(); -} - -GradientTextureEditorPlugin::~GradientTextureEditorPlugin() { -} - -void GradientTextureEditorPlugin::_bind_methods() { - ClassDB::bind_method(D_METHOD("ramp_changed"), &GradientTextureEditorPlugin::_ramp_changed); - ClassDB::bind_method(D_METHOD("undo_redo_gradient_texture", "offsets", "colors"), &GradientTextureEditorPlugin::_undo_redo_gradient_texture); -} diff --git a/editor/plugins/gradient_texture_editor_plugin.h b/editor/plugins/gradient_texture_editor_plugin.h deleted file mode 100644 index 842d586541b..00000000000 --- a/editor/plugins/gradient_texture_editor_plugin.h +++ /dev/null @@ -1,98 +0,0 @@ -/*************************************************************************/ -/* gradient_texture_editor_plugin.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#ifndef GRADIENT_TEXTURE_EDITOR_PLUGIN_H -#define GRADIENT_TEXTURE_EDITOR_PLUGIN_H - -#include "editor/editor_node.h" -#include "editor/editor_plugin.h" -#include "scene/resources/texture.h" - -class GradientTextureEdit : public Control { - - GDCLASS(GradientTextureEdit, Control); - - PopupPanel *popup; - ColorPicker *picker; - - Ref checker; - - bool grabbing; - int grabbed; - Vector points; - - void _draw_checker(int x, int y, int w, int h); - void _color_changed(const Color &p_color); - int _get_point_from_pos(int x); - void _show_color_picker(); - -protected: - void _gui_input(const Ref &p_event); - void _notification(int p_what); - static void _bind_methods(); - -public: - void set_ramp(const Vector &p_offsets, const Vector &p_colors); - Vector get_offsets() const; - Vector get_colors() const; - void set_points(Vector &p_points); - Vector &get_points(); - virtual Size2 get_minimum_size() const; - - GradientTextureEdit(); - virtual ~GradientTextureEdit(); -}; - -class GradientTextureEditorPlugin : public EditorPlugin { - - GDCLASS(GradientTextureEditorPlugin, EditorPlugin); - - bool _2d; - Ref gradient_texture_ref; - GradientTextureEdit *ramp_editor; - EditorNode *editor; - ToolButton *gradient_button; - -protected: - static void _bind_methods(); - void _ramp_changed(); - void _undo_redo_gradient_texture(const Vector &offsets, const Vector &colors); - -public: - virtual String get_name() const { return "GradientTexture"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - GradientTextureEditorPlugin(EditorNode *p_node); - ~GradientTextureEditorPlugin(); -}; - -#endif // GRADIENT_TEXTURE_EDITOR_PLUGIN_H diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 7b393233f1b..5049c0a1d66 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -1508,13 +1508,6 @@ CurveTexture::~CurveTexture() { #define COLOR_RAMP_SET_COLORS "set_colors" GradientTexture::GradientTexture() { - //Set initial color ramp transition from black to white - points.resize(2); - points[0].color = Color(0, 0, 0, 1); - points[0].offset = 0; - points[1].color = Color(1, 1, 1, 1); - points[1].offset = 1; - is_sorted = true; update_pending = false; width = 2048; @@ -1528,32 +1521,33 @@ GradientTexture::~GradientTexture() { void GradientTexture::_bind_methods() { - ClassDB::bind_method(D_METHOD("add_point", "offset", "color"), &GradientTexture::add_point); - ClassDB::bind_method(D_METHOD("remove_point", "offset", "color"), &GradientTexture::remove_point); - - ClassDB::bind_method(D_METHOD("set_offset", "point", "offset"), &GradientTexture::set_offset); - ClassDB::bind_method(D_METHOD("get_offset", "point"), &GradientTexture::get_offset); - - ClassDB::bind_method(D_METHOD("set_color", "point", "color"), &GradientTexture::set_color); - ClassDB::bind_method(D_METHOD("get_color", "point"), &GradientTexture::get_color); + ClassDB::bind_method(D_METHOD("set_gradient", "gradient:Gradient"), &GradientTexture::set_gradient); + ClassDB::bind_method(D_METHOD("get_gradient:Gradient"), &GradientTexture::get_gradient); ClassDB::bind_method(D_METHOD("set_width", "width"), &GradientTexture::set_width); - ClassDB::bind_method(D_METHOD("interpolate", "offset"), &GradientTexture::get_color_at_offset); - - ClassDB::bind_method(D_METHOD("get_point_count"), &GradientTexture::get_points_count); - ClassDB::bind_method(D_METHOD("_update"), &GradientTexture::_update); - ClassDB::bind_method(D_METHOD(COLOR_RAMP_SET_OFFSETS, "offsets"), &GradientTexture::set_offsets); - ClassDB::bind_method(D_METHOD(COLOR_RAMP_GET_OFFSETS), &GradientTexture::get_offsets); - - ClassDB::bind_method(D_METHOD(COLOR_RAMP_SET_COLORS, "colors"), &GradientTexture::set_colors); - ClassDB::bind_method(D_METHOD(COLOR_RAMP_GET_COLORS), &GradientTexture::get_colors); - + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "gradient", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_gradient", "get_gradient"); ADD_PROPERTY(PropertyInfo(Variant::INT, "width"), "set_width", "get_width"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "offsets"), COLOR_RAMP_SET_OFFSETS, COLOR_RAMP_GET_OFFSETS); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "colors"), COLOR_RAMP_SET_COLORS, COLOR_RAMP_GET_COLORS); +} + +void GradientTexture::set_gradient(Ref p_gradient) { + if (p_gradient == gradient) + return; + if (gradient.is_valid()) { + gradient->disconnect(CoreStringNames::get_singleton()->changed, this, "_update"); + } + gradient = p_gradient; + if (gradient.is_valid()) { + gradient->connect(CoreStringNames::get_singleton()->changed, this, "_update"); + } + _update(); + emit_changed(); +} + +Ref GradientTexture::get_gradient() const { + return gradient; } void GradientTexture::_queue_update() { @@ -1566,16 +1560,22 @@ void GradientTexture::_queue_update() { void GradientTexture::_update() { + if (gradient.is_null()) + return; + update_pending = false; PoolVector data; data.resize(width * 4); { PoolVector::Write wd8 = data.write(); - for (int i = 0; i < width; i++) { - float ofs = float(i) / (width - 1); + Gradient &g = **gradient; + + for (int i = 0; i < width; i++) { + + float ofs = float(i) / (width - 1); + Color color = g.get_color_at_offset(ofs); - Color color = get_color_at_offset(ofs); wd8[i * 4 + 0] = uint8_t(CLAMP(color.r * 255.0, 0, 255)); wd8[i * 4 + 1] = uint8_t(CLAMP(color.g * 255.0, 0, 255)); wd8[i * 4 + 2] = uint8_t(CLAMP(color.b * 255.0, 0, 255)); @@ -1601,112 +1601,6 @@ int GradientTexture::get_width() const { return width; } -Vector GradientTexture::get_offsets() const { - Vector offsets; - offsets.resize(points.size()); - for (int i = 0; i < points.size(); i++) { - offsets[i] = points[i].offset; - } - return offsets; -} - -Vector GradientTexture::get_colors() const { - Vector colors; - colors.resize(points.size()); - for (int i = 0; i < points.size(); i++) { - colors[i] = points[i].color; - } - return colors; -} - -void GradientTexture::set_offsets(const Vector &p_offsets) { - points.resize(p_offsets.size()); - for (int i = 0; i < points.size(); i++) { - points[i].offset = p_offsets[i]; - } - is_sorted = false; - emit_changed(); - _queue_update(); -} - -void GradientTexture::set_colors(const Vector &p_colors) { - if (points.size() < p_colors.size()) - is_sorted = false; - points.resize(p_colors.size()); - for (int i = 0; i < points.size(); i++) { - points[i].color = p_colors[i]; - } - emit_changed(); - _queue_update(); -} - -Vector &GradientTexture::get_points() { - return points; -} - -void GradientTexture::add_point(float p_offset, const Color &p_color) { - - Point p; - p.offset = p_offset; - p.color = p_color; - is_sorted = false; - points.push_back(p); - - emit_changed(); - _queue_update(); -} - -void GradientTexture::remove_point(int p_index) { - - ERR_FAIL_INDEX(p_index, points.size()); - ERR_FAIL_COND(points.size() <= 2); - points.remove(p_index); - emit_changed(); - _queue_update(); -} - -void GradientTexture::set_points(Vector &p_points) { - points = p_points; - is_sorted = false; - emit_changed(); - _queue_update(); -} - -void GradientTexture::set_offset(int pos, const float offset) { - if (points.size() <= pos) - points.resize(pos + 1); - points[pos].offset = offset; - is_sorted = false; - emit_changed(); - _queue_update(); -} - -float GradientTexture::get_offset(int pos) const { - if (points.size() > pos) - return points[pos].offset; - return 0; //TODO: Maybe throw some error instead? -} - Ref GradientTexture::get_data() const { return VisualServer::get_singleton()->texture_get_data(texture); } - -void GradientTexture::set_color(int pos, const Color &color) { - if (points.size() <= pos) { - points.resize(pos + 1); - is_sorted = false; - } - points[pos].color = color; - emit_changed(); - _queue_update(); -} - -Color GradientTexture::get_color(int pos) const { - if (points.size() > pos) - return points[pos].color; - return Color(0, 0, 0, 1); //TODO: Maybe throw some error instead? -} - -int GradientTexture::get_points_count() const { - return points.size(); -} diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 2c36cdef87e..ff5a58c221f 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -34,6 +34,7 @@ #include "io/resource_loader.h" #include "math_2d.h" #include "resource.h" +#include "scene/resources/color_ramp.h" #include "servers/visual_server.h" /** @@ -451,7 +452,7 @@ public: //VARIANT_ENUM_CAST( Texture::CubeMapSide ); class GradientTexture : public Texture { - GDCLASS(GradientTexture, Texture); + GDCLASS(GradientTexture, Texture) public: struct Point { @@ -464,8 +465,7 @@ public: }; private: - Vector points; - bool is_sorted; + Ref gradient; bool update_pending; RID texture; int width; @@ -477,23 +477,8 @@ protected: static void _bind_methods(); public: - void add_point(float p_offset, const Color &p_color); - void remove_point(int p_index); - - void set_points(Vector &points); - Vector &get_points(); - - void set_offset(int pos, const float offset); - float get_offset(int pos) const; - - void set_color(int pos, const Color &color); - Color get_color(int pos) const; - - void set_offsets(const Vector &offsets); - Vector get_offsets() const; - - void set_colors(const Vector &colors); - Vector get_colors() const; + void set_gradient(Ref p_gradient); + Ref get_gradient() const; void set_width(int p_width); int get_width() const; @@ -505,52 +490,8 @@ public: virtual void set_flags(uint32_t p_flags) {} virtual uint32_t get_flags() const { return FLAG_FILTER; } - _FORCE_INLINE_ Color get_color_at_offset(float p_offset) { - - if (points.empty()) - return Color(0, 0, 0, 1); - - if (!is_sorted) { - points.sort(); - is_sorted = true; - } - - //binary search - int low = 0; - int high = points.size() - 1; - int middle; - - while (low <= high) { - middle = (low + high) / 2; - Point &point = points[middle]; - if (point.offset > p_offset) { - high = middle - 1; //search low end of array - } else if (point.offset < p_offset) { - low = middle + 1; //search high end of array - } else { - return point.color; - } - } - - //return interpolated value - if (points[middle].offset > p_offset) { - middle--; - } - int first = middle; - int second = middle + 1; - if (second >= points.size()) - return points[points.size() - 1].color; - if (first < 0) - return points[0].color; - Point &pointFirst = points[first]; - Point &pointSecond = points[second]; - return pointFirst.color.linear_interpolate(pointSecond.color, (p_offset - pointFirst.offset) / (pointSecond.offset - pointFirst.offset)); - } - virtual Ref get_data() const; - int get_points_count() const; - GradientTexture(); virtual ~GradientTexture(); };