/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ #include "LyShine_precompiled.h" #include "LyShineDebug.h" #include "IConsole.h" #include #include "IRenderer.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include AllocateConstIntCVar(LyShineDebug, CV_r_DebugUIDraw2dFont); AllocateConstIntCVar(LyShineDebug, CV_r_DebugUIDraw2dImage); AllocateConstIntCVar(LyShineDebug, CV_r_DebugUIDraw2dLine); AllocateConstIntCVar(LyShineDebug, CV_r_DebugUIDraw2dDefer); static const int g_numColors = 8; static const char* g_colorNames[g_numColors] = { "white", "red", "green", "blue", "yellow", "cyan", "magenta", "black" }; static AZ::Vector3 g_colorVec3[g_numColors] = { AZ::Vector3(1.0f, 1.0f, 1.0f), AZ::Vector3(1.0f, 0.0f, 0.0f), AZ::Vector3(0.0f, 1.0f, 0.0f), AZ::Vector3(0.0f, 0.0f, 1.0f), AZ::Vector3(1.0f, 1.0f, 0.0f), AZ::Vector3(0.0f, 1.0f, 1.0f), AZ::Vector3(1.0f, 0.0f, 1.0f), AZ::Vector3(0.0f, 0.0f, 0.0f), }; static const int g_numSrcBlendModes = 11; static int g_srcBlendModes[g_numSrcBlendModes] = { GS_BLSRC_ZERO, GS_BLSRC_ONE, GS_BLSRC_DSTCOL, GS_BLSRC_ONEMINUSDSTCOL, GS_BLSRC_SRCALPHA, GS_BLSRC_ONEMINUSSRCALPHA, GS_BLSRC_DSTALPHA, GS_BLSRC_ONEMINUSDSTALPHA, GS_BLSRC_ALPHASATURATE, GS_BLSRC_SRCALPHA_A_ZERO, // separate alpha blend state GS_BLSRC_SRC1ALPHA, // dual source blending }; static const int g_numDstBlendModes = 10; static int g_dstBlendModes[g_numDstBlendModes] = { GS_BLDST_ZERO, GS_BLDST_ONE, GS_BLDST_SRCCOL, GS_BLDST_ONEMINUSSRCCOL, GS_BLDST_SRCALPHA, GS_BLDST_ONEMINUSSRCALPHA, GS_BLDST_DSTALPHA, GS_BLDST_ONEMINUSDSTALPHA, GS_BLDST_ONE_A_ZERO, // separate alpha blend state GS_BLDST_ONEMINUSSRC1ALPHA, // dual source blending }; static bool g_deferDrawsToEndOfFrame = false; //////////////////////////////////////////////////////////////////////////////////////////////////// // LOCAL STATIC FUNCTIONS //////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// static int Create2DTexture(int width, int height, byte* data, ETEX_Format format) { IRenderer* renderer = gEnv->pRenderer; return renderer->DownLoadToVideoMemory(data, width, height, format, format, 1); } //////////////////////////////////////////////////////////////////////////////////////////////////// static void FillTextureRectWithCheckerboard(uint32* data, int textureWidth, int textureHeight, int minX, int minY, int rectWidth, int rectHeight, int tileWidth, int tileHeight, uint32* colors, bool varyAlpha) { for (int i = minX; i < minX + rectHeight && i < textureWidth; ++i) { for (int j = minY; j < minY + rectHeight && j < textureHeight; ++j) { // if both even then colors[0], if one even & one odd then colors[1], if both odd then colors[2] int index = ((i / tileWidth) % 2) + ((j / tileHeight) % 2); uint32 color = colors[index]; if (varyAlpha) { // across y we fade the alpha from 0 at top to 1 at bottom uint32 alpha = (j - minY) * 255 / rectHeight; color = (color & 0x00ffffff) | (alpha << 24); } data[i + j * textureWidth] = color; } } } //////////////////////////////////////////////////////////////////////////////////////////////////// static ITexture* CreateMonoTestTexture() { const int width = 32; const int height = 32; uint32 data[width * height]; const uint32 black = 0xff000000; const uint32 grey = 0xff7f7f7f; const uint32 white = 0xffffffff; uint32 colors[3] = {black, grey, white}; // create a checker board // top left quadrant, change every pixel FillTextureRectWithCheckerboard(data, width, height, 0, 0, width / 2, height / 2, 1, 1, colors, false); // top right quadrant, change every 2 pixels FillTextureRectWithCheckerboard(data, width, height, width / 2, 0, width / 2, height / 2, 2, 2, colors, false); // bottom right quadrant, change every 4 pixels FillTextureRectWithCheckerboard(data, width, height, width / 2, height / 2, width / 2, height / 2, 4, 4, colors, false); // bottom left quadrant, change every 8 pixels FillTextureRectWithCheckerboard(data, width, height, 0, height / 2, width / 2, height / 2, 8, 8, colors, false); int textureId = Create2DTexture(width, height, (uint8*)data, eTF_R8G8B8A8); return gEnv->pRenderer->EF_GetTextureByID(textureId); } //////////////////////////////////////////////////////////////////////////////////////////////////// static ITexture* CreateColorTestTexture() { const int width = 32; const int height = 32; uint32 data[width * height]; const uint32 red = 0xffff0000; const uint32 green = 0xff00ff00; const uint32 blue = 0xff0000ff; uint32 colors[3] = { red, green, blue }; // create a checker board // top left quadrant, change every pixel FillTextureRectWithCheckerboard(data, width, height, 0, 0, width / 2, height / 2, 1, 1, colors, false); // top right quadrant, change every 2 pixels FillTextureRectWithCheckerboard(data, width, height, width / 2, 0, width / 2, height / 2, 2, 2, colors, false); // bottom right quadrant, change every 4 pixels FillTextureRectWithCheckerboard(data, width, height, width / 2, height / 2, width / 2, height / 2, 4, 4, colors, false); // bottom left quadrant, change every 8 pixels FillTextureRectWithCheckerboard(data, width, height, 0, height / 2, width / 2, height / 2, 8, 8, colors, false); int textureId = Create2DTexture(width, height, (uint8*)data, eTF_R8G8B8A8); return gEnv->pRenderer->EF_GetTextureByID(textureId); } //////////////////////////////////////////////////////////////////////////////////////////////////// static ITexture* CreateMonoAlphaTestTexture() { const int width = 32; const int height = 32; uint32 data[width * height]; const uint32 black = 0xff000000; const uint32 grey = 0xff7f7f7f; const uint32 white = 0xffffffff; uint32 colors[3] = { black, grey, white }; // create a checker board // top left quadrant, change every pixel FillTextureRectWithCheckerboard(data, width, height, 0, 0, width / 2, height / 2, 1, 1, colors, true); // top right quadrant, change every 2 pixels FillTextureRectWithCheckerboard(data, width, height, width / 2, 0, width / 2, height / 2, 2, 2, colors, true); // bottom right quadrant, change every 4 pixels FillTextureRectWithCheckerboard(data, width, height, width / 2, height / 2, width / 2, height / 2, 4, 4, colors, true); // bottom left quadrant, change every 8 pixels FillTextureRectWithCheckerboard(data, width, height, 0, height / 2, width / 2, height / 2, 8, 8, colors, true); int textureId = Create2DTexture(width, height, (uint8*)data, eTF_R8G8B8A8); return gEnv->pRenderer->EF_GetTextureByID(textureId); } //////////////////////////////////////////////////////////////////////////////////////////////////// static ITexture* CreateColorAlphaTestTexture() { const int width = 32; const int height = 32; uint32 data[width * height]; const uint32 red = 0x00ff0000; const uint32 green = 0x0000ff00; const uint32 blue = 0x000000ff; uint32 colors[3] = { red, green, blue }; // create a checker board // top left quadrant, change every pixel FillTextureRectWithCheckerboard(data, width, height, 0, 0, width / 2, height / 2, 1, 1, colors, true); // top right quadrant, change every 2 pixels FillTextureRectWithCheckerboard(data, width, height, width / 2, 0, width / 2, height / 2, 2, 2, colors, true); // bottom right quadrant, change every 4 pixels FillTextureRectWithCheckerboard(data, width, height, width / 2, height / 2, width / 2, height / 2, 4, 4, colors, true); // bottom left quadrant, change every 8 pixels FillTextureRectWithCheckerboard(data, width, height, 0, height / 2, width / 2, height / 2, 8, 8, colors, true); int textureId = Create2DTexture(width, height, (uint8*)data, eTF_R8G8B8A8); return gEnv->pRenderer->EF_GetTextureByID(textureId); } //////////////////////////////////////////////////////////////////////////////////////////////////// static ITexture* GetMonoTestTexture() { static ITexture* testImageMono = nullptr; if (!testImageMono) { testImageMono = CreateMonoTestTexture(); } return testImageMono; } //////////////////////////////////////////////////////////////////////////////////////////////////// static ITexture* GetColorTestTexture() { static ITexture* testImageColor = nullptr; if (!testImageColor) { testImageColor = CreateColorTestTexture(); } return testImageColor; } //////////////////////////////////////////////////////////////////////////////////////////////////// static ITexture* GetMonoAlphaTestTexture() { static ITexture* testImageMonoAlpha = nullptr; if (!testImageMonoAlpha) { testImageMonoAlpha = CreateMonoAlphaTestTexture(); } return testImageMonoAlpha; } //////////////////////////////////////////////////////////////////////////////////////////////////// static ITexture* GetColorAlphaTestTexture() { static ITexture* testImageColorAlpha = nullptr; if (!testImageColorAlpha) { testImageColorAlpha = CreateColorAlphaTestTexture(); } return testImageColorAlpha; } //////////////////////////////////////////////////////////////////////////////////////////////////// static void DebugDrawColoredBox(AZ::Vector2 pos, AZ::Vector2 size, AZ::Color color, IDraw2d::HAlign horizontalAlignment = IDraw2d::HAlign::Left, IDraw2d::VAlign verticalAlignment = IDraw2d::VAlign::Top) { IDraw2d* draw2d = Draw2dHelper::GetDraw2d(); IRenderer* renderer = gEnv->pRenderer; IDraw2d::ImageOptions imageOptions = draw2d->GetDefaultImageOptions(); int whiteTextureId = renderer->GetWhiteTextureId(); imageOptions.color = color.GetAsVector3(); draw2d->DrawImageAligned(whiteTextureId, pos, size, horizontalAlignment, verticalAlignment, color.GetA(), 0.0f, nullptr, &imageOptions); } //////////////////////////////////////////////////////////////////////////////////////////////////// static void DebugDrawStringWithSizeBox(IFFont* font, unsigned int effectIndex, const char* sizeString, const char* testString, AZ::Vector2 pos, float spacing, float size) { IDraw2d* draw2d = Draw2dHelper::GetDraw2d(); IDraw2d::TextOptions textOptions = draw2d->GetDefaultTextOptions(); if (font) { textOptions.font = font; } textOptions.effectIndex = effectIndex; draw2d->DrawText(sizeString, pos, size, 1.0f, &textOptions); AZ::Vector2 sizeTextSize = draw2d->GetTextSize(sizeString, size, &textOptions); AZ::Vector2 testTextSize = draw2d->GetTextSize(testString, size, &textOptions); AZ::Vector2 pos2(pos.GetX() + sizeTextSize.GetX() + spacing, pos.GetY()); DebugDrawColoredBox(AZ::Vector2(pos2.GetX() - 1, pos2.GetY() - 1), AZ::Vector2(testTextSize.GetX() + 2, testTextSize.GetY() + 2), AZ::Color(0.5f, 0.5f, 0.5f, 1.0f)); DebugDrawColoredBox(pos2, testTextSize, AZ::Color(0.0f, 0.0f, 0.0f, 1.0f)); draw2d->DrawText(testString, pos2, size, 1.0f, &textOptions); AZ::Vector2 pos3(pos2.GetX() + testTextSize.GetX() + spacing, pos.GetY()); char buffer[32]; sprintf_s(buffer, "Pixel height = %5.2f", testTextSize.GetY()); AZ::Vector2 pixelHeightTextSize = draw2d->GetTextSize(buffer, size, &textOptions); // Draw a light background to see if there is a drop shadow DebugDrawColoredBox(AZ::Vector2(pos3.GetX() - 1, pos3.GetY() - 1), AZ::Vector2(pixelHeightTextSize.GetX() + 2, pixelHeightTextSize.GetY() + 2), AZ::Color(0.65f, 0.65f, 0.65f, 1.0f)); draw2d->DrawText(buffer, pos3, size, 1.0f, &textOptions); } //////////////////////////////////////////////////////////////////////////////////////////////////// static void DebugDraw2dFontSizes(IFFont* font, unsigned int effectIndex, const char* fontName) { IDraw2d* draw2d = Draw2dHelper::GetDraw2d(); IRenderer* renderer = gEnv->pRenderer; draw2d->BeginDraw2d(g_deferDrawsToEndOfFrame); float xOffset = 20.0f; float yOffset = 20.0f; float xSpacing = 20.0f; char buffer[32]; sprintf_s(buffer, "Font = %s, effect = %d", fontName, effectIndex); draw2d->DrawText(buffer, AZ::Vector2(xOffset, yOffset), 32); yOffset += 40.0f; draw2d->DrawText("NOTE: if the effect includes a drop shadow baked into font then the pixel size", AZ::Vector2(xOffset, yOffset), 16); draw2d->DrawText("NOTE: The pixel height reported takes no account of the actual characters used.", AZ::Vector2(xOffset + draw2d->GetViewportWidth() * 0.5f, yOffset), 16); yOffset += 20.0f; draw2d->DrawText("will include the drop shadow offset.", AZ::Vector2(xOffset, yOffset), 16); yOffset += 20.0f; const char* testString = "AbdfhkltgjpqyWw|01!"; const char* minimalTestString = "ace"; DebugDrawStringWithSizeBox(font, effectIndex, "Size 16", testString, AZ::Vector2(xOffset, yOffset), xSpacing, 16); DebugDrawStringWithSizeBox(font, effectIndex, "Size 16", minimalTestString, AZ::Vector2(xOffset + draw2d->GetViewportWidth() * 0.5f, yOffset), xSpacing, 16); yOffset += 40.0f; DebugDrawStringWithSizeBox(font, effectIndex, "Size 17", testString, AZ::Vector2(xOffset, yOffset), xSpacing, 17); yOffset += 40.0f; DebugDrawStringWithSizeBox(font, effectIndex, "Size 18", testString, AZ::Vector2(xOffset, yOffset), xSpacing, 18); yOffset += 40.0f; DebugDrawStringWithSizeBox(font, effectIndex, "Size 23", testString, AZ::Vector2(xOffset, yOffset), xSpacing, 23); yOffset += 40.0f; DebugDrawStringWithSizeBox(font, effectIndex, "Size 24", testString, AZ::Vector2(xOffset, yOffset), xSpacing, 24); yOffset += 40.0f; DebugDrawStringWithSizeBox(font, effectIndex, "Size 25", testString, AZ::Vector2(xOffset, yOffset), xSpacing, 25); yOffset += 40.0f; DebugDrawStringWithSizeBox(font, effectIndex, "Size 30", testString, AZ::Vector2(xOffset, yOffset), xSpacing, 30); yOffset += 40.0f; DebugDrawStringWithSizeBox(font, effectIndex, "Size 31", testString, AZ::Vector2(xOffset, yOffset), xSpacing, 31); yOffset += 40.0f; DebugDrawStringWithSizeBox(font, effectIndex, "Size 32", testString, AZ::Vector2(xOffset, yOffset), xSpacing, 32); yOffset += 40.0f; DebugDrawStringWithSizeBox(font, effectIndex, "Size 33", testString, AZ::Vector2(xOffset, yOffset), xSpacing, 33); yOffset += 40.0f; DebugDrawStringWithSizeBox(font, effectIndex, "Size 34", testString, AZ::Vector2(xOffset, yOffset), xSpacing, 34); yOffset += 40.0f; DebugDrawStringWithSizeBox(font, effectIndex, "Size 47", testString, AZ::Vector2(xOffset, yOffset), xSpacing, 47); yOffset += 55.0f; DebugDrawStringWithSizeBox(font, effectIndex, "Size 48", testString, AZ::Vector2(xOffset, yOffset), xSpacing, 48); yOffset += 55.0f; DebugDrawStringWithSizeBox(font, effectIndex, "Size 49", testString, AZ::Vector2(xOffset, yOffset), xSpacing, 49); draw2d->EndDraw2d(); } //////////////////////////////////////////////////////////////////////////////////////////////////// static void DebugDrawAlignedTextWithOriginBox(AZ::Vector2 pos, IDraw2d::HAlign horizontalAlignment, IDraw2d::VAlign verticalAlignment, float pointSize, AZ::Vector3 textColor) { Draw2dHelper draw2d(g_deferDrawsToEndOfFrame); const char* haStr = 0; const char* vaStr = 0; switch (horizontalAlignment) { case IDraw2d::HAlign::Left: haStr = "Left"; break; case IDraw2d::HAlign::Center: haStr = "Center"; break; case IDraw2d::HAlign::Right: haStr = "Right"; break; } switch (verticalAlignment) { case IDraw2d::VAlign::Top: vaStr = "Top"; break; case IDraw2d::VAlign::Center: vaStr = "Center"; break; case IDraw2d::VAlign::Bottom: vaStr = "Bottom"; break; } char buffer[64]; sprintf_s(buffer, "%s %s, size=%5.2f", haStr, vaStr, pointSize); AZ::Color backgroundColor(0.3f, 0.3f, 0.3f, 1.0f); DebugDrawColoredBox(pos, draw2d.GetTextSize(buffer, pointSize), backgroundColor, horizontalAlignment, verticalAlignment); AZ::Color boxColor(1.0f, 0.25f, 0.25f, 1.0f); DebugDrawColoredBox(AZ::Vector2(pos.GetX() - 2.0f, pos.GetY() - 2.0f), AZ::Vector2(5.0f, 5.0f), boxColor); draw2d.SetTextAlignment(horizontalAlignment, verticalAlignment); draw2d.SetTextColor(textColor); draw2d.DrawText(buffer, pos, pointSize, 1.0f); } //////////////////////////////////////////////////////////////////////////////////////////////////// static void DebugDraw2dFontAlignment() { IDraw2d* draw2d = Draw2dHelper::GetDraw2d(); float w = draw2d->GetViewportWidth(); float h = draw2d->GetViewportHeight(); float yPos = 20; { Draw2dHelper draw2dHelper(g_deferDrawsToEndOfFrame); draw2dHelper.DrawText( "Text Alignment. Red dot is the pos passed to DrawText. Default font, effect 0", AZ::Vector2(20, yPos), 16); yPos += 20; } AZ::Vector3 color1(1, 1, 1); DebugDrawAlignedTextWithOriginBox(AZ::Vector2(20, yPos), IDraw2d::HAlign::Left, IDraw2d::VAlign::Top, 32, color1); DebugDrawAlignedTextWithOriginBox(AZ::Vector2(w / 2, yPos), IDraw2d::HAlign::Center, IDraw2d::VAlign::Top, 32, color1); DebugDrawAlignedTextWithOriginBox(AZ::Vector2(w - 20, yPos), IDraw2d::HAlign::Right, IDraw2d::VAlign::Top, 32, color1); yPos += 60; DebugDrawAlignedTextWithOriginBox(AZ::Vector2(20, yPos), IDraw2d::HAlign::Left, IDraw2d::VAlign::Center, 32, color1); DebugDrawAlignedTextWithOriginBox(AZ::Vector2(w / 2, yPos), IDraw2d::HAlign::Center, IDraw2d::VAlign::Center, 32, color1); DebugDrawAlignedTextWithOriginBox(AZ::Vector2(w - 20, yPos), IDraw2d::HAlign::Right, IDraw2d::VAlign::Center, 32, color1); yPos += 60; DebugDrawAlignedTextWithOriginBox(AZ::Vector2(20, yPos), IDraw2d::HAlign::Left, IDraw2d::VAlign::Bottom, 32, color1); DebugDrawAlignedTextWithOriginBox(AZ::Vector2(w / 2, yPos), IDraw2d::HAlign::Center, IDraw2d::VAlign::Bottom, 32, color1); DebugDrawAlignedTextWithOriginBox(AZ::Vector2(w - 20, yPos), IDraw2d::HAlign::Right, IDraw2d::VAlign::Bottom, 32, color1); AZ::Vector3 color2(0.25f, 0.5f, 1.0f); yPos += 30; DebugDrawAlignedTextWithOriginBox(AZ::Vector2(20, yPos), IDraw2d::HAlign::Left, IDraw2d::VAlign::Top, 24, color2); DebugDrawAlignedTextWithOriginBox(AZ::Vector2(w / 2, yPos), IDraw2d::HAlign::Center, IDraw2d::VAlign::Top, 24, color2); DebugDrawAlignedTextWithOriginBox(AZ::Vector2(w - 20, yPos), IDraw2d::HAlign::Right, IDraw2d::VAlign::Top, 24, color2); yPos += 50; DebugDrawAlignedTextWithOriginBox(AZ::Vector2(20, yPos), IDraw2d::HAlign::Left, IDraw2d::VAlign::Center, 24, color2); DebugDrawAlignedTextWithOriginBox(AZ::Vector2(w / 2, yPos), IDraw2d::HAlign::Center, IDraw2d::VAlign::Center, 24, color2); DebugDrawAlignedTextWithOriginBox(AZ::Vector2(w - 20, yPos), IDraw2d::HAlign::Right, IDraw2d::VAlign::Center, 24, color2); yPos += 50; DebugDrawAlignedTextWithOriginBox(AZ::Vector2(20, yPos), IDraw2d::HAlign::Left, IDraw2d::VAlign::Bottom, 24, color2); DebugDrawAlignedTextWithOriginBox(AZ::Vector2(w / 2, yPos), IDraw2d::HAlign::Center, IDraw2d::VAlign::Bottom, 24, color2); DebugDrawAlignedTextWithOriginBox(AZ::Vector2(w - 20, yPos), IDraw2d::HAlign::Right, IDraw2d::VAlign::Bottom, 24, color2); } //////////////////////////////////////////////////////////////////////////////////////////////////// static AZ::Vector2 DebugDrawFontColorTestBox(AZ::Vector2 pos, const char* string, AZ::Vector3 color, float opacity) { IDraw2d* draw2d = Draw2dHelper::GetDraw2d(); float pointSize = 32.0f; const float spacing = 6.0f; IDraw2d::TextOptions textOptions = draw2d->GetDefaultTextOptions(); textOptions.effectIndex = 1; // no drop shadow baked in textOptions.color = color; AZ::Vector2 textSize = draw2d->GetTextSize(string, pointSize, &textOptions); AZ::Vector2 totalBackgroundSize(textSize.GetX() + spacing * 2.0f, textSize.GetY() + spacing * 4.0f); AZ::Vector2 whiteBackgroundSize(totalBackgroundSize.GetX() * 0.5f, totalBackgroundSize.GetY()); AZ::Vector2 blackBackgroundSize = whiteBackgroundSize; AZ::Vector2 whiteBackgroundPos = pos; AZ::Vector2 blackBackgroundPos = pos + AZ::Vector2(whiteBackgroundSize.GetX(), 0); AZ::Vector2 textPos = pos + AZ::Vector2(spacing, spacing); AZ::Vector2 boxPos = pos + AZ::Vector2(spacing, spacing + textSize.GetY() + spacing); DebugDrawColoredBox(whiteBackgroundPos, whiteBackgroundSize, AZ::Color(1.0f, 1.0f, 1.0f, 1.0f)); DebugDrawColoredBox(blackBackgroundPos, blackBackgroundSize, AZ::Color(0.0f, 0.0f, 0.0f, 1.0f)); draw2d->DrawText(string, textPos, pointSize, opacity, &textOptions); DebugDrawColoredBox(boxPos, AZ::Vector2(textSize.GetX(), spacing), AZ::Color::CreateFromVector3AndFloat(color, opacity)); return totalBackgroundSize; } //////////////////////////////////////////////////////////////////////////////////////////////////// static void DebugDraw2dFontColorAndOpacity() { IDraw2d* draw2d = Draw2dHelper::GetDraw2d(); IRenderer* renderer = gEnv->pRenderer; draw2d->BeginDraw2d(g_deferDrawsToEndOfFrame); AZ::Vector2 size; AZ::Vector2 pos(20.0f, 20.0f); for (int color = 0; color < g_numColors; ++color) { AZ::Vector2 boxPos = pos; size = DebugDrawFontColorTestBox(boxPos, g_colorNames[color], g_colorVec3[color], 1.0f); boxPos.SetX(boxPos.GetX() + 200.0f); size = DebugDrawFontColorTestBox(boxPos, g_colorNames[color], g_colorVec3[color], 0.75f); boxPos.SetX(boxPos.GetX() + 200.0f); size = DebugDrawFontColorTestBox(boxPos, g_colorNames[color], g_colorVec3[color], 0.5f); boxPos.SetX(boxPos.GetX() + 200.0f); size = DebugDrawFontColorTestBox(boxPos, g_colorNames[color], g_colorVec3[color], 0.25f); boxPos.SetX(boxPos.GetX() + 200.0f); size = DebugDrawFontColorTestBox(boxPos, g_colorNames[color], g_colorVec3[color], 0.00f); pos.SetY(pos.GetY() + size.GetY() + 10.0f); } draw2d->DrawText("Opacity=1.00f", pos, 24.0f); pos.SetX(pos.GetX() + 200.0f); draw2d->DrawText("Opacity=0.75f", pos, 24.0f); pos.SetX(pos.GetX() + 200.0f); draw2d->DrawText("Opacity=0.50f", pos, 24.0f); pos.SetX(pos.GetX() + 200.0f); draw2d->DrawText("Opacity=0.25f", pos, 24.0f); pos.SetX(pos.GetX() + 200.0f); draw2d->DrawText("Opacity=0.00f", pos, 24.0f); draw2d->EndDraw2d(); } //////////////////////////////////////////////////////////////////////////////////////////////////// static void DebugDraw2dImageRotations() { IDraw2d* draw2d = Draw2dHelper::GetDraw2d(); ITexture* texture = GetMonoTestTexture(); int texId = texture->GetTextureID(); draw2d->BeginDraw2d(g_deferDrawsToEndOfFrame); float width = (float)texture->GetWidth(); float height = (float)texture->GetHeight(); AZ::Vector2 size(width, height); float row = 20.0f; float xSpacing = size.GetX() * 2.0f; float xStart = 50.0f; AZ::Color posBoxColor(1.0f, 0.25f, 0.25f, 1.0f); AZ::Color pivotBoxColor(1.0f, 1.00f, 0.00f, 1.0f); draw2d->DrawText("No pivot, rotation about pos (drawn in red), increments of 45 degrees", AZ::Vector2(xStart, row), 16); row += 16 + 60.0f; for (int i = 0; i < 10; ++i) { AZ::Vector2 pos(xStart + xSpacing * i, row); draw2d->DrawImage(texId, pos, size, 1.0f, 45.0f * i); DebugDrawColoredBox(AZ::Vector2(pos.GetX() - 2, pos.GetY() - 2), AZ::Vector2(5, 5), posBoxColor); } row += 60.0f; draw2d->DrawText("Rotation about pivot. Pos drawn in red, pivot is yellow. Increments of 45 degrees", AZ::Vector2(xStart, row), 16); row += 16 + 40.0f; AZ::Vector2 pivotOffset(10, 20); for (int i = 0; i < 10; ++i) { AZ::Vector2 pos(xStart + xSpacing * i, row); AZ::Vector2 pivot = pos + pivotOffset; draw2d->DrawImage(texId, pos, size, 1.0f, 45.0f * i, &pivot); DebugDrawColoredBox(AZ::Vector2(pos.GetX() - 2, pos.GetY() - 2), AZ::Vector2(5, 5), posBoxColor); DebugDrawColoredBox(AZ::Vector2(pivot.GetX() - 2, pivot.GetY() - 2), AZ::Vector2(5, 5), pivotBoxColor); } row += 100.0f; draw2d->DrawText("DrawImageAligned (center,center). Pos drawn in red. Increments of 45 degrees", AZ::Vector2(xStart, row), 16); row += 16 + 30.0f; for (int i = 0; i < 10; ++i) { AZ::Vector2 pos(xStart + xSpacing * i + size.GetX() * 0.5f, row + size.GetY() * 0.5f); draw2d->DrawImageAligned(texId, pos, size, IDraw2d::HAlign::Center, IDraw2d::VAlign::Center, 1.0f, 45.0f * i); DebugDrawColoredBox(AZ::Vector2(pos.GetX() - 2, pos.GetY() - 2), AZ::Vector2(5, 5), posBoxColor); } draw2d->EndDraw2d(); } //////////////////////////////////////////////////////////////////////////////////////////////////// static void DebugDraw2dImageColor() { IDraw2d* draw2d = Draw2dHelper::GetDraw2d(); ITexture* texture = GetMonoAlphaTestTexture(); int texId = texture->GetTextureID(); IDraw2d::ImageOptions imageOptions = draw2d->GetDefaultImageOptions(); draw2d->BeginDraw2d(g_deferDrawsToEndOfFrame); draw2d->DrawText( "Testing image colors, image is black and white, top row is opacity=1, bottom row is opacity = 0.5", AZ::Vector2(20, 20), 16); float width = texture->GetWidth() * 2.0f; float height = texture->GetHeight() * 2.0f; AZ::Vector2 size(width, height); float xStart = 20.0f; float yStart = 50.0f; float xSpacing = size.GetX() + 20.0f; float ySpacing = size.GetY() + 20.0f; for (int color = 0; color < g_numColors; ++color) { AZ::Vector2 pos(xStart + xSpacing * color, yStart); // Draw the image with this color imageOptions.color = g_colorVec3[color]; draw2d->DrawImage(texId, pos, size, 1.0f, 0.0f, 0, 0, &imageOptions); // draw below with half opacity to test combination of color and opacity pos.SetY(pos.GetY() + ySpacing); draw2d->DrawImage(texId, pos, size, 0.5f, 0.0f, 0, 0, &imageOptions); } draw2d->EndDraw2d(); } //////////////////////////////////////////////////////////////////////////////////////////////////// static void DebugDraw2dImageBlendMode() { IDraw2d* draw2d = Draw2dHelper::GetDraw2d(); IRenderer* renderer = gEnv->pRenderer; int whiteTextureId = renderer->GetWhiteTextureId(); ITexture* texture = GetColorAlphaTestTexture(); int texId = texture->GetTextureID(); IDraw2d::ImageOptions imageOptions = draw2d->GetDefaultImageOptions(); draw2d->BeginDraw2d(g_deferDrawsToEndOfFrame); draw2d->DrawText("Testing blend modes, src blend changes across x-axis, dst blend changes across y axis", AZ::Vector2(20, 20), 16); float width = (float)texture->GetWidth(); float height = (float)texture->GetHeight(); AZ::Vector2 size(width, height); float xStart = 20.0f; float yStart = 60.0f; float xSpacing = width + 2.0f; float ySpacing = height + 2.0f; for (int srcIndex = 0; srcIndex < g_numSrcBlendModes; ++srcIndex) { for (int dstIndex = 0; dstIndex < g_numDstBlendModes; ++dstIndex) { AZ::Vector2 pos(xStart + xSpacing * srcIndex, yStart + ySpacing * dstIndex); // first draw a background with varying color and alpha IDraw2d::VertexPosColUV verts[4] = { { // top left AZ::Vector2(pos.GetX(), pos.GetY()), AZ::Color(1.0f, 0.0f, 0.0f, 1.0f), AZ::Vector2(0.0f, 0.0f) }, { // top right AZ::Vector2(pos.GetX() + width, pos.GetY()), AZ::Color(0.0f, 1.0f, 0.0f, 1.0f), AZ::Vector2(1.0f, 0.0f) }, { // bottom right AZ::Vector2(pos.GetX() + width, pos.GetY() + height), AZ::Color(1.0f, 1.0f, 1.0f, 0.0f), AZ::Vector2(1.0f, 1.0f) }, { // bottom left AZ::Vector2(pos.GetX(), pos.GetY() + height), AZ::Color(0.0f, 0.0f, 1.0f, 1.0f), AZ::Vector2(0.0f, 1.0f) }, }; draw2d->DrawQuad(whiteTextureId, verts); // Draw the image with this color imageOptions.blendMode = g_srcBlendModes[srcIndex] | g_dstBlendModes[dstIndex]; draw2d->DrawImage(texId, pos, size, 1.0f, 0.0f, 0, 0, &imageOptions); } } draw2d->EndDraw2d(); } //////////////////////////////////////////////////////////////////////////////////////////////////// static void DebugDraw2dImageUVs() { IDraw2d* draw2d = Draw2dHelper::GetDraw2d(); ITexture* texture = GetColorTestTexture(); int texId = texture->GetTextureID(); IDraw2d::ImageOptions imageOptions = draw2d->GetDefaultImageOptions(); draw2d->BeginDraw2d(g_deferDrawsToEndOfFrame); draw2d->DrawText( "Testing DrawImage with minMaxTexCoords. Full image, top left quadrant, middle section, full flipped", AZ::Vector2(20, 20), 16); AZ::Vector2 size((float)texture->GetWidth() * 2.0f, (float)texture->GetHeight() * 2.0f); float xStart = 20.0f; float yStart = 50.0f; float xSpacing = size.GetX() + 20.0f; float ySpacing = size.GetY() + 20.0f; AZ::Vector2 pos(xStart, yStart); AZ::Vector2 minMaxTexCoords[2]; // full image minMaxTexCoords[0] = AZ::Vector2(0, 0); minMaxTexCoords[1] = AZ::Vector2(1, 1); draw2d->DrawImage(texId, pos, size, 1.0f, 0.0f, 0, minMaxTexCoords); // top left quadrant of image pos.SetX(pos.GetX() + xSpacing); minMaxTexCoords[0] = AZ::Vector2(0, 0); minMaxTexCoords[1] = AZ::Vector2(0.5, 0.5); draw2d->DrawImage(texId, pos, size, 1.0f, 0.0f, 0, minMaxTexCoords); // middle of image pos.SetX(pos.GetX() + xSpacing); minMaxTexCoords[0] = AZ::Vector2(0.25, 0.25); minMaxTexCoords[1] = AZ::Vector2(0.75, 0.75); draw2d->DrawImage(texId, pos, size, 1.0f, 0.0f, 0, minMaxTexCoords); // flip of image pos.SetX(pos.GetX() + xSpacing); minMaxTexCoords[0] = AZ::Vector2(0.0, 1.0); minMaxTexCoords[1] = AZ::Vector2(1.0, 0.0); draw2d->DrawImage(texId, pos, size, 1.0f, 0.0f, 0, minMaxTexCoords); draw2d->EndDraw2d(); } //////////////////////////////////////////////////////////////////////////////////////////////////// static void DebugDraw2dImagePixelRounding() { IDraw2d* draw2d = Draw2dHelper::GetDraw2d(); ITexture* texture = GetColorTestTexture(); int texId = texture->GetTextureID(); IDraw2d::ImageOptions imageOptions = draw2d->GetDefaultImageOptions(); draw2d->BeginDraw2d(g_deferDrawsToEndOfFrame); draw2d->DrawText("Testing DrawImage pixel rounding options", AZ::Vector2(20, 20), 16); AZ::Vector2 size((float)texture->GetWidth(), (float)texture->GetHeight()); float xStart = 20.0f; float yStart = 50.0f; float xSpacing = size.GetX() + 4.0f; float ySpacing = size.GetY() + 4.0f; float offsets[4] = { 0.0f, 0.17f, 0.5f, 0.67f }; IDraw2d::Rounding roundings[4] = { IDraw2d::Rounding::None, IDraw2d::Rounding::Nearest, IDraw2d::Rounding::Down, IDraw2d::Rounding::Up }; for (int i = 0; i < 4; ++i) // loop through pixel offsets (along x axis) { for (int j = 0; j < 4; ++j) // loop through rounding options (along y axis) { AZ::Vector2 pos(xStart + xSpacing * i + offsets[i], yStart + ySpacing * j + offsets[i]); imageOptions.pixelRounding = roundings[j]; draw2d->DrawImage(texId, pos, size, 1.0f, 0.0f, 0, 0, &imageOptions); } } draw2d->EndDraw2d(); } //////////////////////////////////////////////////////////////////////////////////////////////////// static void DebugDraw2dLineBasic() { IDraw2d* draw2d = Draw2dHelper::GetDraw2d(); ITexture* texture = GetColorTestTexture(); int texId = texture->GetTextureID(); IDraw2d::ImageOptions imageOptions = draw2d->GetDefaultImageOptions(); draw2d->BeginDraw2d(g_deferDrawsToEndOfFrame); draw2d->DrawText("Testing DrawLine", AZ::Vector2(20, 20), 16); AZ::Vector2 center = AZ::Vector2(draw2d->GetViewportWidth() * 0.5f, draw2d->GetViewportHeight() * 0.5f); float offset = 300.0f; AZ::Color white(1.0f, 1.0f, 1.0f, 1.0f); draw2d->DrawLine(center, center + AZ::Vector2(offset, 0), AZ::Color(1.0f, 1.0f, 1.0f, 1.0f)); draw2d->DrawLine(center, center + AZ::Vector2(offset, offset), AZ::Color(1.0f, 0.0f, 0.0f, 1.0f)); draw2d->DrawLine(center, center + AZ::Vector2(0, offset), AZ::Color(1.0f, 1.0f, 0.0f, 1.0f)); draw2d->DrawLine(center, center + AZ::Vector2(-offset, offset), AZ::Color(0.0f, 1.0f, 0.0f, 1.0f)); draw2d->DrawLine(center, center + AZ::Vector2(-offset, 0), AZ::Color(0.0f, 1.0f, 1.0f, 1.0f)); draw2d->DrawLine(center, center + AZ::Vector2(-offset, -offset), AZ::Color(0.0f, 0.0f, 1.0f, 1.0f)); draw2d->DrawLine(center, center + AZ::Vector2(0, -offset), AZ::Color(1.0f, 0.0f, 1.0f, 1.0f)); draw2d->DrawLine(center, center + AZ::Vector2(offset, -offset), AZ::Color(0.0f, 0.0f, 0.0f, 1.0f)); draw2d->EndDraw2d(); } static AZ::EntityId g_testCanvasId; static void CreateComponent(AZ::Entity* entity, const AZ::Uuid& componentTypeId) { entity->Deactivate(); entity->CreateComponent(componentTypeId); entity->Activate(); } //////////////////////////////////////////////////////////////////////////////////////////////////// static AZ::Entity* CreateButton(const char* name, bool atRoot, AZ::EntityId parent, UiTransform2dInterface::Anchors anchors, UiTransform2dInterface::Offsets offsets, const char* text, AZ::Color baseColor, AZ::Color selectedColor, AZ::Color pressedColor, AZ::Color textColor) { AZ::Entity* buttonElem = nullptr; if (atRoot) { EBUS_EVENT_ID_RESULT(buttonElem, parent, UiCanvasBus, CreateChildElement, name); } else { EBUS_EVENT_ID_RESULT(buttonElem, parent, UiElementBus, CreateChildElement, name); } { AZ::EntityId buttonId = buttonElem->GetId(); // create components for button elem CreateComponent(buttonElem, LyShine::UiTransform2dComponentUuid); CreateComponent(buttonElem, LyShine::UiImageComponentUuid); CreateComponent(buttonElem, LyShine::UiButtonComponentUuid); AZ_Assert(UiTransform2dBus::FindFirstHandler(buttonId), "Transform2d component missing"); EBUS_EVENT_ID(buttonId, UiTransform2dBus, SetAnchors, anchors, false, false); EBUS_EVENT_ID(buttonId, UiTransform2dBus, SetOffsets, offsets); EBUS_EVENT_ID(buttonId, UiImageBus, SetColor, baseColor); EBUS_EVENT_ID(buttonId, UiInteractableStatesBus, SetStateColor, UiInteractableStatesInterface::StateHover, buttonId, selectedColor); EBUS_EVENT_ID(buttonId, UiInteractableStatesBus, SetStateAlpha, UiInteractableStatesInterface::StateHover, buttonId, selectedColor.GetA()); EBUS_EVENT_ID(buttonId, UiInteractableStatesBus, SetStateColor, UiInteractableStatesInterface::StatePressed, buttonId, pressedColor); EBUS_EVENT_ID(buttonId, UiInteractableStatesBus, SetStateAlpha, UiInteractableStatesInterface::StatePressed, buttonId, pressedColor.GetA()); string pathname = "Textures/Basic/Button_Sliced_Normal.sprite"; ISprite* sprite = gEnv->pLyShine->LoadSprite(pathname); EBUS_EVENT_ID(buttonId, UiImageBus, SetSprite, sprite); EBUS_EVENT_ID(buttonId, UiImageBus, SetImageType, UiImageInterface::ImageType::Sliced); } { // create child text element for the button AZ::Entity* textElem = nullptr; EBUS_EVENT_ID_RESULT(textElem, buttonElem->GetId(), UiElementBus, CreateChildElement, "ButtonText"); AZ::EntityId textId = textElem->GetId(); CreateComponent(textElem, LyShine::UiTransform2dComponentUuid); CreateComponent(textElem, LyShine::UiTextComponentUuid); AZ_Assert(UiTransform2dBus::FindFirstHandler(textId), "Transform component missing"); EBUS_EVENT_ID(textId, UiTransform2dBus, SetAnchors, UiTransform2dInterface::Anchors(0.5, 0.5, 0.5, 0.5), false, false); EBUS_EVENT_ID(textId, UiTransform2dBus, SetOffsets, UiTransform2dInterface::Offsets(0, 0, 0, 0)); EBUS_EVENT_ID(textId, UiTextBus, SetText, text); EBUS_EVENT_ID(textId, UiTextBus, SetTextAlignment, IDraw2d::HAlign::Center, IDraw2d::VAlign::Center); EBUS_EVENT_ID(textId, UiTextBus, SetColor, textColor); EBUS_EVENT_ID(textId, UiTextBus, SetFontSize, 24.0f); } return buttonElem; } //////////////////////////////////////////////////////////////////////////////////////////////////// static AZ::Entity* CreateCheckbox(const char* name, bool atRoot, AZ::EntityId parent, UiTransform2dInterface::Anchors anchors, UiTransform2dInterface::Offsets offsets, const char* text, AZ::Color baseColor, AZ::Color selectedColor, AZ::Color pressedColor, AZ::Color textColor) { AZ::Entity* checkboxElem = nullptr; { if (atRoot) { EBUS_EVENT_ID_RESULT(checkboxElem, parent, UiCanvasBus, CreateChildElement, name); } else { EBUS_EVENT_ID_RESULT(checkboxElem, parent, UiElementBus, CreateChildElement, name); } CreateComponent(checkboxElem, LyShine::UiTransform2dComponentUuid); CreateComponent(checkboxElem, LyShine::UiImageComponentUuid); CreateComponent(checkboxElem, LyShine::UiCheckboxComponentUuid); AZ_Assert(UiTransform2dBus::FindFirstHandler(checkboxElem->GetId()), "Transform2d component missing"); EBUS_EVENT_ID(checkboxElem->GetId(), UiTransform2dBus, SetAnchors, anchors, false, false); EBUS_EVENT_ID(checkboxElem->GetId(), UiTransform2dBus, SetOffsets, offsets); EBUS_EVENT_ID(checkboxElem->GetId(), UiImageBus, SetColor, baseColor); EBUS_EVENT_ID(checkboxElem->GetId(), UiInteractableStatesBus, SetStateColor, UiInteractableStatesInterface::StateHover, checkboxElem->GetId(), selectedColor); EBUS_EVENT_ID(checkboxElem->GetId(), UiInteractableStatesBus, SetStateAlpha, UiInteractableStatesInterface::StateHover, checkboxElem->GetId(), selectedColor.GetA()); ISprite* backgroundSprite = gEnv->pLyShine->LoadSprite("textures/defaults/unchecked_nohover.tif"); EBUS_EVENT_ID(checkboxElem->GetId(), UiImageBus, SetSprite, backgroundSprite); } AZ::Entity* onElem; { EBUS_EVENT_ID_RESULT(onElem, checkboxElem->GetId(), UiElementBus, CreateChildElement, "onElem"); CreateComponent(onElem, LyShine::UiTransform2dComponentUuid); CreateComponent(onElem, LyShine::UiImageComponentUuid); EBUS_EVENT_ID(onElem->GetId(), UiTransform2dBus, SetAnchors, anchors, false, false); EBUS_EVENT_ID(onElem->GetId(), UiTransform2dBus, SetOffsets, offsets); ISprite* sprite0 = gEnv->pLyShine->LoadSprite("textures/defaults/checkmark.tif"); EBUS_EVENT_ID(onElem->GetId(), UiImageBus, SetSprite, sprite0); } // Link the on and off child entities to the parent checkbox entity. EBUS_EVENT_ID(checkboxElem->GetId(), UiCheckboxBus, SetCheckedEntity, onElem->GetId()); // Trigger all InGamePostActivate EBUS_EVENT_ID(onElem->GetId(), UiInitializationBus, InGamePostActivate); EBUS_EVENT_ID(checkboxElem->GetId(), UiInitializationBus, InGamePostActivate); return checkboxElem; } //////////////////////////////////////////////////////////////////////////////////////////////////// static AZ::Entity* CreateSlider(AZ::EntityId parent) { //////////////////////////////////////////////////////////////////////////////////////////////////// AZ::Entity* sliderElem = nullptr; { EBUS_EVENT_ID_RESULT(sliderElem, parent, UiCanvasBus, CreateChildElement, "sliderElem"); CreateComponent(sliderElem, LyShine::UiTransform2dComponentUuid); CreateComponent(sliderElem, LyShine::UiSliderComponentUuid); // 500 x 50, + 100 units padding all around UiTransform2dInterface::Offsets offsets(-300.0f /*left*/, -75.0f /*top*/, 300.0f /*right*/, 75.0f /*bottom*/); EBUS_EVENT_ID(sliderElem->GetId(), UiTransform2dBus, SetOffsets, offsets); //ok //EBUS_EVENT_ID(sliderElem->GetId(), UiSliderBus, SetMinValue, -10.0f); //EBUS_EVENT_ID(sliderElem->GetId(), UiSliderBus, SetMaxValue, -5.0f); //ok EBUS_EVENT_ID(sliderElem->GetId(), UiSliderBus, SetMinValue, 5.0f); EBUS_EVENT_ID(sliderElem->GetId(), UiSliderBus, SetMaxValue, 10.0f); //ok //EBUS_EVENT_ID(sliderElem->GetId(), UiSliderBus, SetMinValue, 10.0f); //EBUS_EVENT_ID(sliderElem->GetId(), UiSliderBus, SetMaxValue, 5.0f); //ok //EBUS_EVENT_ID(sliderElem->GetId(), UiSliderBus, SetMinValue, -5.0f); //EBUS_EVENT_ID(sliderElem->GetId(), UiSliderBus, SetMaxValue, -10.0f); //EBUS_EVENT_ID(sliderElem->GetId(), UiSliderBus, SetStepValue, 0.125f); EBUS_EVENT_ID(sliderElem->GetId(), UiSliderBus, SetStepValue, 1.0f); //ok //EBUS_EVENT_ID(sliderElem->GetId(), UiTransformBus, SetZRotation, -45.0f); //EBUS_EVENT_ID(sliderElem->GetId(), UiTransformBus, SetZRotation, -135.0f); //EBUS_EVENT_ID(sliderElem->GetId(), UiTransformBus, SetZRotation, 180.0f); //EBUS_EVENT_ID(sliderElem->GetId(), UiTransformBus, SetZRotation, -90.0f); } //////////////////////////////////////////////////////////////////////////////////////////////////// AZ::Entity* sliderTrackElem = nullptr; { EBUS_EVENT_ID_RESULT(sliderTrackElem, sliderElem->GetId(), UiElementBus, CreateChildElement, "sliderTrackElem"); CreateComponent(sliderTrackElem, LyShine::UiTransform2dComponentUuid); CreateComponent(sliderTrackElem, LyShine::UiImageComponentUuid); //dark green EBUS_EVENT_ID(sliderTrackElem->GetId(), UiImageBus, SetColor, AZ::Color(0.0f, 1.0f / 3.0f, 0.0f, 1.0f)); // 500 x 50 UiTransform2dInterface::Offsets offsets(-250.0f /*left*/, -25.0f /*top*/, 250.0f /*right*/, 25.0f /*bottom*/); EBUS_EVENT_ID(sliderTrackElem->GetId(), UiTransform2dBus, SetOffsets, offsets); } //////////////////////////////////////////////////////////////////////////////////////////////////// AZ::Entity* sliderFillElem = nullptr; { EBUS_EVENT_ID_RESULT(sliderFillElem, sliderTrackElem->GetId(), UiElementBus, CreateChildElement, "sliderFillElem"); CreateComponent(sliderFillElem, LyShine::UiTransform2dComponentUuid); CreateComponent(sliderFillElem, LyShine::UiImageComponentUuid); //light green EBUS_EVENT_ID(sliderFillElem->GetId(), UiImageBus, SetColor, AZ::Color(0.0f, 2.0f / 3.0f, 0.0f, 1.0f)); // 500 x 50 UiTransform2dInterface::Offsets offsets(0.0f /*left*/, -25.0f /*top*/, 0.0f /*right*/, 25.0f /*bottom*/); EBUS_EVENT_ID(sliderFillElem->GetId(), UiTransform2dBus, SetOffsets, offsets); } //////////////////////////////////////////////////////////////////////////////////////////////////// AZ::Entity* sliderManipulatorElem = nullptr; { EBUS_EVENT_ID_RESULT(sliderManipulatorElem, sliderTrackElem->GetId(), UiElementBus, CreateChildElement, "sliderManipulatorElem"); CreateComponent(sliderManipulatorElem, LyShine::UiTransform2dComponentUuid); CreateComponent(sliderManipulatorElem, LyShine::UiImageComponentUuid); ISprite* sprite0 = gEnv->pLyShine->LoadSprite("textures/defaults/sliderManipulator.tif"); EBUS_EVENT_ID(sliderManipulatorElem->GetId(), UiImageBus, SetSprite, sprite0); // 100 x 100 UiTransform2dInterface::Offsets offsets(-50.0f /*left*/, -50.0f /*top*/, 50.0f /*right*/, 50.0f /*bottom*/); EBUS_EVENT_ID(sliderManipulatorElem->GetId(), UiTransform2dBus, SetOffsets, offsets); } //////////////////////////////////////////////////////////////////////////////////////////////////// // Link the child entities to the parent slider entity. EBUS_EVENT_ID(sliderElem->GetId(), UiSliderBus, SetTrackEntity, sliderTrackElem->GetId()); EBUS_EVENT_ID(sliderElem->GetId(), UiSliderBus, SetFillEntity, sliderFillElem->GetId()); EBUS_EVENT_ID(sliderElem->GetId(), UiSliderBus, SetManipulatorEntity, sliderManipulatorElem->GetId()); // Trigger all InGamePostActivate EBUS_EVENT_ID(sliderTrackElem->GetId(), UiInitializationBus, InGamePostActivate); EBUS_EVENT_ID(sliderFillElem->GetId(), UiInitializationBus, InGamePostActivate); EBUS_EVENT_ID(sliderManipulatorElem->GetId(), UiInitializationBus, InGamePostActivate); EBUS_EVENT_ID(sliderElem->GetId(), UiInitializationBus, InGamePostActivate); EBUS_EVENT_ID(sliderElem->GetId(), UiSliderBus, SetValue, 0.75f); return sliderElem; } //////////////////////////////////////////////////////////////////////////////////////////////////// static AZ::Entity* CreateText(const char* name, bool atRoot, AZ::EntityId parent, UiTransform2dInterface::Anchors anchors, UiTransform2dInterface::Offsets offsets, const char* text, AZ::Color textColor, IDraw2d::HAlign hAlign, IDraw2d::VAlign vAlign) { // create a text AZ::Entity* textElem = nullptr; if (atRoot) { EBUS_EVENT_ID_RESULT(textElem, parent, UiCanvasBus, CreateChildElement, name); } else { EBUS_EVENT_ID_RESULT(textElem, parent, UiElementBus, CreateChildElement, name); } AZ_Assert(textElem, "Failed to create child element for text"); AZ::EntityId textId = textElem->GetId(); CreateComponent(textElem, LyShine::UiTransform2dComponentUuid); CreateComponent(textElem, LyShine::UiTextComponentUuid); AZ_Assert(UiTransform2dBus::FindFirstHandler(textId), "Transform component missing"); EBUS_EVENT_ID(textId, UiTransform2dBus, SetAnchors, anchors, false, false); EBUS_EVENT_ID(textId, UiTransform2dBus, SetOffsets, offsets); EBUS_EVENT_ID(textId, UiTextBus, SetText, text); EBUS_EVENT_ID(textId, UiTextBus, SetTextAlignment, hAlign, vAlign); EBUS_EVENT_ID(textId, UiTextBus, SetColor, textColor); return textElem; } //////////////////////////////////////////////////////////////////////////////////////////////////// static AZ::Entity* CreateTextInput(const char* name, bool atRoot, AZ::EntityId parent, UiTransform2dInterface::Anchors anchors, UiTransform2dInterface::Offsets offsets, const char* text, const char* placeHolderText, AZ::Color baseColor, AZ::Color selectedColor, AZ::Color pressedColor, AZ::Color textColor, AZ::Color placeHolderColor) { AZ::Entity* textInputElem = nullptr; if (atRoot) { EBUS_EVENT_ID_RESULT(textInputElem, parent, UiCanvasBus, CreateChildElement, name); } else { EBUS_EVENT_ID_RESULT(textInputElem, parent, UiElementBus, CreateChildElement, name); } { AZ::EntityId textInputId = textInputElem->GetId(); // create components for text input element CreateComponent(textInputElem, LyShine::UiTransform2dComponentUuid); CreateComponent(textInputElem, LyShine::UiImageComponentUuid); CreateComponent(textInputElem, LyShine::UiTextInputComponentUuid); AZ_Assert(UiTransform2dBus::FindFirstHandler(textInputId), "Transform2d component missing"); EBUS_EVENT_ID(textInputId, UiTransform2dBus, SetAnchors, anchors, false, false); EBUS_EVENT_ID(textInputId, UiTransform2dBus, SetOffsets, offsets); EBUS_EVENT_ID(textInputId, UiImageBus, SetColor, baseColor); EBUS_EVENT_ID(textInputId, UiInteractableStatesBus, SetStateColor, UiInteractableStatesInterface::StateHover, textInputId, selectedColor); EBUS_EVENT_ID(textInputId, UiInteractableStatesBus, SetStateAlpha, UiInteractableStatesInterface::StateHover, textInputId, selectedColor.GetA()); EBUS_EVENT_ID(textInputId, UiInteractableStatesBus, SetStateColor, UiInteractableStatesInterface::StatePressed, textInputId, pressedColor); EBUS_EVENT_ID(textInputId, UiInteractableStatesBus, SetStateAlpha, UiInteractableStatesInterface::StatePressed, textInputId, pressedColor.GetA()); string pathname = "Textures/Basic/Button_Sliced_Normal.sprite"; ISprite* sprite = gEnv->pLyShine->LoadSprite(pathname); EBUS_EVENT_ID(textInputId, UiImageBus, SetSprite, sprite); EBUS_EVENT_ID(textInputId, UiImageBus, SetImageType, UiImageInterface::ImageType::Sliced); } // create child text element AZ::Entity* textElem = CreateText("Text", false, textInputElem->GetId(), UiTransform2dInterface::Anchors(0.0f, 0.0f, 1.0f, 1.0f), UiTransform2dInterface::Offsets(5.0f, 5.0f, -5.0f, -5.00f), text, textColor, IDraw2d::HAlign::Center, IDraw2d::VAlign::Center); // reduce the font size EBUS_EVENT_ID(textElem->GetId(), UiTextBus, SetFontSize, 24.0f); // now link the textInputComponent to the child text entity EBUS_EVENT_ID(textInputElem->GetId(), UiTextInputBus, SetTextEntity, textElem->GetId()); // create child placeholder text element AZ::Entity* placeHolderElem = CreateText("PlaceholderText", false, textInputElem->GetId(), UiTransform2dInterface::Anchors(0.0f, 0.0f, 1.0f, 1.0f), UiTransform2dInterface::Offsets(5.0f, 5.0f, -5.0f, -5.00f), placeHolderText, placeHolderColor, IDraw2d::HAlign::Center, IDraw2d::VAlign::Center); // reduce the font size EBUS_EVENT_ID(placeHolderElem->GetId(), UiTextBus, SetFontSize, 24.0f); // now link the textInputComponent to the child placeholder text entity EBUS_EVENT_ID(textInputElem->GetId(), UiTextInputBus, SetPlaceHolderTextEntity, placeHolderElem->GetId()); // Trigger all InGamePostActivate EBUS_EVENT_ID(textInputElem->GetId(), UiInitializationBus, InGamePostActivate); EBUS_EVENT_ID(textElem->GetId(), UiInitializationBus, InGamePostActivate); EBUS_EVENT_ID(placeHolderElem->GetId(), UiInitializationBus, InGamePostActivate); return textInputElem; } //////////////////////////////////////////////////////////////////////////////////////////////////// // Very simple test class implementing IUiCanvasActionListener // This just calls the callback passed into the constructor namespace { class ActionListener : public UiCanvasNotificationBus::Handler { public: ActionListener(AZ::EntityId canvasId, LyShine::ActionName actionName, AZStd::function fn) : m_canvasId(canvasId) , m_actionName(actionName) , m_fn(fn) { UiCanvasNotificationBus::Handler::BusConnect(m_canvasId); } ~ActionListener() { Unregister(); } void OnAction(AZ::EntityId canvasId, const LyShine::ActionName& actionName) override { if (actionName == m_actionName) { m_fn(); } } void Unregister() { if (m_canvasId.IsValid()) { UiCanvasNotificationBus::Handler::BusDisconnect(m_canvasId); } } private: AZ::EntityId m_canvasId; LyShine::ActionName m_actionName; AZStd::function m_fn; }; } static ActionListener* g_testActionListener1 = nullptr; static ActionListener* g_testActionListener2 = nullptr; //////////////////////////////////////////////////////////////////////////////////////////////////// // Gets the test canvas pointer from the ID. We do this in case the canvas has been deleted // (by exiting the game for example) static UiCanvasInterface* GetTestCanvas() { UiCanvasInterface* canvasInterface = nullptr; if (g_testCanvasId.IsValid()) { canvasInterface = UiCanvasBus::FindFirstHandler(g_testCanvasId); } return canvasInterface; } //////////////////////////////////////////////////////////////////////////////////////////////////// static void DestroyTestCanvas() { if (g_testCanvasId.IsValid()) { delete g_testActionListener1; g_testActionListener1 = nullptr; delete g_testActionListener2; g_testActionListener2 = nullptr; gEnv->pLyShine->ReleaseCanvas(g_testCanvasId, false); g_testCanvasId.SetInvalid(); } } //////////////////////////////////////////////////////////////////////////////////////////////////// static void TestCanvasCreate (IConsoleCmdArgs* Cmd) { if (gEnv->IsEditing()) { return; } const AZ::Color grey(.3f, .3f, .4f, .5f); const AZ::Color blue(.2f, .3f, 1.f, 1.f); const AZ::Color red(1.f, .1f, .1f, 1.f); const AZ::Color pink(1.f, .5f, .5f, 1.f); const AZ::Color white(1.f, 1.f, 1.f, 1.f); const AZ::Color yellow(1.f, 1.f, 0.f, 1.f); // remove the existing test canvas if it exists DestroyTestCanvas(); // test creation of canvas and some simple elements AZ::EntityId canvasEntityId = gEnv->pLyShine->CreateCanvas(); UiCanvasInterface* canvas = UiCanvasBus::FindFirstHandler(canvasEntityId); if (!canvas) { return; } g_testCanvasId = canvasEntityId; // create an image to be the menu background AZ::Entity* pauseMenuElem = canvas->CreateChildElement("Menu1"); CreateComponent(pauseMenuElem, LyShine::UiTransform2dComponentUuid); CreateComponent(pauseMenuElem, LyShine::UiImageComponentUuid); AZ::EntityId pauseMenuId = pauseMenuElem->GetId(); AZ_Assert(UiTransform2dBus::FindFirstHandler(pauseMenuId), "Transform component missing"); EBUS_EVENT_ID(pauseMenuId, UiTransform2dBus, SetAnchors, UiTransform2dInterface::Anchors(0.25, 0.25, 0.75, 0.75), false, false); EBUS_EVENT_ID(pauseMenuId, UiTransform2dBus, SetOffsets, UiTransform2dInterface::Offsets(0, 0, 0, 0)); EBUS_EVENT_ID(pauseMenuId, UiImageBus, SetColor, grey); // create a title, centered at top of menu CreateText("Heading", false, pauseMenuId, UiTransform2dInterface::Anchors(0.5f, 0.0f, 0.5f, 0.0f), UiTransform2dInterface::Offsets(0, 20, 0, 50), "Pause Menu", yellow, IDraw2d::HAlign::Center, IDraw2d::VAlign::Top); // create a test text at left top CreateText("TopLeftText", false, pauseMenuId, UiTransform2dInterface::Anchors(0.0f, 0.0f, 0.0f, 0.0f), UiTransform2dInterface::Offsets(0, 0, 50, 50), "LT", yellow, IDraw2d::HAlign::Left, IDraw2d::VAlign::Top); // create a test text at left center CreateText("CenterLeftText", false, pauseMenuId, UiTransform2dInterface::Anchors(0.0f, 0.5f, 0.0f, 0.5f), UiTransform2dInterface::Offsets(0, -25, 50, 25), "LC", yellow, IDraw2d::HAlign::Left, IDraw2d::VAlign::Center); // create a test text at left bottom CreateText("BottomLeftText", false, pauseMenuId, UiTransform2dInterface::Anchors(0.0f, 1.0f, 0.0f, 1.0f), UiTransform2dInterface::Offsets(0, -50, 50, 0), "LB", yellow, IDraw2d::HAlign::Left, IDraw2d::VAlign::Bottom); // create a test text at center bottom CreateText("BottomCenterText", false, pauseMenuId, UiTransform2dInterface::Anchors(0.5f, 1.0f, 0.5f, 1.0f), UiTransform2dInterface::Offsets(-25, -50, 25, 0), "CB", yellow, IDraw2d::HAlign::Center, IDraw2d::VAlign::Bottom); // create a test text at center bottom CreateText("CenterRightText", false, pauseMenuId, UiTransform2dInterface::Anchors(1.0f, 1.0f, 1.0f, 1.0f), UiTransform2dInterface::Offsets(-50, -50, 0, 0), "CR", yellow, IDraw2d::HAlign::Right, IDraw2d::VAlign::Bottom); // Create a "Show Image" button AZ::Entity* showImageButtonElem = CreateButton("ShowImage", false, pauseMenuId, UiTransform2dInterface::Anchors(0.5, 0.5, 0.5, 0.5), UiTransform2dInterface::Offsets(-120.0f, -25.0f, 120.0f, 25.0f), "Show Image", blue, pink, red, white); // Create a "Hide Image" button CreateButton("HideImage", false, pauseMenuId, UiTransform2dInterface::Anchors(0.5f, 1.0f, 0.5f, 1.0f), UiTransform2dInterface::Offsets(-120.0f, -100.0f, 120.0f, -50.0f), "Hide Image", blue, pink, red, white); // Create a "Enter name" text input element AZ::Color colGreenYellow(0.678f, 1.000f, 0.184f, 1.0f); AZ::Entity* textInputElem = CreateTextInput("EnterName", false, pauseMenuId, UiTransform2dInterface::Anchors(0.5f, 0.0f, 0.5f, 0.0f), UiTransform2dInterface::Offsets(-120.0f, 70.0f, 120.0f, 120.0f), "", "Enter Name", blue, pink, red, white, colGreenYellow); // Create an image that these buttons will show/hide // create an image to be the menu background AZ::Entity* testImageElem = canvas->CreateChildElement("TestImage"); CreateComponent(testImageElem, LyShine::UiTransform2dComponentUuid); CreateComponent(testImageElem, LyShine::UiImageComponentUuid); EBUS_EVENT_ID(testImageElem->GetId(), UiTransform2dBus, SetAnchors, UiTransform2dInterface::Anchors(0.78f, 0.25f, 0.95f, 0.75f), false, false); EBUS_EVENT_ID(testImageElem->GetId(), UiTransform2dBus, SetOffsets, UiTransform2dInterface::Offsets(0.0f, 0.0f, 0.0f, 0.0f)); EBUS_EVENT_ID(testImageElem->GetId(), UiImageBus, SetColor, yellow); // create some text items that the textInputItem will edit, AZ::Color colGreen(0.000f, 0.502f, 0.000f, 1.0f); AZ::Entity* changedTextElem = CreateText("ChangedText", true, canvasEntityId, UiTransform2dInterface::Anchors(0.8f, 0.30f, 0.93f, 0.30f), UiTransform2dInterface::Offsets(0.0f, 0.0f, 0.0f, 50.0f), "Changed Text", colGreen, IDraw2d::HAlign::Center, IDraw2d::VAlign::Top); AZ::Entity* editedTextElem = CreateText("EditedText", true, canvasEntityId, UiTransform2dInterface::Anchors(0.8f, 0.40f, 0.93f, 0.40f), UiTransform2dInterface::Offsets(0.0f, 0.0f, 0.0f, 50.0f), "Edited Text", colGreen, IDraw2d::HAlign::Center, IDraw2d::VAlign::Top); AZ::Entity* enteredTextElem = CreateText("EnteredText", true, canvasEntityId, UiTransform2dInterface::Anchors(0.8f, 0.50f, 0.93f, 0.50f), UiTransform2dInterface::Offsets(0.0f, 0.0f, 0.0f, 50.0f), "Entered Text", colGreen, IDraw2d::HAlign::Center, IDraw2d::VAlign::Top); // now setup on-click callbacks to hide and show the menus, use the various ways of doing it // First button uses a simple callback AZ::Entity* buttonElem = nullptr; EBUS_EVENT_ID_RESULT(buttonElem, pauseMenuId, UiElementBus, FindDescendantByName, "ShowImage"); auto setEnabledCallbackFn = [testImageElem](AZ::EntityId clickedEntityId, AZ::Vector2 point) { EBUS_EVENT_ID(testImageElem->GetId(), UiElementBus, SetIsEnabled, true); }; EBUS_EVENT_ID(buttonElem->GetId(), UiButtonBus, SetOnClickCallback, setEnabledCallbackFn); // Second button uses an ActionListener EBUS_EVENT_ID_RESULT(buttonElem, pauseMenuId, UiElementBus, FindDescendantByName, "HideImage"); LyShine::ActionName actionName1("ShowImage"); auto setDisabledActionFn = [testImageElem](void) { EBUS_EVENT_ID(testImageElem->GetId(), UiElementBus, SetIsEnabled, false); }; g_testActionListener1 = new ActionListener(canvasEntityId, actionName1, setDisabledActionFn); EBUS_EVENT_ID(buttonElem->GetId(), UiButtonBus, SetOnClickActionName, actionName1); // Setup callbacks for the text input field auto setChangedTextFn = [changedTextElem](AZ::EntityId textInputEntityId, LyShine::StringType textString) { EBUS_EVENT_ID(changedTextElem->GetId(), UiTextBus, SetText, textString); }; auto setEditedTextFn = [editedTextElem](AZ::EntityId textInputEntityId, LyShine::StringType textString) { EBUS_EVENT_ID(editedTextElem->GetId(), UiTextBus, SetText, textString); }; auto setEnteredTextFn = [enteredTextElem](AZ::EntityId textInputEntityId, LyShine::StringType textString) { EBUS_EVENT_ID(enteredTextElem->GetId(), UiTextBus, SetText, textString); }; EBUS_EVENT_ID(textInputElem->GetId(), UiTextInputBus, SetOnChangeCallback, setChangedTextFn); EBUS_EVENT_ID(textInputElem->GetId(), UiTextInputBus, SetOnEndEditCallback, setEditedTextFn); EBUS_EVENT_ID(textInputElem->GetId(), UiTextInputBus, SetOnEnterCallback, setEnteredTextFn); // test clone feature by cloning the whole pause menu AZ::Entity* clonedMenuElem = nullptr; EBUS_EVENT_ID_RESULT(clonedMenuElem, canvasEntityId, UiCanvasBus, CloneElement, pauseMenuElem, nullptr); AZ::EntityId clonedMenuId = clonedMenuElem->GetId(); EBUS_EVENT_ID(clonedMenuId, UiTransform2dBus, SetAnchors, UiTransform2dInterface::Anchors(0.0f, 0.25f, 0.23f, 0.75f), false, false); EBUS_EVENT_ID(clonedMenuId, UiImageBus, SetColor, grey); // The clone will copy the action name on the Hide button but not the callback on the // Show button, so set that up on the cloned menu buttonElem = nullptr; EBUS_EVENT_ID_RESULT(buttonElem, clonedMenuId, UiElementBus, FindDescendantByName, "ShowImage"); EBUS_EVENT_ID(buttonElem->GetId(), UiButtonBus, SetOnClickCallback, setEnabledCallbackFn); //! test GUIDs LyShine::ElementId id = 0; EBUS_EVENT_ID_RESULT(id, buttonElem->GetId(), UiElementBus, GetElementId); AZ::Entity* foundElem = canvas->FindElementById(id); AZ_Assert(foundElem == buttonElem, "FindElementById failed"); //! test find by name EBUS_EVENT_ID_RESULT(foundElem, canvasEntityId, UiCanvasBus, FindElementByName, "ChangedText"); AZ_Assert(foundElem == changedTextElem, "FindElementByName failed"); LyShine::EntityArray foundElements; EBUS_EVENT_ID(canvasEntityId, UiCanvasBus, FindElementsByName, "ShowImage", foundElements); AZ_Assert(foundElements.size() == 2, "FindElementsByName failed, should find 2 elements"); EBUS_EVENT_ID_RESULT(foundElem, canvasEntityId, UiCanvasBus, FindElementByHierarchicalName, "Menu1/ShowImage"); AZ_Assert(foundElem == showImageButtonElem, "FindElementByHierarchicalName failed to find Menu1/ShowImage"); EBUS_EVENT_ID_RESULT(foundElem, canvasEntityId, UiCanvasBus, FindElementByHierarchicalName, "/Menu1/ShowImage"); AZ_Assert(foundElem == showImageButtonElem, "FindElementByHierarchicalName failed to find /Menu1/ShowImage"); EBUS_EVENT_ID_RESULT(foundElem, canvasEntityId, UiCanvasBus, FindElementByHierarchicalName, "Menu1/ShowImage/ButtonText"); AZ_Assert(foundElem, "FindElementByHierarchicalName failed to find Menu1/ShowImage/ButtonText"); EBUS_EVENT_ID_RESULT(foundElem, canvasEntityId, UiCanvasBus, FindElementByHierarchicalName, "Menu1/ShowImage/ButtonText/"); AZ_Assert(!foundElem, "FindElementByHierarchicalName succeeded with bad path"); EBUS_EVENT_ID_RESULT(foundElem, canvasEntityId, UiCanvasBus, FindElementByHierarchicalName, "ShowImage"); AZ_Assert(!foundElem, "FindElementByHierarchicalName found ShowImage when it should not"); } static void TestCanvasRemove(IConsoleCmdArgs* Cmd) { if (gEnv->IsEditing()) { return; } // remove the existing test canvas if it exists DestroyTestCanvas(); } //////////////////////////////////////////////////////////////////////////////////////////////////// // PUBLIC STATIC MEMBER FUNCTIONS //////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// void LyShineDebug::Initialize() { #ifndef EXCLUDE_DOCUMENTATION_PURPOSE DefineConstIntCVar3("r_DebugUIDraw2dFont", CV_r_DebugUIDraw2dFont, 0, VF_CHEAT, "0=off, 1=display various features of the UI font rendering to verify function and to document usage"); DefineConstIntCVar3("r_DebugUIDraw2dImage", CV_r_DebugUIDraw2dImage, 0, VF_CHEAT, "0=off, 1=display various features of the UI image rendering to verify function and to document usage"); DefineConstIntCVar3("r_DebugUIDraw2dLine", CV_r_DebugUIDraw2dLine, 0, VF_CHEAT, "0=off, 1=display various features of the UI line rendering to verify function and to document usage"); DefineConstIntCVar3("r_DebugUIDraw2dDefer", CV_r_DebugUIDraw2dDefer, 0, VF_CHEAT, "0=draws 2D immediately in debug tests, 1=defers calls in debug tests"); REGISTER_COMMAND("ui_TestCanvasCreate", &TestCanvasCreate, VF_NULL, ""); REGISTER_COMMAND("ui_TestCanvasRemove", &TestCanvasRemove, VF_NULL, ""); #endif // EXCLUDE_DOCUMENTATION_PURPOSE } //////////////////////////////////////////////////////////////////////////////////////////////////// void LyShineDebug::Reset() { // remove the existing test canvas if it exists DestroyTestCanvas(); } //////////////////////////////////////////////////////////////////////////////////////////////////// void LyShineDebug::RenderDebug() { #if !defined(_RELEASE) #ifndef EXCLUDE_DOCUMENTATION_PURPOSE if (!Draw2dHelper::GetDraw2d()) { return; } g_deferDrawsToEndOfFrame = (CV_r_DebugUIDraw2dDefer) ? true : false; if (CV_r_DebugUIDraw2dFont) { switch (CV_r_DebugUIDraw2dFont) { case 1: // test font sizes (default font, effect 0) DebugDraw2dFontSizes(0, 0, "default"); break; case 2: // test font sizes (default font, effect 1) DebugDraw2dFontSizes(0, 1, "default"); break; case 3: // test font alignment DebugDraw2dFontAlignment(); break; case 4: // test font color and opacity DebugDraw2dFontColorAndOpacity(); break; } } if (CV_r_DebugUIDraw2dImage) { switch (CV_r_DebugUIDraw2dImage) { case 1: // test image rotation DebugDraw2dImageRotations(); break; case 2: // test image color DebugDraw2dImageColor(); break; case 3: // test image blend mode DebugDraw2dImageBlendMode(); break; case 4: // test image UVs DebugDraw2dImageUVs(); break; case 5: // test image pixel rounding DebugDraw2dImagePixelRounding(); break; } } if (CV_r_DebugUIDraw2dLine) { switch (CV_r_DebugUIDraw2dLine) { case 1: // test basic draw line DebugDraw2dLineBasic(); break; } } #endif #endif }