Objekte verschoben nach gluLookAt

Für Probleme bezüglich Grafik, Audio, GL, ACS, ...
Antworten
wegnera
Beiträge: 14
Registriert: Sa 21. Jan 2017, 16:21

Objekte verschoben nach gluLookAt

Beitrag von wegnera »

Liebe Gemeinde,

als Anfänger habe ich mich langsam an die Darstellung einer Sonne, der Erde und des Mondes herangewagt. Die ersten Schritte waren - nach einigen Tutorials rauf und runter lesen - auch noch halbwegs verständlich. Doch dann habe ich den faden komplett verloren.
Ich wollte mir mal anschauen, wie sich meine Objekte im Raum positionieren und habe mir dazu ein Koordinatensystem gezeichnet. Bereits dort gab es den ersten Aha-Effekt. Die nachfolgenden Zeilen führten nicht zu dem erwarteten Ergebnis, nämlich rote X-Achse nach rechts, grüne y-Achse nach oben und blaue z-Achse nach hinten abgehend. Stattdessen sind x & z vertauscht.

glBegin (GL_Lines);
glColor3f(1,0,0);
glVertex3f(0,0,0);glVertex3f(60,0,0);
glColor3f(0,1,0);
glVertex3f(0,0,0);glVertex3f(0,60,0);
glColor3f(0,0,1);
glVertex3f(0,0,0);glVertex3f(0,0,60);
glend;

Dennoch wurde meine Sonne im Ursprung erstellt. Was soweit nachvollziehbar war. Doch dann habe ich mit

gluLookAt(-40,10,20, 0,0,0, 0,1,0);

meinen Betrachterpunkt verändern wollen, um die Objekte aus einiger Entfernung und mit Tiefe sehen zu wollen. nachdem ich diesen aber eingefügt hatte, verschiebt sich die Sonne aus dem Ursprung heraus und das verstehe ich gar nicht mehr.

Ich habe mal die komplette Datei angehangen, vielleicht hat ja jemand eine Idee, an welcher Stelle ich Unsinn gemacht habe.

u_kugel_zwei.pas
(5.55 KiB) 124-mal heruntergeladen
Dateianhänge
sonne_verschoben.GIF
sonne_verschoben.GIF (2.07 KiB) 2772 mal betrachtet
sonne_im_ursprung.GIF
sonne_im_ursprung.GIF (6.31 KiB) 2772 mal betrachtet

Mathias
Beiträge: 6165
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Objekte verschoben nach gluLookAt

Beitrag von Mathias »

Stattdessen sind x & z vertauscht.

Mit

Code: Alles auswählen

gluLookAt(-60,10,20, 0,0,0, 0,1,0)
hast du eine Drehung in der Y-Achse gemacht.
Wen du hier guckst https://wiki.delphigl.com/index.php/gluLookAt , ist das der Parameter "upy".

Mach anstelle von gluLooAt(...

Code: Alles auswählen

  glTranslatef(0,0, -10); 
, dann wirst du die X und Y -Linie am richtigen Ort haben. Z sieht man nicht, weil sie senkrecht in den Bildschirm rein geht.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Objekte verschoben nach gluLookAt

Beitrag von wp_xyz »

wegnera hat geschrieben:Ich wollte mir mal anschauen, wie sich meine Objekte im Raum positionieren und habe mir dazu ein Koordinatensystem gezeichnet. Bereits dort gab es den ersten Aha-Effekt. Die nachfolgenden Zeilen führten nicht zu dem erwarteten Ergebnis, nämlich rote X-Achse nach rechts, grüne y-Achse nach oben und blaue z-Achse nach hinten abgehend. Stattdessen sind x & z vertauscht.

Code: Alles auswählen

glBegin  (GL_Lines);
  glColor3f(1,0,0);
  glVertex3f(0,0,0);glVertex3f(60,0,0);
  glColor3f(0,1,0);
  glVertex3f(0,0,0);glVertex3f(0,60,0);
  glColor3f(0,0,1);
  glVertex3f(0,0,0);glVertex3f(0,0,60);
glEnd;


Das Koordinatensystem ist ein ganz wichtiger Schritt, sich in dem OpenGL-Raum zurechtzufinden!

Standardmäßig hat OpenGL ein rechtshändiges Koordinatensystem. x zeigt horizontal nach rechts, y nach oben - wohin zeigt z? In den Bildschirm oder aus dem Bildschirm? Nimm deine rechte Hand und strecke Daumen, Zeige- und Mittelfinger in Form eines Koordinatensystems aus. Lasse den Daumen horizontal entlang der x-Achse von links nach rechts zeigen. Drehe die Hand so, dass der Zeigefinger von unten nach oben zeigt. Dann gibt der Mittelfinger in Richtung der z-Achse --> z verläuft AUS dem Bildschirm. In deinem gluLookout(-60, 10, 20, ...) ist die z-Koorindate positiv, also vor dem Bildschirm. Die x-Koordinate ist negativ, daher sitzt der Beobachter außerhalb des durch die drei Achsen aufgespannten Würfels. Solange rot/grün/blau wie Daumen/Zeigefinger/Mittelfinger angeordnet sind, ist alles richtig.

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Objekte verschoben nach gluLookAt

Beitrag von wp_xyz »

In deinem Code zur Sonnenbewegung sehe ich einige probleme

In FormPaint (warum nennst du das eigentlich nicht OpenGLControl1Paint?) würde ich vor dem glLoadIdentity ein glMatrixMode(GL_MODELVIEW) setzen. Falls nämlich gerade die Projektionsmatrix aktiv ist, dann werden alle Operationen auf diese angewendet.

Du hat in derselben Routine zweimal gluLookat aufgerufen. Das geht nicht. gluLookAt definiert den Standort, der muss während einunddemselben Zeichenvorgang gleich bleiben. In diesem Fall hast du vom 1.Standpunkt aus das Koordinatensystem gezeichnet, vom 2. aus die Sonne. Dadurch hat sich das koordiantensystem gegenüber der Sonne verschoben.

Einige Probleme gibt es auch, wenn du dann Erde und Mond aktivierst: Wie im vorigen Post schon erläutert, stelle ich mir das immer vom Standpunkt des Betrachters vor. Manche Tutorials beschrieben das mit Hilfe verschobener/gedrehter Koordinatensysteme, was wesentlich undurchsichtiger ist. nachteil meiner Methode ist, dann man den Code von unten nach oben lesen/schreiben muss.

  • Beginne mit dem Mond:
  • Erstelle die Kugel im Ursprung - das steht ganz unten im Code.
  • Verschiebe die Kugel vom Ursprung weg - glTranslate muss in die Zeile vorher
  • Dann dreht sich die Kugel um den Ursprung - glRotate muss in die Zeile vorher.
  • Nun erstellen wir die Erde im Ursprung.
  • Die Erde soll sich um die eigene Achse drehen (Tag/Nacht) --> glRotate in die Zeile drüber.
  • Damit die Eigenrotation den im Code folgenden Mond nicht beeinflusst, wird der Code für die Erde (glRotate + Kugel-Erzeugung) mit glPushMatrix/glPopMatrix eingekapselt (glPushmatrix speichert den aktuellen zustand der ModelView-Matrix bevor die Erde ins Spiel kommt und glPopMatrix stellt ihn nach der Drehung der Erde wieder her).
  • Dieses ganze System, Erde + Mond, muss sich um die Sonne drehen. Daher frieren wir das aktuelle Koordinatensystem für Erde und Mode mit glPushMatrix/glPopMatrix ein - glPushMatrix am Anfang, glPopMatrix am Ende.
  • Nun schieben wir Erde+Mond vom Ursprung weg (--> glTranslate in der Zeile drüber)
  • und drehen alles um den Ursprung (--> glRotate um y)
  • Zum schluss erzeugen wir die Sonne im Ursprung.

Du findest das ganze im Anhang. Nachdem ich jetzt schon ziemlich viel verraten habe, versuche zur Übung auch der Sonne und dem Mond eine Eigenrotation zu geben und/oder vielleicht noch einen weiteren Planeten einzubauen, und/oder das ganze Sonnensystem um das Zentrum der Milchstraße zu rotieren.
Dateianhänge
drei_kugeln.zip
(3.37 KiB) 124-mal heruntergeladen

Mathias
Beiträge: 6165
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Objekte verschoben nach gluLookAt

Beitrag von Mathias »

Was ich noch generall bei OpenGL machen würde, ich würde Float anstelle von Double nehmen.
32Bit sind schneller und Platzsparender als 64Bit.
Bei diesen 3 Kugeln wirst du dies nicht merken, aber komplexen Mesh.

Dies könntest auch noch einbauen und du hast schön geglättete Linien.

Code: Alles auswählen

    OpenGLControl1.MultiSampling := 4;
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

wegnera
Beiträge: 14
Registriert: Sa 21. Jan 2017, 16:21

Re: Objekte verschoben nach gluLookAt

Beitrag von wegnera »

Danke euch Beiden !!

Ich habe deine (wp_xyz) Idee aufgegriffen und Venus sowie Mars mit zwei Monden eingebaut. Die Kapselung hat mit sehr dabei geholfen. Auch die Problematik, dass mir anfangs die Planeten hinten rausgelaufen sind konnte ich durch Parameterveränderung der gluPerspektive lösen.

Anbei mein Ergebnis :-)

Nun stellen sich mir die nächsten Fragen:

1. Die Kreisbahnen um die Sonne sind ja eigentlich elliptische Bahnen. Lassen sich diese auch mittels Rotte abbilden oder muss ich über sin & cos die Position ermitteln und setzen?
2. Wenn ich an den Saturn denke, wie bekomme ich seine typische Form hin?
3. kann ich den Betrachterwinkel jederzeit über onKey Events neu setzen? gluLookAt oder bietet sich dort etwas anderes an? Worauf sollte ich achten?
4. Bisher habe ich mit dem Thema Texturen noch gar nicht beschäftigt. Benötige ich dort "nur" ein Oberflächenbild meiner Planeten oder ist da mehr zu beachten.

@Mathias: Ich habe versucht das MultiSampling in der Erzeugung des OpenGL-Objektes zu setzen. Er scheint aber die Eigenschaft nicht zu kennen.
Dateianhänge
Sonnensystem.zip
(3.14 KiB) 140-mal heruntergeladen

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Objekte verschoben nach gluLookAt

Beitrag von wp_xyz »

wegnera hat geschrieben:1. Die Kreisbahnen um die Sonne sind ja eigentlich elliptische Bahnen. Lassen sich diese auch mittels Rotte abbilden oder muss ich über sin & cos die Position ermitteln und setzen?

Rotte? Du kannst mit Hilfe einer glScaled(x,y,z)-Transformation den Kreis stauchen (z.B.x=0.8, y=1, z=1 --> Stauchung in x-Richtung). Du musst dir nur die richtige Stelle im Code überlegen, an der das aufgerufen wird. Und aufpassen, dass es nicht auch die Kugeln zu Ellipsoiden verformt! Außerdem ist bei der Planetenbewegung die Sonne in einem Brennpunkt der Ellipse, nicht im Mittelpunkt --> du braucht auch noch eine Translation für die Sonne. Eine Formel, wie man die Lage des Brennpunkts berechnen kann, findest du in https://de.wikipedia.org/wiki/Ellipse#F ... chungen.29.

wegnera hat geschrieben:2. Wenn ich an den Saturn denke, wie bekomme ich seine typische Form hin?

Du meinst die Ringe? Ich kenne mich mit glut nicht so gut aus, aber ich denke an sowas wie glutTorus o.ä. Oder du kannst dir eine Ring-Scheibe mit Hilfe von Dreiecken selbst zusammenbasteln. Und denke daran, die Kugel und Ringe mit einem glPushMatrix/glPopMatrix miteinander zu gruppieren.

wegnera hat geschrieben:3. kann ich den Betrachterwinkel jederzeit über onKey Events neu setzen? gluLookAt oder bietet sich dort etwas anderes an? Worauf sollte ich achten?

Kein Problem, solange gluLookAt nicht im Paint-Event geändert wird. Definiere Koordinaten, wo sich die Kamera gerade befindet und setze diese im Aufruf von gluLookAt ein. Es ist aber nicht ratsam, die kartesichen Koordinaten x,y,z, die in gluLookAt eingetragen werden, einzeln zu ändern, weil sich damit der Abstand zum Ursprung ändert. Besser würde mir gefallen, sich x,y,z in Kugelkoordinaten r, theta, phi (r = Abstand, theta = "Breitengrad", phi = "Längengrad") umzurechnen und nur eine von diesen zu variieren, z.B. theta, um sich auf einem Kreis zwischen Äquator und Pol zu bewegen. Siehe dazu https://de.wikipedia.org/wiki/Kugelkoordinaten. Sorry, dass das alles sehr mathematisch ist, aber da muss man durch, wenn man OpenGL selbst programmieren will (sonst nimm Programme wie Blender etc.).

wegnera hat geschrieben:4. Bisher habe ich mit dem Thema Texturen noch gar nicht beschäftigt. Benötige ich dort "nur" ein Oberflächenbild meiner Planeten oder ist da mehr zu beachten.

Auch hier bin ich kein Spezialist. Aber eine Google-Suche nach "OpenGL texture sphere" liefert eine Menge.

Jole
Beiträge: 114
Registriert: Fr 4. Jul 2014, 14:39
OS, Lazarus, FPC: Linux
CPU-Target: amd64

Re: Objekte verschoben nach gluLookAt

Beitrag von Jole »

wegnera hat geschrieben:4. Bisher habe ich mit dem Thema Texturen noch gar nicht beschäftigt. Benötige ich dort "nur" ein Oberflächenbild meiner Planeten oder ist da mehr zu beachten.

Schau mal hier, da findest du alle Planeten für unser Sonnensystem als Texturen die du in OpenGL einsetzen kannst.

Mathias
Beiträge: 6165
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Objekte verschoben nach gluLookAt

Beitrag von Mathias »

@Mathias: Ich habe versucht das MultiSampling in der Erzeugung des OpenGL-Objektes zu setzen. Er scheint aber die Eigenschaft nicht zu kennen.

Kennt er nicht, oder wird es einfach nicht ausgeführt ?
Wen die Graka zu alt ist, wird dies ingnoriert.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Minits
Beiträge: 30
Registriert: So 30. Okt 2016, 21:13
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Objekte verschoben nach gluLookAt

Beitrag von Minits »

In diesem Thread wird die Antwort auf die Frage mit den elliptischen Bahnen zwar teils gegeben, doch ich schaffe es einfach nicht den Befehl glscale* richtig in den Code einzubinden:

Code: Alles auswählen

  // Erde + Mond
  glPushMatrix;
  glscalef(0.5,0.2,1);
  glPopMatrix;
  glRotated(EarthRot,0, 1,0);
  gltranslatef(30,0,0);
 
    // Erde
      glRotated(EarthSpin,0, 1,0);
      glColor3f(0,0,1);
      Kugel(5, 20, 20);


Kapsel ich den Befehl so passiert logischerweise gar nichts.

Code: Alles auswählen

  // Erde + Mond
  glPushMatrix;
  glscalef(0.5,0.2,1);
  glRotated(EarthRot,0, 1,0);
  glPopMatrix;
  gltranslatef(30,0,0);
 
    // Erde
      glRotated(EarthSpin,0, 1,0);
      glColor3f(0,0,1);
      Kugel(5, 20, 20)


Bei dieser Variante dreht sich die Erde nur noch um sich selbst und nicht mehr um die Sonne

Code: Alles auswählen

  // Erde + Mond
  glPushMatrix;
  glscalef(0.9,0.2,1);
  glRotated(EarthRot,0, 1,0);
  gltranslatef(30,0,0);
 
    // Erde
      glRotated(EarthSpin,0, 1,0);
      glColor3f(0,0,1);
      Kugel(5, 20, 20);
      glPopMatrix;


und so ist zwar die Bahn elliptisch, der Planet ist aber auch ein Ellipsoid...

Wo muss ich den Befehl nun hineinschreiben und wie muss ich ihn mit den Matritzenstacks einkapseln? :)

Mathias
Beiträge: 6165
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Objekte verschoben nach gluLookAt

Beitrag von Mathias »

und so ist zwar die Bahn elliptisch, der Planet ist aber auch ein Ellipsoid...

Das wird man kaum direkt mit glScale lösen können.

Ich würde den Parameter(30) bei Translatte anpassen. Somit kannst du die Planeten in einem Oval bewegen, aber die Planten bleiben dabei Kugelrund. Mit Trigo sollte dies lösbar sein
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten