Kamera (2): Unterschied zwischen den Versionen

Aus DGL Wiki
Wechseln zu: Navigation, Suche
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;<br>
+
   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;<br>
+
   TPCamera=^TCamera;
implementation<br>
+
 
 +
implementation
 +
 
 
constructor TCameraMatrix.Create;
 
constructor TCameraMatrix.Create;
// beim erzeugen der Matrix wird die Identitätsmatrix zugewiesen
 
 
begin
 
begin
   Identity;
+
   Identity; // beim erzeugen der Matrix wird die Identitätsmatrix zugewiesen
end;<br>
+
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; // die Funktion GetArrIdentity findet Ihr in der Datei OpenGL.pas
 
   InverseMatrix := GetArrIdentity;
 
   InverseMatrix := GetArrIdentity;
end;<br>
+
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];
+
     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;<br>
+
  // 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();
  // aktuelle Position und Lage der Kamera herstellen
+
   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);
+
     glRotatef(rx,1,0,0);               // wenn gewünscht um die X-Achse drehen
 
 
  // wenn gewünscht um die Y-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
 
 
  // 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);                // 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;
  
  // die neu erzeugte Matrix auslesen
 
  glGetFloatv(GL_MODELVIEW_MATRIX, @newMatrix);
 
  // und in die Kameramatrix sichern
 
  CameraMatrix.Load(newMatrix);
 
  glPopMatrix();
 
end;<br>
 
 
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;<br><br>
+
end;
 +
 
 
procedure TCamera.Identity;
 
procedure TCamera.Identity;
 
begin
 
begin
Zeile 112: Zeile 111:
  
 
   Enabled := true;
 
   Enabled := true;
end;<br>
+
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;<br>
+
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;<br>
+
end;
procedure TCamera.PositionCamera(PositionVec: TGLvector;
+
 
                          ViewVec: TGLvector;
+
procedure TCamera.PositionCamera(PositionVec: TGLvector; ViewVec: TGLvector; upVec: 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;<br>
+
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;<br>
+
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;<br>
+
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;<br>
+
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;<br>
+
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;<br>
+
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);
                -PointOfRotation.y,
+
end;
                -PointOfRotation.Z);
+
 
end;<br>
 
 
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;<br>
+
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;<br>
+
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;<br>
+
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;<br>
+
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;<br><br>
+
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.