Post by scalion on Dec 3, 2021 11:09:22 GMT 1
Hi all,
This new functionnality is very usefull if you want for example load d2bitmap and conserve only a part of this bitmap or if you want produce a new d2bitmap using a d2 drawing.
Unfortunaly the actual Direct2D Library use pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE with memory DC target.
You can modify your Direct2D library and recompile with pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED.
The problem is you can't use D2D1_ALPHA_MODE_IGNORE the next time...
Here is how to work around this problem (then dont need 2 versions of Direct2D) :
' Author : Nicolas Rey - 03/12/2021
' purpose : The new feature of D2getRT with a Memory DC
' usefull to create D2Bitmap using D2 functions !
$Library "Direct2D"
Type BITMAPINFOHEADER
- DWord biSize
- Long biWidth
- Long biHeight
- Word biPlanes
- Word biBitCount
- DWord biCompression
- DWord biSizeImage
- Long biXPelsPerMeter
- Long biYPelsPerMeter
- DWord biClrUsed
- DWord biClrImportant
EndType
FullW 1
Global Object Win1RT, dcRT, bmp
Global Long bitmapdc, bmpAdr, bmpW = 200, bmpH = 200, bmpalphaAdr
Global Long hdc, bitmapdc
// Create the memory DC
hdc = CreateCompatibleDC(_DC(1))
// Create a DIB bitmap
SuperBitmap bitmapdc, bmpAdr, bmpW, bmpH
// Link this bitmap with the memory DC
Void SelectObject(hdc, bitmapdc)
// Create a memory buffer to produce a alpha channel by comparing 2 drawing later
bmpalphaAdr = mAlloc(bmpW * bmpH * 4)
// Create the Render Target for the memory DC
Set dcRT = D2GetRT(hdc, bmpW, bmpH)
// Draw something 2 times with different backroung color for computing alpha chanel
Global Long i, d
For i = 1 To 2
If i = 1 // Firt pass with black background
D2BeginDraw dcRT, D2C_Black
Else // Second with white background
D2BeginDraw dcRT, D2C_White
EndIf
Randomize 1.17
D2DefLine , 0
While Rnd > 0.02
d = Rnd * 360
D2PCircle 100, 100, Rnd * 100, d, d + 90, 0, D2Brush(&H88000000 | Int(Rnd * &hFFFFFF))
Wend
D2SetFont "arial", 35
D2DrawText 0, 0, 200, 200, "Created"#13#10"with DC"#13#10"Render Target", D2T_CENTER | D2T_PARCENTER, , D2Brush(D2C_Black)
D2DrawText 2, -2, 202, 198, "Created"#13#10"with DC"#13#10"Render Target", D2T_CENTER | D2T_PARCENTER, , D2Brush(D2C_Orange)
D2EndDraw
If i = 1 // Store the drawing with black background
BMove bmpAdr, bmpalphaAdr, bmpW * bmpH * 4
EndIf
Next i
' Compare White and black background to see where alpha must be set
' and write the result in DIB (bmpAdr)
For i = bmpAdr To bmpAdr + bmpW * bmpH * 4 - 4 Step 4
Poke i + 3 , 255 - Abs(Peek(i) - Peek(i - bmpAdr + bmpalphaAdr))
Next i
// We dont need the memory DC and buffer anymore
Void DeleteDC(hdc)
Void mFree(bmpalphaAdr)
// Now show the result using a window RT
Set Win1RT = D2GetRT(Me)
D2SetRT Win1RT
// Create the bitmap from BitmapDC without ignoring alpha channel
Set bmp = D2Bitmap(bitmapdc, WICBitmapUseAlpha)
// Bitmap of DC not usefull anymore, free it
FreeBmp bitmapdc
// A loop with some graphics using the bitmap created
Do
Affichage
PeekEvent
Loop Until Me Is Nothing
Proc Affichage
Local Double t
Local Long i
D2BeginDraw Win1RT, D2C_Beige
D2DefLine , 3
For i = 1 To 20
t = Frac(i / 20 + Timer / 20) ^ (1 / 2)
D2ForeColor = ARGB(254 - t * 253, 0, 0, 0)
D2PCircle _X / 2, _Y / 2, t * 500, 360 * i / 20, 360 * i / 20 + 20 , 0, D2Brush(ARGB(254 - t * 253, Mod(i * 57, 255), Mod(i * 33, 255), i * 25))
Next i
D2Transform D2TF_ROTATE, Frac(Timer / 4) * 360, MouseX + 100, MouseY + 100
D2Put MouseX, MouseY, bmp
Local Double s = 1 + Sin(Frac(Timer / 2) * 2 * PI) / 4
D2Transform D2TF_SCALE, s, 2 - s, MouseX - 100, MouseY - 100
D2TransformAdd D2TF_ROTATE, Frac(0.5 + Timer / 8) * -360, MouseX - 100, MouseY - 100
D2Put MouseX - 200, MouseY - 200, bmp
D2Transform
D2Put Abs(1 - Frac(Timer / 25) * 2) * (_X - 200), _Y - 200 - Abs(Cos(Frac(Timer) * 2 * PI)) * 50, bmp
D2Put Abs(1 - Frac(0.5 + Timer / 20) * 2) * (_X - 200), _Y - 200 - Abs(Cos(Frac(Timer / 1.5) * 2 * PI)) * 150, bmp
D2EndDraw
EndProc
Sub Win_1_ReSize
D2ResizeRT Win1RT, Max(1, _X), Max(1, _Y)
EndSub
Proc SuperBitmap(ByRef Bitmap%, ByRef Adr%, width%, height%)
Local BIH As BITMAPINFOHEADER
BIH.biSize = SizeOf(BIH)
BIH.biPlanes = 1
BIH.biBitCount = 32
BIH.biWidth = width
BIH.biHeight = height
Bitmap = CreateDIBSection(Null, *BIH, DIB_RGB_COLORS, V:Adr, Null, 0)
If Adr = 0
Message "Saperlipopette !"
EndIf
EndProc