![]() |
OpenGL - Grundsatzfragen
Ich habe mal ein bischen über OpenGL gelesen.
Infos findet man vor allem hier: ![]() Und in der DP habe ich einen alten Kurs gefunden: ![]() (Nachträglichen Dank an Mr_T!) Zur Klärung einiger Fragen habe ich das Konzept aber noch nicht verstanden. Ich werde am Wochenende noch einige Turorials lesen, aber vielleicht kann ja wer schon mal kurz und knackig zu etwas Erleuchtung beitragen? 1) Rendern im Mainthread Das Rendern wird über Timer oder OnIdle laufend erledigt und das fertige Abbild mit SwapBuffers auf das Formular geklatscht. In der Renderfunktion wird ein Würfel gezeichnet, gestretcht und gedreht und wird somit dargestellt. Alles paletti. Wenn ich aber eine riesige Welt habe kann ich doch nicht in der Renderfunktion alle Objekte berechnen. Prüft man daher erst, ob sich das Objekt oder Würfel nah genug an der aktuellen Kamera befindet? 2) Maus Kann man (ähnlich der VCL) ermitteln, über welchem Objet und an welcher Position genau sich die Maus befindet? Ich stelle mir das schwer vor, da ein Objekt ja gedreht, gekippt und scaliert sein kann. Kann man mit vertretbarem Aufwand irgendwie ein Drag&Drop realisieren und kann ich einem Objekt beibringen, dass es unter Umständen für die Maus transparent sein soll (dass also z.B. ein DragOver vom dahinter liegenden Objekt verarbeitet würde)? 3) Tastatur + TextCursor Wenn man so eine Art Edit oder Memo basteln wollte ... ist so etwas denkbar bzw. gibt es bereits grundlegende Funktionalitäten, die dabei unterstützen? In GLScene gibt es ja solche Komponenten, aber könnte man das mit vertretbarem Aufwand auch selbst realisieren? 4) Businesslogik und Threads Einen Würfel zeichnen und über Timer drehen lassen ist ja schön und gut. Aber für eine echte Anwendung ist das m.E. kein schlüssiges Konzept. Wenn meine Drehfunktion z.B. 1 Minute brauchen würde, dann würde meine Anwendung 1 Minute hängen, genau wie in diesem Fall die VCL. Ich dachte - so meine bisherige Unterstellung - in einer Grafikengine würde ein anderes Konzept vorliegen, dass also die Darstellung auf der Zeichenfläche vom Ablauf der Anwendung (Businbesslogik) stärker entkoppelt wäre. Wenn ich mit meiner Figur eine Mauer einrenne und ein paar Feuerkugeln werfe, fallen ja die Mauersteine runter und die Feuerkugeln vernichten alle Monster. Wie wird so etwas denn dann i.d.R. verarbeitet? Läuft dann ein MauereinsturzThread bis alle Steine unten liegen und währendessen kann ich im Mainthread meine Figur weiter steuern? Müsste man also aufwendigere Aktionen auch immer in eingenen Threads ausführen damit das Formular nicht einfriert? (Wenn ich gerade so drüber nachdenke wird es wohl so sein, da Windows sonst ja sicher schon selbst das Formular als inaktiv erkennt - oder?). Insofern ist mein Versuch ![]() |
AW: OpenGL - Grundsatzfragen
Da ich mir dein Projekt selbst noch nicht genau angesehen habe kann, hier nur ganz konkret auf die Fragen:
1) Wenn es dir um die Performance geht fängt man entweder an, Objekte vom Rendering auszuschließen und/oder in einem niedrigeren Level of Detail darzustellen. Bei reinen Sprites macht das heute keinen wirklichen Sinn, für "richtige" 3D-Szenen mit viel Geometrie und komplexen Shadern kann man hier aber viele tolle Dinge anstellen, mehr als meist tatsächlich getan wird. Beispielsweise könntest du Cluster bilden und wenn der Großteil der enthaltenen Objekte nicht wichtig ist (bsp. sich nicht vollständig im View Frustum befindet oder die Entfernung von der Kamera hoch ist), sie alle durch eine vereinfachte Cluster-Repräsentation ersetzen. 2) Such mal nach "Mouse Picking" und "Ray Casting". ![]() 4) So etwas hatten wir, meine ich, neulich schon einmal- Die Verarbeitung der Eingabe (Tastatur), die Rendering Pipeline und bsp. die Physik-Berechnung laufen in der Regel nicht synchron. |
AW: OpenGL - Grundsatzfragen
Zu 4:
Bei einer Animation merkst du dir in der Regel die Startzeit der Animation. Dann prüfst du in jedem Frame die aktuelle Zeit und berechnest den Fortschritt der Animation (z.b. der Winkel der Rotation) anhand der vergangenen Zeit. Für eine linear ablaufende Animation wäre das z.b. ganz einfach: 360 * Round((CurrentTime - StartTime) / AnimationTime) |
AW: OpenGL - Grundsatzfragen
Ok, danke schonmal.
Wenn ich einen fallenden Zielstein darstelle, dann befindet sich nicht das fertige Objekt im Speicher und wird nur noch gedreht und verschoben, sondern der Stein wird bei jedem Frame abhängig von seiner Lage und Position neu "zusammengesetzt", dargestellt und als grafisches Objekt wieder "vergessen" - richtig? Im Prinzip machen es die VCL und FMX ja genau so - nur dass dort noch ständige gegenseitige Neuzeichnungen ausgelöst werden, wenn ein Objekt verschoben wird. In meinem oben verlinkten Versuch habe ich dagegen die "2D-Objekte" nur einmal gezeichnet und diese erzeugten Abbilder immer wieder beim Zeichnen des Formulars verwendet. Es sind also völlig unterschiedliche Ansätze und ich tue mich derzeit schwer zu entscheiden, welcher für Fachanwendungen der bessere ist (3D ist ja normalerweise nicht erforderlich). Die dritte Frage würde mich natürlich trotzdem noch interessieren. Wenn man ein Memo selbst aufbauen sollte, incl. Wortumbrüchen, Textcursor usw. das wäre ja ein echtes Mammutprojekt. |
AW: OpenGL - Grundsatzfragen
Hi!
OpenGL oder auch DirectX ( ![]() Hat ja im eigentlichen nix mit der Logic zu tun, sondern bildet ja "nur" die Schnittstelle zur Grafikkarte und zur GPU. Ob und welche Teile du in Thread auslagerst spielt eigentlich keine Rolle. I.d.R. hast Du heute TFT's mit 60Hz also ist 60 FPS das Ziel. Wenn Deine Berechnungen schneller sind, Prima dann hast Du Zeit für andere Dinge. Ich frage zwischen jedem Frame die Tastatur ab, weil es ich nicht leiden kann, wenn eine Tastenreaktion nicht sofort einen Effekt hat. Wenn Deine 3D Scene zu aufwendig wird, musst Du also gemäß Deinem Kamerawinkel und der Entfernung der Objekte erst mal Deine 3D Objekte vor sortieren. Dann über einen ZBuffer rausbekommen ob nicht ggf. eine Vielzahl von Objekten überhaupt nicht sichtbar sind. (Beispiel: Hinter der Wand stehen 1000 Bäume) Ich habe vor meinem Snakeland 3D ![]() Für bewegte Objekte z.B. ein Schuss oder ein sich bewegendes Objekt, rechnest Du ja nicht strikt alle Positionen der Bewegung nacheinander, sondern Du berechnest gemäß der Zeit an welcher Position das Objekt gerade seien soll. ggf. werden dann 20 Zwischenpositionen einfach weggelassen. Für jedem Mauerstein hast Du also in Deiner Renderpipeline einen Eintrag. (Lassen wir mal die Kollisionen und Beeinflussungen durch andere Steine weg) Bei Start von "Mauereinsturz" stehen also gemäß "soll 2 Sekunden dauern" schon alle Positionen fest. Wenn Du also den Aufruf für RenderSteinXY bekommst, musst Du berechnen wie viel Zeit seit dem Start vergangen ist und dann den Stein an der richtigen Position Rendern. Nur so bekommst Du Bewegungen die unabhängig von CPU,GPU Taktfrequenz und Dauer der Berechnung ist. Mavarik |
AW: OpenGL - Grundsatzfragen
Zitat:
|
AW: OpenGL - Grundsatzfragen
Zitat:
|
AW: OpenGL - Grundsatzfragen
Danke Euch! Das waren so schon sehr hilfreiche Antworten.
Mein Interesse ist schon eine Fachanwendung, kein Spiel. Dennoch könnte man das ja mit einer 3D-Engine angehen, was sicher Vor- aber auch Nachteile hätte. FMX ist m.E. leider nicht so ernst zu nehmen, dass man darauf dauerhaft setzen könnte. Teile sind sicher gut umgesetzt aber in der Gesamtheit ist das eher unbrauchbar. Dass sich daran noch etwas ändern wird ist wohl leider auch nicht zu erwarten. Daher interessieren mich mögliche Alternativen. Aber es ist schon nicht einfach, die grundlegenden unterschiedlichen Ansätze zu verstehen. In einer Spieleengine kann man ja m.E. z.B. ein Karussell schnappen und in die Landschaft packen. Ab sofort dreht sich das "eigenständig", ohne dass man sich drum kümmern muss. Das würde ich mir auch von einem AniIndicator erwarten und von einer Progressbar, wenn deren Value geändert wird. Ich hatte so etwas bei FMX erwartet. Inzwischen sehe ich, dass das gar nicht so einfach zu realisieren ist. Das ändert aber nichts daran, dass FMX bei mir inzwischen (fast) aus der Wertung ist - vor allem auch wegen der Firmenpolitik von Emba. Wegen möglichen Alternativen bin ich mir noch unsicher... |
AW: OpenGL - Grundsatzfragen
Ich verstehe noch nicht ganz wo das 3D herkommt und was die Zielplattformen sind. Würdest du es auf Windows beschränken können/wollen? Könnte man perspektivisches 3D-Rendern nicht ausschließen?
|
AW: OpenGL - Grundsatzfragen
Wenn ich das nur wüsste! :stupid:
Ich versuche erst einmal nur, mir einen Überblick über die möglichen Ansätze und Konzepte zu verschaffen. 3D ist für Fachanwendungen i.d.R. ja nicht erforderlich. Man könnte sich aber u.U. auch neue Ansätze vorstellen (ich jedenfalls :stupid:). Z.B. wäre ein Effekt denkbar, dass die Controls leicht kippeln, wenn man mit der Maus drüber fährt. Oder man könnte Kundenkärtchen hintereinander aufreihen, als Historie der letzten bearbeiten Adressen z.B. FMX hat ja da auch bereits Lösungen (jedenfalls grundsätzlich). Jedenfalls könnte eine Anwendung mit 3D-Inhalten optisch ansprechend und angenehm bedienbar sein. Natürlich braucht man dann keine 3D-Landschaften usw. Statt dessen müssten die üblichen Controls angeordnet werden können, die aber mit einer Textur überzogen werden könnten. Einiges wird einfacher, wenn man sich auf 2D beschränkt (geht ja auch mit OpenGL bzw. ![]() Wenn man eine entsprechende Engine bauen wollte, würde man schon erst einmal vor der Frage stehen, ob 2D oder 3D. Davon abhängig sind dann die weiteren Möglichkeiten, Aufwände und mögliche Plattformen. Ich versuche nur herauszufinden was ich mir eigentlich wünsche, selbst wenn das dann nicht erfüllt wird. :stupid: |
AW: OpenGL - Grundsatzfragen
Von 3D würde ich dir abraten. Ich bastele selbst momentan an einem eigenen GUI Framework, welches sich neben GDI+ auch per DirectX und OpenGL rendern lassen soll. Das Projekt ist schon recht fortgeschritten und das Grundgerüst inklusive Standardcontrols (Form, Button, Label, PageControl, etc.) funktioniert schon sehr gut.
Bisher ist nur der DirectX Renderer implementiert und bereits für reine 2D Darstellung (primär gefüllte und nicht-gefüllte Rechtecke und Grafiken / Icons) ist der Aufwand schon enorm hoch (mehrere 1000 Zeilen Code). An kreisförmige Objekte oder sonstige nicht rectanguläre Polygone möchte ich im Moment noch gar nicht denken. Wenn du doch kleine 3D Effekte haben willst (z.b. beim Click auf einen Button), kannst du das wunderbar durch Farbänderungen vortäuschen, ohne dass deine Engine im Hintergrund mit irgendwelchen 3D Matrizen und unterschiedlichen Z Werten hantieren muss. |
AW: OpenGL - Grundsatzfragen
Sehe ich auch so. 2D ist kompliziert genug...
|
AW: OpenGL - Grundsatzfragen
Sehe ich - inzwischen - auch so. ;-)
|
AW: OpenGL - Grundsatzfragen
Zitat:
Was machst Du den in diesen Zeilen alles... "Mein 2D GUI auf DirectX" mit animierter Maus, Labels, Checkbox, Combobox und Button, welches ein 2D GUI im 3D Adressraum für mein Spiel rendert ist nur 1200 Zeilen lang. Es erhebt zwar nicht den Anspruch an die Funktionalität der VCL, aber funktioniert. Mavarik PS.: Ohne die Diskussion anzufangen ob es Sinn mach ein eigenes Framework zu schreiben, wofür die Arbeit? Um sich damit zu beschäftigen und etwas zu lernen, OK! Um damit Geld zu verdienen? Doch eher nicht, oder? |
AW: OpenGL - Grundsatzfragen
Zitat:
Grundklassen wie "TDXComponent" und "TDXControl" fallen nochmal mit 2200 Zeilen ins Gewicht. Dazu muss ich allerdings sagen, dass ich bestimmte (umfangreichere) Funktionalitäten der VCL (wie z.b. Aligning) durchaus nachgebaut habe. |
AW: OpenGL - Grundsatzfragen
Zitat:
|
AW: OpenGL - Grundsatzfragen
Auch wenn das meiste bereits beantwortet wurde, hier noch mein Senf dazu :):
zu 1) Wenn du eine konstante Animationsgeschwindigkeit willst, google mal nach "Framerate independent movement / animation". Die Lösung per Timer ist meistens ungenau, da man kaum sagen kann, wann der Timer wirklich getriggert wird, selbst bei einem MMC-Timer. Das Prinzip basiert einfach darauf, dass der Animations-Fortschritt bei jedem "OnIdle" o.Ä. neu berechnet wird und somit bei jedem Frame die Zeitdifferenz zwischen dem letzten gerenderten Frame / Event und dem aktuellen genommen wird und dort interpoliert wird, wie weit die Animation bei der aktuellen Zeitdifferenz "weiterbewegt" werden muss. Als Ergebniss erhälst du eine konstante Animationsgeschwindigkeit, die unabhängig von der aktuellen Framerate ist. Dieses Prinzip solltest du von Anfang an berücksichtigen, da bei "Vergessen" die nachträgliche Implementation durchaus schmerzhaft sein kann :) Um Objekte auszuschliessen, die gerade in einer "riesigen" Welt nicht berechnet werden müssen und um die Performance zu optimieren, verwendest du am besten ein vierstufiges Verfahren: 1. Frustum Culling Das bedeutet, alle Objekte, die sich gänzlich nicht im Bereich des aktuellen Viewport / Frustum befinden, werden komplett ignoriert / nicht gerendert. 2. Z-Buffer Culling Das bedeutet, im Bereich des Frustums werden Objekte, die gänzlich von anderen verdeckt werden, nicht gerendert. 3. Z-Buffer LOD Das bedeutet, im Bereich des Frustums werden sichtbare Objekte, die weiter von der aktuellen Kameraposition entfernt sind, mit geringerer Detailstufe / Polygonanzahl gerendert. 4. Texture Mip-Mapping Das bedeutet, im Bereich des Frustums werden sichtbare Objekte, die weiter entfernt sind, mit einer kleineren Texturauflösung / mit weniger Details gerendert. zu 2) Verwendest du OpenGL, vergiss ganz schnell die implementierten "Picking-Funktionen". Diese sind, gelinde gesagt, extrem langsam. Viel schneller bist du mit Raycasting, das heisst, du prüfst einfach anhand des Aussendes eines "Strahls" und des Z-Buffers, welches Objekt bei deiner Mausposition an vordester Front liegt (oder überhaupt vom Vektor geschnitten wird). zu 3) Hier wird es aufwändig. Da 3D-Apis so etwas wie "Schrift" an sich nicht wirklich kennen und alles meist über Bitmap-Fonts und Texturen gelöst wird, musst du die vollständige Funktionalität eines Memos o.Ä. selbst in Code giessen, wenn du keine Komponenten benutzen willst. Das ist durchaus machbar, aber extrem langwierig zu implementieren und aufwändig. Macht aber Spaß :) Ansonsten kannst du ggf. auch auf solche Nettigkeiten wie "ScaleForm" zugreifen, falls du ein wenig Geld dafür ausgeben willst. zu 4) siehe 1). Eine 3D-Anwendung arbeitet nie eine Animation "als Ganzes" ab, so dass eine Anwendung während einer Animation nie hängt, sondern nur immer Schrittweise per Frame mit den entsprechenden Berechnungen und Anpassungen weitergeht. Willst du Physik implementieren, dann machen separate Threads durchaus Sinn, das Ganze dann aber Event-gesteuert und nicht linear / strikt funktional. |
AW: OpenGL - Grundsatzfragen
Ja danke!
Inzwischen habe ich ein paar Dinge auch schon besser verstanden. In meiner kleinen Demo ( ![]() Und ich bin zu dem Schluss gekommen, dass 3D eher keinen Sinn macht. Eine gute 2D-Alternative zur VCL und FMX würde mir aber sehr gefallen - unabhängig mal, wo die her kommt... ;-) Man müsste sich nicht mit Altlasten (VCL) und Problemen (FMX) herumschlagen und könnte auf schlanke Basiscontrols aufbauen. Träume darf man ja haben! :) |
AW: OpenGL - Grundsatzfragen
Zitat:
Als "intermediate Layer" gibt es auch noch die SDL mit ihren diversen GUI-Frameworks. |
AW: OpenGL - Grundsatzfragen
Jap, Qt ist echt cool. Vor allem weil es durch das Signal-Slot-System so leicht ist, mit mehreren Threads zu arbeiten und die GUI z.B. asynchron zu updaten.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:17 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