Skip to content

Commit

Permalink
Color blending fixes (#208)
Browse files Browse the repository at this point in the history
* Fixed the animation color blending, and fixed an error in the gradient color lerp.

* Didn't mean to square the alpha.

* Moved the rounded lerp for Colourbs into its own function.

Co-authored-by: Jacqueline <jacquelineory@gmail.com>
  • Loading branch information
jac8888 and Jacqueline authored Jul 24, 2021
1 parent f0e7ad2 commit 8b6a361
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 35 deletions.
7 changes: 7 additions & 0 deletions Include/RmlUi/Core/Math.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,13 @@
#define RMLUI_CORE_MATH_H

#include "Header.h"
#include <type_traits>

namespace Rml {

using byte = unsigned char;
template <typename ColourType, int AlphaDefault> class Colour;
using Colourb = Colour< byte, 255 >;
template <typename Type> class Vector2;
using Vector2f = Vector2< float >;

Expand Down Expand Up @@ -74,9 +78,12 @@ Type Clamp(Type value, Type min, Type max)
template< typename Type >
Type Lerp(float t, Type v0, Type v1)
{
static_assert(!std::is_same<Type, Colourb>::value, "Lerp currently cannot be used with Colourb. Use RoundedLerp instead.");
return v0 * (1.0f - t) + v1 * t;
}

Colourb RoundedLerp(float t, Colourb v0, Colourb v1);

/// Evaluates if a number is, or close to, zero.
/// @param[in] value The number to compare to zero.
/// @return True if the number if zero or close to it, false otherwise.
Expand Down
8 changes: 4 additions & 4 deletions Source/Core/DecoratorGradient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,16 +95,16 @@ DecoratorDataHandle DecoratorGradient::GenerateElementData(Element* element) con
{
for (int i = 0; i < (int)vertices.size(); i++)
{
const float t = (vertices[i].position.x - padding_offset.x) / padding_size.x;
vertices[i].colour = Math::Lerp(Math::Clamp(t, 0.0f, 1.0f), colour_start, colour_stop);
const float t = Math::Clamp((vertices[i].position.x - padding_offset.x) / padding_size.x, 0.0f, 1.0f);
vertices[i].colour = Math::RoundedLerp(t, colour_start, colour_stop);
}
}
else if (dir == Direction::Vertical)
{
for (int i = 0; i < (int)vertices.size(); i++)
{
const float t = (vertices[i].position.y - padding_offset.y) / padding_size.y;
vertices[i].colour = Math::Lerp(t, colour_start, colour_stop);
const float t = Math::Clamp((vertices[i].position.y - padding_offset.y) / padding_size.y, 0.0f, 1.0f);
vertices[i].colour = Math::RoundedLerp(t, colour_start, colour_stop);
}
}

Expand Down
17 changes: 10 additions & 7 deletions Source/Core/ElementAnimation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,22 @@ static Colourf ColourToLinearSpace(Colourb c)
{
Colourf result;
// Approximate inverse sRGB function
result.red = Math::SquareRoot((float)c.red / 255.f);
result.green = Math::SquareRoot((float)c.green / 255.f);
result.blue = Math::SquareRoot((float)c.blue / 255.f);
result.alpha = (float)c.alpha / 255.f;
result.red = c.red / 255.f;
result.red *= result.red;
result.green = c.green / 255.f;
result.green *= result.green;
result.blue = c.blue / 255.f;
result.blue *= result.blue;
result.alpha = c.alpha / 255.f;
return result;
}

static Colourb ColourFromLinearSpace(Colourf c)
{
Colourb result;
result.red = (byte)Math::Clamp(c.red*c.red*255.f, 0.0f, 255.f);
result.green = (byte)Math::Clamp(c.green*c.green*255.f, 0.0f, 255.f);
result.blue = (byte)Math::Clamp(c.blue*c.blue*255.f, 0.0f, 255.f);
result.red = (byte)Math::Clamp(Math::SquareRoot(c.red)*255.f, 0.0f, 255.f);
result.green = (byte)Math::Clamp(Math::SquareRoot(c.green)*255.f, 0.0f, 255.f);
result.blue = (byte)Math::Clamp(Math::SquareRoot(c.blue)*255.f, 0.0f, 255.f);
result.alpha = (byte)Math::Clamp(c.alpha*255.f, 0.0f, 255.f);
return result;
}
Expand Down
26 changes: 2 additions & 24 deletions Source/Core/GeometryBackgroundBorder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,22 +258,11 @@ void GeometryBackgroundBorder::DrawArc(Vector2f pos_center, Vector2f r, float a0
const float t = float(i) / float(num_points - 1);

const float a = Math::Lerp(t, a0, a1);
const Colourb color
{
static_cast<unsigned char>(Math::RoundToInteger(Math::Lerp(t,
static_cast<float>(color0[0]), static_cast<float>(color1[0])))),
static_cast<unsigned char>(Math::RoundToInteger(Math::Lerp(t,
static_cast<float>(color0[1]), static_cast<float>(color1[1])))),
static_cast<unsigned char>(Math::RoundToInteger(Math::Lerp(t,
static_cast<float>(color0[2]), static_cast<float>(color1[2])))),
static_cast<unsigned char>(Math::RoundToInteger(Math::Lerp(t,
static_cast<float>(color0[3]), static_cast<float>(color1[3]))))
};

const Vector2f unit_vector(Math::Cos(a), Math::Sin(a));

vertices[offset_vertices + i].position = unit_vector * r + pos_center;
vertices[offset_vertices + i].colour = color;
vertices[offset_vertices + i].colour = Math::RoundedLerp(t, color0, color1);
}
}

Expand Down Expand Up @@ -346,18 +335,7 @@ void GeometryBackgroundBorder::DrawArcArc(Vector2f pos_center, float R, Vector2f
const float t = float(i) / float(num_points - 1);

const float a = Math::Lerp(t, a0, a1);
const Colourb color
{
static_cast<unsigned char>(Math::RoundToInteger(Math::Lerp(t,
static_cast<float>(color0[0]), static_cast<float>(color1[0])))),
static_cast<unsigned char>(Math::RoundToInteger(Math::Lerp(t,
static_cast<float>(color0[1]), static_cast<float>(color1[1])))),
static_cast<unsigned char>(Math::RoundToInteger(Math::Lerp(t,
static_cast<float>(color0[2]), static_cast<float>(color1[2])))),
static_cast<unsigned char>(Math::RoundToInteger(Math::Lerp(t,
static_cast<float>(color0[3]), static_cast<float>(color1[3]))))
};

const Colourb color = Math::RoundedLerp(t, color0, color1);
const Vector2f unit_vector(Math::Cos(a), Math::Sin(a));

vertices[offset_vertices + 2 * i].position = unit_vector * r + pos_center;
Expand Down
14 changes: 14 additions & 0 deletions Source/Core/Math.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,5 +248,19 @@ RMLUICORE_API bool RandomBool()
return RandomInteger(2) == 1;
}

Colourb RoundedLerp(float t, Colourb v0, Colourb v1)
{
return Colourb{
static_cast<unsigned char>(RoundToInteger(Lerp(t,
static_cast<float>(v0[0]), static_cast<float>(v1[0])))),
static_cast<unsigned char>(RoundToInteger(Lerp(t,
static_cast<float>(v0[1]), static_cast<float>(v1[1])))),
static_cast<unsigned char>(RoundToInteger(Lerp(t,
static_cast<float>(v0[2]), static_cast<float>(v1[2])))),
static_cast<unsigned char>(RoundToInteger(Lerp(t,
static_cast<float>(v0[3]), static_cast<float>(v1[3]))))
};
}

}
} // namespace Rml

0 comments on commit 8b6a361

Please sign in to comment.