acidrainstudios / TrueReality

True Reality (TR) is an open source LGPL Game and Simulation Engine written entirely in Standard C++ and OpenGL. It runs on all Windows platforms and GNU/Linux. OpenSceneGraph is used as its graphics engine, along with many other open source projects for support of various features.
GNU Lesser General Public License v3.0
12 stars 7 forks source link

Add Color utilities #89

Open AODQ opened 5 years ago

AODQ commented 5 years ago

TR could be improved with a color class that has many helpful constructors and utility functions. It should be compatible with multiple floating-point and integral data types

DieSlower commented 5 years ago

Can you list what kind of constructors you would like to see?

AODQ commented 5 years ago

Design Considerations:

These are examples in what would make sense to me in pseudo-code

enum FormatChannelType {
  Red, 
  Green,
  Blue,
  Alpha
};

// https://www.khronos.org/opengl/wiki/Image_Format#Color_formats 
enum class FormatType {
  UnsignedNormalized,
  SignedNormalized,
  UnsignedIntegral,
  SignedIntegral,
  FloatingPoint
};

void test ( ) {
  static constexpr std::array<FormatChannelType> RgbaChannel
  {
      FormatChannelType::Red,
      FormatChannelType::Green,
      FormatChannelType::Blue,
      FormatChannelType::Alpha
  };

  static constexpr std::array<FormatChannelType> RedChannel
  {
    FormatChannelType::Red
  };

  using ColorRgba =
    Color<
      RgbaChannel,
      FormatType::UnsignedIntegral
    >;

  using ColorRgbaF =
    Color<
      RgbaChannel,
      FormatType::FloatingPoint
    >;

  using ColorR16 =
    Color<
      RedChannel,
      FormatType::UnsignedIntegral
    >;

  ColorRgba  bufferColor { vec3{1.0f}, 0.0f }  // {1, 1, 1, 0}
  ColorRgba  bufferColor { vec3ub{128}, 0.0f } // {0.5, 0.5, 0.5, 0}
  ColorRgbaF luminance   { 0.5f }              // {0.5, 0.5, 0.5, 0.5}
  ColorR16   luminance2  { 32767 }             // {32767} (ei 0.5)
  ColorR8    luminance2  { 127 }               // {127} (ei 0.5)
  ColorR8    luminance2  { 0.5f }              // approx {127} (ei 0.5)

  // -- to consider:

  // -- explicit integral/floating point conversions --

  uint32_t i = luminance.r();
  assert(i == 0);

  float f = luminance2.r();
  assert(i == 32767.0);

  i = luminance.asIntegral<uint32_t>().r();
  assert(i == 32767);

  f = luminance.asFloating<float>().r();
  assert(f == 0.5f);
}