|
Post by Roger Cabo on Dec 29, 2023 20:31:03 GMT 1
Hi everyone,
I like to create a DC compatible bitmap and write into the bitmap by {adrOfDIP%} = anycolor% Then to use D2PUT x,y, myBMP to display.
The bitmap should be 32 bit per pixel and have any x,y size until 4K - UHD I thought about:
Type BITMAPINFOHEADER biSize As DWord biWidth As Long biHeight As Long biPlanes As Word biBitCount As Word biCompression As DWord biSizeImage As DWord biXPelsPerMeter As Long biYPelsPerMeter As Long biClrUsed As DWord biClrImportant As DWord End Type
Type BITMAPINFO bmh As BITMAPINFOHEADER End Type
Global bminfo As BITMAPINFO
bminfo.bmh.biSize = SizeOf(bminfo.bmh) bminfo.bmh.biWidth = size_x bminfo.bmh.biHeight = size_y bminfo.bmh.biPlanes = 1 bminfo.bmh.biBitCount = 32 ' biCompression, biSizeImage, biXPelsPerMeter, biYPelsPerMeter, biClrUsed, und biClrImportant können auf 0 gesetzt oder unverändert gelassen werden
Dim BmpAdr As Long Global hDib As Long = CreateDIBSection(Null, bminfo, DIB_RGB_COLORS, BmpAdr, Null, 0)
But how can I use it with D2Put, and is there perhaps any better way?
|
|
|
Post by scalion on Jan 1, 2024 12:44:12 GMT 1
Happy new year ! But how can I use it with D2Put, and is there perhaps any better way?
You said "D2PUT x,y, myBMP to display", and that's work. What you want to do ?
Just write : Global Object myBMP
Set myBMP = D2Bitmap(hDib, 0)
|
|
|
Post by Roger Cabo on Jan 1, 2024 21:35:10 GMT 1
$Library "gfawinx" $Library "UpdateRT" $Library "direct2d" // UpdateRuntime ' Patches GfaWin23.Ocx
OpenW 1, 0, 0, _X, _Y, ~15 Global Object Win1RT Set Win1RT = D2GetRT(Win_1.hWnd) Set Me = Win_1 // ...............................
// Create a bitmap in the PC Ram Type BITMAPINFOHEADER - DWord biSize - Long biWidth, biHeight - Word biPlanes, biBitCount - DWord biCompression, biSizeImage - Long biXPelsPerMeter, biYPelsPerMeter - DWord biClrUsed, biClrImportant End Type
Type BITMAPINFO bmh As BITMAPINFOHEADER End Type
Global bminfo As BITMAPINFO
bminfo.bmh.biSize = SizeOf(bminfo.bmh) bminfo.bmh.biWidth = 512 bminfo.bmh.biHeight = 512 bminfo.bmh.biPlanes = 1 bminfo.bmh.biBitCount = 32 // ... biCompression, biSizeImage, biXPelsPerMeter, biYPelsPerMeter, biClrUsed, und biClrImportant = 0
Global RenderBmpRamAdr As Long
// ... Create a Bitmap in the PC Ram Global RenderDib As Handle = CreateDIBSection(Null, bminfo, DIB_RGB_COLORS, V:RenderBmpRamAdr, Null, 0)
''' Draw something into the RAM Bitmap Global Object D2DRenderBMP
MsgBox Hex$(128)
// ..........................
Do D2BeginDraw Win1RT, D2C_Gray Dim x As Long, y As Long Dim pixelIndex As Long Dim rowWidth As Long Dim redColor As Long // Roten Farbwert definieren (ARGB-Format) auf Alpha 0.5 redColor = $80FF0000 // Breite einer Zeile in Bytes rowWidth = bminfo.bmh.biWidth * 4 // Durch alle Pixel iterieren For y = 0 To bminfo.bmh.biHeight - 1 For x = 0 To bminfo.bmh.biWidth - 1 // Pixelindex in der Speicheradresse berechnen pixelIndex = (y * rowWidth) + (x * 4) // Pixelwert im Speicher setzen {RenderBmpRamAdr + pixelIndex} = redColor Next x Next y Set D2DRenderBMP = D2Bitmap(RenderDib, WICBitmapUsePremultipliedAlpha) D2Put 0, 0, D2DRenderBMP D2EndDraw PeekEvent Until Me Is Nothing Set Win1RT = Nothing
Seems I got it to work! Do I have to use everytime Set D2DRenderBMP = D2Bitmap(RenderDib, WICBitmapUsePremultipliedAlpha)in the loop while I change pixels in every frame? Or is there any faster different way to do?
|
|
|
Post by scalion on Jan 2, 2024 0:01:38 GMT 1
I m happy you have found what you want ! One more thing : instead Type BitmapInfoHeader etc... juste write in start of your code $library "gdip.inc" you Will Win précious time ! Unfortunaly a d2d object cant be directly accessible. But tommorow i Will Take à look , searching à turnaround.
|
|
|
Post by Roger Cabo on Jan 2, 2024 0:17:53 GMT 1
I m happy you have found what you want ! One more thing : instead Type BitmapInfoHeader etc... juste write in start of your code $library "gdip.inc" you Will Win précious time ! Unfortunaly a d2d object cant be directly accessible. But tommorow i Will Take à look , searching à turnaround. Yes happy new year! and thanks a lot!
|
|
|
Post by scalion on Jan 2, 2024 11:29:17 GMT 1
EDIT 1 :
For the test i wrote this little minimal Direc2D program :
$Library "gfawinx" $Library "UpdateRT" UpdateRuntime ' Patches GfaWin23.Ocx
$Library "Direct2D" $Library "Gdip.inc" Global Object Win1RT FullW 1 Set Win1RT = D2GetRT(Win_1) Global Object MyD2Bitmap Set MyD2Bitmap = CreateEmptyBitmap(256, 256, D2C_Gray) Do DrawAll Sleep Loop Until Me Is Nothing Proc DrawAll D2BeginDraw Win1RT, D2C_Black D2Put 0, 0, MyD2Bitmap D2EndDraw EndProc Function CreateEmptyBitmap(W As Long, H As Long, DefaultColorARGB As Long) As Object Local bminfo As BITMAPINFO Local Object hD2Bitmap bminfo.bmiHeader.biSize = SizeOf(bminfo.bmiHeader) bminfo.bmiHeader.biWidth = W bminfo.bmiHeader.biHeight = H bminfo.bmiHeader.biPlanes = 1 bminfo.bmiHeader.biBitCount = 32 // ... biCompression, biSizeImage, biXPelsPerMeter, biYPelsPerMeter, biClrUsed, und biClrImportant = 0 Local RenderBmpRamAdr As Long // ... Create a Bitmap in the PC Ram Local RenderDib As Handle = CreateDIBSection(Null, bminfo, DIB_RGB_COLORS, V:RenderBmpRamAdr, Null, 0) MemLFill RenderBmpRamAdr, W * H * 4, DefaultColorARGB Set CreateEmptyBitmap = D2Bitmap(RenderDib, WICBitmapUsePremultipliedAlpha) FreeBmp RenderDib EndFunc EDIT 2 :
To change pixel in d2bitmap we must lock it.
IID_IWICBitmapLock 00000123-a8f2-4877-ba0a-fd2b6645fb94
typedef enum WICBitmapLockFlags { WICBitmapLockRead = 0x1, WICBitmapLockWrite = 0x2, WICBITMAPLOCKFLAGS_FORCE_DWORD = 0x7fffffff } ;
EDIT 3 :
I think i must write something like this in Direct2d Library but some informations missing for the moment :
Global Enum WICBitmapLock = 0x00000000, _ WICBitmapLockRead = 0x00000001, _ WICBitmapLockWrite = 0x00000002, _ WICBITMAPLOCKFLAGS_FORCE_DWORD = 0x7fffffff // CODEC_FORCE_DWORD GUID IID_IWIBitmapLock = 00000123-a8f2-4877-ba0a-fd2b6645fb94 Type IWICBitmapLockVtbl - Long QueryInterface, AddRef, Release - Long GetSize, GetStride, GetDataPointer, GetPixelFormat EndType
EDIT 4 :
Too much difficult for me, i send mail to Sjouke...
brb
|
|
|
Post by Roger Cabo on Jan 2, 2024 18:13:45 GMT 1
Explication courte de ce que j'aimerais faire : Ce programme devrait dessiner en temps réel dans la bitmap : Do // Boucle de Frame --------------
Local RenderDib As Handle = CreateDIBSection(Null, bminfo, DIB_RGB_COLORS, V:RenderBmpRamAdr, Null, 0) MemLFill RenderBmpRamAdr, W * H * 4, DefaultColorARGB
// Puis écrire en temps réel dans la bitmap via {RenderBmpRamAdr%} = Color, comme le fait le GPU. // Parce que D2Plot n'est pas assez rapide.
// Dans chaque frame, je dois utiliser pour passer chaque RenderDib nouvellement dessiné dans le D2DRenderBMP Set D2DRenderBMP = D2Bitmap(RenderDib, WICBitmapUsePremultipliedAlpha) D2Put 0, 0, D2DRenderBMP
... etc... Loop jusqu'à ce que quelque chose soit vrai :-)
Ma question est la suivante : est-ce la manière la plus efficace de transférer à chaque frame la RenderDib nouvellement dessinée dans D2DRenderBMP ? Avec Set D2DRenderBMP = D2Bitmap(RenderDib, WICBitmapUsePremultipliedAlpha) ? ---------------------------------------------- learn.microsoft.com/en-us/windows/win32/api/wincodec/ne-wincodec-wicbitmaplockflags): hr = pIDecoder->GetFrame(0, &pIDecoderFrame);Cet exemple montre comment modifier un flux d'image et sélectionner un cadre spécifique de ce flux. Ce n'est pas ce que je souhaite faire.
|
|
|
Post by Roger Cabo on Jan 2, 2024 18:36:14 GMT 1
Quick info: J'ai trouvé un code de rasterisation capable de dessiner environ 2 millions de pixels en 1 ms dans n'importe quel triangle orienté vers la droite dans la mémoire. De plus, je vais créer une image de tampon Z pour éviter le tri en 3D des triangles.
Mon objectif est d'essayer de rendre des triangles dans 6 fils d'exécution, soit 12 millions de pixels en triangles par milliseconde. Et ceci est possible car je n'ai pas besoin de trier les triangles en profondeur Z grâce au tampon Z. Attachments:
|
|
|
Post by scalion on Jan 2, 2024 21:42:51 GMT 1
Non. A chaque fois les data du bitmap sont copiés ailleurs pour êtres utilisé par l'objet. Le seul avantage est que tu bénicies du VSYNC de Direct2D, mais tu perds le temps de la copie. Il serait préférable de pouvoir écrire directement dans la zone mémoire de l'objet. Le seul moyen est d'utiliser BitmapLock (Pas implémenté pour l'instant).
Après écrire directement dans un DIB pour l'afficher dans une boucle via GDI s'avère très efficace, et du coup on a plus le VSYNC.
J'ai moi aussi une question, puisque tu veux afficher des triangles, pourquoi ne pas utiliser OpenGL ?
|
|
|
Post by Roger Cabo on Jan 3, 2024 19:08:14 GMT 1
J'ai moi aussi une question, puisque tu veux afficher des triangles, pourquoi ne pas utiliser OpenGL ?
C'est une bonne question... je ne savais pas que gb32 pouvait aussi gérer la 3D... j'ai été tellement surpris par la démo )) Je dois d'abord me familiariser avec opengl32... si je l'utilise. Et je ne peux voir que le déroulement des commandes à partir de tes exemples !! À des fins de test, j'ai créé mat et Quaternion dans gb32. Avec ceux-ci, on peut déplacer et faire tourner une hiérarchie d'objets qui sont tous liés ou les bouger individuellement. Comme modèle, j'utilise la référence C de unity dans ChatGPT 4.0. Le code que j'ai écrit jusqu'à présent n'est pas long. Mais il manque évidemment encore pas mal de code. Mais peut-être que tout cela est maintenant inutile. Donc, je ne sais pas exactement ce dont j'ai besoin ou comment je peux tout mettre en œuvre. Dans unity 3d, j'écris mes valeurs pour tourner dans un Transform et c'est tout. C'est ce que je voudrais aussi dans Gb32. Qu'au final, on puisse donner un ensemble de commandes et ne pas avoir à se soucier des rotations et des mouvements. Quaternion_3.G32 (12.12 KB) En dehors de cela, j'aimerais intégrer un système de collision simple. mais peut-être plus tard. Mon problème maintenant est, comment puis-je connecter le système de transformation simple avec opengl_3d, ou est-ce que tout est déjà intégré ?
|
|
|
Post by scalion on Jan 3, 2024 21:32:31 GMT 1
J'aurai bien testé ton programme Quaternion_3.g32 mais il en manque un bout on dirait ? En tout cas chapeau, moi je n'ai jamais rien compris aux matrices et aux quaternions ( (x)Man à pas mal bossé la dessus aussi ). En tout cas OpenGL c'est on ne peut plus simple depuis que la librairie "OpenGL.inc" a été implémentée pas Sjouke. Par contre pour les collisions, bon courage, OpenGl ne gère PAS et personnellement ca me semble très compliqué. Si je devais implémenter un système de collision en 3D je simplifierais en réduisant à quelques points précis les zones de tests des objets qui peuvent entrer en collision (exemple pour une voiture seulement 4 points pour les roues).
|
|
|
Post by Roger Cabo on Jan 3, 2024 23:19:40 GMT 1
Dans la nouvelle version, j'ai tout intégré... mais je ne sais pas encore ce que cela va donner. Je dois d'abord réfléchir à la manière dont je dois appliquer les points 3D les uns après les autres pour arriver à un rendu en 2D. --- In the new version, I have integrated everything... but I still don't know what the outcome will be. I first need to think about how I should apply the 3D points one after another to achieve a 2D rendering. Quaternion_4.G32 (14.03 KB)
|
|