NAP
color.h
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4 
5 #pragma once
6 
7 #include <rtti/rtti.h>
8 #include <nap/numeric.h>
9 #include <utility/dllexport.h>
10 #include <glm/glm.hpp>
11 
12 namespace nap
13 {
17  enum class EColorChannel : int
18  {
19  Red = 0,
20  Green = 1,
21  Blue = 2,
22  Alpha = 3
23  };
24 
25 
37  class NAPAPI BaseColor
38  {
39  RTTI_ENABLE()
40  public:
46  BaseColor(int channels, int size) : mChannels(channels), mValueSize(size) { }
47 
48  virtual ~BaseColor() = default;
49 
50 
51  bool operator==(const BaseColor& rhs) = delete;
52  bool operator!=(const BaseColor& rhs) = delete;
53 
57  using Converter = std::function<void(const BaseColor&, BaseColor&, int)>;
58 
62  inline int getNumberOfChannels() const { return mChannels; }
63 
67  inline int valueSize() const { return mValueSize; }
68 
72  virtual rtti::TypeInfo getValueType() const = 0;
73 
77  virtual bool isPointer() const = 0;
78 
94  void convert(BaseColor& target) const;
95 
100  Converter getConverter(const BaseColor& target) const;
101 
123  template<typename T>
124  T convert() const;
125 
130  virtual const void* getData(int channel) const = 0;
131 
136  virtual void* getData(int channel) = 0;
137 
141  int size() const { return mChannels * mValueSize; }
142 
154  static void convertColor(const BaseColor& source, BaseColor& target);
155 
175  static void convertColor(const BaseColor& source, BaseColor& target, const Converter& converter);
176 
181  static Converter getConverter(const BaseColor& source, const BaseColor& target);
182 
183  private:
184  int mChannels = 0;
185  int mValueSize = 0;
186  };
187 
188 
200  template<typename T, int CHANNELS>
201  class Color : public BaseColor
202  {
203  public:
204  using value_type = T;
205 
209  Color() : BaseColor(CHANNELS, sizeof(T)) { mValues.fill(0); }
210 
221  Color(const std::array<T, CHANNELS>& colors) :
222  BaseColor(CHANNELS, sizeof(T)), mValues(colors) { }
223 
229  Color(const nap::BaseColor& source);
230 
234  rtti::TypeInfo getValueType() const override { return RTTI_OF(T).get_raw_type(); }
235 
239  bool isPointer() const override;
240 
247  T getValue(EColorChannel channel) const;
248 
254  T& getValue(EColorChannel channel);
255 
262  void setValue(EColorChannel channel, T value);
263 
267  const std::array<T, CHANNELS>& getValues() const { return mValues; }
268 
272  T* getData() { return mValues.data(); }
273 
277  const T* getData() const { return mValues.data(); }
278 
286  void setData(const T* data);
287 
293  float getDistance(const Color<T, CHANNELS>& other) const;
294 
300  bool operator== (const Color<T, CHANNELS>& rhs) const;
301 
305  bool operator!=(const Color<T, CHANNELS>& rhs) const { return !(rhs == mValues); }
306 
311  bool operator<(const Color<T, CHANNELS>& rhs) const;
312 
317  bool operator>(const Color<T, CHANNELS>& rhs) const { return rhs < *this; }
318 
323  bool operator<=(const Color<T, CHANNELS>& rhs) const { return !(*this > rhs); }
324 
329  bool operator>=(const Color<T, CHANNELS>& rhs) const { return !(*this < rhs); }
330 
335  T& operator[](std::size_t index) { return mValues[index]; }
336 
341  const T& operator[](std::size_t index) const { return mValues[index]; }
342 
346  std::array<T, CHANNELS> mValues;
347 
348  private:
352  const void* getData(int channel) const override;
353 
357  void* getData(int channel) override;
358  };
359 
360  template<typename T>
362 
363  template<typename T>
365 
366  template<typename T>
368 
372  template<typename T>
373  class RGBColor : public Color<T, 3>
374  {
375  RTTI_ENABLE(BaseColor)
376  public:
380  RGBColor(T red, T green, T blue) : Color<T, 3>({red, green, blue}) { }
381 
385  RGBColor() : Color<T, 3>() { }
386 
392  RGBColor(const nap::BaseColor& source) : Color<T, 3>(source) { }
393 
398  void setRed(T value) { Color<T,3>::setValue(EColorChannel::Red, value); }
399 
400  /*
401  * @return the red color value
402  */
404 
410 
415 
421 
426 
430  glm::vec3 toVec3() const;
431 
436  operator glm::vec3() { return toVec3(); }
437  };
438 
439 
443  template<typename T>
444  class RGBAColor : public Color<T,4>
445  {
446  RTTI_ENABLE(BaseColor)
447  public:
451  RGBAColor(T red, T green, T blue, T alpha) :
452  Color<T, 4>({ red, green, blue, alpha }) { }
453 
459  RGBAColor(const RGBColor<T>& rgb, T alpha) :
460  Color<T, 4>({rgb[0], rgb[1], rgb[2], alpha}) { }
461 
465  RGBAColor() : Color<T, 4>() { }
466 
472  RGBAColor(const nap::BaseColor& source) : Color<T, 4>(source) { }
473 
478  void setRed(T value) { Color<T,4>::setValue(EColorChannel::Red, value); }
479 
480  /*
481  * @return the red color value
482  */
484 
490 
491  /*
492  * @return the green color value
493  */
495 
501 
502  /*
503  * @return the blue color value
504  */
506 
512 
513  /*
514  * @return the alpha color value
515  */
517 
521  glm::vec4 toVec4() const;
522 
527  operator glm::vec4() { return toVec4(); }
528  };
529 
534  template<typename T>
535  class RColor : public Color<T,1>
536  {
537  RTTI_ENABLE(BaseColor)
538  public:
542  RColor(T value) : Color<T, 1>({ value }) { }
543 
547  RColor() : Color<T, 1>() { }
548 
554  RColor(const nap::BaseColor& source) : Color<T, 1>(source) { }
555 
560  void setRed(T value) { Color<T,1>::setValue(EColorChannel::Red, value); }
561 
562  /*
563  * @return the red color value
564  */
566  };
567 
568 
570  // Type definitions for all supported hash-able color types
571  // These color types can be used as a resource
572  // The color values can be declared with the property: Values
574 
584 
585 
587  // Declarations for all supported memory (data) color types
588  // These colors are used to point to color values in memory
589  // These colors can't be serialized or used as a resource
591 
601 
602 
603 
605  // Template Definitions
607 
608 
609  template<typename T, int CHANNELS>
610  nap::Color<T, CHANNELS>::Color(const nap::BaseColor& source) : BaseColor(CHANNELS, sizeof(T))
611  {
612  source.convert(*this);
613  }
614 
615 
616  template<typename T, int CHANNELS>
618  {
619  for (auto i = 0; i < CHANNELS; i++)
620  {
621  if (mValues[i] != rhs.mValues[i])
622  return false;
623  }
624  return true;
625  }
626 
627  template<typename T, int CHANNELS>
629  {
630  std::hash<Color<T, CHANNELS>> lhs_hash;
631  std::hash<Color<T, CHANNELS>> rhs_hash;
632 
633  return lhs_hash(*this) < rhs_hash(rhs);
634  }
635 
636  template<typename T, int CHANNELS>
638  {
639  int idx = static_cast<int>(channel);
640  assert(idx < CHANNELS);
641  return mValues[idx];
642  }
643 
644  template<typename T, int CHANNELS>
646  {
647  int idx = static_cast<int>(channel);
648  assert(idx < CHANNELS);
649  return mValues[idx];
650  }
651 
652  template<typename T, int CHANNELS>
654  {
655  int idx = static_cast<int>(channel);
656  assert(idx < CHANNELS);
657  mValues[idx] = value;
658  }
659 
660  template<typename T, int CHANNELS>
661  const void* nap::Color<T, CHANNELS>::getData(int channel) const
662  {
663  assert(channel < CHANNELS);
664  return &(mValues[channel]);
665  }
666 
667  template<typename T, int CHANNELS>
668  void* nap::Color<T, CHANNELS>::getData(int channel)
669  {
670  assert(channel < CHANNELS);
671  return &(mValues[channel]);
672  }
673 
674  template<typename T, int CHANNELS>
676  {
677  return std::is_pointer<T>();
678  }
679 
680  template<typename T>
682  {
683  T color;
684  assert(!(color.isPointer()));
685  BaseColor::convertColor(*this, color);
686  return color;
687  }
688 
689  template<typename T, int CHANNELS>
691  {
692  memcpy(mValues.data(), data, sizeof(T) * CHANNELS);
693  }
694 
695  template<typename T, int CHANNELS>
697  {
698  float dist(0);
699  for (int i = 0; i < CHANNELS; i++)
700  {
701  float diff = (float)(this->mValues[i]) - (float)(other.mValues[i]);
702  dist += pow(diff,2);
703  }
704  return dist;
705  }
706 
707  template<typename T>
708  glm::vec3 nap::RGBColor<T>::toVec3() const
709  {
710  return
711  {
712  (float)(RGBColor<T>::mValues[0]),
713  (float)(RGBColor<T>::mValues[1]),
714  (float)(RGBColor<T>::mValues[2])
715  };
716  };
717 
718  template<typename T>
719  glm::vec4 nap::RGBAColor<T>::toVec4() const
720  {
721  return
722  {
723  (float)(RGBAColor<T>::mValues[0]),
724  (float)(RGBAColor<T>::mValues[1]),
725  (float)(RGBAColor<T>::mValues[2]),
726  (float)(RGBAColor<T>::mValues[3])
727  };
728  }
729 }
730 
731 
733 // Hash functions for 8 and 16 bit integer colors
734 // Float colors are also hashable but something you probably should not do
736 
737 namespace std
738 {
739  template<>
740  struct hash <nap::Color<nap::uint8, 1>>
741  {
742  size_t operator()(const nap::Color<nap::uint8, 1>& v) const
743  {
744  return hash<nap::uint8>()(v.getValue(nap::EColorChannel::Red));
745  }
746  };
747 
748 
749  template <>
750  struct hash<nap::RColor<nap::uint8>>
751  {
752  size_t operator()(const nap::RColor<nap::uint8>& v) const
753  {
754  return hash<nap::Color<nap::uint8, 1>>()(static_cast<nap::Color<nap::uint8, 1>>(v));
755  }
756  };
757 
758 
759  template <>
760  struct hash<nap::Color<nap::uint8, 3>>
761  {
762  size_t operator()(const nap::Color<nap::uint8, 3>& v) const
763  {
764  return nap::uint32((
768  }
769 
770  };
771 
772 
773  template <>
774  struct hash<nap::RGBColor<nap::uint8>>
775  {
776  size_t operator()(const nap::RGBColor<nap::uint8>& v) const
777  {
778  return hash<nap::Color<nap::uint8, 3>>()(static_cast<nap::Color<nap::uint8, 3>>(v));
779  }
780  };
781 
782 
783  template <>
784  struct hash<nap::Color<nap::uint8, 4>>
785  {
786  size_t operator()(const nap::Color<nap::uint8, 4>& v) const
787  {
788  return nap::uint32((
793  }
794  };
795 
796  template <>
797  struct hash<nap::RGBAColor<nap::uint8>>
798  {
799  size_t operator()(const nap::RGBAColor<nap::uint8>& v) const
800  {
801  return hash<nap::Color<nap::uint8, 4>>()(static_cast<nap::Color<nap::uint8, 4>>(v));
802  }
803  };
804 
805  template <>
806  struct hash<nap::Color<nap::uint16, 1>>
807  {
808  size_t operator()(const nap::Color<nap::uint16, 1>& v) const
809  {
810  return hash<nap::uint16>()(v.getValue(nap::EColorChannel::Red));
811  }
812 
813  };
814 
815  template <>
816  struct hash<nap::RColor<nap::uint16>>
817  {
818  size_t operator()(const nap::RColor<nap::uint16>& v) const
819  {
820  return hash<nap::Color<nap::uint16, 1>>()(static_cast<nap::Color<nap::uint16, 1>>(v));
821  }
822 
823  };
824 
825  template <>
826  struct hash<nap::Color<nap::uint16, 3>>
827  {
828  size_t operator()(const nap::Color<nap::uint16, 3>& v) const
829  {
830  return nap::uint64((
834  }
835 
836  };
837 
838  template <>
839  struct hash<nap::RGBColor<nap::uint16>>
840  {
841  size_t operator()(const nap::RGBColor<nap::uint16>& v) const
842  {
843  return hash<nap::Color<nap::uint16, 3>>()(static_cast<nap::Color<nap::uint16, 3>>(v));
844  }
845 
846  };
847 
848  template <>
849  struct hash<nap::Color<nap::uint16, 4>>
850  {
851  size_t operator()(const nap::Color<nap::uint16, 4>& v) const
852  {
853  return nap::uint64((
858  }
859  };
860 
861  template <>
862  struct hash<nap::RGBAColor<nap::uint16>>
863  {
864  size_t operator()(const nap::RGBAColor<nap::uint16>& v) const
865  {
866  return hash<nap::Color<nap::uint16, 4>>()(static_cast<nap::Color<nap::uint16, 4>>(v));
867  }
868  };
869 
870  template <>
871  struct hash<nap::Color<float, 1>>
872  {
873  size_t operator()(const nap::Color<float, 1>& v) const
874  {
875  return std::hash<float>{}(v.getValue(nap::EColorChannel::Red));
876  }
877 
878  };
879 
880  template <>
881  struct hash<nap::RColor<float>>
882  {
883  size_t operator()(const nap::RColor<float>& v) const
884  {
885  return hash<nap::Color<float, 1>>()(static_cast<nap::Color<float, 1>>(v));
886  }
887 
888  };
889 
890  template <>
891  struct hash<nap::Color<float, 3>>
892  {
893  size_t operator()(const nap::Color<float, 3>& v) const
894  {
895  std::size_t value1 = std::hash<float>{}(v.getValue(nap::EColorChannel::Red));
896  std::size_t value2 = std::hash<float>{}(v.getValue(nap::EColorChannel::Green));
897  std::size_t value3 = std::hash<float>{}(v.getValue(nap::EColorChannel::Blue));
898  return value1 ^ value2 ^ value3;
899  }
900 
901  };
902 
903  template <>
904  struct hash<nap::RGBColor<float>>
905  {
906  size_t operator()(const nap::RGBColor<float>& v) const
907  {
908  return hash<nap::Color<float, 3>>()(static_cast<nap::Color<float, 3>>(v));
909  }
910 
911  };
912 
913  template <>
914  struct hash<nap::Color<float, 4>>
915  {
916  size_t operator()(const nap::Color<float, 4>& v) const
917  {
918  std::size_t value1 = std::hash<float>{}(v.getValue(nap::EColorChannel::Red));
919  std::size_t value2 = std::hash<float>{}(v.getValue(nap::EColorChannel::Green));
920  std::size_t value3 = std::hash<float>{}(v.getValue(nap::EColorChannel::Blue));
921  std::size_t value4 = std::hash<float>{}(v.getValue(nap::EColorChannel::Alpha));
922  return value1 ^ value2 ^ value3 ^ value4;
923  }
924  };
925 
926  template <>
927  struct hash<nap::RGBAColor<float>>
928  {
929  size_t operator()(const nap::RGBAColor<float>& v) const
930  {
931  return hash<nap::Color<float, 4>>()(static_cast<nap::Color<float, 4>>(v));
932  }
933  };
934 
935  template <>
936  struct hash<nap::EColorChannel>
937  {
938  size_t operator()(const nap::EColorChannel& v) const
939  {
940  return hash<int>()(static_cast<int>(v));
941  }
942  };
943 }
nap::RGBAColor::setRed
void setRed(T value)
Definition: color.h:478
nap::RGBColor::RGBColor
RGBColor()
Definition: color.h:385
nap::Color::getValueType
rtti::TypeInfo getValueType() const override
Definition: color.h:234
nap::RGBAColor::RGBAColor
RGBAColor(const RGBColor< T > &rgb, T alpha)
Definition: color.h:459
nap::Color::getValues
const std::array< T, CHANNELS > & getValues() const
Definition: color.h:267
nap::Color::operator>
bool operator>(const Color< T, CHANNELS > &rhs) const
Definition: color.h:317
nap::RGBColor::setRed
void setRed(T value)
Definition: color.h:398
nap::Color
Definition: color.h:201
nap::Color::operator<
bool operator<(const Color< T, CHANNELS > &rhs) const
Definition: color.h:628
nap::Color::operator[]
const T & operator[](std::size_t index) const
Definition: color.h:341
nap::BaseColor::BaseColor
BaseColor(int channels, int size)
Definition: color.h:46
nap::RGBColor
Definition: color.h:373
nap::RGBAColor::toVec4
glm::vec4 toVec4() const
Definition: color.h:719
nap::BaseColor::valueSize
int valueSize() const
Definition: color.h:67
nap::RGBAColor::getRed
T getRed() const
Definition: color.h:483
nap::RGBColor::setGreen
void setGreen(T value)
Definition: color.h:409
nap::RGBAColor
Definition: color.h:444
nap::BaseColor::convert
void convert(BaseColor &target) const
nap::uint64
uint64_t uint64
Definition: numeric.h:22
nap::Color::Color
Color(const std::array< T, CHANNELS > &colors)
Definition: color.h:221
nap::Color::getData
T * getData()
Definition: color.h:272
nap::RGBAColor::RGBAColor
RGBAColor()
Definition: color.h:465
nap::RGBColor::toVec3
glm::vec3 toVec3() const
Definition: color.h:708
nap::EColorChannel::Red
@ Red
Red Color Channel: 0.
nap::RColor::RColor
RColor(const nap::BaseColor &source)
Definition: color.h:554
nap::RColor
Definition: color.h:535
nap::Color< T, 4 >::value_type
T value_type
Definition: color.h:204
nap::RGBAColor::setGreen
void setGreen(T value)
Definition: color.h:489
nap::RGBAColor::getAlpha
T getAlpha() const
Definition: color.h:516
nap::Color::setValue
void setValue(EColorChannel channel, T value)
Definition: color.h:653
nap::RGBAColor::setBlue
void setBlue(T value)
Definition: color.h:500
nap::uint32
uint32_t uint32
Definition: numeric.h:20
nap::EColorChannel::Green
@ Green
Green Color Channel: 1.
nap::EColorChannel::Alpha
@ Alpha
Alpha Color Channel: 3.
nap::Color::operator[]
T & operator[](std::size_t index)
Definition: color.h:335
nap::Color::mValues
std::array< T, CHANNELS > mValues
Definition: color.h:346
nap::Color::operator>=
bool operator>=(const Color< T, CHANNELS > &rhs) const
Definition: color.h:329
nap::RGBAColor::RGBAColor
RGBAColor(const nap::BaseColor &source)
Definition: color.h:472
nap::Color::operator<=
bool operator<=(const Color< T, CHANNELS > &rhs) const
Definition: color.h:323
nap::RGBColor::getBlue
T getBlue() const
Definition: color.h:425
nap::RGBColor::getRed
T getRed() const
Definition: color.h:403
nap::Color::setData
void setData(const T *data)
Definition: color.h:690
nap::BaseColor::getNumberOfChannels
int getNumberOfChannels() const
Definition: color.h:62
nap::RGBAColor::RGBAColor
RGBAColor(T red, T green, T blue, T alpha)
Definition: color.h:451
nap::RColor::getRed
T getRed() const
Definition: color.h:565
nap::BaseColor::Converter
std::function< void(const BaseColor &, BaseColor &, int)> Converter
Definition: color.h:57
nap::RGBColor::RGBColor
RGBColor(const nap::BaseColor &source)
Definition: color.h:392
nap::RGBColor::RGBColor
RGBColor(T red, T green, T blue)
Definition: color.h:380
nap::RColor::RColor
RColor()
Definition: color.h:547
nap::RGBAColor::getGreen
T getGreen() const
Definition: color.h:494
nap
Definition: templateapp.h:17
nap::Color::isPointer
bool isPointer() const override
Definition: color.h:675
nap::RColor::RColor
RColor(T value)
Definition: color.h:542
nap::Color::getDistance
float getDistance(const Color< T, CHANNELS > &other) const
Definition: color.h:696
nap::BaseColor::convertColor
static void convertColor(const BaseColor &source, BaseColor &target)
nap::BaseColor::convert
T convert() const
Definition: color.h:681
nap::Color::Color
Color()
Definition: color.h:209
nap::rtti::TypeInfo
rttr::type TypeInfo
Definition: typeinfo.h:140
nap::RGBColor::setBlue
void setBlue(T value)
Definition: color.h:420
nap::EColorChannel::Blue
@ Blue
Blue Color Channel: 2.
nap::RGBAColor::getBlue
T getBlue() const
Definition: color.h:505
nap::BaseColor::size
int size() const
Definition: color.h:141
nap::Color::getData
const T * getData() const
Definition: color.h:277
nap::Color::getValue
T getValue(EColorChannel channel) const
Definition: color.h:645
nap::BaseColor
Definition: color.h:37
nap::Color::operator!=
bool operator!=(const Color< T, CHANNELS > &rhs) const
Definition: color.h:305
nap::RColor::setRed
void setRed(T value)
Definition: color.h:560
nap::EColorChannel
EColorChannel
Definition: color.h:17
nap::RGBAColor::setAlpha
void setAlpha(T value)
Definition: color.h:511
nap::Color::operator==
bool operator==(const Color< T, CHANNELS > &rhs) const
Definition: color.h:617
nap::RGBColor::getGreen
T getGreen() const
Definition: color.h:414