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

Aktuelle Zeit: Sa Jul 19, 2025 12:23

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



Ein neues Thema erstellen Auf das Thema antworten  [ 6 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Rotation: ein verflixte Problem
BeitragVerfasst: Mi Nov 28, 2007 14:20 
Offline
DGL Member

Registriert: Di Nov 27, 2007 21:53
Beiträge: 3
Hi,
ich programmiere zur Zeit an einer Welt, in der ich mit einem Flugzeug rumdüsen kann. Soll irgendwann mal ein Space-Shooter werden, aber bis dahin dauerts noch. Mein aktuelles Problem ist folgendes:

Ich selbst bin ja das Raumschiff und betrachte damit auch aus dessen Perspektive die Umgebung. Drehe ich mich nach links, dreht die Welt sich nach rechts... ihr kennt das ja ;-) Bei mir ist es eigenartiger Weise so, dass meine Tastenbelegung zum drehen um die Achsen je nach aktueller Position/Blickwinkel des Raumschiffs plötzlich anders wird. ZB:
Meine Standardbelegung:
A/D um y-Achse
W/S um x-Achse
Q/E um z-Achse

Drehe ich mich nun mit der A-Taste 90° nach links, so rotiere ich mit der W-Taste plötzlich um die Z-Achse. Ich habe schon zich Möglichkeiten und Tutorials durchgeackert und hab es nicht hinbekommen. Ging das eine, so war das andere wieder kaputt... Meine einzige Hoffnung seid ihr ;-)

Nun zu der Programmierung:

Ihr rotiere ich die Welt entsprechend meiner Bewegung, bzw. so sollte es zumindest sein:
Code:
  1.  
  2. procedure TEngine.move;
  3. var
  4.   RotMat  : TMatrix4f;
  5.   Ang: single;
  6.   RotateX  : single;
  7.   RotateY  : single;
  8.   RotateZ  : single;
  9. begin
  10.   RotateX := 0;
  11.   RotateY := 0;
  12.   RotateZ := 0;
  13.   if Keys[ord('W')] then RotateX := RotSpeed;
  14.   if Keys[ord('S')] then RotateX := -RotSpeed;
  15.   if Keys[ord('D')] then RotateY := -RotSpeed;
  16.   if Keys[ord('A')] then RotateY := RotSpeed;
  17.   if Keys[ord('Q')] then RotateZ := RotSpeed;
  18.   if Keys[ord('E')] then RotateZ := -RotSpeed;
  19.  
  20.   if Keys[ord('R')] then
  21.     if Direction > 0 then Direction := Direction + BreakSpeed
  22.                      else Direction := Direction + MoveSpeed
  23.   else
  24.     if Keys[ord('F')] then
  25.       if Direction < 0 then Direction := Direction - BreakSpeed
  26.                        else Direction := Direction - MoveSpeed;
  27.  
  28.   Ang := DegToRad(RotateX);
  29.   VectorRotate(LocalY, LocalX, Ang);
  30.   VectorRotate(LocalZ, LocalX, Ang);
  31.  
  32.   RotMat := CreateRotationMatrix(LocalX, Ang);
  33.   WorldMat := MatrixMultiply(WorldMat, RotMat);
  34.  
  35.   Ang := DegToRad(RotateY);
  36.   VectorRotate(LocalX, LocalY, Ang);
  37.   VectorRotate(LocalZ, LocalY, Ang);
  38.  
  39.   RotMat := CreateRotationMatrix(LocalY, Ang);
  40.   WorldMat := MatrixMultiply(WorldMat, RotMat);
  41.  
  42.   Ang := DegToRad(RotateZ);
  43.   VectorRotate(LocalX, LocalZ, Ang);
  44.   VectorRotate(LocalY, LocalZ, Ang);
  45.  
  46.   RotMat := CreateRotationMatrix(LocalZ, Ang);
  47.   WorldMat := MatrixMultiply(WorldMat, RotMat);
  48.  
  49.  
  50.   PosVect[0] := PosVect[0] + (LocalZ[0] * Direction);
  51.   PosVect[1] := PosVect[1] + (LocalZ[1] * Direction);
  52.   PosVect[2] := PosVect[2] + (LocalZ[2] * Direction);
  53. end;
  54.  


Und so sieht das dann in der Render aus:
Code:
  1.  
  2. glTranslatef(0,-3,-30); //damit ich nicht mitten im Raumschiff henge, sondern dahinter
  3. ObjMan.ShowObjekt('rschiff1'); //bewirkt einfach nur das Zeichnen des Raumschiffs
  4.   glMultMatrixf(@WorldMat); //die in der Prozedur move erstellte World-Matrix wird mit der 'Hauptmatrix' multipliziert
  5.   glTranslatef(-PosVect[0], PosVect[1], PosVect[2]); //ich verschiebe die Welt entsprechend der Bewegung meines Raumschiffs
  6.   glCallList(List); //aufrufen der Skybox
  7.  



Ich hoffe, ihr könnt mir dabei helfen. Bin noch nicht lange an OGL dran, bitte nicht auslachen, wenns einfach ist ;-)

LG, Nico


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Nov 28, 2007 14:44 
Offline
DGL Member

Registriert: Di Jun 06, 2006 09:59
Beiträge: 474
Das geht am einfachsten mit Rotationsmatrizen oder Quaternionen. Bei Matrizen musst du nur eine neue rot-matrix erstellen und rechts ranmultiplizieren. Im wiki gibt es glaube ich ein Kameratutorial was Rotationen um den Beobachter erklärt.

_________________
Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Nov 28, 2007 15:19 
Offline
DGL Member

Registriert: Di Nov 27, 2007 21:53
Beiträge: 3
Falls ich deinen Hinweis richtig verstehe, dann mache ich doch genau das in der Move-Prozedur. Ich erstelle Rotationsmatrizen abgeleitet aus den Tastatureingaben und multipliziere diese mit der Worldmatrx, die ich dann wiederum in der Render mit der eigentlichen Matrix multipliziere.
LG, Nico


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Nov 29, 2007 07:48 
Offline
DGL Member

Registriert: Do Mai 30, 2002 18:48
Beiträge: 1617
ich habs jetzt den code nicht ganz durchgecheckt, aber bei Matrizenmultiplikation ist die Reihenfolge sehr wichtig....

Schonmal sorum getauscht?
WorldMat := MatrixMultiply(RotMat,WorldMat);

Ach ja, wenn Du die WorldMat sowieso hast und Du darin nur Rotationen speicherst, musst Du nicht deine Local Variablen immer berechnen. Du transponierst WorldMat und liest Spaltenweise heraus... Da stehen die drinne ;-) Einfach mal anzeigen lassen und vergleichen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Nov 29, 2007 08:35 
Offline
DGL Member

Registriert: Di Jun 06, 2006 09:59
Beiträge: 474
Deine Renderproc ist eher DirectX-Stil. Üblicherweise bewegen wir Objekte und nicht die Welt. Also Rendert man als erstes die Skybox, berechnet dann die matrix für die Kamera (wenn man das nicht in der P-Matrix macht), anschließend pusht man für jedes objekt die weltmatrix, multipliziert die matrix des objekts rechts ran(manuell oder mit den OpenGL-Funktionen) und rendert das objekt. Anschließend popt man die matrix wieder vom stack, um wieder auf weltebene zu sein.

Was ich auch nicht verstehe wofür LocalX, etc da sind. Im lokalen system ist LocalX einfach (1,0,0). Wenn du um den drehst, und das dann rechts an die Raumschiffmatrix ranmultiplizierst sollte es funktionieren.

_________________
Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Nov 29, 2007 21:33 
Offline
DGL Member

Registriert: Di Nov 27, 2007 21:53
Beiträge: 3
Hi,
ich freue mich über eure Hilfe.
Leider bin ich wie gesagt ein ziemlicher Anfänger, weshalb es mir weiterhelfen würde, wenn ihr meinen geposteten Code direkt übernehmt und umbaut.
Ich weiss, dass es faul klingt, aber ich kann aus reinen Tipps wirklich nichts sinnvolles produzieren. Trotzdem natürlich vielen Dank für die bisherigen Vorschläge.

LG, Nico


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


Wer ist online?

Mitglieder in diesem Forum: Bing [Bot] und 10 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:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.009s | 15 Queries | GZIP : On ]