Ich mal wieder, mit nem Thread der vermutlich auch wieder etwas länger wird, diesmal gehts, wie oben schon erwähnt um FBOs. Ich bin momentan dabei, mich um eine OpenGL-GUI zu kümmern, und diese soll unter anderem auch eine Komponente erhalten, die etwa analog zu TForm funktioniert (nennen wirs im folgenden mal TOGLForm) - also andere Kontrollelemente beinhaltet, wie zum Beispiel Labels oder Buttons, und sie soll mittels Drag & Drop bewegbar sein. Gleich vorweg, dazu existiert noch kein Code, da ich mich zunächst vergewissern wollte, ob ich nicht irgendwo einen fatalen Denkfehler mache, der dazu führt, dass ich am Ende sowieso wieder alles über den Haufen werfen muss.
Ich hab mir jetzt gedacht, da sich nicht in jedem Frame etwas am Inhalt dieser Menüs ändern wird, verpasse ich jedem Ableger von TOGLForm ein Boolean, dass solange False ist, bis ein Attribut verändert wird, welches die Ausgabe beeinflusst. In der Renderprozedur von TOGLForm wollte ich dann abfrage, ob dieses Booleanfeld True oder False ist:
False - Binde die Textur, in die TOGLForm gerendert wurde und rendere ein Quad an der Position von TOGLForm. True - Schalte auf Offscreen-Rendering in die der Form zugewiesenen Textur, rendere alle Komponenten von TOGLForm dort hinein, und verfahre danach wie bei False.
Nach dem ich etwas zum Thema Offscreen-Rendering gestöbert hatte, dachte ich mir, prinzipiell schreit das nach einem FBO. Und hier meine erste Frage: Ist das ein Irrtum meinerseits, oder stimmt das soweit? Im Tutorial FBO steht nämlich zwar, dass FBOs gut zum Offscreenrendern geeignet sind, aber nicht so wahrlich, wofür genau man sowas dann einsetzt. (Meiner Meinung nach fehlt in dem Tutorial tatsächlich ein kleiner Absatz zum Thema Motivation)
Nun stellen sich da einige weitere Fragen: ("Textur" meint im folgenden immer eine Textur, in die via FBO gerendert werden soll)
1. Im Tutorial ist die Textur, in die gerendert wurde quadratisch und eine POT-Textur (512x512) - kann ich: a) mittels FBOs auch in nicht-quadratische Texturen rendern? (Ich denke doch, oder?) b) auch NPOT-Texturen ohne (signifikante) Performanceeinbußen benutzen? (Hier bin ich mir unsicher, tendiere aber zu nein)
2. Wenn 1a oder 1b zu verneinen sind - wie stell ich es am geschicktesten an, meine Methode auf rechteckige Menüs mit womöglich recht "krummen" größen anzuwenden? Meine Herangehensweise dazu wäre bis jetzt, die TOGLForms jeweils in (quadratische) POT-Texturen zu zerlegen und beim Rendern der Form in das FBO jeweils abfragen, was in welcher Textur landet.
3. Laut Tutorial ist es schneller, in einem FBO mehrere Texturen, in die offscreen gerendert wird zu verwalten, als für jede Textur ein neues FBO zu erzeugen. Macht es da Sinn, eine Art FBO-Manager zu schreiben, der dafür sorgt, dass bei jeder neu zu erstellenden Textur geprüft wird, ob alle bis jetzt vorhandenen FBOs "voll" sind, und wenn nicht diese Textur in einem FBO erstellt, in dem noch Platz ist? Der müsste sich dann (natürlich) auch darum kümmern, sich zu merken welche Textur in welchem FBO steckt, damit beim Rendern kein Chaos entsteht...
Das wars vorerst mal wieder von mir, danke im Vorraus fürs Weiterhelfen!
P.S.: Mit dem VBO-Tutorial hab ich ein ähnliches Problem, auch hier fehlt irgendwie der "Wenn du das machen willst, solltest du zu einem VBO greifen"-Absatz. Bei beiden Tutorials wärs auch ganz nett, wenn ein anschauliches Beispiel vorhanden wäre, ähnlich wie das beim Tutorial Renderpass der Fall ist. Im momentanen Zustand sind sowohl das FBO- als auch das VBO-Tutorial meiner Meinung nach eher etwas, für Leute, die schon wissen, wofür man die Extensions einsetzen sollte, aber nochmal nachschlagen müssen, wie das eigentlich funktioniert.
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Der Ansatz, die Teile in eine Textur zu rendern, um Performance zu sparen, ist denke ich schon mal nicht schlecht. Nur wenn irgendwann Animationen hinzu kommen, solltest du überlegen, ob das überhaupt noch effizient ist. Ich gehe fest davon aus, dass FBOs keine NPOT-Texturen können. Du könntest also entweder Platz verschwenden, indem du die Texturen auf die nächstgrößere POT-Größe aufrundest (das ginge auf jeden Fall schneller, weil du hier nicht zerlegen und mit Quads zusammensetzen musst) oder halt wirklich aufspaltest.
greetings p.s.: Für GUIs eignet sich meines Erachtens der Immediate Mode (beziehungsweise in OpenGL3 dann Vertex Arrays) besser als VBO. Die Daten ändern sich ja gerne mal.
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Registriert: Di Mai 18, 2004 16:45 Beiträge: 2623 Wohnort: Berlin
Programmiersprache: Go, C/C++
Gui Elemente sind sehr primitive Elemente und ein Gewinn bei FBO hast du nur, wenn diese wirklich komplex sind. Also für ein einzelnes Element ist es nicht geeignet aber wenn du die ganze gui in ein FBO renderst, dann hast du was von. Ein FBO jeden Frame zu updaten ist nicht tragisch und wenn die GUI sich nicht ändert entfällt das update und man muss nur noch mit Alpha den FBO über die Szene Zeichnen(das bringt dann erst wirklich Entlastung). Beim Rendern der GUI geht die meiste Zeit für das zeichnen von Schriften drauf und da kann man nicht wirklich was machen. Du solltest deine GUI auch immer mit Tiefenpuffer aktiv zeichnen und von niedrigsten Kind-Element nach oben zum Root zeichnen. Dadurch fällt der ganze Overdraw weg. Sinnvoll ist es auch Scissor vor dem Rendern an zu machen und immer Fleißig ein zu setzen. Erstens kannst du so problemlos überstehenden Text/Widgets einfach cutten und es spart viel Renderzeit, da er schon am Anfang der Pipeline alles verwirft.
Die meiste Entwicklungszeit solltest du in den Font-Manager stecken, mit dem steht und Fällt die GUI. Wichtig sind, der support von Symbolen ausserhalb des ANSI, unterschiedliche Pixelgrößen, Färbung von Schrift und Stiel(Fett/Kursiv/Normal).
Die restliche Zeit ist bei den Callbacks gut aufgehoben, da diese nach Fonts so ziemlich der größte Zeitfresser sind. Diese können sehr schnell sehr sehr langsam werden, wenn man es nicht wirklich vorher genau durch plant. Möglichst nur 1 Parameter, wenn überhaupt im Callback nutzen, damit der Stack nicht unnötig belastet wird und Pointer sind hier dein Freund. Vermeide jedes Callback was nicht wirklich notwendig ist, denn funktionsaufrufe sind einfach teuer. Verifiziere bei einem Event erstmal den Empfänger und schick nichts über rekursive Aufrufe raus. Wenn deine Maus sich bewegt, kannst du z.B. erstmal prüfen ob die Maus innerhalb vom Fenster ist, dann Prüfst du die Rootelemente(rekursiv würde bei jeder prüfung ein overhead(funktionsaufrufe, stackaufbau,stackabbau) anfallen). Ist ein positives Ergebnis dabei, dann gehst du die Kinder des positiven Rootelementes durch und so weiter, alles innerhalb von einer Funktion und am Ende generierst du dann deine Eventstruktur und schickst den Callback an das Widget. Vor der Boundingbox Prüfung sollte erstmal eine Prüfung durchlaufen, ob das Widget überhaupt das Event verarbeiten soll(es reicht ein set mit IN prüfung und bei der Erstellung sowie verbinden von den OnEventIrgendwas wird eventuell noch die Variable um ein Element aus dem Set erweitert).
Sollte die Performance dann immer noch zu schlecht sein gibt es dann ganz schicke Optimierungen wie z.B. Quadtree zur schnelleren Widgetbestimmung bei Maus Events und zerlegung der Kind-Elemente in diverse Listen, sortiert durch deren möglichen Events. Da muss die Zielhardware aber schon echt bescheiden sein, wenn sowas notwendig wird.
Wie du die Widgets zeichnest ist auch noch so ein Problem. Bei Spielen wird in der Regel die GUI einmal designed und dann ledeglich mit der Auflösung passend skaliert, also das vergrößern von Höhe oder Breite, eines Fensters gibt es nicht. Dies erlaubt die reduzierung von den komplexen WindowManager Widgets, mit klassischen 3x3 Tabellen layout(Rand links,oben,rechts,unten, Darstellungsfläche mitte) auf ein einfaches 1 Quad Element und oh wunder das kann man mit VBO problemlos zeichnen, ohne updates an der GUI machen zu müssen. Willst du allerdings schon Fenster größer und kleiner machen, dann kommst du um das klassische 3x3 Tabellen Layout nicht drum rum aber das ist nicht so tragisch. Man kann davon ausgehen, das ein resize eines Widgets nicht gerade 30x in der Sekunde passiert und da kann man das vbo auch ruhig mal updaten, ohne große Performanceverluste. Gerade hier zeigt sich dann auch die Stärke von VBO gegenüber Immediate Mode, da man nun schon 18 Dreiecke zeichnet und dazu noch Texturkoordinaten hat und man ja nicht nur 1 Widget zeichnet. Dank Shader kann man heute auch ganz schicke dinge tun, so hab ich z.B. über ein Shader quadratische und kubische bezierkurven für 2D implementiert. So kann ich aus 2 Triangles eine makellose Fensterrundung realisieren, die sogar Kantenglättung hat und nicht wie Texturen dann an der Texturauflösung scheitern(siehe http://dl.dropbox.com/u/1672275/Bildschirmfoto-GraphicContext-Demo.png).
_________________ "Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren" Benjamin Franklin
Registriert: Do Sep 25, 2003 15:56 Beiträge: 7810 Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Es gibt hier im Forum bereits diverse GUIs für verschiedene Sprachen. Wenn du damit Leben kannst, dass die GUI nicht 100% deinen Codestyle/Architekturprinzipien entspricht und du dir 1/4-1/2Jahr Arbeit sparen willst, dann nimm dir lieber eine von denen. GUIs fressen eine Menge zeit!
Für Delphi/Pascal hatte Traude eine GUI geschrieben Für Java/JOGL hab ich eine (wo gern auch jemand anderes etwas optimieren/erweitern kann... )
Falls du mit Delphi/Pascal arbeitest: Nimm die TextSuite von Lossy für Fonts. Besser kriegst du es nicht!
_________________ Blog: kevin-fleischer.de und fbaingermany.com
Auf die Idee, die Textur einfach mit transparentem Hintergrund zu erstellen und über den Hintergrund zu blenden war ich gar nich gekommen - wie man manchmal an die einfachsten Dinge nicht denkt...peinlich. Aufspalten kommt damit nicht mehr in Frage Wie das mit Animationen aussieht werd ich dann ja sehen, noch keine Ahnung, wie animiert die Geschichte letztlich wird.
@TAK: Deinen Post hab ich zugegebenermaßen erstmal nur überflogen. Wenn ich dich richtig verstehe, meinst du, das selbst bei Animationen, die jeden Frame geupdatet werden die FBO-Lösung immernoch performanter sein sollte - zumal die Animationen ja auch nicht die ganze Zeit laufen. Zum Thema Schriften wollte ich mich eigentlich auf Lossy's Textsuite verlassen - SketchtowerWars ist zwar kein großes Projekt, und die Wahrscheinlichkeit, dass die Textsuite am Ende mehr als 50% des Gesamtcodes ausmacht ist nicht klein, aber a) Hält sich die Tutorialsammlung, was Schriften angeht enorm zurück und b) Hab ich dann was Ausgereiftes an der Hand und damit einen Teil weniger, den ich verbocken kann Ich hab allerdings auch keine großen Ansprüche zum Thema Schriften - grob überschlagen brauch ich maximal 1-2 Schriften in vielleicht 3 verschiedenen Größen - mehr nicht.
Den Teil über Ereignisverarbeitung muss ich in Ruhe verdauen - für eine Antwort im Anfängerforum ist der ehrlich gesagt sehr....erschlagend. Aber ich glaube, der Grundgedanke is mir klar geworden und entspricht etwa dem, was ich mir auch schon überlegt hatte
Größenänderungen sollen btw. nicht möglich sein, das sollte also keine Implementationsprobleme nach sich ziehen ^^
@Flash: Selber die GUI zu schreiben war an sich schon ein Ziel, dass ich mir gesetzt hatte - sie muss ja nicht perfekt sein, aber ich hab schon ein paar eigene Ideen und würde auch gern das ein oder andere "spezielle" Kontrollelement einbauen...wenns mir wirklich zu viel wird, oder das ganze sich als zu unperformant herausstellt - kann ich immernoch umschwenken. Zur Textsuite - siehe oben
Registriert: Do Sep 25, 2003 15:56 Beiträge: 7810 Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Naja... die GUIs sind ja kein finales Produkt. Ich habe meine GUI in meinem Spiel Balance verwendet. Dort habe ich dann gedacht... "Die Karte die ich hier darstellen will (das Spielfeld quasi) soll ja auch anklickbar sein... wieso leite ich das nicht einfach von einer GUI Klasse ab" Gesagt getan. Dadurch hatte ich alle Mauseventhandling Sachen, Klickfindung etc. schon fertig.
Kurz: Wenn du dir eine GUI nimmst die schon geht, kannst du mit recht geringen Aufwand deine Spezialkomponenten davon ableiten und musst nicht wieder vom Urschleim anfangen.
_________________ Blog: kevin-fleischer.de und fbaingermany.com
Mitglieder in diesem Forum: 0 Mitglieder und 6 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.