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

Aktuelle Zeit: Fr Jul 18, 2025 08:03

Foren-Übersicht » Programmierung » OpenGL
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 12 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Sa Mär 14, 2009 18:20 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Jan 04, 2008 21:29
Beiträge: 419
Wohnort: Lübeck
Hi, ich habe mal eine Frage zum thema ModelViewMatrix.

Ich schreibe gerade an einer Camera Klasse und habe es so geregelt, dass ich für jede Camera ein Koordinatensystem speicher, das sind bei mir jetzt 4 vektoren der Dimension 3. Die Rotation der Camera wird hauptsächlich über Quaternions gelöst, bzw. wenn möglich über einfachere bekannte Vektorfunktionen. Um nun die Ansicht der Camera zu setzen führe ich einfach vor dem Zeichnen einen Aufruf durch, der anhand der Orientierung der Kamera die Winkel zur Rotation für die Y und X achse errechnet und anschließend die Szene um den Standort der Camera verschiebt. an sich bin ich schon glücklich damit, da es alles fehlerfrei funktioniert und sich verschiedenste Camera-modi diverser Spiele damit nachbauen lassen, ohne dass man für alle Modi ne neue Klasse ableiten/schreiben muss, allerdings find ich es nicht sehr performant die Orientierung in Winkel umzurechnen und anschließend mit glrotate und gltranslate zu erzeugen. Dazu habe ich mir den Befehl glLoadMatrix nocheinmal genauer angeschaut mit dem ich unteranderem auch schon einige verrückte Perspektiven erzeugt habe für die Projektionmatrix.

Nun zum eigentlichen Problem. Wenn ich die ModelViewMatrix auslese und während der Camera interaktion anzeigen lasse, dann wird deutlich, dass selbst bei einer Rotation ohne Translation ebenfalls der Positions Vektor verändert wird. Setze ich meine Orientierung im typischen Schema:

X-Achse (x y z 0)
Y-Achse (x y z 0)
Z-Achse (x y z 0)
Position (x y z 1)

(evtl. auch transponiert, halt in der reihenfolge wie es aus der ModelViewMatrix abzulesen ist), dann dreht sich die Camera immer um den Ursprung, das ist aber alles andere was ich erreichen will. Allso wie kann es sein, dass die Ergebnisse unterschiedlich sind? Wie muss ich aus der Orientierung die Matrix errechnen, damit ich erst die Rotation habe und dann die Verschiebung?

der Code sieht ungefähr so aus, wenn ich die gl-internen Transformationen verwende:

Code:
  1.  
  2.   glrotatef(a,1,0,0);
  3.   glrotatef(b,0,1,0);
  4.   gltranslatef(-origin[e_pos].x,-origin[e_pos].y,-origin[e_pos].z);
  5.  


Ich kann mir aber vorstellen, das es schneller ist, die Matrix direkt zu berechnen wenn man die Orientierung und Positionierung der Camera kennt. ( zu berücksichtigen ist, dass ich jedesmal vorher aus der Orientierung die Winkel anhand von Skalarprodukten und Bereichsprüfungen erhalte, die meiner Meinung nach auch unperformant wirken).

schonmal danke im vorraus!

ach, bevor ich es vergesse, ich habe keine Problem die Funktion selbst zu verstehen und habe auch viel im Forum gesucht bzw. gegoogelt, aber irgendwie gibts zum Thema Cameras sehr viel forsches Zeug. Die Camera-klasse hier im Wiki finde ich bisher auch ziemlich abenteuerlich, aber wer weiß, vielleicht bin ja auch ich einfach etwas neben der Spur und habe viel zu viele wichtige Dinge nicht bedacht.

_________________
Klar Soweit?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mär 14, 2009 18:43 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jul 29, 2003 00:11
Beiträge: 436
Modelviewmatrix:
x1 y1 z1 t1
x2 y2 z2 t2
x3 y3 z3 t3
0 0 0 1

x/y/z sind die Achsenvektoren deines lokalen Koordinatensystems der Kamera. t ist die Translation. Fertig. :)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mär 14, 2009 18:46 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Jan 04, 2008 21:29
Beiträge: 419
Wohnort: Lübeck
Das hab ich ja auch gedacht (habs bei mir transponiert aufgeschrieben), aber da scheint noch ein gravierender untershied zu sein, denn wenn ich ich die orientierung meiner Cam so übergebe, dann rotiert sie von der position um den Koordinatenursprung. merkwürdig ist für mich das verhalten, dass sich die Spalte, die den Positionsvektor enthalten soll sich ebenfalls verändert, wenn ich nur die Kamera rotiere, ohne sie vom Fleck zu bewegen.

_________________
Klar Soweit?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mär 14, 2009 19:44 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Ähm, ich hab das hier jetzt nur überflogen, aber was spricht gegen gluLookAt ?

Ist auch leicht selbst implementiert. eye ist die Position der Kamera, center ist ein Punkt auf den die Kamera schaut. Der Vektor up gibt an wo oben ist. In folgendem Code entspricht der Operator % dem üblichen 3D-Kreuzprodukt.
Code:
  1. template<class T> inline void CMatrix44<T>::setLookAt(
  2.             const CVector3<T>& eye, const CVector3<T>& center, const CVector3<T>& up) {
  3.     CVector3<T> f = (center - eye).normalized();
  4.     CVector3<T> s = (f % up.normalized()).normalized();
  5.     CVector3<T> u = s % f;
  6.     _11 = s.x;    _12 = u.x;    _13 = -f.x;  _14 = 0.0f;
  7.     _21 = s.y;    _22 = u.y;    _23 = -f.y;  _24 = 0.0f;
  8.     _31 = s.z;    _32 = u.z;    _33 = -f.z;  _34 = 0.0f;
  9.     _41 = -s*eye; _42 = -u*eye; _43 = f*eye; _44 = 1.0f;
  10. }

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 15, 2009 10:43 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
@Philip: Dieser Vorschlag ist richtig, aber unvollständig:
Zitat:
Modelviewmatrix:
x1 y1 z1 t1
x2 y2 z2 t2
x3 y3 z3 t3
0 0 0 1

Diese Matrix entspricht den folgenden OpenGL-Befehlen:
1.glRotate ...
2.glTranslate ...

Was nämlich dabei zu berücksichtigen ist, ist die Tatsache, dass diese Matrix bereits das Ergebnis einer Matrizen-Multiplikation ist: Zuerst eine Translation, dann eine Rotation (genau umgekehrt, wie man es aufgrund der Notation erwarten würde). Diese Matrix ist daher in der Reihenfolge der Transformationen bereits FESTGELEGT und daher unflexibel.

Um die Matrix zu erhalten, die zuerst rotiert und dann verschiebt, muss man:
1. eine reine Rotationsmatrix (RotMat) erzeugen
2. eine reine Verschiebungsmatrix (ShiftMat) erzeugen
3. und sie in der richtigen Reihenfolge miteinander multiplizieren. Ich gaube, das ist ShiftMat X RotMat, aber hau mich nicht, wenn's andersrum ist. :wink:

Oder man macht es per OpenGL:
1.glTranslate ...
2.glRotate ...

Am besten wäre natürlich, wenn man beide Möglichkeiten zur Verfügung hat (zuerst rotieren, dann verschieben ODER auch umgelehrt).
Traude


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 15, 2009 12:20 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jul 29, 2003 00:11
Beiträge: 436
Huch, natürlich...


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 15, 2009 12:43 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Jan 04, 2008 21:29
Beiträge: 419
Wohnort: Lübeck
Okay, danke für die Antwort! Ich dachte man könnte das auf einem schnelleren Weg direkt berechnen, wie die Modelviewmatrix dann aussehen muss. In dem Fall wie ich sie brauche müsste ich also selbst multiplizieren und damit meine CPU belasten, dann belasse ich es lieber dabei, dass ich dass über glrotate und gltranslate mache!

vielen Dank für die Mühe :)

_________________
Klar Soweit?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 15, 2009 12:47 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jul 29, 2003 00:11
Beiträge: 436
Könntest du auch direkt auslesen und irgendwo wegspeichern, die Matrix, erspart die ständige Neuberechnung, solange die Kamera still steht.
Code:
  1.  
  2. glPushMatrix();
  3. glLoadIdentity();
  4. glTranslate(...);
  5. glRotate(...);
  6. glTranslate(...);
  7. GLfloat m[16];
  8. glGetFloatv(GL_MODELVIEW_MATRIX, m);
  9. glPopMatrix();
  10.  


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 15, 2009 16:41 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
und damit meine CPU belasten, dann belasse ich es lieber dabei, dass ich dass über glrotate und gltranslate mache!

Was glaubst du wie glRotate und glTranslate implementiert sind ;)

Zitat:
Ich dachte man könnte das auf einem schnelleren Weg direkt berechnen, wie die Modelviewmatrix dann aussehen muss.

Also du hast bereits das lokale Koordinatensystem und einen Ursprung? Dann musst du nichts weiter tun als in dem Code steht den ich oben gepostet habe. Dort ist der Unterschied nur das die drei Achsen (f,s,u) erst noch erzeugt werden.

Um das nach zu vollziehen, schreib dir die Rotationsmatrix und die Translationsmatrix auf und multipliziere sie von Hand. Es wird darauf hinaus laufen das du die Rotation einfach übernimmst und für die Translation jeweils das Dot-Produkt von Translation und Koordinatenachse nimmst.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 15, 2009 18:44 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Jan 04, 2008 21:29
Beiträge: 419
Wohnort: Lübeck
wow, du hast recht! Ich hab das Punktprodukt nicht berücksichtigt. so gefällt mir das jetzt noch viel mehr.

So jetzt bin ich endgültig zufrieden. vielen Dank noch einmal

Zitat:
Was glaubst du wie glRotate und glTranslate implementiert sind :wink:


werden rotate,translate und scale nicht von der gpu übernommen? Würde mich wundern wenn das auf der cpu gemacht wird, weil das dann doch absoluter Blödsinn wäre.

_________________
Klar Soweit?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 15, 2009 20:18 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Würde mich wundern wenn das auf der cpu gemacht wird, weil das dann doch absoluter Blödsinn wäre.

Matrix-Operationen sind assoziativ. Daher multipliziert die CPU zunächst alle Matrizen zu einer einzigen zusammen, der ModelViewProjection-Matrix. Im Shader kommt man da via gl_ModelViewProjectionMatrix dran. Die Grafikkarte multipliziert jeden Vertex dann mit dieser einen Matrix.
(Sofern du im Shader noch weitere eingebaute Uniforms benutzt, werden natürlich auch diese berechnet.)

Es wäre ziemlicher Unfug die Matrizen erst auf der GPU zu multiplizieren oder gar jeder Matrix einzeln auf jeden Vertex anzuwenden. Ein einzelne Matrix-Multiplikation sind doch nur einmalig 64 Multiplikationen und 48 Additionen. Sowas kann man schneller auf der CPU machen, als die Daten zuerst an die Grafikkarte zu senden.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Mär 16, 2009 12:30 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Jan 04, 2008 21:29
Beiträge: 419
Wohnort: Lübeck
aha, achon wieder ein stückchen schlauer geworden. :)

_________________
Klar Soweit?


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 4 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.008s | 15 Queries | GZIP : On ]