000
13.09.2004, 08:24 Uhr
tronaccount
|
Hallo,
ich hatte vor einiger Zeit mal nach einem Vorbild für eine um eine OpenGL-Szene kreisende Kamera gefragt und dabei (danke nochmals) den Tip bekommen, mir die Seite www.nigels.com/glt/gltzpr/ mal anzuschauen. Top, da habe ich genau gefunde, was ich suche. Leider ist das eine Implementation für GLUT, und ich arbeite mit der MFC und einem Windows-Fenster, aber immerhin. Es werden für die Kamerasteuerung selbst auch gar keine GLUT-Befehle verwendet, also sollte(!) die Portierung einfach sein.
Die Idee: Die Szene soll in eine virtuelle Kugel eingepackt werder, die man mit der Maus "anfassen" und dann drehen kann.
Ich muß also die Transformationsmatrix der Szene invertieren, meine globalen Koordinaten (in dem Fall die x- und y-Achse meiner "Monitorebene", um die ich drehen will, um einen realisischen Eindruck zu bekommen) ins Modellkoordinatensystem transformieren und mit glRotate() anwenden. Schon rotiert die Szene im die "Monitorachsen"...
Richtig? Ich hoffe...
Ich starte in OnCreate() mit der Initialisierung von OpenGL und einem glLoadIdentity().
Ich hole mir in OnMouseMove() meine aktuelle Matrix und invertiere
C++: |
//Aktuelle MODELVIEW-Matrix holen glGetFloatv(GL_MODELVIEW, mvMatrix); //Matrix invertieren MatrixInvert(mvMatrix, invMatrix);
|
dann hole ich die Mauskoordinaten und baue mir einen Drehvektor. Erst den globalen in Bildschirmkoordianten, dann transformiere ich und wende an.
C++: |
//Inkrementelle Mausbewegung erfassen, MousePos wird bei OnButtonDown() erfaßt, point ist die akutelle Mausposition aus der OnMouseMove() dx = MousePos.x - point.x; dy = MousePos.y - point.y; //Drehvektor bestimmen rotVectorGlobal[0] = dy; rotVectorGlobal[1] = dx; rotVectorGlobal[2] = 0;
rotVectorLokal[0] = invMatrix[0]*rotVectorGlobal[0] + invMatrix[4]*rotVectorGlobal[1] + invMatrix[8]*rotVectorGlobal[2]; rotVectorLokal[1] = invMatrix[1]*rotVectorGlobal[0] + invMatrix[5]*rotVectorGlobal[1] + invMatrix[9]*rotVectorGlobal[2]; rotVectorLokal[2] = invMatrix[2]*rotVectorGlobal[0] + invMatrix[6]*rotVectorGlobal[1] + invMatrix[10]*rotVectorGlobal[2]; //Winkel bestimmen angle = 0; angle = sqrt(dx*dx + dy*dy); glRotatef(angle, rotVectorLokal[0], rotVectorLokal[1], rotVectorLokal[2]); //darstellen Invalidate(FALSE);
|
In OnDraw() wird dann nach einem glPush() gezeichnet und anschließend glPop() aufgerufen.
Leider klappt das Ganze nicht. Die ModelView-Matrix sieht nämlich schon total seltsam aus und ist immer die gleiche, trotz Aufruf von glRotale:
t = 0: Globaler Vektor 1 6 0 ModelView Matrix (nur Drehanteil) -4.31602e+008 -4.31602e+008 -4.31602e+008 -4.31602e+008 -4.31602e+008 -4.31602e+008 -4.31602e+008 -4.31602e+008 -4.31602e+008 Lokaler Vektor nach Invertierung der ModelView -4.31602e+008 -4.31602e+008 0
t = 1: Globaler Vektor 1 12 0 ModelView Matrix (nur Drehanteil) -4.31602e+008 -4.31602e+008 -4.31602e+008 -4.31602e+008 -4.31602e+008 -4.31602e+008 -4.31602e+008 -4.31602e+008 -4.31602e+008 Lokaler Vektor nach Invertierung der ModelView -3.02121e+009 -3.02121e+009 0 . . .
Auf dem Bildschirm dreht die Szene immer um dieselbe Achse, was ja auch zum immer gleich orientierten Lokalen Vektor paßt :-(
Wiese bekomme ich so eine seltsame ModelView-Matrix? Müßte nach dem ersten Aufruf nicht die Einheitsmatrix ausgegeben bekommen?
Danke schonmal & sorry für's lange Posting :-) |