Add Tint to Render2D.

This commit is contained in:
Jean-Baptiste Perrier
2021-02-27 18:14:20 +01:00
parent ca3948ad69
commit ab77e5ef31
2 changed files with 80 additions and 7 deletions

View File

@@ -210,6 +210,8 @@ namespace
Array<ClipMask, InlinedAllocation<64>> ClipLayersStack;
Array<Color, InlinedAllocation<64>> TintLayersStack;
// Shader
AssetReference<Shader> GUIShader;
CachedPSO PsoDepth;
@@ -252,9 +254,9 @@ FORCE_INLINE Render2DVertex MakeVertex(const Vector2& pos, const Vector2& uv, co
{
point,
Half2(uv),
color,
color * TintLayersStack.Peek(),
{ 0.0f, (float)Render2D::Features },
ClipLayersStack.Peek().Mask,
ClipLayersStack.Peek().Mask
};
}
@@ -270,6 +272,18 @@ FORCE_INLINE Render2DVertex MakeVertex(const Vector2& point, const Vector2& uv,
};
}
FORCE_INLINE Render2DVertex MakeVertex(const Vector2& point, const Vector2& uv, const Color& color, const RotatedRectangle& mask, const Vector2& customData, const Color& tint)
{
return
{
point,
Half2(uv),
color * tint,
customData,
mask
};
}
void WriteTri(const Vector2& p0, const Vector2& p1, const Vector2& p2, const Vector2& uv0, const Vector2& uv1, const Vector2& uv2, const Color& color0, const Color& color1, const Color& color2)
{
Render2DVertex tris[3];
@@ -548,6 +562,7 @@ bool Render2DService::Init()
void Render2DService::Dispose()
{
TintLayersStack.Resize(0);
ClipLayersStack.Resize(0);
DrawCalls.Resize(0);
Lines.Resize(0);
@@ -620,6 +635,9 @@ void Render2D::Begin(GPUContext* context, GPUTextureView* output, GPUTextureView
ClipLayersStack.Clear();
ClipLayersStack.Add({ defaultMask, defaultBounds });
TintLayersStack.Clear();
Color defaultColor(1, 1, 1, 1);
TintLayersStack.Add(defaultColor);
// Scissors can be enabled only for 2D orthographic projections
IsScissorsRectEnabled = false;
@@ -795,6 +813,25 @@ void Render2D::PopClip()
OnClipScissors();
}
void Render2D::PushTint(const Color& tint)
{
RENDER2D_CHECK_RENDERING_STATE;
TintLayersStack.Push(tint);
}
void Render2D::PeekTint(Color& tint)
{
tint = TintLayersStack.Peek();
}
void Render2D::PopTint()
{
RENDER2D_CHECK_RENDERING_STATE;
TintLayersStack.Pop();
}
void CalculateKernelSize(float strength, int32& kernelSize, int32& downSample)
{
kernelSize = Math::RoundToInt(strength * 3.0f);
@@ -1263,12 +1300,32 @@ void Render2D::DrawText(Font* font, const StringView& text, const TextRange& tex
DrawText(font, StringView(text.Get() + textRange.StartIndex, textRange.Length()), color, layout, customMaterial);
}
FORCE_INLINE bool NeedAlphaWithTint(const Color& color)
{
return (color.A * TintLayersStack.Peek().A) < 1.0f;
}
FORCE_INLINE bool NeedAlphaWithTint(const Color& color1, const Color& color2)
{
return (color1.A * TintLayersStack.Peek().A) < 1.0f || (color2.A * TintLayersStack.Peek().A) < 1.0f;
}
FORCE_INLINE bool NeedAlphaWithTint(const Color& color1, const Color& color2, const Color& color3)
{
return (color1.A * TintLayersStack.Peek().A) < 1.0f || (color2.A * TintLayersStack.Peek().A) < 1.0f || (color3.A * TintLayersStack.Peek().A) < 1.0f;
}
FORCE_INLINE bool NeedAlphaWithTint(const Color& color1, const Color& color2, const Color& color3, const Color& color4)
{
return (color1.A * TintLayersStack.Peek().A) < 1.0f || (color2.A * TintLayersStack.Peek().A) < 1.0f || (color3.A * TintLayersStack.Peek().A) < 1.0f || (color4.A * TintLayersStack.Peek().A) < 1.0f;
}
void Render2D::FillRectangle(const Rectangle& rect, const Color& color)
{
RENDER2D_CHECK_RENDERING_STATE;
Render2DDrawCall& drawCall = DrawCalls.AddOne();
drawCall.Type = color.A < 1.0f ? DrawCallType::FillRect : DrawCallType::FillRectNoAlpha;
drawCall.Type = NeedAlphaWithTint(color) ? DrawCallType::FillRect : DrawCallType::FillRectNoAlpha;
drawCall.StartIB = IBIndex;
drawCall.CountIB = 6;
WriteRect(rect, color);
@@ -1279,7 +1336,7 @@ void Render2D::FillRectangle(const Rectangle& rect, const Color& color1, const C
RENDER2D_CHECK_RENDERING_STATE;
Render2DDrawCall& drawCall = DrawCalls.AddOne();
drawCall.Type = color1.A < 1.0f || color2.A < 1.0f || color3.A < 1.0f || color4.A < 1.0f ? DrawCallType::FillRect : DrawCallType::FillRectNoAlpha;
drawCall.Type = NeedAlphaWithTint(color1, color2, color3, color4) ? DrawCallType::FillRect : DrawCallType::FillRectNoAlpha;
drawCall.StartIB = IBIndex;
drawCall.CountIB = 6;
WriteRect(rect, color1, color2, color3, color4);
@@ -1374,7 +1431,7 @@ void Render2D::DrawRectangle(const Rectangle& rect, const Color& color1, const C
}
#else
Render2DDrawCall& drawCall = DrawCalls.AddOne();
drawCall.Type = color1.A < 1.0f || color2.A < 1.0f ? DrawCallType::FillRect : DrawCallType::FillRectNoAlpha;
drawCall.Type = NeedAlphaWithTint(color1, color2) ? DrawCallType::FillRect : DrawCallType::FillRectNoAlpha;
drawCall.StartIB = IBIndex;
drawCall.CountIB = 4 * (6 + 3);
@@ -1638,7 +1695,7 @@ void DrawLines(const Vector2* points, int32 pointsCount, const Color& color1, co
#else
const float thicknessHalf = thickness * 0.5f;
drawCall.Type = color1.A < 1.0f || color2.A < 1.0f ? DrawCallType::FillRect : DrawCallType::FillRectNoAlpha;
drawCall.Type = NeedAlphaWithTint(color1, color2) ? DrawCallType::FillRect : DrawCallType::FillRectNoAlpha;
drawCall.CountIB = 0;
ApplyTransform(points[0], p1t);
@@ -1781,7 +1838,7 @@ void Render2D::FillTriangle(const Vector2& p0, const Vector2& p1, const Vector2&
RENDER2D_CHECK_RENDERING_STATE;
Render2DDrawCall& drawCall = DrawCalls.AddOne();
drawCall.Type = color.A < 1.0f ? DrawCallType::FillRect : DrawCallType::FillRectNoAlpha;
drawCall.Type = NeedAlphaWithTint(color) ? DrawCallType::FillRect : DrawCallType::FillRectNoAlpha;
drawCall.StartIB = IBIndex;
drawCall.CountIB = 3;
WriteTri(p0, p1, p2, color, color, color);

View File

@@ -153,6 +153,22 @@ public:
/// </summary>
API_FUNCTION() static void PopClip();
/// <summary>
/// Pushes tint color.
/// </summary>
/// <param name="tint">The tint color.</param>
API_FUNCTION() static void PushTint(API_PARAM(Ref) const Color& tint);
/// <summary>
/// Peeks the current tint color.
/// </summary>
/// <param name="tint">The output tint color.</param>
API_FUNCTION() static void PeekTint(API_PARAM(Out) Color& tint);
/// <summary>
/// Pops tint color.
/// </summary>
API_FUNCTION() static void PopTint();
public:
/// <summary>