Add back text drawing using Draw2d (#928)
This is used by the UI Editor's viewport and also by LyShine to display debug text.
This commit is contained in:
@@ -11,11 +11,13 @@
|
||||
*/
|
||||
#include "LyShine_precompiled.h"
|
||||
#include "IFont.h"
|
||||
#include <IRenderer.h> // for SVF_P3F_C4B_T2F which will be removed in a coming PR
|
||||
|
||||
#include <LyShine/Draw2d.h>
|
||||
|
||||
#include <AzCore/Math/Matrix3x3.h>
|
||||
#include <AzCore/Math/MatrixUtils.h>
|
||||
#include <AzFramework/Font/FontInterface.h>
|
||||
|
||||
#include <Atom/RPI.Public/Image/ImageSystemInterface.h>
|
||||
#include <Atom/RPI.Public/RPISystemInterface.h>
|
||||
@@ -55,7 +57,7 @@ CDraw2d::CDraw2d(AZ::RPI::ViewportContextPtr viewportContext)
|
||||
m_defaultImageOptions.pixelRounding = Rounding::Nearest;
|
||||
m_defaultImageOptions.baseState = g_defaultBaseState;
|
||||
|
||||
m_defaultTextOptions.font = (gEnv && gEnv->pCryFont != nullptr) ? gEnv->pCryFont->GetFont("default") : nullptr;
|
||||
m_defaultTextOptions.fontName = "default";
|
||||
m_defaultTextOptions.effectIndex = 0;
|
||||
m_defaultTextOptions.color.Set(1.0f, 1.0f, 1.0f);
|
||||
m_defaultTextOptions.horizontalAlignment = HAlign::Left;
|
||||
@@ -283,13 +285,20 @@ void CDraw2d::DrawText(const char* textString, AZ::Vector2 position, float point
|
||||
{
|
||||
TextOptions* actualTextOptions = (textOptions) ? textOptions : &m_defaultTextOptions;
|
||||
|
||||
AzFramework::FontId fontId = AzFramework::InvalidFontId;
|
||||
AzFramework::FontQueryInterface* fontQueryInterface = AZ::Interface<AzFramework::FontQueryInterface>::Get();
|
||||
if (fontQueryInterface)
|
||||
{
|
||||
fontId = fontQueryInterface->GetFontId(actualTextOptions->fontName);
|
||||
}
|
||||
|
||||
// render the drop shadow, if needed
|
||||
if ((actualTextOptions->dropShadowColor.GetA() > 0.0f) &&
|
||||
(actualTextOptions->dropShadowOffset.GetX() || actualTextOptions->dropShadowOffset.GetY()))
|
||||
{
|
||||
// calculate the drop shadow pos and render it
|
||||
AZ::Vector2 dropShadowPosition(position + actualTextOptions->dropShadowOffset);
|
||||
DrawTextInternal(textString, actualTextOptions->font, actualTextOptions->effectIndex,
|
||||
DrawTextInternal(textString, fontId, actualTextOptions->effectIndex,
|
||||
dropShadowPosition, pointSize, actualTextOptions->dropShadowColor,
|
||||
actualTextOptions->rotation,
|
||||
actualTextOptions->horizontalAlignment, actualTextOptions->verticalAlignment,
|
||||
@@ -298,7 +307,7 @@ void CDraw2d::DrawText(const char* textString, AZ::Vector2 position, float point
|
||||
|
||||
// draw the text string
|
||||
AZ::Color textColor = AZ::Color::CreateFromVector3AndFloat(actualTextOptions->color, opacity);
|
||||
DrawTextInternal(textString, actualTextOptions->font, actualTextOptions->effectIndex,
|
||||
DrawTextInternal(textString, fontId, actualTextOptions->effectIndex,
|
||||
position, pointSize, textColor,
|
||||
actualTextOptions->rotation,
|
||||
actualTextOptions->horizontalAlignment, actualTextOptions->verticalAlignment,
|
||||
@@ -398,20 +407,35 @@ void CDraw2d::DrawRectOutlineTextured(AZ::Data::Instance<AZ::RPI::Image> image,
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
AZ::Vector2 CDraw2d::GetTextSize(const char* textString, float pointSize, TextOptions* textOptions)
|
||||
{
|
||||
TextOptions* actualTextOptions = (textOptions) ? textOptions : &m_defaultTextOptions;
|
||||
|
||||
if (!actualTextOptions->font)
|
||||
AzFramework::FontDrawInterface* fontDrawInterface = nullptr;
|
||||
AzFramework::FontQueryInterface* fontQueryInterface = AZ::Interface<AzFramework::FontQueryInterface>::Get();
|
||||
if (fontQueryInterface)
|
||||
{
|
||||
TextOptions* actualTextOptions = (textOptions) ? textOptions : &m_defaultTextOptions;
|
||||
AzFramework::FontId fontId = fontQueryInterface->GetFontId(actualTextOptions->fontName);
|
||||
fontDrawInterface = fontQueryInterface->GetFontDrawInterface(fontId);
|
||||
}
|
||||
if (!fontDrawInterface)
|
||||
{
|
||||
return AZ::Vector2(0.0f, 0.0f);
|
||||
}
|
||||
|
||||
STextDrawContext fontContext;
|
||||
fontContext.SetEffect(actualTextOptions->effectIndex);
|
||||
fontContext.SetSizeIn800x600(false);
|
||||
fontContext.SetSize(vector2f(pointSize, pointSize));
|
||||
// Set up draw parameters
|
||||
AzFramework::TextDrawParameters drawParams;
|
||||
drawParams.m_drawViewportId = GetViewportContext()->GetId();
|
||||
drawParams.m_position = AZ::Vector3(0.0f, 0.0f, 1.0f);
|
||||
drawParams.m_effectIndex = 0;
|
||||
drawParams.m_textSizeFactor = pointSize;
|
||||
drawParams.m_scale = AZ::Vector2(1.0f, 1.0f);
|
||||
drawParams.m_lineSpacing = 1.0f;
|
||||
drawParams.m_monospace = false;
|
||||
drawParams.m_depthTest = false;
|
||||
drawParams.m_virtual800x600ScreenSize = false;
|
||||
drawParams.m_scaleWithWindow = false;
|
||||
drawParams.m_multiline = true;
|
||||
|
||||
Vec2 textSize = actualTextOptions->font->GetTextSize(textString, true, fontContext);
|
||||
return AZ::Vector2(textSize.x, textSize.y);
|
||||
AZ::Vector2 textSize = fontDrawInterface->GetTextSize(drawParams, textString);
|
||||
return textSize;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -559,100 +583,89 @@ void CDraw2d::RotatePointsAboutPivot(AZ::Vector2* points, [[maybe_unused]] int n
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void CDraw2d::DrawTextInternal(const char* textString, IFFont* font, unsigned int effectIndex,
|
||||
void CDraw2d::DrawTextInternal(const char* textString, AzFramework::FontId fontId, unsigned int effectIndex,
|
||||
AZ::Vector2 position, float pointSize, AZ::Color color, float rotation,
|
||||
HAlign horizontalAlignment, VAlign verticalAlignment, int baseState)
|
||||
HAlign horizontalAlignment, VAlign verticalAlignment, [[maybe_unused]] int baseState)
|
||||
{
|
||||
if (!font)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
STextDrawContext fontContext;
|
||||
fontContext.SetEffect(effectIndex);
|
||||
fontContext.SetSizeIn800x600(false);
|
||||
fontContext.SetSize(vector2f(pointSize, pointSize));
|
||||
fontContext.SetColor(ColorF(color.GetR(), color.GetG(), color.GetB(), color.GetA()));
|
||||
fontContext.m_baseState = baseState;
|
||||
fontContext.SetOverrideViewProjMatrices(false);
|
||||
|
||||
// FFont.cpp uses the alpha value of the color to decide whether to use the color, if the alpha value is zero
|
||||
// (in a ColorB format) then the color set via SetColor is ignored and it usually ends up drawing with an alpha of 1.
|
||||
// This is not what we want so in this case do not draw at all.
|
||||
if (!fontContext.IsColorOverridden())
|
||||
if (AZ::IsClose(color.GetA(), 0.0f))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AZ::Vector2 alignedPosition;
|
||||
if (horizontalAlignment == HAlign::Left && verticalAlignment == VAlign::Top)
|
||||
// Convert Draw2d alignment to text alignment
|
||||
AzFramework::TextHorizontalAlignment hAlignment = AzFramework::TextHorizontalAlignment::Left;
|
||||
switch (horizontalAlignment)
|
||||
{
|
||||
alignedPosition = position;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we align based on the size of the default font effect, because we do not want the
|
||||
// text to move when the font effect is changed
|
||||
unsigned int fontEffectIndex = fontContext.m_fxIdx;
|
||||
fontContext.SetEffect(0);
|
||||
Vec2 textSize = font->GetTextSize(textString, true, fontContext);
|
||||
fontContext.SetEffect(fontEffectIndex);
|
||||
|
||||
alignedPosition = Align(position, AZ::Vector2(textSize.x, textSize.y), horizontalAlignment, verticalAlignment);
|
||||
case HAlign::Left:
|
||||
hAlignment = AzFramework::TextHorizontalAlignment::Left;
|
||||
break;
|
||||
case HAlign::Center:
|
||||
hAlignment = AzFramework::TextHorizontalAlignment::Center;
|
||||
break;
|
||||
case HAlign::Right:
|
||||
hAlignment = AzFramework::TextHorizontalAlignment::Right;
|
||||
break;
|
||||
default:
|
||||
AZ_Assert(false, "Attempting to draw text with unsupported horizontal alignment.");
|
||||
break;
|
||||
}
|
||||
|
||||
int flags = 0;
|
||||
AzFramework::TextVerticalAlignment vAlignment = AzFramework::TextVerticalAlignment::Top;
|
||||
switch (verticalAlignment)
|
||||
{
|
||||
case VAlign::Top:
|
||||
vAlignment = AzFramework::TextVerticalAlignment::Top;
|
||||
break;
|
||||
case VAlign::Center:
|
||||
vAlignment = AzFramework::TextVerticalAlignment::Center;
|
||||
break;
|
||||
case VAlign::Bottom:
|
||||
vAlignment = AzFramework::TextVerticalAlignment::Bottom;
|
||||
break;
|
||||
default:
|
||||
AZ_Assert(false, "Attempting to draw text with unsupported vertical alignment.");
|
||||
break;
|
||||
}
|
||||
|
||||
// Set up draw parameters for font interface
|
||||
AzFramework::TextDrawParameters drawParams;
|
||||
drawParams.m_drawViewportId = GetViewportContext()->GetId();
|
||||
drawParams.m_position = AZ::Vector3(position.GetX(), position.GetY(), 1.0f);
|
||||
drawParams.m_color = color;
|
||||
drawParams.m_effectIndex = effectIndex;
|
||||
drawParams.m_textSizeFactor = pointSize;
|
||||
drawParams.m_scale = AZ::Vector2(1.0f, 1.0f);
|
||||
drawParams.m_lineSpacing = 1.0f; //!< Spacing between new lines, as a percentage of m_scale.
|
||||
drawParams.m_hAlign = hAlignment;
|
||||
drawParams.m_vAlign = vAlignment;
|
||||
drawParams.m_monospace = false;
|
||||
drawParams.m_depthTest = false;
|
||||
drawParams.m_virtual800x600ScreenSize = false;
|
||||
drawParams.m_scaleWithWindow = false;
|
||||
drawParams.m_multiline = true;
|
||||
|
||||
if (rotation != 0.0f)
|
||||
{
|
||||
// rotate around the position (if aligned to center will rotate about center etc)
|
||||
float rotRad = DEG2RAD(rotation);
|
||||
Vec3 pivot(position.GetX(), position.GetY(), 0.0f);
|
||||
Matrix34A moveToPivotSpaceMat = Matrix34A::CreateTranslationMat(-pivot);
|
||||
Matrix34A rotMat = Matrix34A::CreateRotationZ(rotRad);
|
||||
Matrix34A moveFromPivotSpaceMat = Matrix34A::CreateTranslationMat(pivot);
|
||||
AZ::Vector3 pivot(position.GetX(), position.GetY(), 0.0f);
|
||||
AZ::Matrix3x4 moveToPivotSpaceMat = AZ::Matrix3x4::CreateTranslation(-pivot);
|
||||
AZ::Matrix3x4 rotMat = AZ::Matrix3x4::CreateRotationZ(rotRad);
|
||||
AZ::Matrix3x4 moveFromPivotSpaceMat = AZ::Matrix3x4::CreateTranslation(pivot);
|
||||
|
||||
Matrix34A transform = moveFromPivotSpaceMat * rotMat * moveToPivotSpaceMat;
|
||||
fontContext.SetTransform(transform);
|
||||
flags |= eDrawText_UseTransform;
|
||||
drawParams.m_transform = moveFromPivotSpaceMat * rotMat * moveToPivotSpaceMat;
|
||||
drawParams.m_useTransform = true;
|
||||
}
|
||||
|
||||
// The font system uses these alignment flags to force text to be in the safe zone
|
||||
// depending on overscan etc
|
||||
if (horizontalAlignment == HAlign::Center)
|
||||
{
|
||||
flags |= eDrawText_Center;
|
||||
}
|
||||
else if (horizontalAlignment == HAlign::Right)
|
||||
{
|
||||
flags |= eDrawText_Right;
|
||||
}
|
||||
DeferredText newText;
|
||||
newText.m_drawParameters = drawParams;
|
||||
newText.m_fontId = fontId;
|
||||
newText.m_string = textString;
|
||||
|
||||
if (verticalAlignment == VAlign::Center)
|
||||
{
|
||||
flags |= eDrawText_CenterV;
|
||||
}
|
||||
else if (verticalAlignment == VAlign::Bottom)
|
||||
{
|
||||
flags |= eDrawText_Bottom;
|
||||
}
|
||||
|
||||
fontContext.SetFlags(flags);
|
||||
|
||||
if (m_deferCalls)
|
||||
{
|
||||
DeferredText* newText = new DeferredText;
|
||||
|
||||
newText->m_fontContext = fontContext;
|
||||
newText->m_font = font;
|
||||
newText->m_position = alignedPosition;
|
||||
newText->m_string = textString;
|
||||
|
||||
m_deferredPrimitives.push_back(newText);
|
||||
}
|
||||
else
|
||||
{
|
||||
font->DrawString(alignedPosition.GetX(), alignedPosition.GetY(), textString, true, fontContext);
|
||||
}
|
||||
DrawOrDeferTextString(&newText);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -685,6 +698,20 @@ void CDraw2d::DrawOrDeferLine(const DeferredLine* line)
|
||||
}
|
||||
}
|
||||
|
||||
void CDraw2d::DrawOrDeferTextString(const DeferredText* text)
|
||||
{
|
||||
if (m_deferCalls)
|
||||
{
|
||||
DeferredText* newText = new DeferredText;
|
||||
*newText = *text;
|
||||
m_deferredPrimitives.push_back(newText);
|
||||
}
|
||||
else
|
||||
{
|
||||
text->Draw(m_dynamicDraw, m_shaderData, GetViewportContext());
|
||||
}
|
||||
}
|
||||
|
||||
void CDraw2d::DrawOrDeferRectOutline(const DeferredRectOutline* rectOutline)
|
||||
{
|
||||
if (m_deferCalls)
|
||||
@@ -919,6 +946,15 @@ void CDraw2d::DeferredText::Draw([[maybe_unused]] AZ::RHI::Ptr<AZ::RPI::DynamicD
|
||||
[[maybe_unused]] const Draw2dShaderData& shaderData,
|
||||
[[maybe_unused]] AZ::RPI::ViewportContextPtr viewportContext) const
|
||||
{
|
||||
m_font->DrawString(m_position.GetX(), m_position.GetY(), m_string.c_str(), true, m_fontContext);
|
||||
AzFramework::FontDrawInterface* fontDrawInterface = nullptr;
|
||||
AzFramework::FontQueryInterface* fontQueryInterface = AZ::Interface<AzFramework::FontQueryInterface>::Get();
|
||||
if (fontQueryInterface)
|
||||
{
|
||||
fontDrawInterface = fontQueryInterface->GetFontDrawInterface(m_fontId);
|
||||
if (fontDrawInterface)
|
||||
{
|
||||
fontDrawInterface->DrawScreenAlignedText2d(m_drawParameters, m_string.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user