AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Canvas: Änderungen/Bewegungen zeichnen

Ein Thema von Scurra · begonnen am 26. Aug 2018 · letzter Beitrag vom 2. Jan 2020
Antwort Antwort
Scurra

Registriert seit: 19. Jan 2015
81 Beiträge
 
Delphi 10.3 Rio
 
#1

AW: Canvas: Änderungen/Bewegungen zeichnen

  Alt 25. Dez 2019, 10:16
Hallo zusammen,

nach einer langen Pause habe ich mir nun endlich wieder die Zeit genommen, an diesem Projekt weiter zu arbeiten.

Aktuell beschäftigt mich immer noch das Zeichnen. Aktuell mache ich das folgendermaßen (ich benutze die GR32-Komponente):

Ich habe folgendes Interface, das mir den Inhalt der Radarfläche kapselt:
Delphi-Quellcode:
IRadarScreen = interface(IBaseInterface)
    function GetContent: TImage32;

    /// <summary>The image-information which shall be displayed.</summary>
    /// <remarks>The interface will free the content when implementation is freed. Do not
    /// hold a reference to the content unless you are sure that implementation lives longer than
    /// your reference!</remarks>
    property Content: TImage32 read GetContent;
  end;
Ganz innen habe ich einen Thread zum Zeichnen. Dieser erzeugt eine TImage32-Instanz mit den gewünschten Bitmap-Layern und verpackt diese Instanz im IRadarScreen-Interface. Über eine Callback-Methode reicht der Thread dieses Interface nach außen. Hier mein aktueller Code:
Delphi-Quellcode:
procedure TDrawerThread.Run;
var
  radarScreen: IRadarScreen;
begin
  inherited;

  while not Terminated do
  begin
    radarScreen := TestRadarScreenUpdate; // diese Methode erzeugt die TImage32-Instanz und liefert dieses als IRadarScreen-Interface zurück.
    if Assigned(FOnDrawSuccess) then
      Synchronize(procedure
                  begin
                    FOnDrawSuccess(radarScreen)
                  end);
    sleep(33);
  end;
end;
(Später soll dieser Code immer dann getriggert werden, wenn etwas neu gezeichnet werden muss, sei es durch eine Neuberechnung der Positionen in der Simulation oder durch ein Resize der Radar-Fläche. Die Prozedur FOnDrawSuccess wird per Constructor-Injection an den Thread übergeben)

Das IRadarScreen-Interface wird dann über verschiedene Schichten im Model an den Presenter und von dort an mein View übergeben. Das View hat schließlich Zugriff aufs Formular und führt bei einem Update folgenden Code aus:

Delphi-Quellcode:
procedure TMainView.SetRadarScreen(const UpdatedRadarScreen: IRadarScreen);
var
  radarScreenRefOld: IRadarScreen;
begin
  // ensure that the old IRadarScreen is freed only after the reference to its image has been removed!
  radarScreenRefOld := FRadarScreenRef;
  FRadarScreenRef := UpdatedRadarScreen;

  if Assigned(FRadarScreenContent) then
    FRadarScreenContent.Parent := nil;

  FRadarScreenContent := UpdatedRadarScreen.Content;
  radarScreenRefOld := nil;
  FRadarScreenContent.Parent := Form.pnlRadar;
  FRadarScreenContent.Left := 0;
  FRadarScreenContent.Top := 0;
end;
Kurz gesagt heißt das, dass ich immer die komplette TImage32-Instanz auf dem Formular austausche. Ich habe es schon einmal mit TImage32.Assign ausprobiert, aber das liefert eine Exception, weil man TImage32 das zuweisen auf diese Art wohl nicht unterstützt.
Da ich bisher noch kaum Erfahrung mit dem Zeichnen/Neuzeichnen habe, wollte ich mal fragen, ob meine Implementierung vllt. zu unerwünschten Effekten führen könnte (weil ich immer das komplette TImage32-Objekt austausche) und ob es da vllt. bessere Möglichkeiten gibt.
  Mit Zitat antworten Zitat
Jens01

Registriert seit: 14. Apr 2009
673 Beiträge
 
#2

AW: Canvas: Änderungen/Bewegungen zeichnen

  Alt 25. Dez 2019, 10:37
Probier das mal: TImage32.Bitmap := NewBitmap; TImage32 assigned das neue Bitmap.

Frohe Weihnachten ...
Achtung: Bin kein Informatiker sondern komme vom Bau.
  Mit Zitat antworten Zitat
Michael II

Registriert seit: 1. Dez 2012
Ort: CH BE Eriswil
771 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Canvas: Änderungen/Bewegungen zeichnen

  Alt 25. Dez 2019, 11:59
(weil ich immer das komplette TImage32-Objekt austausche)
Bei GR32 musst du dich um Dinge wie "Bitmap zeichnen im Hintergrund und dann raus auf den Schirm" nicht kümmern: Du schreibst, dass du Layer verwendest. Du passt einfach die Grafik im Layer an, änderst allenfalls die Position des Layers - fertig.

Also etwa so:

Delphi-Quellcode:
MeinImage32.BeginUpdate;

BitMapLayersAnpassen...

MeinImage32.EndUpdate;
Wobei MeinImage32 ein TImage32 ist, welches den ganzen Anzeigebereich ausfüllt.

Dann ruckelt nix.

(Es gibt Demoprogramme, welche mit GR32 mitgeliefert werden.)
Michael Gasser

Geändert von Michael II (25. Dez 2019 um 13:24 Uhr)
  Mit Zitat antworten Zitat
Scurra

Registriert seit: 19. Jan 2015
81 Beiträge
 
Delphi 10.3 Rio
 
#4

AW: Canvas: Änderungen/Bewegungen zeichnen

  Alt 27. Dez 2019, 17:37
Danke für eure Hinweise.

Ich war mal wieder etwas überängstlich. Ich tausche jetzt weiterhin jedes Mal die TImage32-Komponente aus. Beim Verändern der Formulargröße gibt es zwar einen deutlichen "Nachzieh-Effekt", aber da meine Fläche ohnehin fast nur schwarz ist, kann ich das Problem leicht beheben, indem ich auch das Panel, auf dem die TImage32-Komponente liegt, schwarz einfärbe.

Inzwischen habe ich mich schon etwas an das händische Zeichnen auf ein Canvas gewöhnt, aber mir ist da trotzdem ein Fehler aufgefallen. Oder mache ich etwas falsch?

Ich möchte eine gestrichelte Linie zeichnen. Ich habe bereits gelesen, dass die Winapi wohl fehlerhaft ist und man dazu einen gepunkteten (anstatt einem gestrichelten) Pen benutzen muss. Aber leider wird die Farbe nicht übernommen, die gestrichelte Linie wird weiß gezeichnet, unabhängig davon, welche Farbe ich wähle. Das hier ist mein Code dazu:

Delphi-Quellcode:
procedure TRunwayRenderer.DrawIlsLine(const Bitmap: TBitmap32);
var
  penHandle: HPEN;
  pen: TPen;
  logBrush: TLogBrush;
  canvas: TCanvas;
begin
  penHandle := ExtCreatePen(PS_GEOMETRIC or PS_DOT or PS_ENDCAP_FLAT or PS_JOIN_MITER, 1, logBrush, 0, nil);
  canvas := Bitmap.Canvas;
  pen := canvas.Pen;
  pen.Handle := penHandle;
  pen.Style := psDot;
  pen.Color := $00222222;

  canvas.MoveTo(1, 100);
  canvas.LineTo(500, 100);
end;
Als workaround fällt mir nur ein, die gestrichelte Linie wirklich komplett händisch zu zeichnen, also eine durchgezogene Linie zusammen mit einer Abfolge von canvas.MoveTo und canvas.LineTo zu verwenden.
  Mit Zitat antworten Zitat
Jens01

Registriert seit: 14. Apr 2009
673 Beiträge
 
#5

AW: Canvas: Änderungen/Bewegungen zeichnen

  Alt 27. Dez 2019, 17:55
Ich glaube, Du verfolgst einen etwas falschen Ansatz.
Eigentlich bearbeitest Du ein TBitmap32. Dafür gibt es viele Tools und Methoden in Bitmap32. (Das ist ja der Grund, weswegen Du TBitmap32 und TImage32 verwendest.) Und portierst es dann (wie von mir gezeigt) zu TImage32.

Die Layervariante von Micheal ist noch viel besser, aber auch komplizierter. Das solltest Du machen, wenn Du noch fitter bist mit GR32.
Achtung: Bin kein Informatiker sondern komme vom Bau.
  Mit Zitat antworten Zitat
Alt 28. Dez 2019, 06:03     Erstellt von Frühlingsrolle
Dieser Beitrag wurde von Daniel gelöscht. - Grund: Verdacht auf SPAM und den damit verbundenen verschwenderischen Umgang von wertvollen Bits und Bytes
Scurra

Registriert seit: 19. Jan 2015
81 Beiträge
 
Delphi 10.3 Rio
 
#7

AW: Canvas: Änderungen/Bewegungen zeichnen

  Alt 31. Dez 2019, 08:57
Zitat:
Eigentlich bearbeitest Du ein TBitmap32. Dafür gibt es viele Tools und Methoden in Bitmap32. (Das ist ja der Grund, weswegen Du TBitmap32 und TImage32 verwendest.)
Mir war bislang nicht klar, dass es da so viele Hilfsmittel zur Verfügung stehen. Ich habe es jetzt aber mal ausprobiert. Es hat zwar zugegebenermaßen trotz der Demo-Programme von Graphics32 über einen halben Tag gedauert, bis ich es etwas besser verstanden habe (z. B. was genau es mit dem Stippling auf sich hat), aber jetzt funktioniert es und das Ergebnis sieht mit Antialiasing wesentlich besser aus, als wenn man es von Hand zeichnet.

Zitat:
Die Farbe wird nicht angenommen, weil der LOGBRUSH-Struktur kein Farbwert zugewiesen wurde.
Generell halte ich dein Code-Beispiel für undurchdacht.
Danke, dass man dem LOGBRUSH noch eine Farbe zuweisen muss, wusste ich nicht. Mit deinem Beispiel funktioniert es jedenfalls.

Geändert von Scurra (31. Dez 2019 um 12:05 Uhr)
  Mit Zitat antworten Zitat
Jens01

Registriert seit: 14. Apr 2009
673 Beiträge
 
#8

AW: Canvas: Änderungen/Bewegungen zeichnen

  Alt 31. Dez 2019, 10:48
Es gibt nicht nur in TBitmap32 sondern auch umzu viele Tools. Ein Veraltetes hatte ich hier zuvor mal geposted. Angus hat aber zwischenzeitlich auch etwas Neues. Mußt vllt mal ausprobieren:
http://www.angusj.com/delphi/image32/Docs/Examples.htm
https://sourceforge.net/projects/image32/

Die Linien werden hierbei als gefülltes Polygon erstellt und sind deswegen besser und schärfer als die Canvas-Linien.
Aber natürlich ist der Schwierigkeitsgrad auch etwas höher.

Guten Rutsch ...
Achtung: Bin kein Informatiker sondern komme vom Bau.

Geändert von Jens01 (31. Dez 2019 um 10:52 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:08 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz