Warum wird hier auf ImageOutput nichts gezeichnet

Anfängerfragen zum Programmieren mit PureBasic.
SMaag
Beiträge: 184
Registriert: 08.05.2022 12:58

Warum wird hier auf ImageOutput nichts gezeichnet

Beitrag von SMaag »

Ich hab hier einen Code, der direkt auf ein Image Zeichnen soll. Einfach einen Kreis mit einer Unterteilungslinie für alle 2 Grad
Das geht, sofern ich ein 24Bit Image verwende (also 3 Byte pro Farbe).
Mit einem 32Bit Image (4Byte RGBA) geht das nicht, obwohl der Alpha Kanal auf 255 intransparent gesetzt ist!
Warum???

Code: Alles auswählen

#Image = 0
#Window = 0
#ImageGadget = 1

If OpenWindow(#Window, 100, 100, 800, 800, "Direct Draw Line", #PB_Window_SystemMenu)
  
  CreateImage(#Image, WindowWidth(#Window), WindowHeight(#Window), 24, RGB(200,200,200)) 
  ;CreateImage(#Image, WindowWidth(#Window), WindowHeight(#Window), 32, RGBA(200,200,200,255)) ; DAS GEHT NICHT! WARUM???

  ImageGadget(#ImageGadget, 0,0, WindowWidth(#Window), WindowHeight(#Window), ImageID(#Image))
  
  
  ; *Buffer = DrawingBuffer()
  Define I, N, Phi.d
  
  StartDrawing(ImageOutput(0)) 
  DrawingMode(#PB_2DDrawing_Outlined) 
  Circle(400,400, 390, RGBA(0,0,0,255))
  
  For I = 0 To 358 Step 2
    Phi = Radian(I)
    LineXY(400, 400, 400- 390*Cos(Phi), 400+ 390*Sin(Phi), RGBA(255,0,0,255) )
  Next

  StopDrawing()
  
  Define Event
  Repeat
    Event = WaitWindowEvent()
    
  Until Event = #PB_Event_CloseWindow
  
EndIf

freak
PureBasic Team
Beiträge: 766
Registriert: 29.08.2004 00:20
Wohnort: Stuttgart

Re: Warum wird hier auf ImageOutput nichts gezeichnet

Beitrag von freak »

Der ImageGadget() Befehl muss nach dem Drawing-Code stehen. Alternativ einfach nach dem Zeichnen nochmal das ImageGadget refreshen:

Code: Alles auswählen

SetGadgetState(#ImageGadget, ImageID(#Image))
So ist es eigentlich immer nötig. Das es bei 24bit auch ohne geht ist eher Zufall.
SMaag
Beiträge: 184
Registriert: 08.05.2022 12:58

Re: Warum wird hier auf ImageOutput nichts gezeichnet

Beitrag von SMaag »

Code: Alles auswählen

SetGadgetState(#ImageGadget, ImageID(#Image))
Danke, das funktioniert!
Es ist aber ein recht komisches Verhalten des ImageGadgets, da es bei 24Bit ohne funktioniert und in der Doku steht das auch nirgends.
Das Beispiel in der PB-Hilfe ist auch nur mit 24Bit Bitmaps.
Ich halte das für eine Bug! Wurde das schon diskutiert?
freak
PureBasic Team
Beiträge: 766
Registriert: 29.08.2004 00:20
Wohnort: Stuttgart

Re: Warum wird hier auf ImageOutput nichts gezeichnet

Beitrag von freak »

Das ist kein Bug. Das ImageGadget ist für statische Inhalte optimiert. Wenn sich das Image ändert muss man das Gadget updaten. Das ist bei den anderen OS auch so.

Für dynamischere Inhalte ist das CanvasGadget gedacht.
SMaag
Beiträge: 184
Registriert: 08.05.2022 12:58

Re: Warum wird hier auf ImageOutput nichts gezeichnet

Beitrag von SMaag »

Das ist kein Bug. Das ImageGadget ist für statische Inhalte optimiert. Wenn sich das Image ändert muss man das Gadget updaten. Das ist bei den anderen OS auch so.
Komisch ist nicht, dass man das updaten muss, sondern dass man das nur bei 32Bit Pixelformat machen muss. Bei 24Bit kann man das Update weglassen. Warum?
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Warum wird hier auf ImageOutput nichts gezeichnet

Beitrag von STARGÅTE »

SMaag hat geschrieben: 06.09.2023 10:52
Das ist kein Bug. Das ImageGadget ist für statische Inhalte optimiert. Wenn sich das Image ändert muss man das Gadget updaten. Das ist bei den anderen OS auch so.
Komisch ist nicht, dass man das updaten muss, sondern dass man das nur bei 32Bit Pixelformat machen muss. Bei 24Bit kann man das Update weglassen. Warum?
In der Tat wird seit PB 6.0 wohl im 24 bit Pixelformat das Image automatisch aktualisiert. Zumindest konnte ich das hier auch reproduzieren.
Um zu klären, ob dieses Verhalten ein Bug ist, sollte Freak mal ein offizielles Statement abgeben, was genau nach Übergabe der ImageID beim ImageGadget eigentlich passiert.
Hierzu gab und gibt es nämlich immer noch offene Fragen:
ImageGadget, nach Zuweisung eines Image dann FreeImage ok ?
Is it safe to delete an ImageGadget image after setting it?
Wird das Image im Moment des Aufrufs von ImageGadget oder SetGadgetState "genommen" und kopiert oder greift das Gadget für immer auf die original Ressource (also das Image) zurück?
Denn wenn sich unter Windows und mit 24 Bit Images das Gadget einfach selbst aktualisiert, würde ich das als Bug einstufen, da es unvorhergesehene Effekte hat, wenn man ein Image für mehrere Gadgets nutzt, es dazwischen aber verändert.


Auf der Microsoft Seite gibt es hierzu auch ein interessanten Kommentar. Demnach gibt es tatsächlich einen Unterschied zwischen 32 Bit und 24 Bit:
https://learn.microsoft.com/en-us/windows/win32/controls/stm-setimage hat geschrieben: Important

In version 6 of the Microsoft Win32 controls, a bitmap passed to a static control using the STM_SETIMAGE message was the same bitmap returned by a subsequent STM_SETIMAGE message. The client is responsible to delete any bitmap sent to a static control.

With Windows XP, if the bitmap passed in the STM_SETIMAGE message contains pixels with nonzero alpha, the static control takes a copy of the bitmap. This copied bitmap is returned by the next STM_SETIMAGE message. The client code may independently track the bitmaps passed to the static control, but if it does not check and release the bitmaps returned from STM_SETIMAGE messages, the bitmaps are leaked.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Antworten