View Full Version : [Frage] Transformationen, Matrizen usw.
Hallo!
Hab bis jetzt einmal ein kleines Framework programmiert und hänge etwas bei der Steuerung.
Ich habe einen "block1" aus kamera und spielfigur, und einen weiteren block2 der die umgebung darstellt.
Soweit ich mich nun an cg1 erinnere ist es so: block 1 ist fix und block 2 wird mit den inversen bewegungen von block 1 multipliziert. somit entsteht der eindruck der bewegung.
Im code wie folgt:
-----------------
<Hier lade ich meine spielfigur die sich ja "nicht" bewegt bzw. nicht transformiert wird>
glTranslatef(0.0,0.0,z); //hier verschiebe ich
glRotatef(y,0.0,1.0,0.0);//und rotiere
<Hier lade ich die restliche welt, die zB rotiert>
-----------------
aber da muss ein denkfehler sein denn
zu beginn ist spielfigur und umgebung im zentrum und alles ist ok.
sobald die spielfigur aber vom "umgebungsnullpunkt" weg fährt rotiert sie nicht mehr um ihr eigenes zentrum sondern um das der umgebung.
hab mir schon den kopf zerbrochen aber ich komme nicht drauf was nicht passt.
ist etwas schwer zu beschreiben aber vielleicht hing jemand am selben punkt.
Anbei @ Tutoren und Übungsleiter, ich glaube auf der tipps seite ist ein kleiner Fehler an dem ich lange zu kiefeln hatte. Dort steht ein Pseudocode mit einer KeyboardFunc und dann einem case GLUT_KEY_UP aber das geht soweit ich es probiert habe ja nur bei einer SpecialFunc.(kenn mich nicht so gut aus also vielleicht ist das auch 100% blödsinn)
LG gepetto
kannst du deinen rendering loop ein wenig genauer beschreiben?
wobei versuch vorher vielleicht zuerst zu rotieren und dann zu verschieben (also anstatt
glTranslatef(0.0,0.0,z); //hier verschiebe ich
glRotatef(y,0.0,1.0,0.0);//und rotiere
eher
glRotatef(y,0.0,1.0,0.0);//und rotiere
glTranslatef(0.0,0.0,z); //hier verschiebe ich
falls das nämlich die rotation sein soll, um die die kamera sich gedreht hat, dann muss die zuerst durchgeführt werden. die darauffolgende translation ist dann die inverse position der kamera)
wobei falls die spielfigur vor der kamera dargestellt werden soll, dann musst du ja ausserdem noch darauf achten, dass die kamera sich nicht um sich selbst, sondern um die spielfigur dreht... sprich du musst bevor du die spielfigur zeichnest eine translation um die inverse relative position der kamera zu der figur machen, dann die figur zeichnen, dann die inverse rotation der kamera und dann erst die translation um die inverse position der figur (also nicht der kamera). danach erst die umgebung zeichnen.
btw das ganze ist um ein vieles praktischer, falls man sich eine eigene kamera klasse bastelt, die sowohl projektions als auch modelview matrizen aus position, blickrichtung und upvector der ansicht berechnet und dann direkt auch bei bedarf lädt... hierzu muss kann ich das entsprechende kapitel in dem buch zur cg1 vorlesung nur wärmstens empfehlen :) .
Wenn man die operationen vertauscht rotiert die figur zwar wirklich um sich selbst, fährt aber nicht in blickrichtung sondern die Zkoordinate entlang.
Ich vermute man kann sich dass nicht so wie in CG1 überlegen da man die matrix bei jedem schritt neu bauen muss.
LG gepetto
ahm naja schon klar... die translation muss immer die inverse absolute position der figur sein. und ja normalerweise baut man in einem rendering loop seine modelview matrix immer von neuem auf. insofern muss halt eben einiges auch in deinem programm berechnet werden (wie zb die position der figur, bzw wie sie sich verändert, falls sie sich in eine bestimmte richtung bewegt. dazu einfach die blickrichtung irgendwo speichern und falls rotiert wird halt die auch mit einer rotationsmatrix multiplizieren)
im endeffekt sollte der rendering loop dann ca so aussehen (vorher muss natürlich die projektionsmatrix initialisiert werden und in der modelview matrix muss die identitätsmatrix stehen):
glPushMatrix
glTranslatef um die inverse relative position der kamera zur spielfigur (im koordinatensystem der spielfigur)
zeichnen der spielfigur
glRotatef die aktuelle inverse drehung der spielfigur
glTranslatef um die inverse absolute position der spielfigur in der spielwelt
zeichnen der spielwelt
glPopMatrix
ja, damit gibts häufig verwirrung - meine empfehlung: im anderen thread wurde schonmal der link zur online-version des redbook gepostet (die "opengl programming guide") oder sucht es einfach in google. lest euch dort das chapter "viewing" über die transformationen durch - dort wird es wirklich gut und verständlich erklärt, normalerweise gehören diese probleme danach der vergangenheit an. zahlt sich wirklich aus :)
Der tip mit dem Redbook war sehr hilfreich, jetzt habe ich zumindest verstanden warum es nicht geht.
Ich initialisiere bei jedem Mainloop die matrix neu mit der identität, bin also im Ursprung und wende nun jedes mal die absolute rotation und translation an.
Die Steuerung erhöht den Wert für den Winkel und den Wert für die zTranslation.
Primär habe ich mir gedacht muss ich nun irgendwie die aktuelle Matrix speichern und im nächsten loop wieder einlesen, sprich die letzte Position laden.
Hat jemand eine idee wie man das macht. Push und Pop ist ja nicht Loop übergreifend. Ich habe versucht eine Matrix selber aufzubauen in die ich meine position und rotation hineinschreibe aber es wäre wesentlich effizenter die matrix von opengl zu speichern.
LG gepetto
ChrisChiu
10-04-2004, 23:04
Ich hab eigentlich immer meine Matrizen in jeder Loop neu aufgebaut (da es nicht immer wünschenswert ist, die Matriz aus dem letzten Frame mitzunehmen).
Vielleicht sollte ich auf die gluLookAt() Funktion hinweisen, die ich manchmal im Rahmen meiner Camera/View Klasse benutze. Im Spielekontext (speziell mit der Abstraktion der Kamera wie im "echten Leben" mit Kameraposition und Ziel) ist denk ich die Semantik von gluLookAt() recht nützlich (die Implementation baut aus dem Eye Point, View, und Up Vector eine View Matrix auf).
Denkbar wäre dann dass man etwa den Eye-Point der Kamera speichert sowie die View Direction (bei den meisten Spielen, also jenen, wo die Ansicht meistens so ist, dass man sowieso einigermaßen "aufrecht" am Boden geht, also keine Loopings macht, ist es nicht unbedingt notwendig den Up Vector anders als (0, 1, 0) anzugeben... ist aber anwendungsabhängig), und dann auf die Steuerung reagiert mit Ändern dieses Eye-Points und View Directions. Damit kann man zumindest eine recht flexible Kamera basteln.
Der Performancenachteil wenn man die Matrizen immer in jedem Frame neu aufbaut ist vernachlässigbar.
Wieso soll Push und Pop nicht loop-übergreifend sein? Ich glaube zwar dass du arge Probleme kriegst (bezüglich genug Pops wie Pushes zu haben, wenn Push und Pop nicht irgendwie einen fixen Codeblock einklammern), aber theoretisch solle eine gepushte Matrix erst nach dem zugehörigen Pop wieder aktuell sein, egal wo im Code du jetzt diesen zugehörigen Pop hast (also etwa im nächsten Loop-Durchlauf).
Uebungsleitung
14-04-2004, 17:26
Der Tip mit dem Redbook steht übrigens auch auf der Tips und Tricks Seite auf der Homepage, die ich jedem nur empfehlen kann...
Michael Wimmer
vBulletin® v3.7.1, Copyright ©2000-2009, Jelsoft Enterprises Ltd.