Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Di Mär 19, 2024 10:19

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 3 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Mo Apr 26, 2021 14:16 
Offline
DGL Member

Registriert: Mo Jul 17, 2006 13:16
Beiträge: 69
Hallo mal wieder, danke für's Lesen!

(Hinweis: Es handelt sich um eine reine 2D-Anwendung, Delphi 10.4.2. aktuelle dglOpenGL und glBitmap Header).

Ich habe einen Grafikeffekt nachgebaut (siehe: http://www.sulaco.co.za/opengl_project_render_to_texture.htm), der für ein wenig Bewegung im Hintergrundbild sorgen soll. Letztendlich wird mehrmals die gleiche Textur -leicht gedreht, leicht andere Farbe- übereinander gerendert, so dass schöne Effekte entstehen.

Möchte ich diesen Effekt in meinem Programm nur in einem bestimmten Bereich darstellen lassen, z.B. x/y = 100px, Breite/Höhe = 500px, reichen natürlich die gedrehten Texturen über diesen viereckigen Bereich hinaus, da die Position(x,y) des Bereichs ja nur den Ankerpunkt für die gedrehten Texturen darstellt:
Dateianhang:
2021-04-26 14_34_11-Window.jpg


Der Autor verwendet den kompletten Viewport, um daraus in jedem Render-Durchlauf eine Textur zu erzeugen, die er danach im selben Viewport/Context/was-auch-immer auf einem Würfel darstellt.

Leider kann ich das Beispiel nicht 1:1 auf meine Anwendung übertragen, da ja im ViewPort/Context/Was-auch-immer schon gezeichnet wurde, entsprechend würden die zum Erstellen der Textur benötigten Befehle alles bisherige komplett weglöschen.

Tatsächlich funktioniert die Lösung über Framebuffer / FBO hervorragend, ABER die Prozessorlast meines gehobenen i7 Systems geht von 0,8% (ohne FBO) voll durch die Decke (dauerhaft > 25% mit FBO), das kann also keine Lösung sein. Ich verstehe nicht, was bei FBO so anspruchsvoll ist.

Gibt es denn eine einfache Lösung, wie ich sagen kann, ich möchte nur das Rechteck des Bildschirms im Bereich Rect(100, 100, 600, 600) bearbeiten [können], bzw. dass sich alle Aktionen nur darauf auswirken? In der Wiki etc. stößt man immer wieder auf den Stencil Buffer. Auch hierzu habe ich ein Beispiel http://www.sulaco.co.za/opengl_project_stencil_buffers.htmgefunden, was ich aber nicht schaffe korrekt auf mich umzuändern (Auch weil mir nicht vollkommen klar ist, was genau zur -imo sehr aufwändigen- Demo gehört, und was jetzt genau die Befehle der Lektion sind...).

Code:
  1.   glEnable(GL_STENCIL_TEST);    {** ENABLE STENCIL BUFFER **}
  2.   // Create a square area in the stencil buffer
  3.   glPolygonMode(GL_FRONT, GL_FILL);
  4.   glPolygonMode(GL_BACK, GL_FILL);
  5.   glStencilFunc(GL_ALWAYS, 1, 1);
  6.   glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
  7.  
  8.   //glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);    // Clear The Screen And The Depth Buffer
  9.   // ^-- Auskommentiert. Auch hier kann ich nicht alles schon gezeichnete wegwerfen!
  10.   glStencilFunc(GL_EQUAL, 1, 1);
  11.   glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
  12.   glBegin(GL_QUADS);
  13.     glVertex3f(PositionViewer.Left, PositionViewer.Top, 0);
  14.     glVertex3f(PositionViewer.Left, PositionViewer.Bottom, 0);
  15.     glVertex3f(PositionViewer.Right, PositionViewer.Bottom, 0);
  16.     glVertex3f(PositionViewer.Right, PositionViewer.Top, 0);
  17.   glEnd;
  18.  
  19.   // Meine Zeichnen-Befehle kommen hier (die, die sich nur auf das o.g. Rechteck auswirken sollen)
  20.  
  21.   // Cleanup: Wieder Alles für Alles freigeben
  22.   glStencilFunc(GL_NOTEQUAL, 1, 1);
  23.   glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
  24.   glDisable(GL_STENCIL_TEST);
  25.  


Ich nehme an, der Fehler liegt darin, dass zunächst der komplette Bildschirm die Bitmaske "Darf-Zeichnen" hat, und ich deshalb mit dem markierten Rechteck "Hier-Darf-Gezeichnet-Werden" sprichwörtlich Wasser in den Rhein trage, wohl auch weil ich glClear hier nicht nochmal verwenden kann? Wie müsste das Beispiel korrekt aussehen?
Danke!


Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Apr 27, 2021 09:09 
Offline
Ernährungsberater
Benutzeravatar

Registriert: Sa Jan 01, 2005 17:11
Beiträge: 2067
Programmiersprache: C++
Hast du Delays eingebaut? Wenn du das Hintergrundbild ständig aktualisierst geht die Auslastung immer auf 100% (auf einem Kern) hoch.

_________________
Steppity,steppity,step,step,step! :twisted:
❆ ❄ ❄ ❄ ❅ ❄ ❆ ❄ ❅ ❄ ❅ ❄ ❅ ❄ ❄
❄ ❄ ❄ ❅ ❄ ❄ ❄ ❅ ❄ ❄ ❆ ❄ ❄


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Apr 27, 2021 10:05 
Offline
DGL Member

Registriert: Mo Jul 17, 2006 13:16
Beiträge: 69
Das Problem mit dem FBO liegt tatsächlich daran, dass alles auf dem Kopf gerendert wird, und auch mit glOrtho und glScale das nicht wirklich klappt, richtig herum zu drehen. Also musste -bis dato- die Textur bei jedem Rendervorgang vertikal gespiegelt werden, was mit Runterladen-FlipV-Hochladen durchaus sehr rechenintensiv war. Ich habe jetzt eine eigene Render-Prozedur für den FBO der immer alles auf dem Kopf rendert (dadurch stimmt es ja dann letztendlich wieder), ich muss es jetzt nur noch wieder soweit anpassen, dass meine exporte der Textur als .png-Datei nachher auch wieder richtigrum sind (also vor dem Export richtig drehen, exportieren, zurückdrehen).

Letztendlich ist also FlipV das essenzielle Problem bei der Benutzung des FBO.

Zusätzlich blieb mir nichts anderes übrig, als das Erzeugen/Freigeben des FBO an Create/Destroy meines eigentlichen Objektes zu koppeln. Hier könnte ich nochmal die Prozessorlast in der Demo-Anwendung von ca. 8% auf 0,8% senken.

Momentan scheint es so, als ob ich die Aufgabe mit nem FBO doch gelöst habe.

Ich habe gestern noch viele Stunden Anleitungen und Videos zu Stencil Buffer gelesen bzw. gesehen. Das eigentliche Prinzip ist mir klar, aber leider verstehe ich den Quelltext der dazugehörigen Beispiele gar nicht. Ja, die Zeilen schon, aber die Zusammenhänge nicht: "Hier zeichen wir die Maske mit GL_Always damit sie auf jeden Fall gezeichnet werden kann, und jetzt stellen wir alles auf GL_Keep, weil wir ja schon alles gezeichnet haben..." - ???. Es kommt bei den ganzen Tutorials nicht rüber, bis wohin die Maske erstellt wird, und ab wann jetzt unter welcher Bedingung tatsächlich gezeichnet werden kann, und wo nicht. Gerade reden wir im Tutorial über Stencil Buffer, auf einmal dreht sich alles nur noch um bestandene Tiefen-Tests. Klar, Stencil Buffer arbeiten mit Tiefentest-Prüfung... aber warum? Und was hat das jetzt damit zu tun, wenn ich alles gleichzeitig nur auf Z Ebene 0 zeichne?

Ein -für mich geeignetes- Tutorial würde in der ersten Stufe beispielhaft so aussehen:
Dateianhang:
StencilBuffer_Tut.jpg

Alles in 2D, Z-Ebene 0.
1) Hintergrund zeichen (glQuad mit unterschiedlichen Farben an allen Ecken), um zu zeigen, dass man StencilBuffer auch erst nachträglich einbauen kann
2) evtl. mit glClear(GL_STENCIL_BUFFER_BIT) oder so den alten Stencil-Buffer löschen, dann mit den passenden Optionen mit glQuads einen [un]sichtbaren Bereich zeichnen (Orangenes Rechteck), der die StencilBufferBits (=1 ??) enthält.
3) Modus Umschalten auf "Zeichne nur, wo StencilBufferBit = 1" --> grünes Rechteck
4) Modus Umschalten auf "Zeichne nur, wo StencilBufferBit = 0" --> rotes Rechteck
5) Stencil-einschränkungen aufheben und/oder StencilBuffer löschen und blaues Rechteck zeichnen

Die zweite Stufe des Tutorials würde dann wahrscheinlich Sonderfälle abdecken, z.B. wären dann rotes und grünes Rechteck größer, und dort, wo nur sie sich (im StencilBufferBit>2 Bereich) überlappen, wird gezeichnet oder sowas.
Stufe 3 wäre dann mit einer Textur (wie in der Wiki das Beispiel mit dem Cockpit), Stufe 4 dann die Erweiterung um Z mit Tiefentests etc.

Der Bonus wäre natürlich, wenn man mit einem Steuerelement oder Tastendruck die verschiedenen Modi umschalten kann, um zu sehen, wie sich das Ergebnis dann ändert (GL_LESS, GL_GREATER, GL_EQUAL, GL_NOTEQUAL etc.), bzw. eine Ansicht, die zeigen würde, wo die Stencil-Buffer Maske nun aktiv ist, und wo nicht. Vielleicht ist ja mal jemandem Langweilig ;-)

Ich bin super dankbar, für die ganze Arbeit die hier im Forum (Danke hier auch ionos), in der Wiki und dem drumherum geleistet wird!


Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 3 Beiträge ] 
Foren-Übersicht » Programmierung » Einsteiger-Fragen


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 5 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.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.045s | 17 Queries | GZIP : On ]