Kamera (2): Unterschied zwischen den Versionen
Andyh (Diskussion | Beiträge) |
Andyh (Diskussion | Beiträge) |
||
Zeile 1: | Zeile 1: | ||
unit Camera; | unit Camera; | ||
+ | |||
interface | interface | ||
+ | |||
Uses DglOpenGL, OpenGLUtil, Windows, Classes;<br> | Uses DglOpenGL, OpenGLUtil, Windows, Classes;<br> | ||
+ | |||
type | type | ||
TCameraMatrix=Class | TCameraMatrix=Class | ||
Zeile 9: | Zeile 12: | ||
procedure Load(M: TArrMatrix); | procedure Load(M: TArrMatrix); | ||
constructor Create; | constructor Create; | ||
− | end; | + | end; |
+ | |||
TCamera=Class | TCamera=Class | ||
CameraMatrix: TCameraMatrix; | CameraMatrix: TCameraMatrix; | ||
Zeile 38: | Zeile 42: | ||
property PointOfRotation: TGLvector read FPointOfRotation; | property PointOfRotation: TGLvector read FPointOfRotation; | ||
end; | end; | ||
− | TPCamera=^TCamera; | + | TPCamera=^TCamera; |
− | implementation | + | |
+ | implementation | ||
+ | |||
constructor TCameraMatrix.Create; | constructor TCameraMatrix.Create; | ||
− | |||
begin | begin | ||
− | Identity; | + | Identity; // beim erzeugen der Matrix wird die Identitätsmatrix zugewiesen |
− | end; | + | end; |
+ | |||
procedure TCameraMatrix.Identity; | procedure TCameraMatrix.Identity; | ||
− | |||
var | var | ||
i: integer; | i: integer; | ||
begin | begin | ||
− | Matrix := GetArrIdentity; | + | Matrix := GetArrIdentity; // die Funktion GetArrIdentity findet Ihr in der Datei OpenGL.pas |
InverseMatrix := GetArrIdentity; | InverseMatrix := GetArrIdentity; | ||
− | end; | + | end; |
+ | |||
procedure TCameraMatrix.Load(M: TArrMatrix); | procedure TCameraMatrix.Load(M: TArrMatrix); | ||
− | |||
var | var | ||
i: integer; | i: integer; | ||
begin | begin | ||
for i:=0 to 15 do | for i:=0 to 15 do | ||
− | Matrix[i]:=M[i]; | + | Matrix[i]:=M[i]; // die Matrix mit den Werten einer beliebigen anderen matrix füllen |
− | InvertMatrix (M, InverseMatrix); | + | InvertMatrix (M, InverseMatrix); // die inverse Matrix erzeugen |
− | end; | + | // die invertierte Matrix kann benutzt werden um Objkekte immer zum Benutzer auszurichten |
+ | end; | ||
+ | |||
procedure TCamera.RotateRoundAxis(rx, ry, rz: TGLfloat); | procedure TCamera.RotateRoundAxis(rx, ry, rz: TGLfloat); | ||
// hier drehen wir jetzt um die einzelnen Achsen. | // hier drehen wir jetzt um die einzelnen Achsen. | ||
Zeile 70: | Zeile 77: | ||
glMatrixMode (GL_MODELVIEW); | glMatrixMode (GL_MODELVIEW); | ||
glPushMatrix(); | glPushMatrix(); | ||
− | + | glLoadMatrixf(@CameraMatrix.Matrix); // aktuelle Position und Lage der Kamera herstellen | |
− | glLoadMatrixf(@CameraMatrix.Matrix); | ||
− | |||
− | |||
if(rx <> 0) then | if(rx <> 0) then | ||
− | glRotatef(rx,1,0,0); | + | glRotatef(rx,1,0,0); // wenn gewünscht um die X-Achse drehen |
− | |||
− | |||
if(ry <> 0) then | if(ry <> 0) then | ||
− | glRotatef(ry,0,1,0); | + | glRotatef(ry,0,1,0); // wenn gewünscht um die Y-Achse drehen |
− | |||
− | |||
if(rz <> 0) then | if(rz <> 0) then | ||
− | glRotatef(rz,0,0,1); | + | glRotatef(rz,0,0,1); // wenn gewünscht um die Z-Achse drehen |
+ | glGetFloatv(GL_MODELVIEW_MATRIX, @newMatrix); // die neu erzeugte Matrix auslesen | ||
+ | CameraMatrix.Load(newMatrix); // und in die Kameramatrix sichern | ||
+ | glPopMatrix(); | ||
+ | end; | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
constructor TCamera.Create; | constructor TCamera.Create; | ||
var | var | ||
Zeile 105: | Zeile 103: | ||
for i := 0 to 9 do | for i := 0 to 9 do | ||
PosArray[i] := TCameraMatrix.Create; | PosArray[i] := TCameraMatrix.Create; | ||
− | end; | + | end; |
+ | |||
procedure TCamera.Identity; | procedure TCamera.Identity; | ||
begin | begin | ||
Zeile 112: | Zeile 111: | ||
Enabled := true; | Enabled := true; | ||
− | end; | + | end; |
+ | |||
destructor TCamera.Destroy; | destructor TCamera.Destroy; | ||
var | var | ||
Zeile 121: | Zeile 121: | ||
for i := 0 to 9 do | for i := 0 to 9 do | ||
PosArray[i].Free; | PosArray[i].Free; | ||
− | end; | + | end; |
+ | |||
procedure TCamera.Offset(x, y, z: TGLfloat); | procedure TCamera.Offset(x, y, z: TGLfloat); | ||
var | var | ||
Zeile 138: | Zeile 139: | ||
CameraMatrix.Load(newMatrix); | CameraMatrix.Load(newMatrix); | ||
glPopMatrix(); | glPopMatrix(); | ||
− | end; | + | end; |
− | procedure TCamera.PositionCamera(PositionVec: TGLvector; | + | |
− | + | procedure TCamera.PositionCamera(PositionVec: TGLvector; ViewVec: TGLvector; upVec: TGLvector); | |
− | |||
var | var | ||
newMatrix: TArrMatrix; | newMatrix: TArrMatrix; | ||
Zeile 148: | Zeile 148: | ||
Identity; | Identity; | ||
FPointOfRotation := ViewVec; | FPointOfRotation := ViewVec; | ||
− | |||
glMatrixMode (GL_MODELVIEW); | glMatrixMode (GL_MODELVIEW); | ||
glPushMatrix; | glPushMatrix; | ||
Zeile 160: | Zeile 159: | ||
HomeMatrix.Load(newMatrix); | HomeMatrix.Load(newMatrix); | ||
glPopMatrix; | glPopMatrix; | ||
− | |||
if not Initiated then | if not Initiated then | ||
begin | begin | ||
Zeile 167: | Zeile 165: | ||
Initiated := true; | Initiated := true; | ||
end; | end; | ||
− | end; | + | end; |
+ | |||
procedure TCamera.CameraHome; | procedure TCamera.CameraHome; | ||
// Move the camera to the home position | // Move the camera to the home position | ||
begin | begin | ||
CameraMatrix.Load(HomeMatrix.Matrix); | CameraMatrix.Load(HomeMatrix.Matrix); | ||
− | end; | + | end; |
+ | |||
procedure TCamera.SavePosition (pos: integer); | procedure TCamera.SavePosition (pos: integer); | ||
begin | begin | ||
Zeile 178: | Zeile 178: | ||
exit;<br> | exit;<br> | ||
PosArray[pos].Load(CameraMatrix.Matrix); | PosArray[pos].Load(CameraMatrix.Matrix); | ||
− | end; | + | end; |
+ | |||
procedure TCamera.RestorePosition (pos: integer); | procedure TCamera.RestorePosition (pos: integer); | ||
begin | begin | ||
Zeile 184: | Zeile 185: | ||
exit;<br> | exit;<br> | ||
CameraMatrix.Load(PosArray[pos].Matrix); | CameraMatrix.Load(PosArray[pos].Matrix); | ||
− | end; | + | end; |
+ | |||
procedure TCamera.TranslateCamera(ix, iy, iz: TGLdouble); | procedure TCamera.TranslateCamera(ix, iy, iz: TGLdouble); | ||
begin | begin | ||
Offset (ix, iy, iz); | Offset (ix, iy, iz); | ||
− | end; | + | end; |
+ | |||
procedure TCamera.RotateCamera(ix, iy, iz: TGLdouble); | procedure TCamera.RotateCamera(ix, iy, iz: TGLdouble); | ||
begin | begin | ||
RotateMatrix (ix, iy, iz); | RotateMatrix (ix, iy, iz); | ||
− | end; | + | end; |
+ | |||
procedure TCamera.Apply; | procedure TCamera.Apply; | ||
begin | begin | ||
Zeile 199: | Zeile 203: | ||
glMatrixMode (GL_MODELVIEW); | glMatrixMode (GL_MODELVIEW); | ||
glLoadMatrixf(@CameraMatrix.Matrix); | glLoadMatrixf(@CameraMatrix.Matrix); | ||
− | glTranslatef (-PointOfRotation.X, | + | glTranslatef (-PointOfRotation.X, -PointOfRotation.y, -PointOfRotation.Z); |
− | + | end; | |
− | + | ||
− | end; | ||
procedure TCamera.RotateMatrix (ix, iy, iz: TGLdouble); | procedure TCamera.RotateMatrix (ix, iy, iz: TGLdouble); | ||
begin | begin | ||
RotateRoundAxis (iy, ix, iz); | RotateRoundAxis (iy, ix, iz); | ||
− | end; | + | end; |
+ | |||
function TCamera.Position: TGLvector; | function TCamera.Position: TGLvector; | ||
var | var | ||
Zeile 217: | Zeile 221: | ||
CameraMatrix.Matrix[14]); | CameraMatrix.Matrix[14]); | ||
result := return; | result := return; | ||
− | end; | + | end; |
+ | |||
function TCamera.ViewDirection: TGLvector; | function TCamera.ViewDirection: TGLvector; | ||
var | var | ||
Zeile 228: | Zeile 233: | ||
CameraMatrix.Matrix[10]); | CameraMatrix.Matrix[10]); | ||
result := return; | result := return; | ||
− | end; | + | end; |
+ | |||
function TCamera.UpVector: TGLvector; | function TCamera.UpVector: TGLvector; | ||
var | var | ||
Zeile 239: | Zeile 245: | ||
CameraMatrix.Matrix[06]); | CameraMatrix.Matrix[06]); | ||
result := return; | result := return; | ||
− | end; | + | end; |
+ | |||
procedure TCamera.Adjust; | procedure TCamera.Adjust; | ||
var | var | ||
Zeile 252: | Zeile 259: | ||
temp[15] := CameraMatrix.Matrix[15]; | temp[15] := CameraMatrix.Matrix[15]; | ||
CameraMatrix.Load(temp); | CameraMatrix.Load(temp); | ||
− | end; | + | end; |
+ | |||
end. | end. |
Version vom 15. Oktober 2005, 14:29 Uhr
unit Camera;
interface
Uses DglOpenGL, OpenGLUtil, Windows, Classes;
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; begin
Identity; // beim erzeugen der Matrix wird die Identitätsmatrix zugewiesen
end;
procedure TCameraMatrix.Identity; var
i: integer;
begin
Matrix := GetArrIdentity; // die Funktion GetArrIdentity findet Ihr in der Datei OpenGL.pas InverseMatrix := GetArrIdentity;
end;
procedure TCameraMatrix.Load(M: TArrMatrix); var
i: integer;
begin
for i:=0 to 15 do Matrix[i]:=M[i]; // die Matrix mit den Werten einer beliebigen anderen matrix füllen InvertMatrix (M, InverseMatrix); // die inverse Matrix erzeugen // die invertierte Matrix kann benutzt werden um Objkekte immer zum Benutzer auszurichten
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(); glLoadMatrixf(@CameraMatrix.Matrix); // aktuelle Position und Lage der Kamera herstellen if(rx <> 0) then glRotatef(rx,1,0,0); // wenn gewünscht um die X-Achse drehen if(ry <> 0) then glRotatef(ry,0,1,0); // wenn gewünscht um die Y-Achse drehen if(rz <> 0) then glRotatef(rz,0,0,1); // wenn gewünscht um die Z-Achse drehen glGetFloatv(GL_MODELVIEW_MATRIX, @newMatrix); // die neu erzeugte Matrix auslesen CameraMatrix.Load(newMatrix); // und in die Kameramatrix sichern 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; 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); 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); var
newMatrix: TArrMatrix; i: integer;
begin
Identity; FPointOfRotation := ViewVec; 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; if not Initiated then begin for i := 0 to 9 do SavePosition (i); Initiated := true; end;
end;
procedure TCamera.CameraHome; // Move the camera to the home position begin
CameraMatrix.Load(HomeMatrix.Matrix);
end;
procedure TCamera.SavePosition (pos: integer); begin
if (pos < 0) or (pos > 9) then exit;
PosArray[pos].Load(CameraMatrix.Matrix);
end;
procedure TCamera.RestorePosition (pos: integer); begin
if (pos < 0) or (pos > 9) then exit;
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; begin
if not Enabled then exit;
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; 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; 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; 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; 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.