lxgui
gui_animated_texture.cpp
1 #include "lxgui/gui_animated_texture.hpp"
2 
3 #include "lxgui/gui_layered_region.hpp"
4 #include "lxgui/gui_manager.hpp"
5 #include "lxgui/gui_material.hpp"
6 #include "lxgui/gui_out.hpp"
7 #include "lxgui/gui_region_tpl.hpp"
8 #include "lxgui/gui_renderer.hpp"
9 #include "lxgui/utils_file_system.hpp"
10 
11 #include <sstream>
12 
13 namespace lxgui::gui {
14 
16  utils::control_block& block, manager& mgr, const region_core_attributes& attr) :
17  layered_region(block, mgr, attr), renderer_(mgr.get_renderer()) {
18 
19  initialize_(*this, attr);
20 }
21 
22 std::string animated_texture::serialize(const std::string& tab) const {
23  std::ostringstream str;
24  str << base::serialize(tab);
25  str << tab << " # File : " << file_ << "\n";
26  str << tab << " # Speed : " << speed_ << "\n";
27  str << tab << " # State : " << state_ << "\n";
28  str << tab << " # Paused : " << is_paused_ << "\n";
29  return str.str();
30 }
31 
33  base::render();
34 
35  if (!is_visible())
36  return;
37 
38  float alpha = get_effective_alpha();
39 
40  if (alpha != 1.0f) {
41  quad blended_quad = quad_;
42  for (std::size_t i = 0; i < 4; ++i)
43  blended_quad.v[i].col.a *= alpha;
44 
45  renderer_.render_quad(blended_quad);
46  } else {
47  renderer_.render_quad(quad_);
48  }
49 }
50 
51 void animated_texture::update(float delta) {
52  base::update(delta);
53 
54  if (is_paused_ || !quad_.mat)
55  return;
56 
57  int num_frames = quad_.mat->get_rect().width() / quad_.mat->get_rect().height();
58 
59  int old_frame =
60  std::clamp(static_cast<int>(std::round(state_ * num_frames - 0.5)), 0, num_frames - 1);
61 
62  state_ += delta * speed_ / num_frames;
63  state_ = std::fmod(state_, 1.0f);
64 
65  int new_frame =
66  std::clamp(static_cast<int>(std::round(state_ * num_frames - 0.5)), 0, num_frames - 1);
67 
68  if (old_frame != new_frame) {
69  update_tex_coords_();
71  }
72 }
73 
75  base::copy_from(obj);
76 
77  const animated_texture* tex_obj = down_cast<animated_texture>(&obj);
78  if (!tex_obj)
79  return;
80 
81  this->set_texture(tex_obj->get_texture_file());
82  this->set_speed(tex_obj->get_speed());
83  this->set_state(tex_obj->get_state());
84  this->set_paused(tex_obj->is_paused());
85 }
86 
88  return speed_;
89 }
90 
92  return state_;
93 }
94 
96  return is_paused_;
97 }
98 
99 const std::string& animated_texture::get_texture_file() const {
100  return file_;
101 }
102 
103 color animated_texture::get_vertex_color(std::size_t index) const {
104  if (index >= 4) {
105  gui::out << gui::error << "gui::" << get_region_type() << ": "
106  << "Vertex index out of bound (" << index << ")." << std::endl;
107  return color::white;
108  }
109 
110  return quad_.v[index].col;
111 }
112 
113 void animated_texture::set_speed(float speed) {
114  speed_ = speed;
115 }
116 
117 void animated_texture::set_state(float state) {
118  if (state == state_)
119  return;
120 
121  state_ = state;
122  update_tex_coords_();
123 }
124 
125 void animated_texture::set_paused(bool is_paused) {
126  is_paused_ = is_paused;
127 }
128 
129 void animated_texture::set_texture(const std::string& file_name) {
130  file_ = parse_file_name(file_name);
131 
132  if (file_.empty())
133  return;
134 
135  auto& renderer = get_manager().get_renderer();
136 
137  std::shared_ptr<gui::material> mat;
138  if (utils::file_exists(file_))
140 
141  quad_.mat = mat;
142 
143  if (mat) {
144  quad_.v[0].uvs = quad_.mat->get_canvas_uv(vector2f(0, 0), true);
145  quad_.v[1].uvs = quad_.mat->get_canvas_uv(vector2f(1, 0), true);
146  quad_.v[2].uvs = quad_.mat->get_canvas_uv(vector2f(1, 1), true);
147  quad_.v[3].uvs = quad_.mat->get_canvas_uv(vector2f(0, 1), true);
148 
150  set_width(quad_.mat->get_rect().width());
151 
153  set_height(quad_.mat->get_rect().height());
154  } else {
155  gui::out << gui::error << "gui::" << get_region_type() << ": "
156  << "Cannot load file \"" << file_ << "\" for \"" << name_
157  << "\". Using white animated_texture instead." << std::endl;
158  }
159 
160  update_tex_coords_();
162 }
163 
164 void animated_texture::set_vertex_color(const color& c, std::size_t index) {
165  if (index == std::numeric_limits<std::size_t>::max()) {
166  for (std::size_t i = 0; i < 4; ++i)
167  quad_.v[i].col = c;
168 
170  return;
171  }
172 
173  if (index >= 4) {
174  gui::out << gui::error << "gui::" << get_region_type() << ": "
175  << "Vertex index out of bound (" << index << ")." << std::endl;
176  return;
177  }
178 
179  quad_.v[index].col = c;
180 
182 }
183 
184 void animated_texture::update_tex_coords_() {
185  if (!quad_.mat)
186  return;
187 
188  const int size = static_cast<int>(quad_.mat->get_rect().height());
189  const int steps = static_cast<int>(quad_.mat->get_rect().width()) / size;
190 
191  int left = size * std::clamp(static_cast<int>(std::round(state_ * steps - 0.5)), 0, steps - 1);
192 
193  auto top_left = quad_.mat->get_canvas_uv(vector2f(left, 0.0f), false);
194  auto bottom_right = quad_.mat->get_canvas_uv(vector2f(left + size, size), false);
195 
196  quad_.v[0].uvs = top_left;
197  quad_.v[1].uvs = vector2f(bottom_right.x, top_left.y);
198  quad_.v[2].uvs = bottom_right;
199  quad_.v[3].uvs = vector2f(top_left.x, bottom_right.y);
200 }
201 
202 void animated_texture::update_borders_() {
204 
205  quad_.v[0].pos = borders_.top_left();
206  quad_.v[1].pos = borders_.top_right();
207  quad_.v[2].pos = borders_.bottom_right();
208  quad_.v[3].pos = borders_.bottom_left();
209 }
210 
211 const std::vector<std::string>& animated_texture::get_type_list_() const {
212  return get_type_list_impl_<animated_texture>();
213 }
214 
215 } // namespace lxgui::gui
A layered_region that can draw animated sequences.
const std::string & get_texture_file() const
Returns this texture's texture file.
float get_state() const
Returns this animated_texture's state (0: begin, 1: end).
animated_texture(utils::control_block &block, manager &mgr, const region_core_attributes &attr)
Constructor.
std::string serialize(const std::string &tab) const override
Prints all relevant information about this region in a string.
void set_vertex_color(const color &c, std::size_t index=std::numeric_limits< std::size_t >::max())
Sets this texture's vertex color.
void update(float delta) override
Updates this region's logic.
color get_vertex_color(std::size_t index) const
Returns this texture's vertex color.
void set_state(float state)
Returns this animated_texture's state (0: begin, 1: end).
void set_texture(const std::string &file_name)
Sets this texture's texture file.
float get_speed() const
Returns this animated_texture's animation speed (frame per second).
void set_speed(float speed)
Set this animated_texture's animation speed (frame per second).
void set_paused(bool is_paused)
Play or pause this animated_texture.
void copy_from(const region &obj) override
Copies a region's parameters into this texture (inheritance).
float is_paused() const
Check if this animated_texture is paused.
void render() const override
Renders this region on the current render target.
Holds a single color (float RGBA, 128 bits)
Definition: gui_color.hpp:12
static const color white
Definition: gui_color.hpp:43
A region that can be rendered in a layer.
void notify_renderer_need_redraw() override
Notifies the renderer of this region that it needs to be redrawn.
std::string serialize(const std::string &tab) const override
Prints all relevant information about this region in a string.
Manages the user interface.
Definition: gui_manager.hpp:44
const renderer & get_renderer() const
Returns the renderer implementation.
The base class of all elements in the GUI.
Definition: gui_region.hpp:161
virtual void set_width(float abs_width)
Changes this region's absolute width (in pixels).
Definition: gui_region.cpp:227
const std::string & get_region_type() const
Returns the type of this region.
Definition: gui_region.cpp:148
void initialize_(T &self, const region_core_attributes &attr)
Set up function to call in all derived class constructors.
float get_effective_alpha() const
Returns this region's effective alpha (opacity).
Definition: gui_region.cpp:161
bool is_apparent_width_defined() const
Checks if this region's apparent width is defined.
Definition: gui_region.cpp:280
bool is_visible() const
Checks if this region can be seen on the screen.
Definition: gui_region.cpp:207
manager & get_manager()
Returns this region's manager.
Definition: gui_region.hpp:693
virtual void render() const
Renders this region on the current render target.
Definition: gui_region.cpp:765
virtual void set_height(float abs_height)
Changes this region's absolute height (in pixels).
Definition: gui_region.cpp:239
std::string name_
Definition: gui_region.hpp:804
virtual void update(float delta)
Updates this region's logic.
Definition: gui_region.cpp:763
bool is_apparent_height_defined() const
Checks if this region's apparent height is defined.
Definition: gui_region.cpp:284
virtual void copy_from(const region &obj)
Copies a region's parameters into this region (inheritance).
Definition: gui_region.cpp:128
std::string parse_file_name(const std::string &file_name) const
Convert an addon-relative file path to a application-relative path.
Definition: gui_region.cpp:818
virtual void update_borders_()
Definition: gui_region.cpp:669
Abstract type for implementation specific management.
std::shared_ptr< material > create_atlas_material(const std::string &atlas_category, const std::string &file_name, material::filter filt=material::filter::none)
Creates a new material from a texture file.
void render_quad(const quad &q)
Renders a quad.
vector2< float > vector2f
Holds 2D coordinates (as floats)
std::ostream out
const std::string error
Definition: gui_out.cpp:7
bool file_exists(const std::string &file)
vector2< T > bottom_left() const noexcept
Definition: gui_bounds2.hpp:44
vector2< T > bottom_right() const noexcept
Definition: gui_bounds2.hpp:40
vector2< T > top_right() const noexcept
Definition: gui_bounds2.hpp:36
vector2< T > top_left() const noexcept
Definition: gui_bounds2.hpp:32
Simple structure holding four vertices and a material.
Definition: gui_quad.hpp:18
std::shared_ptr< material > mat
Definition: gui_quad.hpp:20
std::array< vertex, 4 > v
Definition: gui_quad.hpp:19
Struct holding all the core information about a region necessary for its creation.