int32 FSlateTextLayout::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { const FSlateRect ClippingRect = AllottedGeometry.GetClippingRect().IntersectionWith(MyClippingRect); const ESlateDrawEffect::Type DrawEffects = bParentEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect; static bool ShowDebug = false; FLinearColor BlockHue( 0, 1.0f, 1.0f, 0.5 ); int32 HighestLayerId = LayerId; for (const FTextLayout::FLineView& LineView : LineViews) { // Is this line visible? const FSlateRect LineViewRect(AllottedGeometry.AbsolutePosition + LineView.Offset, AllottedGeometry.AbsolutePosition + LineView.Offset + LineView.Size); const FSlateRect VisibleLineView = ClippingRect.IntersectionWith(LineViewRect); if (VisibleLineView.IsEmpty()) { continue; } // Render any underlays for this line const int32 HighestUnderlayLayerId = OnPaintHighlights( Args, LineView, LineView.UnderlayHighlights, DefaultTextStyle, AllottedGeometry, ClippingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled ); const int32 BlockDebugLayer = HighestUnderlayLayerId; const int32 TextLayer = BlockDebugLayer + 1; int32 HighestBlockLayerId = TextLayer; // Render every block for this line for (const TSharedRef< ILayoutBlock >& Block : LineView.Blocks) { if ( ShowDebug ) { BlockHue.R += 50.0f; // The block size and offset values are pre-scaled, so we need to account for that when converting the block offsets into paint geometry const float InverseScale = Inverse(AllottedGeometry.Scale); FSlateDrawElement::MakeBox( OutDrawElements, BlockDebugLayer, AllottedGeometry.ToPaintGeometry(TransformVector(InverseScale, Block->GetSize()), FSlateLayoutTransform(TransformPoint(InverseScale, Block->GetLocationOffset()))), &DefaultTextStyle.HighlightShape, ClippingRect, DrawEffects, InWidgetStyle.GetColorAndOpacityTint() * BlockHue.HSVToLinearRGB() ); } const TSharedRef< ISlateRun > Run = StaticCastSharedRef< ISlateRun >( Block->GetRun() ); int32 HighestRunLayerId = TextLayer; const TSharedPtr< ISlateRunRenderer > RunRenderer = StaticCastSharedPtr< ISlateRunRenderer >( Block->GetRenderer() ); if ( RunRenderer.IsValid() ) { HighestRunLayerId = RunRenderer->OnPaint( Args, LineView, Run, Block, DefaultTextStyle, AllottedGeometry, ClippingRect, OutDrawElements, TextLayer, InWidgetStyle, bParentEnabled ); } else { HighestRunLayerId = Run->OnPaint( Args, LineView, Block, DefaultTextStyle, AllottedGeometry, ClippingRect, OutDrawElements, TextLayer, InWidgetStyle, bParentEnabled ); } HighestBlockLayerId = FMath::Max( HighestBlockLayerId, HighestRunLayerId ); } // Render any overlays for this line const int32 HighestOverlayLayerId = OnPaintHighlights( Args, LineView, LineView.OverlayHighlights, DefaultTextStyle, AllottedGeometry, ClippingRect, OutDrawElements, HighestBlockLayerId, InWidgetStyle, bParentEnabled ); HighestLayerId = FMath::Max( HighestLayerId, HighestOverlayLayerId ); } return HighestLayerId; }
// draw title void ShellTitle::Render(unsigned int aId, float aTime, const Transform2 &aTransform) { //#define USE_TITLE_VERTEX_ARRAY #ifdef USE_TITLE_VERTEX_ARRAY static Vector2 vertexarray[32768]; static unsigned int colorarray[32768]; Vector2 *vertexptr = vertexarray; unsigned int *colorptr = colorarray; #else glBegin(GL_QUADS); #endif // draw title bar for (int row = 0; row < SDL_arraysize(titlemap); ++row) { float y0 = titley + row * titleh, y1 = y0 + titleh; #ifdef USE_TITLE_VERTEX_ARRAY unsigned int color = (xs_RoundToInt(255*baralpha[row]) << 24) | 0x00505050; *colorptr++ = color; *colorptr++ = color; *colorptr++ = color; *colorptr++ = color; *vertexptr++ = Vector2(0, y0); *vertexptr++ = Vector2(640, y0); *vertexptr++ = Vector2(640, y1); *vertexptr++ = Vector2(0, y1); #else glColor4f(0.3f, 0.3f, 0.3f, baralpha[row]); glVertex2f(0, y0); glVertex2f(640, y0); glVertex2f(640, y1); glVertex2f(0, y1); #endif } // draw title body unsigned short *titlefillptr = titlefill; #if 1 #ifdef USE_TITLE_MIRROR_WATER_EFFECT // starting mirror properties float mirror_y0 = MirrorWaveY(titley - titleh); float mirror_d0 = MirrorWaveX(mirror_y0); float mirror_a0 = mirroralphastart + mirroralphadelta * mirror_y0; #endif for (int row = -1; row < (int)SDL_arraysize(titlemap) + 1; ++row) { float y = titley + row * titleh; #ifdef USE_TITLE_MIRROR_WATER_EFFECT // row mirror properties float mirror_y1 = MirrorWaveY(y + titleh); float mirror_yd = (mirror_y1 - mirror_y0) / titleh; float mirror_d1 = MirrorWaveX(mirror_y1); float mirror_dd = (mirror_d1 - mirror_d0) / titleh; float mirror_a1 = mirroralphastart + mirroralphadelta * mirror_y1; float mirror_ad = (mirror_a1 - mirror_a0) / titleh; #endif for (int col = -1; col < (int)SDL_arraysize(titlemap[0]); ++col) { float x = titlex + col * titlew; if (*titlefillptr != 0) { int phase = *titlefillptr >> 9; int fill = *titlefillptr & 0x1FF; // get block color float R, G, B; float h = BlockHue(col, row); bool border = (fill & ~(1<<4)) != 0; HSV2RGB(h + phase * 0.5f + border * 0.5f, 1.0f, 1.0f - 0.25f * border, R, G, B); // for each block... for (int i = 0; i < 9; ++i) { // if the block is filled if (fill & (1 << i)) { // block borders float x0 = x + block[i][0][0]; float x1 = x + block[i][0][1]; float y0 = y + block[i][1][0]; float y1 = y + block[i][1][1]; // upright #ifdef USE_TITLE_VERTEX_ARRAY unsigned int color = 0xFF000000 | (xs_RoundToInt(B * 255) << 16) | (xs_RoundToInt(G * 255) << 8) | (xs_RoundToInt(R * 255) ); *colorptr++ = color; *colorptr++ = color; *colorptr++ = color; *colorptr++ = color; *vertexptr++ = Vector2(x0, y0); *vertexptr++ = Vector2(x1, y0); *vertexptr++ = Vector2(x1, y1); *vertexptr++ = Vector2(x0, y1); #else glColor4f(R, G, B, 1.0f); glVertex2f(x0, y0); glVertex2f(x1, y0); glVertex2f(x1, y1); glVertex2f(x0, y1); #endif #ifdef USE_TITLE_MIRROR_WATER_EFFECT if (mirror_a0 > 0.0f || mirror_a1 > 0.0f) { // mirrored float m0 = y0 - y; float m1 = y1 - y; float a0 = std::max(mirror_a0 + mirror_ad * m0, 0.0f); float a1 = std::max(mirror_a0 + mirror_ad * m1, 0.0f); float dx0 = mirror_d0 + mirror_dd * m0; float dx1 = mirror_d0 + mirror_dd * m1; float yy0 = mirror_y0 + mirror_yd * m0; float yy1 = mirror_y0 + mirror_yd * m1; #ifdef USE_TITLE_VERTEX_ARRAY color &= 0x00FFFFFF; color |= xs_RoundToInt(a1 * a1 * 255) << 24; *colorptr++ = color; *colorptr++ = color; *vertexptr++ = Vector2(x0 + dx1, yy1); *vertexptr++ = Vector2(x1 + dx1, yy1); color &= 0x00FFFFFF; color |= xs_RoundToInt(a0 * a0 * 255) << 24; *colorptr++ = color; *colorptr++ = color; *vertexptr++ = Vector2(x1 + dx0, yy0); *vertexptr++ = Vector2(x0 + dx0, yy0); #else glColor4f(R, G, B, a1 * a1); glVertex2f(x0 + dx1, yy1); glVertex2f(x1 + dx1, yy1); glColor4f(R, G, B, a0 * a0); glVertex2f(x1 + dx0, yy0); glVertex2f(x0 + dx0, yy0); #endif } #endif } } } ++titlefillptr; } #ifdef USE_TITLE_MIRROR_WATER_EFFECT // mirror shift row mirror_y0 = mirror_y1; mirror_d0 = mirror_d1; mirror_a0 = mirror_a1; #endif }