Antkeeper  0.0.1
material-property.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 Christopher J. Howard
3  *
4  * This file is part of Antkeeper source code.
5  *
6  * Antkeeper source code is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Antkeeper source code is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef ANTKEEPER_RENDER_MATERIAL_PROPERTY_HPP
21 #define ANTKEEPER_RENDER_MATERIAL_PROPERTY_HPP
22 
29 #include <engine/gl/texture-1d.hpp>
30 #include <engine/gl/texture-2d.hpp>
31 #include <engine/gl/texture-3d.hpp>
33 #include <cstddef>
34 
35 namespace render {
36 
37 class material;
38 
43 {
44 public:
51  bool connect(const gl::shader_input* input);
52 
56  void disconnect();
57 
61  virtual void update_tweens() = 0;
62 
69  virtual bool upload(double a) const = 0;
70 
75 
79  bool is_connected() const;
80 
84  virtual material_property_base* clone() const = 0;
85 
86 protected:
88 
90 };
91 
93 {
94  return (input != nullptr);
95 }
96 
102 template <class T>
104 {
105 public:
108 
110  static T default_interpolator(const T& x, const T& y, double a);
111 
117  material_property(std::size_t element_count);
118 
123 
126 
128  virtual void update_tweens();
129 
131  virtual bool upload(double a) const;
132 
138  void set_value(const T& value);
139 
146  void set_value(std::size_t index, const T& value);
147 
155  void set_values(std::size_t index, const T* values, std::size_t count);
156 
163 
165  const T& get_value() const;
166 
173  const T& get_value(std::size_t index) const;
174 
177 
179  virtual material_property_base* clone() const;
180 
181 private:
182  std::size_t element_count;
183  tween<T>* values;
184 };
185 
186 template <typename T>
187 inline T material_property<T>::default_interpolator(const T& x, const T& y, double a)
188 {
189  return y;
190 }
191 
192 template <>
193 inline float material_property<float>::default_interpolator(const float& x, const float& y, double a)
194 {
195  return math::lerp<float, float>(x, y, static_cast<float>(a));
196 }
197 
198 template <>
200 {
201  return math::lerp<float2, float>(x, y, static_cast<float>(a));
202 }
203 
204 template <>
206 {
207  return math::lerp<float3, float>(x, y, static_cast<float>(a));
208 }
209 
210 template <>
212 {
213  return math::lerp<float4, float>(x, y, static_cast<float>(a));
214 }
215 
216 template <class T>
217 material_property<T>::material_property(std::size_t element_count):
218  element_count(element_count),
219  values(nullptr)
220 {
221  values = new tween<T>[element_count];
223 }
224 
225 template <class T>
227 {
228  delete[] values;
229 }
230 
231 template <class T>
233 {
234  for (std::size_t i = 0; i < element_count; ++i)
235  {
236  values[i].update();
237  }
238 }
239 
240 template <class T>
241 bool material_property<T>::upload(double a) const
242 {
243  if (!is_connected())
244  {
245  return false;
246  }
247 
248  if (element_count > 1)
249  {
250  for (std::size_t i = 0; i < element_count; ++i)
251  {
252  if (!input->upload(i, values[i].interpolate(static_cast<float>(a))))
253  return false;
254  }
255 
256  return true;
257  }
258  else
259  {
260  return input->upload(values[0].interpolate(static_cast<float>(a)));
261  }
262 }
263 
264 template <class T>
266 {
267  values[0][1] = value;
268 }
269 
270 template <class T>
271 void material_property<T>::set_value(std::size_t index, const T& value)
272 {
273  values[index][1] = value;
274 }
275 
276 template <class T>
277 void material_property<T>::set_values(std::size_t index, const T* values, std::size_t count)
278 {
279  for (std::size_t i = 0; i < count; ++i)
280  {
281  this->values[index + i][1] = values[i];
282  }
283 }
284 
285 template <class T>
287 {
288  for (std::size_t i = 0; i < element_count; ++i)
289  {
290  this->values[i].set_interpolator(interpolator);
291  }
292 }
293 
294 template <class T>
295 inline const T& material_property<T>::get_value() const
296 {
297  return values[0][1];
298 }
299 
300 template <class T>
301 inline const T& material_property<T>::get_value(std::size_t index) const
302 {
303  return values[index][1];
304 }
305 
306 template <>
308 {
310 }
311 
312 template <>
314 {
316 }
317 
318 template <>
320 {
322 }
323 
324 template <>
326 {
328 }
329 
330 template <>
332 {
334 }
335 
336 template <>
338 {
340 }
341 
342 template <>
344 {
346 }
347 
348 template <>
350 {
352 }
353 
354 template <>
356 {
358 }
359 
360 template <>
362 {
364 }
365 
366 template <>
368 {
370 }
371 
372 template <>
374 {
376 }
377 
378 template <>
380 {
382 }
383 
384 template <>
386 {
388 }
389 
390 template <>
392 {
394 }
395 
396 template <>
398 {
400 }
401 
402 template <>
404 {
406 }
407 
408 template <>
410 {
412 }
413 
414 template <>
416 {
418 }
419 
420 template <>
422 {
424 }
425 
426 template <>
428 {
430 }
431 
432 template <>
434 {
436 }
437 
438 template <>
440 {
442 }
443 
444 template <class T>
446 {
447  material_property<T>* property = new material_property<T>(element_count);
448  for (std::size_t i = 0; i < element_count; ++i)
449  {
450  property->values[i][0] = values[i][0];
451  property->values[i][1] = values[i][1];
452  }
453  property->input = input;
454 
455  return property;
456 }
457 
458 } // namespace render
459 
460 #endif // ANTKEEPER_RENDER_MATERIAL_PROPERTY_HPP
Port through which data can be uploaded to shader variables.
Abstract base class for material properties.
bool connect(const gl::shader_input *input)
Connects the material property to a shader input.
const gl::shader_input * input
void disconnect()
Disconnects the material property from its shader input.
bool is_connected() const
Returns true if the material property is connected to a shader input, false otherwise.
virtual material_property_base * clone() const =0
Creates a copy of this material property.
virtual void update_tweens()=0
Sets state 0 = state 1.
virtual gl::shader_variable_type get_data_type() const =0
Returns the type of data which the property contains.
virtual bool upload(double a) const =0
Uploads the material property to its shader program.
A property of a material which can be uploaded to a shader program via a shader input.
material_property(std::size_t element_count)
Creates a material property.
virtual gl::shader_variable_type get_data_type() const
Returns the type of data which the property contains.
material_property< T > & operator=(const material_property< T > &)=delete
void set_tween_interpolator(interpolator_type interpolator)
Sets the tween interpolator function.
const T & get_value(std::size_t index) const
Returns the value of the first element in this property.
void set_values(std::size_t index, const T *values, std::size_t count)
Sets the values of a range of elements in this array property.
static T default_interpolator(const T &x, const T &y, double a)
Default tween interpolator function for this material property type.
void set_value(const T &value)
Sets the value of this property.
void set_value(std::size_t index, const T &value)
Sets the value of a single element in this array property.
tween< T >::interpolator_type interpolator_type
virtual material_property_base * clone() const
Creates a copy of this material property.
virtual bool upload(double a) const
const T & get_value() const
Returns the value of the first element in this property.
virtual void update_tweens()
Sets state 0 = state 1.
material_property(const material_property< T > &)=delete
virtual ~material_property()
Destroys a material property.
Container which stores two states along with an interpolator, for quick and easy tween<T,...
Definition: tween.hpp:36
std::decay< std::function< value_type(const value_type &, const value_type &, scalar_type)> >::type interpolator_type
Definition: tween.hpp:42
constexpr int count(T x) noexcept
Returns the number of set bits in a value, known as a population count or Hamming weight.
Definition: bit-math.hpp:211
constexpr math::vector2< T > a
Definition: illuminant.hpp:38
void clone(entity::registry &registry, entity::id source, entity::id destination)
Clones all the components of an entity.
Definition: clone.cpp:24
Input devices, events, and mapping.
@ index
General purpose index (uint)
High-level rendering.