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.