Kamera (2): Unterschied zwischen den Versionen
Aus DGL Wiki
Flash (Diskussion | Beiträge) K |
Andyh (Diskussion | Beiträge) |
||
Zeile 51: | Zeile 51: | ||
constructor TCameraMatrix.Create; | constructor TCameraMatrix.Create; | ||
+ | // beim erzeugen der Matrix wird die Identitätsmatrix zugewiesen | ||
begin | begin | ||
− | Identity; | + | Identity; |
end; | end; | ||
procedure TCameraMatrix.Identity; | procedure TCameraMatrix.Identity; | ||
+ | // die Funktion GetArrIdentity findet Ihr in der Datei OpenGL.pas | ||
var | var | ||
i: integer; | i: integer; | ||
begin | begin | ||
− | Matrix := GetArrIdentity; | + | Matrix := GetArrIdentity; |
InverseMatrix := GetArrIdentity; | InverseMatrix := GetArrIdentity; | ||
end; | end; | ||
procedure TCameraMatrix.Load(M: TArrMatrix); | procedure TCameraMatrix.Load(M: TArrMatrix); | ||
+ | // die Matrix mit den Werten einer beliebigen anderen matrix füllen | ||
var | var | ||
i: integer; | i: integer; | ||
begin | begin | ||
for i:=0 to 15 do | for i:=0 to 15 do | ||
− | Matrix[i]:=M[i]; // die Matrix | + | Matrix[i]:=M[i]; |
+ | // die invertierte Matrix kann benutzt werden um Objkekte z.B. | ||
+ | // immer zum Benutzer auszurichten | ||
InvertMatrix (M, InverseMatrix); // die inverse Matrix erzeugen | InvertMatrix (M, InverseMatrix); // die inverse Matrix erzeugen | ||
− | |||
end; | end; | ||
Zeile 81: | Zeile 85: | ||
glMatrixMode (GL_MODELVIEW); | glMatrixMode (GL_MODELVIEW); | ||
glPushMatrix(); | glPushMatrix(); | ||
− | glLoadMatrixf(@CameraMatrix.Matrix); // | + | // aktuelle Position und Lage der Kamera herstellen |
+ | glLoadMatrixf(@CameraMatrix.Matrix); | ||
+ | // wenn gewünscht um die X-Achse drehen | ||
if(rx <> 0) then | if(rx <> 0) then | ||
− | glRotatef(rx,1,0,0); // wenn gewünscht um die | + | glRotatef(rx,1,0,0); |
+ | // wenn gewünscht um die Y-Achse drehen | ||
if(ry <> 0) then | if(ry <> 0) then | ||
− | glRotatef(ry,0,1,0); // wenn gewünscht um die | + | glRotatef(ry,0,1,0); |
+ | // wenn gewünscht um die Z-Achse drehen | ||
if(rz <> 0) then | if(rz <> 0) then | ||
− | glRotatef(rz,0,0,1); // | + | glRotatef(rz,0,0,1); |
− | glGetFloatv(GL_MODELVIEW_MATRIX, @newMatrix); // die | + | // die neu erzeugte Matrix auslesen |
− | CameraMatrix.Load(newMatrix); | + | glGetFloatv(GL_MODELVIEW_MATRIX, @newMatrix); |
+ | // und in die Kameramatrix sichern | ||
+ | CameraMatrix.Load(newMatrix); | ||
glPopMatrix(); | glPopMatrix(); | ||
end; | end; | ||
Zeile 118: | Zeile 128: | ||
destructor TCamera.Destroy; | destructor TCamera.Destroy; | ||
+ | // alle belegten Resourcen wieder freigeben | ||
var | var | ||
i: integer; | i: integer; | ||
Zeile 128: | Zeile 139: | ||
procedure TCamera.Offset(x, y, z: TGLfloat); | procedure TCamera.Offset(x, y, z: TGLfloat); | ||
+ | // verschieben der Kamera auf einer beliebigen Achse | ||
var | var | ||
newMatrix: TArrMatrix; | newMatrix: TArrMatrix; | ||
Zeile 146: | Zeile 158: | ||
procedure TCamera.PositionCamera(PositionVec: TGLvector; ViewVec: TGLvector; upVec: TGLvector); | procedure TCamera.PositionCamera(PositionVec: TGLvector; ViewVec: TGLvector; upVec: TGLvector); | ||
+ | // erstes positionieren der kamera. hierbei werden einige initialisierungen vorgenommen | ||
var | var | ||
newMatrix: TArrMatrix; | newMatrix: TArrMatrix; | ||
i: integer; | i: integer; | ||
begin | begin | ||
+ | // alle kameraeinstellungen zurücknehmen | ||
Identity; | Identity; | ||
+ | // den aktuellen drehpunkt setzen | ||
FPointOfRotation := ViewVec; | FPointOfRotation := ViewVec; | ||
+ | // an die arbeit... | ||
glMatrixMode (GL_MODELVIEW); | glMatrixMode (GL_MODELVIEW); | ||
glPushMatrix; | glPushMatrix; | ||
Zeile 163: | Zeile 179: | ||
HomeMatrix.Load(newMatrix); | HomeMatrix.Load(newMatrix); | ||
glPopMatrix; | glPopMatrix; | ||
+ | // alle positionsspeicher mit der Kameraposition, Blickrichtung und dem | ||
+ | // upVector belegen. Nur beim ersten Aufruf von PositionCamera | ||
if not Initiated then | if not Initiated then | ||
begin | begin | ||
Zeile 172: | Zeile 190: | ||
procedure TCamera.CameraHome; | procedure TCamera.CameraHome; | ||
− | // | + | // Kamera in die beim letzten Aufruf von PositionCamera übergebene |
+ | // Position/Lage bringen | ||
begin | begin | ||
CameraMatrix.Load(HomeMatrix.Matrix); | CameraMatrix.Load(HomeMatrix.Matrix); | ||
Zeile 178: | Zeile 197: | ||
procedure TCamera.SavePosition (pos: integer); | procedure TCamera.SavePosition (pos: integer); | ||
+ | // wie der Prozedurname schon sagt... | ||
begin | begin | ||
if (pos < 0) or (pos > 9) then | if (pos < 0) or (pos > 9) then | ||
Zeile 185: | Zeile 205: | ||
procedure TCamera.RestorePosition (pos: integer); | procedure TCamera.RestorePosition (pos: integer); | ||
+ | // wie der Prozedurname schon sagt... | ||
begin | begin | ||
if (pos < 0) or (pos > 9) then | if (pos < 0) or (pos > 9) then | ||
Zeile 202: | Zeile 223: | ||
procedure TCamera.Apply; | procedure TCamera.Apply; | ||
+ | // hier wird die Kamera eingeschaltet. Nach dem Aufruf dieser Prozedur sollte die Szene | ||
+ | // mit allen benötigten Drehungen, Verschiebungen gezeichnet werden. | ||
begin | begin | ||
if not Enabled then | if not Enabled then | ||
Zeile 216: | Zeile 239: | ||
function TCamera.Position: TGLvector; | function TCamera.Position: TGLvector; | ||
+ | // mit dieser Funktion kann die aktuelle Position der Kamera abgefragt werden | ||
var | var | ||
return: TGLvector; | return: TGLvector; | ||
Zeile 228: | Zeile 252: | ||
function TCamera.ViewDirection: TGLvector; | function TCamera.ViewDirection: TGLvector; | ||
+ | // mit dieser Funktion kann die aktuelle Blickrichtung der Kamera abgefragt werden | ||
var | var | ||
return: TGLvector; | return: TGLvector; | ||
Zeile 240: | Zeile 265: | ||
function TCamera.UpVector: TGLvector; | function TCamera.UpVector: TGLvector; | ||
+ | // mit dieser Funktion kann die aktuelle Ausrichtung der Kamera abgefragt werden | ||
var | var | ||
return: TGLvector; | return: TGLvector; | ||
Zeile 252: | Zeile 278: | ||
procedure TCamera.Adjust; | procedure TCamera.Adjust; | ||
+ | // mit dieser Prozedur kann die Kamera zu jeder Zeit, unabhängig von Drehung und Position, | ||
+ | // senkrecht zur Y-Achse ausgerichtet werden. Die aktuelle Position wird dabei beibehalten. | ||
var | var | ||
temp: TArrMatrix; | temp: TArrMatrix; |
Version vom 17. Oktober 2005, 09:45 Uhr
Eine Beschreibung findet ihr unter Kamera (1).
Die verwendete Toolsammlung findet ihr unter Kamera (3).
unit Camera; interface Uses DglOpenGL, OpenGLUtil, Windows, Classes;<br> type TCameraMatrix=Class Matrix: TArrMatrix; InverseMatrix: TArrMatrix; procedure Identity; procedure Load(M: TArrMatrix); constructor Create; end; TCamera=Class CameraMatrix: TCameraMatrix; Enabled : boolean; Initiated: boolean; constructor Create; destructor Destroy; function Position: TGLvector; function UpVector: TGLvector; function ViewDirection: TGLvector; procedure RestorePosition(pos: integer); procedure SavePosition(pos: integer); procedure RotateCamera(ix, iy, iz: TGLdouble); procedure TranslateCamera(ix, iy, iz: TGLdouble); procedure CameraHome; procedure PositionCamera(PositionVec: TGLvector; ViewVec: TGLvector; upVec: TGLvector); procedure Adjust; procedure Apply; private HomeMatrix: TCameraMatrix; PosArray: array [0..9] of TCameraMatrix; FPointOfRotation: TGLvector; procedure Identity; procedure RotateMatrix(ix, iy, iz: TGLdouble); procedure Offset(x, y, z: TGLfloat); procedure RotateRoundAxis(rx, ry, rz: TGLfloat); published property PointOfRotation: TGLvector read FPointOfRotation; end; TPCamera=^TCamera; implementation constructor TCameraMatrix.Create; // beim erzeugen der Matrix wird die Identitätsmatrix zugewiesen begin Identity; end; procedure TCameraMatrix.Identity; // die Funktion GetArrIdentity findet Ihr in der Datei OpenGL.pas var i: integer; begin Matrix := GetArrIdentity; InverseMatrix := GetArrIdentity; end; procedure TCameraMatrix.Load(M: TArrMatrix); // die Matrix mit den Werten einer beliebigen anderen matrix füllen var i: integer; begin for i:=0 to 15 do Matrix[i]:=M[i]; // die invertierte Matrix kann benutzt werden um Objkekte z.B. // immer zum Benutzer auszurichten InvertMatrix (M, InverseMatrix); // die inverse Matrix erzeugen end; procedure TCamera.RotateRoundAxis(rx, ry, rz: TGLfloat); // hier drehen wir jetzt um die einzelnen Achsen. // die Parameter geben die "Drehgeschwindigkeit" vor. var newMatrix: TArrMatrix; begin glMatrixMode (GL_MODELVIEW); glPushMatrix(); // aktuelle Position und Lage der Kamera herstellen glLoadMatrixf(@CameraMatrix.Matrix); // wenn gewünscht um die X-Achse drehen if(rx <> 0) then glRotatef(rx,1,0,0); // wenn gewünscht um die Y-Achse drehen if(ry <> 0) then glRotatef(ry,0,1,0); // wenn gewünscht um die Z-Achse drehen if(rz <> 0) then glRotatef(rz,0,0,1); // die neu erzeugte Matrix auslesen glGetFloatv(GL_MODELVIEW_MATRIX, @newMatrix); // und in die Kameramatrix sichern CameraMatrix.Load(newMatrix); glPopMatrix(); end; constructor TCamera.Create; var i: integer; begin // Initiated wird gebraucht um einmal alle Positionsspeicher // mit der Anfangsposition zu belegen Initiated := false; // Kameramatrix anlegen CameraMatrix := TCameraMatrix.Create; // Matrix der letzten Position von PositionCamera anlegen HomeMatrix := TCameraMatrix.Create; // Positionsspeicher anlegen for i := 0 to 9 do PosArray[i] := TCameraMatrix.Create; end; procedure TCamera.Identity; begin CameraMatrix.Identity; HomeMatrix.Identity; Enabled := true; end; destructor TCamera.Destroy; // alle belegten Resourcen wieder freigeben var i: integer; begin HomeMatrix.Free; CameraMatrix.Free; for i := 0 to 9 do PosArray[i].Free; end; procedure TCamera.Offset(x, y, z: TGLfloat); // verschieben der Kamera auf einer beliebigen Achse var newMatrix: TArrMatrix; begin glMatrixMode (GL_MODELVIEW); glPushMatrix(); glLoadIdentity; glTranslatef(x,y,z); glGetFloatv(GL_MODELVIEW_MATRIX, @newMatrix); // wenn ich mit der funktion glMultMatrixf arbeite, wird die zeichnung // immer entlang der richtigen achsen verschoben. wenn ich matrixmultiply // nehme, wird sie auf den bildschirmachsen verschoben. das ist angenehmer // zum arbeiten MatrixMultiply (newMatrix, CameraMatrix.Matrix, newMatrix); CameraMatrix.Load(newMatrix); glPopMatrix(); end; procedure TCamera.PositionCamera(PositionVec: TGLvector; ViewVec: TGLvector; upVec: TGLvector); // erstes positionieren der kamera. hierbei werden einige initialisierungen vorgenommen var newMatrix: TArrMatrix; i: integer; begin // alle kameraeinstellungen zurücknehmen Identity; // den aktuellen drehpunkt setzen FPointOfRotation := ViewVec; // an die arbeit... glMatrixMode (GL_MODELVIEW); glPushMatrix; glLoadIdentity; glTranslatef (PositionVec.X, PositionVec.Y, PositionVec.Z); gluLookAt (PositionVec.X, PositionVec.Y, PositionVec.Z, ViewVec.X, ViewVec.Y, ViewVec.Z, upVec.X, upVec.Y, upVec.Z); glGetFloatv(GL_MODELVIEW_MATRIX, @newMatrix); CameraMatrix.Load(newMatrix); HomeMatrix.Load(newMatrix); glPopMatrix; // alle positionsspeicher mit der Kameraposition, Blickrichtung und dem // upVector belegen. Nur beim ersten Aufruf von PositionCamera if not Initiated then begin for i := 0 to 9 do SavePosition (i); Initiated := true; end; end; procedure TCamera.CameraHome; // Kamera in die beim letzten Aufruf von PositionCamera übergebene // Position/Lage bringen begin CameraMatrix.Load(HomeMatrix.Matrix); end; procedure TCamera.SavePosition (pos: integer); // wie der Prozedurname schon sagt... begin if (pos < 0) or (pos > 9) then exit;<br> PosArray[pos].Load(CameraMatrix.Matrix); end; procedure TCamera.RestorePosition (pos: integer); // wie der Prozedurname schon sagt... begin if (pos < 0) or (pos > 9) then exit;<br> CameraMatrix.Load(PosArray[pos].Matrix); end; procedure TCamera.TranslateCamera(ix, iy, iz: TGLdouble); begin Offset (ix, iy, iz); end; procedure TCamera.RotateCamera(ix, iy, iz: TGLdouble); begin RotateMatrix (ix, iy, iz); end; procedure TCamera.Apply; // hier wird die Kamera eingeschaltet. Nach dem Aufruf dieser Prozedur sollte die Szene // mit allen benötigten Drehungen, Verschiebungen gezeichnet werden. begin if not Enabled then exit;<br><br> glMatrixMode (GL_MODELVIEW); glLoadMatrixf(@CameraMatrix.Matrix); glTranslatef (-PointOfRotation.X, -PointOfRotation.y, -PointOfRotation.Z); end; procedure TCamera.RotateMatrix (ix, iy, iz: TGLdouble); begin RotateRoundAxis (iy, ix, iz); end; function TCamera.Position: TGLvector; // mit dieser Funktion kann die aktuelle Position der Kamera abgefragt werden var return: TGLvector; begin // position: letzte Spalte der Matrix InitVector (return, CameraMatrix.Matrix[12], CameraMatrix.Matrix[13], CameraMatrix.Matrix[14]); result := return; end; function TCamera.ViewDirection: TGLvector; // mit dieser Funktion kann die aktuelle Blickrichtung der Kamera abgefragt werden var return: TGLvector; begin // view direction: dritte Spalte der Matrix (Z-Achse) InitVector (return, CameraMatrix.Matrix[08], CameraMatrix.Matrix[09], CameraMatrix.Matrix[10]); result := return; end; function TCamera.UpVector: TGLvector; // mit dieser Funktion kann die aktuelle Ausrichtung der Kamera abgefragt werden var return: TGLvector; begin // upVector: zweite Spalte der Matrix (Y-Achse) InitVector (return, CameraMatrix.Matrix[04], CameraMatrix.Matrix[05], CameraMatrix.Matrix[06]); result := return; end; procedure TCamera.Adjust; // mit dieser Prozedur kann die Kamera zu jeder Zeit, unabhängig von Drehung und Position, // senkrecht zur Y-Achse ausgerichtet werden. Die aktuelle Position wird dabei beibehalten. var temp: TArrMatrix; begin // kamera senkrecht zur Y-Achse ausrichten // position beibehalten temp := GetArrIdentity; temp[12] := CameraMatrix.Matrix[12]; temp[13] := CameraMatrix.Matrix[13]; temp[14] := CameraMatrix.Matrix[14]; temp[15] := CameraMatrix.Matrix[15]; CameraMatrix.Load(temp); end; end.