Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » VC++ / MFC » Maussteuerung mit MFC & OpenGL

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
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 :-)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
16.09.2004, 13:21 Uhr
~c--
Gast


Ja ein Großteil des Sourcecodes wird für das Fenster machen und die Mausabfragen mit Glut verwendet.

Ich habe das ja auch mit MFC umgesetzt. Es ist halt nur ein bisschen Fummelkram sich die richtigen Sachen heraus zu nehmen.

Ich würde an deiner Stelle erst mal versuchen das du deine Szene ohne Rotation auf den Bildschirm bekommst und dann darauf aufbauend die Rotation integrieren.


Im groben habe ich in meiner OnPaint-Funktion
folgenden Aufbau:


void CChildView::OnPaint()
{
CPaintDC dc(this);

::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );


glMatrixMode(GL_PROJECTION);
glLoadIdentity();


glOrtho(....... //für die Viewingvolumen ,damit kann man recht gut auch einen Zoom integrieren

glMatrixMode(GL_MODELVIEW);
glPopMatrix();


if(Rotflag=='r')
{
glRotated(angle,bx,by,bz);
}


glPushMatrix();




glPushMatrix();

glTranslatef(0.0-xmv,0.0-ymv, 0.0-zmv);//hier hatte ich noch eine Verschiebung des Nullpunktes integriert


glCallList((GLint) 1); // meine Szene


glPopMatrix();


glGetDoublev(GL_MODELVIEW_MATRIX,&_matrix[0]);
invertMatrix(&_matrix[0],&_matrixInverse[0]);


::SwapBuffers( m_pDC->GetSafeHdc() );

}



Vielleicht hilft dir das weiter.
Gruß C--
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
22.09.2004, 15:16 Uhr
tronaccount



Danke für die Antwort!

Ich habe den Fehler in meinem Code gefunden:

Statt

glGetFloatv(GL_MODELVIEW, mvMatrix)

muß ich

glGetFloatv(GL_MODELVIEW_MATRIX, mvMatrix)

aufrufen. Kleiner Fehler, große Ursache...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ VC++ / MFC ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: