AGB  ·  Datenschutz  ·  Impressum  







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

FMX = Spiele-Engine in schlecht?

Ein Thema von stahli · begonnen am 26. Mai 2013 · letzter Beitrag vom 5. Sep 2019
Antwort Antwort
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.356 Beiträge
 
Delphi 11 Alexandria
 
#1

AW: FMX = Spiele-Engine in schlecht?

  Alt 15. Jan 2014, 14:53
Also mein Wunsch:

- Optik wie VCL Style oder besser FMX Style incl. Effekten und Schatten ist völlig ausreichend.
- Dinge wie Lichteffekte und 3D wären Schmankerl, müssten aber nicht sein.
- Der Anwender bedient das Programm und auch bei aufwendigen Berechnungen werden Fortschritte eines AniIndicators (drehende Sterne oder Punkte), einer Progressbar oder eines Gitters bei Datensatzwechseln flüssig, verzögerungsfrei und flimmerfrei dargestellt.
- Ich will also auf ein Application.Processmessages verzichten.
- Der AniIndikator soll laufend vor sich hin wackeln wie ein Baum im Spiel, egal was ich in der Anwendung tue. Das ist eigentlich das, was man m.E. ohne negative Vorerfahrungen mit der VCL auch erwarten würde. (Wobei ich natürlich einsehe, dass vor 20 Jahren noch ein anderer Stand der Technik vorherrschte.)
- Wenn ich in meiner Anwendung in Zeile 500.000 schreibe: "Panel1.Left := Panel1.Left + 1" dann will ich die Änderung im Formular auch sehen, wenn ich diese Zeile mit F8 ausführe. Dazu darf die Formularänderung nicht im gleichen Thread laufen wie der Rest der Anwendung.
- Die Funktionalität sollte möglichst auf allen Windows-Versionen ab XP und mit allen möglichen Grafik-Hardwaren gegeben sein.
- Funktionalität auf MAC und mobilen Plattformen wäre natürlich nicht falsch.

Das alles habe ich mir auf Grund der schönen bunten Emba-Videos von FMX erwartet. Im Nachhinein weiß ich, dass ich da ... ma sagen ... äh ... einem Missverständnis auf den Leim gegangen bin.
Nichts desto trotz halte ich die Zielstellung für legitim und im Grunde wohl auch realisierbar.

Ob das Ganze hardwarebeschleunigt laufen muss, glaube ich noch nicht mal. So eine Formularanwendung ist ja doch ziemlich einfach gestrickt, auch wenn man Transparenz, ein paar Styles und Skins verwendet. Es kommt (denke ich) mehr auf eine sinnvolle Optimierung an und auf eine Formularaktualisierung in einem eigenen Thread. Ich denke, das ist der Knackpunkt.

Wer schon mal CodesiteLogging genutzt hat - das ist ein schönes Beispiel. Die Logs werden schnell an eine unabhängige Stelle (LogManager, sage ich mal) geschickt und die Anwendung kann normal weiter laufen. Im LogManager werden die Infos dann aufbereitet und nach und nach ausgegeben.

So ähnlich sollte die Formularaktualisierung laufen. Die Controlabbilder werden nach und nach auf die Formularfläche kopiert und die entsprechenden Regionen vermerkt. Anschließend werden Maus- und Tastaturereignisse geprüft und an die Controls weiter gegeben, die sich unter der Maus befinden oder den Focus haben...

Das hätte ich gern und das würde m.E. völlig neue Möglichkeiten und Anwendungen ergeben.

FMX hat ja leider auf ganzer Linie mehr als enttäuscht.


Ich selbst will eigentlich erst mal nur etwas auf dem Gebiet lernen um etwas Hintergrundwissen zu sammeln.


@jaenicke
Genau. Bitmap und Canvas habe ich jetzt nur der Einfachheit halber auf die Schnelle verwendet. Ich denke, dass das auch schlanker gehen müsste. Gedrehte Controls und Zuweisung von Schatten oder Effekten wäre natürlich auch super. Insofern wären schon komplexere Zeichenfunktionen wünschenswert. Aber lösbar sollte das sein (wenn auch nicht unbedingt für mich, so ohne Vorkenntnisse).
Kann man mal was von Deinem Geraffel sehen?


@all
Die Frage auch an alle anderen: Wer irgendwelche Teilergebnisse, Exen, Bilder, Videos oder Kenntnisse zu diesem Thema vorzeigen kann ... ich würde sofort alles begierig aufsaugen!
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)

Geändert von stahli (15. Jan 2014 um 14:58 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.989 Beiträge
 
Delphi 12 Athens
 
#2

AW: FMX = Spiele-Engine in schlecht?

  Alt 17. Jan 2014, 12:30
@jaenicke
Insofern wären schon komplexere Zeichenfunktionen wünschenswert. Aber lösbar sollte das sein (wenn auch nicht unbedingt für mich, so ohne Vorkenntnisse).
Kann man mal was von Deinem Geraffel sehen?
Ich kann mal die Technik dahinter erläutern. Der Code gehört der Firma, den kann ich nicht einfach posten. Mal schauen, wann ich dafür Zeit finde.

Der Grundgedanke der Komponentenzeichnung im Hintergrund und des späteren Zusammenbaus des Formulars mit den fertigen Bausteinen gefällt mir aber. Ich werde mich wohl mal mit OpenGL befassen (müssen).
Die Hardwarebeschleunigung ist genau der Grund weshalb die Oberfläche von z.B. Vista oder 7 so viel flüssiger läuft als die von XP (vorausgesetzt man macht nicht den Fehler und deaktiviert Aero).
Seit Vista übernimmt das Rendern (inkl. Überlappungen usw.) die Grafikkarte statt der CPU, sofern das möglich und Aero aktiv ist.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.356 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: FMX = Spiele-Engine in schlecht?

  Alt 18. Jan 2014, 03:05
@Daniel
Ich würde gern noch hier bleiben, weil ich noch bei der Idee der gepufferten Bitmaps bleiben will.
Wenn Du das verschieben willst ist das natürlich auch ok (in meinen neuen OpenGL-Thread passt es aber auch nicht besser).

@all
Anbei nochmal eine neue Testversion.
Die GUI wird im Mainthread gezeichnet. Die Businesslogik läuft in einem eigenen Thread. Dort erfolgen die Positionsänderungen usw.
Die Geschwindigkeit des Threads kann über den Sleepwert geändert werden.
Eine echte Anwendung würde man natürlich ohne Sleep laufen lassen. Da würden ja normalerweise keine Controls verschoben.

Wenn man die VCL-Schleife startet, dann hängt die Anwendung natürlich so lange.

Die Test-Schleife vom unteren Button läuft im Business-Thread. Die Geschwindigkeit ist vom Sleepwert abhängig.
Der Zahlenwert in den Controls zeigt den Schleifenzähler an.

Die Controls zeichnen sich jetzt bei jedem Frame neu. Es gibt also keine Bitmaps zum puffern mehr.
Das Ganze läuft trotzdem sehr schnell (bei der einfachen Grafik). Bis 10.000 Panels läuft das flüssig, danach wird es hakelig.

Der Flaschenhals bei FMX dürfte also wohl nicht mit Bitmappuffern zu verbessern sein, wie ich ursprünglich meinte.
Was aber wichtig ist, ist bei Controländerungen nicht rings herum ständige Neuzeichnungen auszulösen.


Ich habe drei neue Controls gebastelt: AniIndicator, Progressbar, Edit.
Die sind natürlich nur mal schnell angetestet.
Der AniIndicator läuft ständig vor sich hin. Die Geschwindigkeit ist einstellbar.
Die Progressbar kann mit der Maus eingestellt werden und läuft dann automatisch auf null zurück. Beide sind verbunden (ist natürlich hier kein echtes Binding )
Die Edits können einen Fokus erhalten und Zeichen annehmen (sonst geht da noch nix - also kein Cursor, kein Select, kein Löschen usw!). Um das weiter auszubauen wäre natürlich einige Arbeit notwendig.

Die VCL-Controls sind natürlich hier nur für Testzwecke. Real könnte man auf VCL-Controls verzichten (wenn es ausreichend Alternativen gäbe).


Warum nun das Ganze?


So richtig habe ich keine Ahnung!

Die VCL und FMX will ich nicht mehr gern verwenden. Die sind einfach nicht angenehm, stabil und flüssig zu händeln.

Die Demo gefällt mir vom Handling schon ganz gut.
Man hat eine flüssige GUI, die unabhängig vom Businessthread läuft, der in einem Objekt gekapselt ist.
Die Windowsereignisse spielen dann eigentlich keine Rolle mehr, außer dass das Formular diese abfängt und an die GUI übergibt.
Die GUI-Controls können direkt in die Businesslogik gebunden werden.

Ich habe jetzt m.E. einen Ablauf, wie er auch mit OpenGL o.ä. funktionieren würde - natürlich auf ganz anderem Niveau.

Wenn ich das Projekt schrittweise debugge, dann werden Änderungen natürlich wie bei der VCL auch nicht sichtbar, da die Formularaktualisierung im Mainthread läuft. Evtl. könnte man den Formularcanvas einer fremden Anwendung kapern, so dass man Formularaktualisierungen so beim Debuggen erkennen könnte.


PS: Jetzt gehe ich erst mal ins´ Bettchen - vielleicht bin ich morgen schon schlauer.
Angehängte Dateien
Dateityp: zip ssDevTest.zip (869,4 KB, 17x aufgerufen)
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)

Geändert von stahli (18. Jan 2014 um 03:13 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.989 Beiträge
 
Delphi 12 Athens
 
#4

AW: FMX = Spiele-Engine in schlecht?

  Alt 18. Jan 2014, 07:47
Wenn ich das Projekt schrittweise debugge, dann werden Änderungen natürlich wie bei der VCL auch nicht sichtbar, da die Formularaktualisierung im Mainthread läuft. Evtl. könnte man den Formularcanvas einer fremden Anwendung kapern, so dass man Formularaktualisierungen so beim Debuggen erkennen könnte.
Du brauchst nur Delphi auf den zweiten Monitor verschieben zum Debuggen und in Strg + F7 einfach Application.ProcessMessages auswerten, schon werden die Fenster des debuggten Programms aktualisiert...
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#5

AW: FMX = Spiele-Engine in schlecht?

  Alt 18. Jan 2014, 10:47
Vollkommen wegkommen von den Windows Events wirst du nicht, wenn du deine Zeichenvorgänge korrekt umsetzen willst. Dazu musst du nunmal zwangsweise auf die WM_PAINT reagieren (wenn du nicht auf gut Glück periodisch alles neu Zeichnen willst).
Dass alle Windows Messages in einem einzigen Message Loop (bei Delphi im "Main-Thread") empfangen werden, kann man als Vor- oder auch als Nachteil sehen. Klar blockiert eine Schleife von 1..10000 dann natürlich erstmal den Empfang weiterer Nachrichten, weshalb dann auch die GUI nicht mehr aktualisiert wird, oder Button Click Ereignisse nicht sofort umgesetzt werden. Auf der anderen Seite kannst du dieses Verhalten recht einfach beeinflussen, indem du (wie von jaenicke schon erwähnt) ein Paar Application.ProcessMessages Aufrufe einstreust (oder System-nah direkt MSDN-Library durchsuchenPeekMessage, MSDN-Library durchsuchenTranslateMessage, MSDN-Library durchsuchenDispatchMessage).

Zu den Neuzeichnungen .. nehmen wir an ich habe folgende Hierachie:
  • Form
    • Button1
    • Button2
    • Panel1
      • Button3
      • Button4

Gehe ich hier mal generell von der Möglichkeit aus, dass eine Komponente semitransparent ist, so muss in jedem Falle alles was darunter liegt neu gezeichnet werden. Im "schlimmsten" Falle würde eine Änderung von Button3 also ebenfalls das Panel und das Formular neu zeichnen. Analog dazu muss natürlich bei einer Änderung des Panels sowohl das Formular (falls das Panel z.b. semintransparent ist oder einen AlphaChannel hat), als auch die darüberliegenden Buttons 3 und 4 (in jedem Falle; da diese ggfls. durch das Neuzeichnen des Panels teilweise überdeckt werden) neu gezeichnet werden.

Man sieht also recht schnell, dass diese Zeichenlogik keine triviale Sache ist und dass man in gewissen Fällen halt einfach nicht um ein Neuzeichnen herumkommt. Optimieren kann man hier z.b. indem man jedem Control ein Flag zuweist, welches angibt, ob die Komponente semitransparent ist oder nicht. Dann spart man sich ein paar Zeichenoperationen von darunterliegenden Controls (macht die VCL soweit ich gesehen habe auch so).
Falls das Zeichnen ansich wirklich ein Flaschenhals sein sollte, kann man natürlich auch das "Bitmap Caching" (mindestens GDI+, weil hier zwingend Transparenz / AlphaChannel benötigt wird) verwenden. Ich wage allerdings mal zu behaupten, dass die Zeichenoperationen in der Regel schneller sind, als die ganze Cache Geschichte.
Auch wichtig ist, dass man exzessiven Gebrauch von Clipping macht und somit wirklich immer nur die Teile aktualisiert, die sich wirklich geändert haben und nicht wild drauf los das komplette Control. Im Hintergrund gehe ich zwar davon aus, dass sich ein Control IMMER komplett neu zeichnet, aber die GDI (oder zumindest mal DirectX, OpenGL) sollten die Zeichenoperationen entsprechend des Clippings optimieren, was sich dann wohl in einer kleinen Performancesteigerung sichtbar macht.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.989 Beiträge
 
Delphi 12 Athens
 
#6

AW: FMX = Spiele-Engine in schlecht?

  Alt 18. Jan 2014, 14:56
So, nun nehme ich mir mal ein paar Minuten um das Konzept meiner selbst gezeichneten Komponenten zu erklären. Das ist vor FireMonkey entstanden. Im Moment sieht es allerdings so aus als ob das in der Praxis wegen FireMonkey nie zum Einsatz kommen wird und wir stattdessen FireMonkey einsetzen werden.
Deshalb kommt das ganze größtenteils aus der Erinnerung und einem kurzen Blick in den Quelltext, denn das ist schon eine Weile her...

Das Grundprinzip:
Beim Zeichnen bekommt die Komponente eine Zeichenfläche mit übergeben. Dort zeichnet sie sich selbst einfach drauf. Ob die Zeichenfläche der Bildschirm oder eine Bitmap ist, interessiert die Komponente nicht.
Jede Komponente besitzt eine Methode, die eine Region erstellt, die die Grenzen der Komponente festlegt. Vor dem Zeichnen wird die Zeichenfläche mit ExtSelectClipRgn auf diese Region in Kombination der Region der Elternkomponente beschränkt. Man kann also z.B. günstige Gradientmethoden usw. nutzen, die eigentlich über die Komponente hinaus zeichnen würden, statt diese manuell auf die konkrete Region anzupassen.
Muss eine Komponente neu gezeichnet werden und ist Transparenz aktiv, wird ein umgebendes Rechteck der Region benutzt um alle Komponenten, die im selben Bereich liegen, zu finden und ebenfalls neu zu zeichnen. Der Vergleich der Regionen kostete bei vielen Komponenten zu viel Zeit, ebenso die Sichtbarkeitsprüfung um nur nicht verdeckte und somit sichtbare Teile neu zu zeichnen.

Dazu kommt nun, dass eine Komponente gedreht, gezerrt, gedrückt usw. werden kann. Dies weiß die Komponente selbst aber nicht, sondern wird über eine Matrixtransformation der Zeichenfläche realisiert. Die Komponente zeichnet sich selbst also ganz normal, sieht aber auf der realen Zeichenfläche entsprechend transformiert aus. Die Transformation geschieht mit SetWorldTransform, die reine Versetzung um einen gedrückten Zustand darzustellen mit SetViewportOrgEx (womit dies vor die weitere Transformation gesetzt wird ohne dass das normale Zeichnen diesen Extraoffset kennt), Transparenz kommt am Ende mit AlphaBlend dazu.

Für den Designmodus wird ebenfalls das umgebende Rechteck verwendet und daran die Henkel zum Anfassen, drehen, zerren usw. gezeichnet. Das funktioniert natürlich direkt in Delphi wie man es gewohnt ist. Für den Objektinspektor war ein wenig Tools API Trickserei nötig, aber es funktioniert gut und war nicht weiter kompliziert.

Quelltext kann ich wie gesagt nicht viel zeigen, daher nur in sehr groben Ausschnitten:
Delphi-Quellcode:
var
  TransForm: TXForm;

  TransForm.eM11 := Cos(RadAngle);
  TransForm.eM12 := Sin(RadAngle);
  TransForm.eM21 := -Sin(RadAngle);
  TransForm.eM22 := Cos(RadAngle);
  TransForm.eDx := OffsetX;
  TransForm.eDy := OffsetY;
Auf diese Weise kann man das Bild z.B. drehen und versetzen. Mehr zu diesen Berechnungen findest du hier in der Doku zu SetWorldTransform:
http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx
bzw. in der Doku zu ExtCreateRegion, mit der Funktion lässt sich eine Region analog transformieren:
http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx

Das Zeichnen selbst ist daher sehr gradlinig:
Delphi-Quellcode:
procedure T...Element.Paint(ACanvas: TCanvas);
var
  RegionRect: TRect;
  DisplayRegion, OldRegion: HRGN;
begin
  DisplayRegion := AutoClipElement(ACanvas, RegionRect, OldRegion);
  try
    PaintTo(ACanvas, RegionRect);
  finally
    SelectClipRgn(ACanvas.Handle, OldRegion);
    DeleteObject(OldRegion);
    DeleteObject(DisplayRegion);
  end;
end;
Sprich es wird immer entsprechend geclipped und auch bei Fehlern das alte Clipping wiederhergestellt. Das try..finally ist hier sehr wichtig.

Das mal als kurze Übersicht...
Sebastian Jänicke
AppCentral

Geändert von jaenicke (18. Jan 2014 um 14:58 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.356 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: FMX = Spiele-Engine in schlecht?

  Alt 18. Jan 2014, 20:57
Schade, dass sich solche Entwicklungen bisher nicht durchgesetzt hatten.
Ich hätte Dir auf jeden Fall mehr Qualität zugetraut als (nach leidlicher Erfahrung) Emba.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  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 07:38 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