123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347 |
- // SuperTux
- // Copyright (C) 2006 Matthias Braun <matze@braunis.de>
- //
- // This program is free software: you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License
- // along with this program. If not, see <http://www.gnu.org/licenses/>.
- #include "object/gradient.hpp"
- #include <utility>
- #include <simplesquirrel/class.hpp>
- #include <simplesquirrel/vm.hpp>
- #include "editor/editor.hpp"
- #include "object/camera.hpp"
- #include "supertux/gameconfig.hpp"
- #include "supertux/level.hpp"
- #include "supertux/sector.hpp"
- #include "util/reader.hpp"
- #include "util/reader_mapping.hpp"
- #include "util/writer.hpp"
- #include "video/video_system.hpp"
- #include "video/viewport.hpp"
- Gradient::Gradient() :
- m_layer(LAYER_BACKGROUND0),
- m_gradient_top(),
- m_gradient_bottom(),
- m_gradient_direction(),
- m_blend(),
- m_target(DrawingTarget::COLORMAP),
- m_start_gradient_top(),
- m_start_gradient_bottom(),
- m_fade_gradient_top(),
- m_fade_gradient_bottom(),
- m_fade_total_time(),
- m_fade_time()
- {
- }
- Gradient::Gradient(const ReaderMapping& reader) :
- GameObject(reader),
- m_layer(LAYER_BACKGROUND0),
- m_gradient_top(),
- m_gradient_bottom(),
- m_gradient_direction(),
- m_blend(),
- m_target(DrawingTarget::COLORMAP),
- m_start_gradient_top(),
- m_start_gradient_bottom(),
- m_fade_gradient_top(),
- m_fade_gradient_bottom(),
- m_fade_total_time(),
- m_fade_time()
- {
- m_layer = reader_get_layer (reader, LAYER_BACKGROUND0);
- std::vector<float> bkgd_top_color, bkgd_bottom_color;
- std::string direction;
- if (reader.get("direction", direction))
- {
- set_direction(direction);
- }
- else
- {
- set_direction(VERTICAL);
- }
- if (reader.get("top_color", bkgd_top_color)) {
- m_gradient_top = Color(bkgd_top_color);
- } else {
- m_gradient_top = Color(0.3f, 0.4f, 0.75f);
- }
- if (reader.get("bottom_color", bkgd_bottom_color)) {
- m_gradient_bottom = Color(bkgd_bottom_color);
- } else {
- m_gradient_bottom = Color(1, 1, 1);
- }
- reader.get_custom("blend", m_blend, Blend_from_string);
- reader.get_custom("target", m_target, DrawingTarget_from_string);
- }
- ObjectSettings
- Gradient::get_settings()
- {
- ObjectSettings result = GameObject::get_settings();
- result.add_rgba(_("Primary Colour"), &m_gradient_top, "top_color");
- result.add_rgba(_("Secondary Colour"), &m_gradient_bottom, "bottom_color");
- result.add_int(_("Z-pos"), &m_layer, "z-pos", LAYER_BACKGROUND0);
- result.add_enum(_("Direction"), reinterpret_cast<int*>(&m_gradient_direction),
- {_("Vertical"), _("Horizontal"), _("Vertical (whole sector)"), _("Horizontal (whole sector)")},
- {"vertical", "horizontal", "vertical_sector", "horizontal_sector"},
- static_cast<int>(VERTICAL), "direction");
- result.add_enum(_("Draw target"), reinterpret_cast<int*>(&m_target),
- {_("Normal"), _("Lightmap")},
- {"normal", "lightmap"},
- static_cast<int>(DrawingTarget::COLORMAP),
- "target");
- result.add_enum(_("Blend mode"), reinterpret_cast<int*>(&m_blend),
- {_("Blend"), _("Additive"), _("Modulate"), _("None")},
- {"blend", "add", "mod", "none"},
- static_cast<int>(Blend::BLEND),
- "blend");
- result.reorder({"blend", "top_color", "bottom_color", "target", "z-pos"});
- result.add_remove();
- return result;
- }
- Gradient::~Gradient()
- {
- }
- void
- Gradient::update(float delta)
- {
- if (m_fade_time <= 0) return;
-
- m_fade_time -= delta;
- if (m_fade_time <= 0)
- {
- m_fade_time = 0;
-
- m_gradient_top = m_fade_gradient_top;
- m_gradient_bottom = m_fade_gradient_bottom;
-
- return;
- }
-
- float progress = m_fade_time / m_fade_total_time;
-
- m_gradient_top = Color(
- m_fade_gradient_top.red + (m_start_gradient_top.red - m_fade_gradient_top.red) * progress,
- m_fade_gradient_top.green + (m_start_gradient_top.green - m_fade_gradient_top.green) * progress,
- m_fade_gradient_top.blue + (m_start_gradient_top.blue - m_fade_gradient_top.blue) * progress,
- m_fade_gradient_top.alpha + (m_start_gradient_top.alpha - m_fade_gradient_top.alpha) * progress
- );
- m_gradient_bottom = Color(
- m_fade_gradient_bottom.red + (m_start_gradient_bottom.red - m_fade_gradient_bottom.red) * progress,
- m_fade_gradient_bottom.green + (m_start_gradient_bottom.green - m_fade_gradient_bottom.green) * progress,
- m_fade_gradient_bottom.blue + (m_start_gradient_bottom.blue - m_fade_gradient_bottom.blue) * progress,
- m_fade_gradient_bottom.alpha + (m_start_gradient_bottom.alpha - m_fade_gradient_bottom.alpha) * progress
- );
- }
- void
- Gradient::set_gradient(const Color& top, const Color& bottom)
- {
- m_gradient_top = top;
- m_gradient_bottom = bottom;
- if (m_gradient_top.red > 1.0f ||
- m_gradient_top.green > 1.0f ||
- m_gradient_top.blue > 1.0f ||
- m_gradient_top.alpha > 1.0f)
- {
- log_warning << "Top gradient color has values above 1.0." << std::endl;
- }
- if (m_gradient_bottom.red > 1.0f ||
- m_gradient_bottom.green > 1.0f ||
- m_gradient_bottom.blue > 1.0f ||
- m_gradient_bottom.alpha > 1.0f)
- {
- log_warning << "Bottom gradient color has values above 1.0." << std::endl;
- }
- }
- void
- Gradient::fade_gradient(const Color& top, const Color& bottom, float time)
- {
- m_start_gradient_top = m_gradient_top;
- m_start_gradient_bottom = m_gradient_bottom;
- m_fade_gradient_top = top;
- m_fade_gradient_bottom = bottom;
- m_fade_total_time = time;
- m_fade_time = time;
- }
- std::string
- Gradient::get_direction_string() const
- {
- if (m_gradient_direction == HORIZONTAL)
- return "horizontal";
- if (m_gradient_direction == VERTICAL)
- return "vertical";
- if (m_gradient_direction == HORIZONTAL_SECTOR)
- return "horizontal_sector";
- if (m_gradient_direction == VERTICAL_SECTOR)
- return "vertical_sector";
- return nullptr;
- }
- void
- Gradient::set_direction(const GradientDirection& direction)
- {
- m_gradient_direction = direction;
- }
- void
- Gradient::set_direction(const std::string& direction)
- {
- if (direction == "horizontal")
- {
- m_gradient_direction = HORIZONTAL;
- }
- else if (direction == "horizontal_sector")
- {
- m_gradient_direction = HORIZONTAL_SECTOR;
- }
- else if (direction == "vertical_sector")
- {
- m_gradient_direction = VERTICAL_SECTOR;
- }
- else if (direction == "vertical")
- {
- m_gradient_direction = VERTICAL;
- }
- else
- {
- log_info << "Invalid direction for gradient \"" << direction << "\"";
- m_gradient_direction = VERTICAL;
- }
- }
- void
- Gradient::set_color1(float red, float green, float blue)
- {
- set_gradient(Color(red, green, blue), m_gradient_bottom);
- }
- void
- Gradient::set_color2(float red, float green, float blue)
- {
- set_gradient(m_gradient_top, Color(red, green, blue));
- }
- void
- Gradient::set_colors(float red1, float green1, float blue1, float red2, float green2, float blue2)
- {
- set_gradient(Color(red1, green1, blue1), Color(red2, green2, blue2));
- }
- void
- Gradient::fade_color1(float red, float green, float blue, float time)
- {
- fade_gradient(Color(red, green, blue), m_gradient_bottom, time);
- }
- void
- Gradient::fade_color2(float red, float green, float blue, float time)
- {
- fade_gradient(m_gradient_top, Color(red, green, blue), time);
- }
- void
- Gradient::fade_colors(float red1, float green1, float blue1, float red2, float green2, float blue2, float time)
- {
- fade_gradient(Color(red1, green1, blue1), Color(red2, green2, blue2), time);
- }
- void
- Gradient::swap_colors()
- {
- set_gradient(m_gradient_bottom, m_gradient_top);
- }
- void
- Gradient::draw(DrawingContext& context)
- {
- if (Editor::is_active() && !g_config->editor_render_background)
- return;
- Rectf gradient_region;
- if (m_gradient_direction != HORIZONTAL && m_gradient_direction != VERTICAL)
- {
- auto camera_translation = Sector::get().get_camera().get_translation();
- auto sector_width = Sector::get().get_width();
- auto sector_height = Sector::get().get_height();
- gradient_region = Rectf(-camera_translation.x, -camera_translation.y, sector_width, sector_height);
- }
- else
- {
- gradient_region = context.get_rect();
- }
- context.push_transform();
- context.set_translation(Vector(0, 0));
- context.transform().scale = 1.f;
- context.get_canvas(m_target).draw_gradient(m_gradient_top, m_gradient_bottom, m_layer, m_gradient_direction,
- gradient_region, m_blend);
- context.pop_transform();
- }
- bool
- Gradient::is_saveable() const
- {
- return !(Level::current() &&
- Level::current()->is_worldmap());
- }
- void
- Gradient::on_flip(float height)
- {
- GameObject::on_flip(height);
- if (m_gradient_direction == VERTICAL || m_gradient_direction == VERTICAL_SECTOR)
- std::swap(m_gradient_top, m_gradient_bottom);
- }
- void
- Gradient::register_class(ssq::VM& vm)
- {
- ssq::Class cls = vm.addAbstractClass<Gradient>("Gradient", vm.findClass("GameObject"));
- cls.addFunc<void, Gradient, const std::string&>("set_direction", &Gradient::set_direction);
- cls.addFunc("get_direction", &Gradient::get_direction_string);
- cls.addFunc("set_color1", &Gradient::set_color1);
- cls.addFunc("set_color2", &Gradient::set_color2);
- cls.addFunc("set_colors", &Gradient::set_colors);
- cls.addFunc("fade_color1", &Gradient::fade_color1);
- cls.addFunc("fade_color2", &Gradient::fade_color2);
- cls.addFunc("fade_colors", &Gradient::fade_colors);
- cls.addFunc("swap_colors", &Gradient::swap_colors);
- }
- /* EOF */
|