Registriert: Do Feb 21, 2008 22:10 Beiträge: 89 Wohnort: Boppard
Hi,
Ich zeichne mein Formular mit der Funktion PaintTo(bmp.Canvas,0,0) in ein Bitmap
und gebe dies später mit glDrawPixels(...); aus.
Dies gibt auch das Formular größtenteils wieder.
Nur habe ich ein paar Probleme:
1.) Popups werden nicht mit PaintTo gezeichnet. Weiß jmd. wie ich die manuell zeichnen kann?
2.) Ich will irgendwie eine TransparentColor Eigenschaft einbauen, damit bei glDrawPixels nicht der
ganze Bildschirm übermalt wird. Hat da jemand eine Idee wei man das machen kann?
Ich hoffe jemand kann mir helfen (wenns auch nur ansatzweise Ideen sind).
Registriert: Do Feb 21, 2008 22:10 Beiträge: 89 Wohnort: Boppard
I just found out that i can use GL_RGBA in glDrawPixels
Hab das zuerst nicht bemerkt. Habe das jetzt schon eingebaut.
Jetzt muss ich nur noch das Alphamasking hinzufügen.
Doch meine 2. Frage ist immer noch offen.
@noeska: A textured Quad wouldn't be so good, because then i have dto generate a Texture each Frame.
Ich habe mal die Unit, mit den GUI-Zeichen-Funktionen angehängt. Wenn das Alphamasking drin ist werde ich eine neue Version anhängen.
PS: Ich frage mich, ob schonmal jemand auf so eine Idee gekommen ist.
Immerhin kan man so doch ohne großen Aufwand Fonts usw. eibauen. Alle möglichen Controls sind ja möglich!
EDIT: Datei ist nun im Post unter "mir" zu finden
Zuletzt geändert von olee am Di Nov 04, 2008 20:39, insgesamt 2-mal geändert.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Die GUI von Windows passt ja meistens nicht unbedingt zu dem Design was in Spielen verwendet wird. Das wird wohl ein Grund sein. Außerdem hast du noch verschiedene Probleme die auf den ersten Blick nicht so recht auffallen. Wenn man damit leben kann ist es sicherlich okay. Wenn nicht, dann muss man wieder so extrem in das Geschehen eingreifen. Dann ist man wohl einfacher dran, wenn man sich eine einfache GUI selber schreibt.
Zum Beispiel. GUI Elemente können gewissermaßen Animationen enthalten. Der Eingabecursor eines TEdits blinkt. Und das ist etwas was innerhalb von Windows passiert. Davon bekommt dein Fenster nichts mit. Bzw ich meine sogar, dass beim Zeichnen von Eingabefeldern der Eingabecursor gar nicht angezeigt wird. Oder wenn du einen Buton runter drückst, dann weiß das höchstens der Button. Entsprechend werden solche Zustände bzw Minianimationen einfach nicht mit übernommen. Bzw du kannst nur extrem Schwer darauf reagieren.
Popups sind seperate Fenster. Also die haben mit deinem Form so direkt nichts zu tun. Genau so auch wie die Liste einer Combobox. Diese Fenster werden von Windows verwaltet. Also ohne deren Fensterhandle kannst du nicht mal darauf zugreifen. Und das Handle weiß man zum Glück nicht. Also bekommst du so etwas nur extrem schwer in ein Bitmap.
Wenn man mit solchen Einschränkungen keine Probleme hat, dann spricht da aber nichts gegen. Aber sofern man so etwas unbedingt braucht wird es nur zu fummelig.
glDrawPixels: Ich weiß im übrigen auch nicht ob glDrawPixels so wirklich performant ist. Denn du zeichnest direkt in den Framebuffer. Und zwar aus einem Speicherbereich der im RAM liegt. Das hat gleich 2 Probleme.
1) glDrawPixels arbeitet direkt auf dem Framebuffer. Das könnte dadurch auch deutlich langsamer sein als normales Rendern. Der Befehl glBitmap arbeitet auch direkt auf dem Framebuffer und der ist mitunter deutlich langsamer. Aber bei dem müssen die Bytes auch in Bits zerlegt werden. Von daher weiß ich nicht ob glDrawPixels tatsächlich entsprechend langsamer ist.
2) Die GPU und die CPU arbeiten asynchron. Normal werden die Befehle genommen und in eine Befehlskette gepackt die dann von der Grafikkarte ausgeführt werden, wenn sie Zeit hat. Die CPU kann in der Zwischenzeit schon wieder ganz andere Sachen machen. glDrawPixels wiederrum kann aber erst ausgeführt werden, wenn die GPU nichts mehr macht, da sie sich sonst die Zeichenreihenfolge nicht mehr stimmt. Entsprechend kann es sein, dass die erst mal CPU warten muss. Beim Zeichnen müssen die Daten außerdem aus dem RAM übertragen werden. Daten im Grafikspeicher werden um ein vielfaches schneller übertragen. glDrawPixels kann sich auch erst beenden, wenn wirklich alles übertragen wurde, da der Speicher im Anschluss gelöscht werden könnte. Wenn du eine unglückliche Stelle für glDrawPixels erwischt hast, dann kann es sein, dass sowohl CPU als auch GPU ausgebremmst werden.
Entsprechend würde ich dahingehend empfehlen das glDrawPixels durch eine echte Textur auszutauschen. Diese liegt dann im Grafikkartenspeicher und wird mit in die Befehlskette eingehangen. Wird schneller verarbeitet und sie bremsen sich nicht gegenseitig aus.
Registriert: Di Mai 18, 2004 16:45 Beiträge: 2623 Wohnort: Berlin
Programmiersprache: Go, C/C++
Nur das ich das nicht falsch verstehe, noch mal wie ich das verstanden habe.
Du zeichnest mit der glDrawPixels Funktion eine Bitmap direkt auf den Screen und stellst darüber GUI Elemente dar.
Wenn das der fall ist, dann empfehle ich dir schon mal den Code zu zippen und ganz weit weg in einen der tiefsten Ordner, die du finden kannst, zu packen.
Denn wenn du nicht gerade vor hast, eine gf280 und 4Ghz und aufwärts CPU als Systemvorraussetzung zu haben, wenn du deine GUI zeichnest dann wirst du damit nicht weit kommen. Diese Funktion ist so ziemlich das langsamste, wie man auf einen Monitor zeichnen kann, mit Ausnahme von Klassenkonstrukten und der Rendermachine von Java :p . Erstmal ist OpenGL überhaupt nicht dafür ausgelegt, externe Pixelmaps auf den Monitor zu zeichnen und die routinen sind auch schon ziemlich veraltet.
Alternativen wären z.B. folgende.
Klassisch über schon geladene Texturen auf ein Quad(im ortho modus) zeichnen.(ziemlich schnell)
Vektorbasierte GUI, welche die GUI durch die normalen OpenGL Mesh Funktionen zeichnet(schneller gehts nicht mehr)
Vektorgui mit Shadern, wie zuvor, nur dass man das ganze in ein FBO rendert und über Shader noch einzelne Texel manipuliert.(langsamer aber sollte von X11 Beryl und Vista Aero Glass bekannt sein)
In einem Software Renderer(wie Mesa) sollte deine Lösung aber mit die Performanteste sein, da man da nur noch memcpy in einer schleife machen muss.
_________________ "Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren" Benjamin Franklin
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
@TAK: Die Bitmap ist seine GUI, die wird nicht darüber gezeichnet. Dennoch, ich würde dir auch die Variante mit einem Texturierten Quad empfehlen. Du musst ja nicht jeden Frame die Textur neu erstellen, du musst sie nur neu füllen. Wenn du das mit glTexSubImage2D machst, kommst du damit ganz gut weg (vorrausgesetzt, du initialisierst die Texturgröße einmal).
Gruß Lord Horazont
_________________ 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: Do Feb 21, 2008 22:10 Beiträge: 89 Wohnort: Boppard
@Lossy eX: Doch, alle Sachen wie wenn ein Button gedrückt ist und auch der Mauszeiger funktionieren.
Immerhin rufe ich ja die Widows zeichenfunktionen auf, um an das Bild meiner GUI zu kommen.
Und zur Geschwindigkeit:
Bei einer Auflösung von 1024*768 kann ich fast ruckelfrei eine (PerFrame) GUI zeichnen lassen,
die den gesamten Bildschirm ausfüllt.
Wenn dann noch Ein großteil dieses Fensters wie bei mir durchsichtig ist (traspColor), wird es durch
das Alphamasking sogar sop schnell, dass man noch eine simple 3D Scene nebenbei rendern kann.
Nun hätte ich ein paar Fragen:
Währe es vllt. schneller das Bild erst in ne Textur zu laden und diese dann nicht mit glDrawPixels zu zeichnen?
EDIT: Man muss ja auch nicht eine gui zeichnen, die den ganzen Bildschirm ausfüllt.
Das ganze ist ja praktisch, dass man z.B. einen Button aufm Formular platziert, und nur den zeichnen lässt und nicht das ganze Formular. Oder auch ein Panel mit ein paar sachen drauf.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Geschwindigkeit: Ich hatte vor 1-2 Jahren ein kleines Beispiel mit einer sehr simplen GUI gemacht. Dort wurde wirklich alles selber gezeichnet. Entsprechend ein Button aus 9 Quads erstellt. Das Beispiel bestand auch nur auch ein paar Buttons, Checkboxen, Radiobuttons. Und auf meiner Radeon 3850 habe ich immer über 2.000 fps bis zu 10.000 bei (500x400). Die Karte hat natürlich ordentlich Leistung aber Transparente Texturen zu zeichnen ist aber auch nicht anspruchsvoll.
Also ich denke es wird sich in jedem Fall lohnen auf Texturen umzustellen. Wobei du natülich sehr sehr häufig diese Textur aktualisieren musst und das ist etwas was dich davon abhalten wird das echte Potential deiner Karte wirklich ausnutzen zu können. Denn glTexSubImage2D unterliegt auch der Synchroniationsproblematik die ich unter "2)" beschrieben habe. Evtl nicht ganz so krass wie glDrawPixels.
Was die Fenster angeht. Ich denke da hast du mich missverstanden. Wenn du ein TEdit auf dem Formular hast und in dieses klickst, dann hast du einen Eingabecursor. Ein Strich der markiert an welcher Stelle Zeichen eingefügt/gelöscht werden. Der ist beim Zeichnen mit PaintTo nicht vorhanden. Die Markierung in einer TListBox ist auch nicht vorhanden. Bzw bei einer TComboBox ist sowohl die ausklappbare Liste bzw der Text nicht da. Zu mindest bei Delphi7 und Delphi 2007. Das heißt grob funktioniert es aber eben nicht immer. Der Fokus auf einem Button ist da. Aber du bekommst es so nicht immer direkt mit, wenn sich was ändert (button nur gedrückt). Sondern du musst dauerhaft die GUI zeichnen lassen und die Textur aktualisieren. Das ist natürlich schon ein gewisser Aufwand. Da wäre es besser nur dann die Textur zu aktualisieren, wenn sich etwas ändert. Aber das bekommt man nicht zuverlässig genug mit.
Registriert: Do Feb 21, 2008 22:10 Beiträge: 89 Wohnort: Boppard
Also mir ist auch klar geworden, das das nicht so praktisch ist.
Nur für Schrift und Buttons kann das praktisch sein. Eigabefelder eher nicht.
Aber eigentlich gibtes nen blöden Grund warum ich das machen wollte:
Ich habe ein Game, bei dem auf Formular ein kleines Panel mit ComboBox und 2 Buttons ist.
Wenn es nicht Fullscreen läuft, sieht man das Panel, wenn Visible=true.
Nun ists aber so:
Alter PC (XP) : Auch bei Fullscreen kann man das panel sehen.
Neuer PC (vista) : Wenn fullscreen aktiviert ist, sieht man hier das Panel einfach nicht,
aber blitzt es am Anfang für ein zwei Frames auf.
Weiß jemand, wie ich das Panel wieder in den Vordergrund kriege?
Registriert: Mi Aug 13, 2008 12:39 Beiträge: 26 Wohnort: Berlin
*laut denk* Hmh wie kann man denn eigentlich Foreneinträge verlinken??
So wie ich das sehe hast du das selbe Problem wie ich auch: Vollbild lässt Komponenten verschwinden. Du kannst ja mal im Einsteiger-Forum gucken, da ist ganz oben ein Beitrag (von mir ) wo eben dieses Problem ebenfalls diskutiert wird und ich glaube eine recht gute Lösung gefunden zu haben.
Mitglieder in diesem Forum: 0 Mitglieder und 10 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.