Should work with x86 and x64.
Code: Select all
'coded by UEZ build 2018-03-24
'inspirated by https://lab.hakim.se/hypnos/
#Include "fbgfx.bi"
#Ifdef __FB_64BIT__
#Inclib "gdiplus"
#Include once "win/gdiplus-c.bi"
#Else
#Include once "win/gdiplus.bi"
using gdiplus
#Endif
Using FB
Dim Shared As Any Ptr hCanvas, hPen, hBrush
Declare Sub _Paint()
Declare Sub PaintLayer(iPos As Ushort, bMask As Ubyte = 0, hB As Any Ptr = hBrush)
Declare Sub PaintLayer2(iPos As Ushort)
'init GDIPlus
Dim Shared gdipToken As ULONG_PTR
Dim Shared GDIp As GdiplusStartupInput
GDIp.GdiplusVersion = 1
If GdiplusStartup(@gdipToken, @GDIp, NULL) <> 0 Then End
'--------------------------------------------------------
Const As Ushort iW = 600, iH = 600, iWh = iW \ 2, iHh = iH \ 2
ScreenControl SET_DRIVER_NAME, "GDI"
ScreenRes iW, iH, 32, 1, GFX_HIGH_PRIORITY Or GFX_NO_SWITCH
Dim As String sTitle = "GDI+ Impossible Possible"
WindowTitle sTitle
'center windows by adding the taskbar to the calculation
Dim as Integer iDW, iDH
ScreenControl GET_DESKTOP_SIZE, iDW, iDH
Dim tWorkingArea As RECT
SystemParametersInfo(SPI_GETWORKAREA, null, @tWorkingArea, null)
ScreenControl SET_WINDOW_POS, (iDW - iW) \ 2, _
((tWorkingArea.Bottom - iH) - (iDH - tWorkingArea.Bottom)) \ 2
'init GDI / GDI+ canvas, pens, brushes, etc. for drawing
Dim as HWND hHWND
ScreenControl(FB.GET_WINDOW_HANDLE, Cast(Integer, hHWND))
Dim As Any Ptr hDC = GetDC(hHWND), _
hHBitmap = CreateCompatibleBitmap(hDC, iW, iH), _
hDC_backbuffer = CreateCompatibleDC(hDC), hObjOld
hObjOld = SelectObject(hDC_backbuffer, hHBitmap)
GdipCreateFromHDC(hDC_backbuffer, @hCanvas)
GdipGraphicsClear(hCanvas, &hFFFFFFFF)
GdipSetSmoothingMode(hCanvas, SmoothingModeAntiAlias)
GdipSetPixelOffsetMode(hCanvas, PixelOffsetModeHalf)
GdipCreatePen1(&hC0000000, 2, 2, @hPen)
GdipCreateSolidFill(&hD0FFFFFF, @hBrush)
Dim Shared As Any Ptr hBitmap, hGfx, hTexture
Type tagRects
x As Single
y As Single
a As Single
End Type
Const As Single fPi = Acos(-1), f2Pi = 2 * fPi
Dim Shared As Ushort iQuantity
iQuantity = 180
Dim Shared As tagRects tRect(iQuantity)
Dim Shared As Single fRadius, fSize, fOverlap
fRadius = Min(iW, iH) * 0.5
fSize = fRadius * 0.25
fOverlap = iQuantity * 0.1
Dim As Ushort i
For i = 0 To iQuantity - 1
tRect(i).x = iWh + Sin(i / iQuantity * f2Pi) * (fRadius - fSize)
tRect(i).y = iHh + Cos(i / iQuantity * f2Pi) * (fRadius - fSize)
tRect(i).a = i Shl 1
Next
GdipCreateBitmapFromScan0(iW, iH, 0, PixelFormat32bppARGB, 0, @hBitmap)
GdipGetImageGraphicsContext(hBitmap, @hGfx)
GdipSetPixelOffsetMode(hGfx, 4)
GdipSetSmoothingMode(hGfx, SmoothingModeAntiAlias)
Do
GdipGraphicsClear(hCanvas, &hFFFFFFFF)
_Paint()
BitBlt(hDC, 0, 0, iW, iH, hDC_backbuffer, 0, 0, SRCCOPY)
Sleep(10, 1)
Loop Until Len(Inkey())
'release resources
GdipDeleteGraphics(hGfx)
GdipDisposeImage(hBitmap)
SelectObject(hDC_backbuffer, hObjOld)
DeleteDC(hDC_backbuffer)
ReleaseDC(hHWND, hDC)
DeleteObject(hHBitmap)
GdipDeleteGraphics(hCanvas)
GdipDeletePen(hPen)
GdipDeleteBrush(hBrush)
GdiplusShutdown(gdipToken)
Sub _Paint()
Dim i As Short
For i = iQuantity - 1 To 0 Step - 1
tRect(i).a += 1.25
PaintLayer(i)
Next
GdipGraphicsClear(hGfx, 0)
For i = iQuantity - 1 To iQuantity - fOverlap Step - 1
PaintLayer2(i)
Next
GdipCreateTexture(hBitmap, 0, @hTexture)
GdipRotateTextureTransform(hTexture, -tRect(0).a, 0)
GdipTranslateTextureTransform(hTexture, -tRect(0).x, -tRect(0).y, 0)
PaintLayer(0, 1, hTexture)
GdipDeleteBrush(hTexture)
End Sub
Sub PaintLayer(iPos As Ushort, bMask As Ubyte = 0, hB As Any Ptr = hBrush)
Dim As Single size, size2
size = fSize + Iif(bMask, 10, 0)
size2 = size / 2
GdipTranslateWorldTransform(hCanvas, tRect(iPos).x, tRect(iPos).y, 0)
GdipRotateWorldTransform(hCanvas, tRect(iPos).a, 0)
If bMask = 0 Then
GdipDrawRectangle(hCanvas, hPen, -size2, -size2, size, size)
End If
GdipFillRectangle(hCanvas, hB, -size2, -size2, size, size)
GdipResetWorldTransform(hCanvas)
End Sub
Sub PaintLayer2(iPos As Ushort)
Dim As Single size, size2
size = fSize
size2 = size / 2
GdipTranslateWorldTransform(hGfx, tRect(iPos).x, tRect(iPos).y, 0)
GdipRotateWorldTransform(hGfx, tRect(iPos).a, 0)
GdipDrawRectangle(hGfx, hPen, -size2, -size2, size, size)
GdipFillRectangle(hGfx, hBrush, -size2, -size2, size, size)
GdipResetWorldTransform(hGfx)
End Sub

If you know a way to use FB native gfx commands only, please post it.
Edit1: changed formula to create angle