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

Aktuelle Zeit: Di Jul 08, 2025 19:18

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



Ein neues Thema erstellen Auf das Thema antworten  [ 8 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Mi Mai 04, 2011 16:28 
Offline
DGL Member

Registriert: Mi Mai 04, 2011 16:09
Beiträge: 11
Hallo Leute!

Ich bin neu hier, zunächst einmal ein dickes Lob an diese Seite! Ich habe eine Virtualisierung im Kopf gehabt und nach nur einigen Stunden Studium dieser Seite tatsächlich mein gewünschtes 3D-Ergebnis auf dem Bildschrim gesehen, große Klasse, Danke an alle!

A)
Eine Frage habe ich nun aber doch, mir ist auch nach lesen der Tutorials nicht genau klar, welche Teilsaspekte in einem 3D-Programm in welcher Reihenfolge bearbeitet werden...

Was bei mir funktioiert:

Code:
  1.  
  2. Init:
  3. * InitOpenGl, DC + RC holen
  4.  
  5. Vorarbeit:
  6. * glViewport(0, 0, Panel1.ClientWidth, Panel1.ClientHeight);
  7. * glMatrixMode(GL_PROJECTION);
  8. * glLoadIdentity;
  9. * gluPerspective(45.0, 1, NearClipping, FarClipping);
  10. * glMatrixMode(GL_MODELVIEW);
  11. * glLoadIdentity;
  12. * gluLookAt(...);
  13. * Clear...
  14.  
  15. Zeichnen
  16. * glBegin, ..... glEnd
  17.  
  18. Anzeigen
  19. * SwapBuffers(DC)
  20.  
  21. Saubermachen:
  22. * RC +, DC Abmelden
  23.  
  24.  


so weit, so gut.

Ich möchte nun während des Programmablaufes um das von mir gezeichnete Objekt laufen. Dazu möchte ich das Objekt aber nicht neu zeichnen, das habe ich ja quasi schon einmal gemacht. Ich versuche also:

Code:
  1.  
  2. gluLookAt(...);
  3. SwapBuffers(DC)
  4.  


Doch nichts passiert....

Welche der obigen Kommandos muss ich ernneut an OpenGl geben, damit "SwapBuffers" greift? Da meine Szene aus knapp 10 Mio Quadraten besteht möchte ich nicht ständig die Szene neu zeichnen, das soll quasi die Graka machen, ich will nur meinen ViewPoint ändern. Ist das naiv? ;-)

B)
Eine zweite kleinere Frage habe ich auch noch:
Wenn ich in einen Panel DC zeichne, sehe ich nach SwapBuffers zunächst nichts, auch nicht, wenn ich die Zeichenroutine mehrfach aufrufe. Erst, wenn ich die Zeichenroutine in OnIdle des Hauptfensters aufrufe sehe ich ein Ergebnis. Warum???


Wie ihr seht, fehlt mir ein bischen die Vorstellung, wie ein Delphi-Programm mit OpenGL interagiert und was OpenGL vom Programm in welcher Reihenfolge eigentlich an Befehlen erwartet....

Vielen Dank an euch!
Delfit


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Mai 04, 2011 16:52 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mär 30, 2007 18:35
Beiträge: 331
Das funktioniert so nicht. Wenn du die Kamera mit glLookAt (oder mit etwas anderem) veränderst, dann musst du die komplette Szene neu zeichnen. Das macht dann natürlich auch die Grafikkarte, du musst ihr aber natürlich sagen, was gezeichnet werden soll. Dazu musst du vorher mit glClear... den kompletten Buffer löschen.

Generell läuft es so ab, dass du am Anfang einmal alle Dinge erstellst. Dazu gehört der OpenGL-Kontext, Texturen, Shader und sonstige Einstellungen. Das passiert genau einmal und ist danach nicht mehr nötig, es sei denn man möchte während der Laufzeit des Programms weitere Texturen ect. dazuladen.

Beim Zeichnen muss man zunächst das im letzten Frame gezeichnete mittels glClear.. löschen. Danach setzt man seine Kamera und Projektionsmatrix (falls sie sich geändert hat) und beginnt danach mit dem Rendern. Zum Schluss wird SwapBuffers aufgerufen um es anzuzeigen. All das wird in jedem Frame gemacht.

Beim Beenden des Programms musst du die Texturen, Shader, Kontexte löschen und fertig.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Mai 04, 2011 17:01 
Offline
DGL Member

Registriert: Mi Mai 04, 2011 16:09
Beiträge: 11
Hi danke für die Antwort, das hatte ich befürchtet.

Aber geht das nicht auch anders? Ich habe doch bereits alle nötigen Infos an die Graka/Treiber gesendet, ich will ja nur die Cam neu setzen, alle übergebenen Punkte hat sie ja schon, wieso nochmal schicken. Vielleicht ist gluLookAt auch einfach nicht der richtige Befehl.

--> Gibt es eine Möglichkeit die Ansicht zu ändern von Bild zu Bild ohne alle Objektdaten neu zu übertragen?

Oder wo liegt hier der Denkfehler?


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Mai 04, 2011 17:06 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mär 30, 2007 18:35
Beiträge: 331
Das geht nicht. Immer wenn sich die Perspektive ändert, muss alles neu gezeichnet werden. glLookAt macht auch nichts anderes als die Kameramatrix zu verändern, du könntest den Befehl selbst implementieren; das ändert aber nichts.

Die Objektdaten musst du allerdings nicht immer neu übertragen. Schau dir im Wiki mal Displaylisten und Vertex Buffer Objects (VBO) an. Mit Displaylisten kannst du den Rendervorgang (z.B. viele glBegin, glEnd, glVertex Aufrufe) zusammenfassen. Die erstellte Liste wird vom Treiber optimiert und kann in jedem Frame mittels glCallList aufgerufen werden. Das ist auch viel schneller als der Immediate-Modus (glBegin, glEnd). Mit VBOs kannst du ähnliches erreichen, indem du die Objektdaten in den Speicher der Grafikkarte legst.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Mai 04, 2011 17:13 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Genau… Die Grafikkarte merkt sich nichts, von dem du ihr nicht sagst, dass sie es sich merken soll. glBegin…glEnd wird nicht umsonst immediate mode genannt. Du gibst mit jedem glBegin…glEnd-Block einen Zeichebefehl, der sofort ausgeführt wird (ähnlich wie mit dem 2D-Canvas).
Die aus dem Zeichnen resultierenden Pixel werden in den Framebuffer geschrieben, den du dann mit SwapBuffers anzeigen lässt.

Kameraposition etc werden nur durch Matrizen dargestellt (mathematische Konstrukte, die Abbildungen beschreiben). Diese werden auf die eingehenden Vertexdaten angewandt, um die Position zu berechnen, wo die Pixel in den Framebuffer müssen. Nicht mehr, aber auch nicht weniger. Wenn du also gluLookAt aufrufst, änderst du nur diese Matrix. Das gilt ab da bis zur nächsten Änderung (OpenGL Ist Eine State Machine), wie auch glColor bis zur nächsten Änderung gilt.

Wie du die Objektdaten nicht neu übertragen musst, hat Markus ebenfalls schon angedeutet: VBOs sind hier das Zauberwort, einfacher zu bedienen sind aber Displaylisten, die aber mit OpenGL 3 nicht mehr existieren (braucht dir vorerst keine Sorgen zu bereiten).

greetings

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy 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


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Mai 04, 2011 22:08 
Offline
DGL Member

Registriert: Mi Mai 04, 2011 16:09
Beiträge: 11
Hallo Leute

Vielen Dank, ich habe verstanden und werde bei den entsprechenden Stichpunkten weiterlesen, wie geschrieben ich bin erst ein paar Tage mit OpenGl dabei und weis noch nicht so richtig wo ich lesen soll. Die Tutorials sind sehr gut aber ich bräuchte momentan glaub eher eine grundsätzliche Erklärung über das Konzept von OpenGl.

Noch zwei kleine Fragen:
gibt es für die von mir in der EIngangsfrage unter "Vorarbeit" genannten Befehle eine notwendige Reihenfolge?

Danke!


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Do Mai 05, 2011 16:22 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mär 30, 2007 18:35
Beiträge: 331
Code:
  1.  
  2. // Das muss immer dann aufgerufen werden, wenn die Größe des Fensters sich ändert (und der OpenGL-Kontext schon erstellt wurde)
  3. * glViewport(0, 0, Panel1.ClientWidth, Panel1.ClientHeight);
  4.  
  5. // Die nächsten drei Befehle stellen die Projektionsmatrix ein, die Reihenfolge muss genau so sein
  6. * glMatrixMode(GL_PROJECTION); // Sagt, dass man die Projektionsmatrix ändern will
  7. * glLoadIdentity; // Setzt sie auf die Einheitsmatrix
  8. * gluPerspective(45.0, 1, NearClipping, FarClipping); // Setzt die korrekte Projektion (danke an Coolcat) 
  9. // Die nächsten drei Befehle stellen ein wo die Kamera ist und wohin sie schaut, das Prinzip ist das gleiche wie oben
  10. // Das wird meistens in jedem Frame vor dem Zeichnen aufgerufen
  11. * glMatrixMode(GL_MODELVIEW);
  12. * glLoadIdentity;
  13. * gluLookAt(...);
  14.  
  15. // Das muss immer dann aufgerufen werden, wenn man einen neuen Frame rendert
  16. * Clear...
  17.  


Die Reihenfolge der Befehlsblöcke ist nicht unbedingt wichtig, sie werden aufgerufen wenn notwendig (Fenstergröße wird verändert, Projektion ändert sich, Kamera ändert sich). Wenn du die Matrizen änderst, ist es allerdings wichtig, dass du erst mittels glMatrixMode() sagtst, auf welche Matrix du dich beziehst.


Zuletzt geändert von Markus am Do Mai 05, 2011 17:42, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Do Mai 05, 2011 16:44 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
gluPerspective(45.0, 1, NearClipping, FarClipping); // Setzt die korrekte Position

Um Verwirrung vorzubeugen: Hier war die Projektion gemeint, also unter anderem den Öffnungswinkel der Kamera.

_________________
Yeah! :mrgreen:


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


Wer ist online?

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.

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