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

Aktuelle Zeit: Fr Jul 18, 2025 19:23

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



Ein neues Thema erstellen Auf das Thema antworten  [ 1 Beitrag ] 
Autor Nachricht
 Betreff des Beitrags: Kamera mit Anleitung
BeitragVerfasst: Fr Okt 14, 2005 11:16 
Offline
DGL Member
Benutzeravatar

Registriert: Do Jun 09, 2005 13:48
Beiträge: 117
Wohnort: Sankt Augustin
Nachdem ich viel Zeit damit verbracht habe eine funktionierende Kamera
zu bauen und es nun endlich geschafft habe, wollte ich diese Funktionalität
auch anderen zur Verfügung stellen.
Da mir schon viel geholfen wurde, kann ich so einen Teil meiner "Schuld"
zurück zahlen.

Die folgend beschriebene Kamera kann sich um alle drei Achsen drehen und sich
in allen ebenen bewegen. Der Drehpunkt um den sich die Kamera dreht wird mit
dem Aufruf der Prozedur PositionCamera festgelegt. Sollte man diesen Dreh-
punkt benötigen (z.B. zum anzeigen eines Koordinatenkreuzes, ...) so kann man
auf die property PointOfRotation zugreifen (read only).

Die Kamera kann bis zu zehn Positionen speichern und auch wieder herstellen.
(SavePosition, RestorePosition)

Die Kamera kann sich selber zu jeder Zeit unter Beibehaltung der aktuellen
Position senkrecht zur Welt ausrichten.
(Adjust)

Um sicher zu sein, dass auch alle nötigen Definitionen und Funktionen zur
Verfügung stehen habe ich einfach mal einen Großteil meiner Funktionssammlung
beigefügt (OpenGLUtil.pas). Diese Funktionen/Prozeduren werden so oder in leicht
abgeänderter Form wohl bei jedem OpenGL Programmierer existieren.

Sollte es noch irgendwelche Fragen zu diesem Modul geben so stehe ich gerne
zur Verfügung.




Camera.pas

Gebrauch der Funktionen:

1. PositionCamera mit Vektoren für Position, Blickrichtung und Ausrichtung
aufrufen. Die Blickrichtung gibt auch gleichzeitig den Drehpunkt der Szene
an um den dann mit RotateCamera gedreht werden kann.

2. Aufruf der Funktionen RotateCamera und TranslateCamera um die Ausrichtung/Lage der
Kamera zu verändern. z.B.:

// FRightMousePressed, FLeftMousePressed,
// FxDelta, FyDelta, FxStart, FyStart,
// FxRot und Fyrot sind als var im aktuellen Modul definiert.

procedure TExample.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
//Dragging is happening only if the mouse button is down
if not (FRightMousePressed or FLeftMousePressed) then exit;

//Calculate how much the mouse has moved
FxDelta := FxStart-X;
FyDelta := FyStart-Y;

//Adjust rotation and scale so it is'nt too fast
FxRot := FxRot - FyDelta/20;
Fyrot := FyRot - FxDelta/20;

//Next time, we start from here
FxStart := X;
FyStart := Y;

if FRightMousePressed then
begin
if FxRot <> 0 then FCamera.RotateCamera (FxRot, 0, 0);
if FyRot <> 0 then FCamera.RotateObject (0, FyRot, 0);
end;
if FLeftMousePressed then
begin
if FxRot <> 0 then FCamera.TranslateCamera (FxRot, 0, 0);
if FyRot <> 0 then FCamera.TranslateCamera (0, FyRot, 0);
end;
Paint;

FxRot := 0;
FyRot := 0;
end;

Dieses Beispiel is vereinfacht dargestellt und es kann sein, dass man
daran noch etwas herumspielen muss. Ich habe noch das Mausrad eingesetzt
um in den Bildschirm hinein- oder aus ihm herauszuzoomen (TranslateCamera(0,0,?)).

3. Szene zeichnen:

Lichteigenschaften setzen
Materialeigenschaften setzen
halt die üblichen Vorbereitungen treffen

FCamera.Apply

Szene zeichnen

Swapbuffers...

usw.


Hier das Kameramodul:
Code:
  1.  
  2. unit Camera;
  3.  
  4. interface
  5.  
  6.   Uses DglOpenGL, OpenGLUtil, Windows, Classes;
  7.  
  8.   type TCameraMatrix=Class
  9.     Matrix: TArrMatrix;
  10.     InverseMatrix: TArrMatrix;
  11.     procedure Identity;
  12.     procedure Load(M: TArrMatrix);
  13.     constructor Create;
  14.   end;
  15.  
  16.   TCamera=Class
  17.     CameraMatrix: TCameraMatrix;
  18.     Enabled  : boolean;
  19.     Initiated: boolean;
  20.     constructor Create;
  21.     destructor Destroy;
  22.     function Position: TGLvector;
  23.     function UpVector: TGLvector;
  24.     function ViewDirection: TGLvector;
  25.     procedure RestorePosition(pos: integer);
  26.     procedure SavePosition(pos: integer);
  27.     procedure RotateCamera(ix, iy, iz: TGLdouble);
  28.     procedure TranslateCamera(ix, iy, iz: TGLdouble);
  29.     procedure CameraHome;
  30.     procedure PositionCamera(PositionVec: TGLvector;
  31.                  ViewVec: TGLvector;
  32.                  upVec: TGLvector);
  33.     procedure Adjust;
  34.     procedure Apply;
  35.   private
  36.     HomeMatrix: TCameraMatrix;
  37.     PosArray: array [0..9] of TCameraMatrix;
  38.     FPointOfRotation: TGLvector;
  39.     procedure Identity;
  40.     procedure RotateMatrix(ix, iy, iz: TGLdouble);
  41.     procedure Offset(x, y, z: TGLfloat);
  42.     procedure RotateRoundAxis(rx, ry, rz: TGLfloat);
  43.   published
  44.     property PointOfRotation: TGLvector read FPointOfRotation;
  45.   end;
  46.   TPCamera=^TCamera;
  47.  
  48. implementation
  49.  
  50. constructor TCameraMatrix.Create;
  51. begin
  52.   Identity;
  53. end;
  54.  
  55. procedure TCameraMatrix.Identity;
  56. var
  57.   i: integer;
  58. begin
  59.   Matrix := GetArrIdentity;
  60.   InverseMatrix := GetArrIdentity;
  61. end;
  62.  
  63. procedure TCameraMatrix.Load(M: TArrMatrix);
  64. var
  65.   i: integer;
  66. begin
  67.   for i:=0 to 15 do
  68.     Matrix[i]:=M[i];
  69.   InvertMatrix (M, InverseMatrix);
  70. end;
  71.  
  72.  
  73. procedure TCamera.RotateRoundAxis(rx, ry, rz: TGLfloat);
  74. var
  75.   newMatrix: TArrMatrix;
  76. begin
  77.   glMatrixMode (GL_MODELVIEW);
  78.   glPushMatrix();
  79.   glLoadMatrixf(@CameraMatrix.Matrix);
  80.  
  81.   if(rx <> 0) then
  82.     glRotatef(rx,1,0,0);
  83.  
  84.   if(ry <> 0) then
  85.     glRotatef(ry,0,1,0);
  86.  
  87.   if(rz <> 0) then
  88.     glRotatef(rz,0,0,1);
  89.  
  90.   glGetFloatv(GL_MODELVIEW_MATRIX, @newMatrix);
  91.   CameraMatrix.Load(newMatrix);
  92.   glPopMatrix();
  93. end;
  94.  
  95. constructor TCamera.Create;
  96. var
  97.   i: integer;
  98. begin
  99.   Initiated := false;
  100.   CameraMatrix := TCameraMatrix.Create;
  101.   HomeMatrix := TCameraMatrix.Create;
  102.   for i := 0 to 9 do
  103.     PosArray[i] := TCameraMatrix.Create;
  104. end;
  105.  
  106. procedure TCamera.Identity;
  107. begin
  108.   CameraMatrix.Identity;
  109.   HomeMatrix.Identity;
  110.  
  111.   Enabled := true;
  112. end;
  113.  
  114. destructor TCamera.Destroy;
  115. var
  116.   i: integer;
  117. begin
  118.   HomeMatrix.Free;
  119.   CameraMatrix.Free;
  120.   for i := 0 to 9 do
  121.     PosArray[i].Free;
  122. end;
  123.  
  124. procedure TCamera.Offset(x, y, z: TGLfloat);
  125. var
  126.   newMatrix: TArrMatrix;
  127. begin
  128.   glMatrixMode (GL_MODELVIEW);
  129.   glPushMatrix();
  130.   glLoadIdentity;
  131.   glTranslatef(x,y,z);
  132.   glGetFloatv(GL_MODELVIEW_MATRIX, @newMatrix);
  133.   // wenn ich mit der funktion glMultMatrixf arbeite, wird die zeichnung
  134.   // immer entlang der richtigen achsen verschoben. wenn ich matrixmultiply
  135.   // nehme, wird sie auf den bildschirmachsen verschoben. das ist angenehmer
  136.   // zum arbeiten
  137.   MatrixMultiply (newMatrix, CameraMatrix.Matrix, newMatrix);
  138.   CameraMatrix.Load(newMatrix);
  139.   glPopMatrix();
  140. end;
  141.  
  142.  
  143. procedure TCamera.PositionCamera(PositionVec: TGLvector;
  144.                                        ViewVec: TGLvector;
  145.                                        upVec: TGLvector);
  146. var
  147.   newMatrix: TArrMatrix;
  148.   i: integer;
  149. begin
  150.   Identity;
  151.   FPointOfRotation := ViewVec;
  152.  
  153.   glMatrixMode (GL_MODELVIEW);
  154.   glPushMatrix;
  155.   glLoadIdentity;
  156.   glTranslatef (PositionVec.X, PositionVec.Y, PositionVec.Z);
  157.   gluLookAt (PositionVec.X, PositionVec.Y, PositionVec.Z,
  158.              ViewVec.X, ViewVec.Y, ViewVec.Z,
  159.              upVec.X, upVec.Y, upVec.Z);
  160.   glGetFloatv(GL_MODELVIEW_MATRIX, @newMatrix);
  161.   CameraMatrix.Load(newMatrix);
  162.   HomeMatrix.Load(newMatrix);
  163.   glPopMatrix;
  164.  
  165.   if not Initiated then
  166.   begin
  167.     for i := 0 to 9 do
  168.       SavePosition (i);
  169.     Initiated := true;
  170.   end;
  171. end;
  172.  
  173. // Move the camera to the home position
  174. procedure TCamera.CameraHome;
  175. begin
  176.   CameraMatrix.Load(HomeMatrix.Matrix);
  177. end;
  178.  
  179. procedure TCamera.SavePosition (pos: integer);
  180. begin
  181.   if (pos < 0) or (pos > 9) then
  182.     exit;
  183.  
  184.   PosArray[pos].Load(CameraMatrix.Matrix);
  185. end;
  186.  
  187. procedure TCamera.RestorePosition (pos: integer);
  188. begin
  189.   if (pos < 0) or (pos > 9) then
  190.     exit;
  191.  
  192.   CameraMatrix.Load(PosArray[pos].Matrix);
  193. end;
  194.  
  195. procedure TCamera.TranslateCamera(ix, iy, iz: TGLdouble);
  196. begin
  197.   Offset (ix, iy, iz);
  198. end;
  199.  
  200. procedure TCamera.RotateCamera(ix, iy, iz: TGLdouble);
  201. begin
  202.   RotateMatrix (ix, iy, iz);
  203. end;
  204.  
  205. procedure TCamera.Apply;
  206. begin
  207.   if not Enabled then
  208.     exit;
  209.  
  210.   glMatrixMode (GL_MODELVIEW);
  211.   glLoadMatrixf(@CameraMatrix.Matrix);
  212.   glTranslatef (-PointOfRotation.X,
  213.                 -PointOfRotation.y,
  214.                 -PointOfRotation.Z);
  215. end;
  216.  
  217. procedure TCamera.RotateMatrix (ix, iy, iz: TGLdouble);
  218. begin
  219.   RotateRoundAxis (iy, ix, iz);
  220. end;
  221.  
  222. function TCamera.Position: TGLvector;
  223. var
  224.   return: TGLvector;
  225. begin
  226.   // position: letzte Spalte der Matrix
  227.   InitVector (return,
  228.               CameraMatrix.Matrix[12],
  229.               CameraMatrix.Matrix[13],
  230.               CameraMatrix.Matrix[14]);
  231.   result := return;
  232. end;
  233.  
  234. function TCamera.ViewDirection: TGLvector;
  235. var
  236.   return: TGLvector;
  237. begin
  238.   // view direction: dritte Spalte der Matrix (Z-Achse)
  239.   InitVector (return,
  240.               CameraMatrix.Matrix[08],
  241.               CameraMatrix.Matrix[09],
  242.               CameraMatrix.Matrix[10]);
  243.   result := return;
  244. end;
  245.  
  246. function TCamera.UpVector: TGLvector;
  247. var
  248.   return: TGLvector;
  249. begin
  250.   // upVector: zweite Spalte der Matrix (Y-Achse)
  251.   InitVector (return,
  252.               CameraMatrix.Matrix[04],
  253.               CameraMatrix.Matrix[05],
  254.               CameraMatrix.Matrix[06]);
  255.  result := return;
  256. end;
  257.  
  258. procedure TCamera.Adjust;
  259. var
  260.   temp: TArrMatrix;
  261. begin
  262.   // kamera senkrecht zur Y-Achse ausrichten
  263.   // position beibehalten
  264.   temp[00] := 1;
  265.   temp[01] := 0;
  266.   temp[02] := 0;
  267.   temp[03] := 0;
  268.   temp[04] := 0;
  269.   temp[05] := 1;
  270.   temp[06] := 0;
  271.   temp[07] := 0;
  272.   temp[08] := 0;
  273.   temp[09] := 0;
  274.   temp[10] := 1;
  275.   temp[11] := 0;
  276.   temp[12] := CameraMatrix.Matrix[12];
  277.   temp[13] := CameraMatrix.Matrix[13];
  278.   temp[14] := CameraMatrix.Matrix[14];
  279.   temp[15] := CameraMatrix.Matrix[15];
  280.   CameraMatrix.Load(temp);
  281. end;
  282.  
  283. end.
  284.  


Und hier die Funktionssammlung:
Code:
  1.  
  2. unit OpenGLUtil;
  3.  
  4. interface
  5.  
  6. uses DglOpenGL, Math, Windows, Graphics, SysUtils, Dialogs;
  7.  
  8. type
  9.   TProjection=(Frustum, Orthographic, Perspective);
  10.  
  11.   TGLPlace=packed record
  12.     X,Y,Z: glFloat;
  13.   end;
  14.  
  15.   TScale=packed record
  16.     X,Y,Z: glFloat;
  17.   end;
  18.  
  19.   TGLPosition=packed record
  20.     X,Y,Z,W: glFloat;
  21.   end;
  22.  
  23.   TPosition = packed record
  24.     X,Y,Z,W: GLdouble;
  25.   end;
  26.  
  27.   TGLVector = packed record
  28.     X,Y,Z: GLfloat;
  29.   end;
  30.   TGLVectorArray = array of TGLvector;
  31.   TGLfloatArray = array of TGLfloat;
  32.  
  33.   TGKVector = packed record
  34.     X,Y,Z: GLfloat;
  35.   end;
  36.  
  37.   TAngle = packed record
  38.     X,Y,Z: GLdouble;
  39.   end;
  40.  
  41.   TGLColor=record
  42.     red,green,blue,alpha: GLclampf;
  43.   end;
  44.  
  45.   TRotation = packed record
  46.     angle, x, y, z: GLfloat;
  47.   end;
  48.  
  49.   TTextureInfo = packed record
  50.     BitmapName: string;
  51.     TextureNum: GLUint;
  52.   end;
  53.   TTextureList = array of TTextureInfo;
  54.  
  55.   TMatrix = array [0..3,0..3] of TGLFloat;
  56.   TArrMatrix = array [0..15] of TGLFloat;
  57.   TFrustum = array [0..5,0..3] of TGLFloat;
  58.   TArrVector = array [0..3] of TGLFloat;
  59.  
  60.   function Multiply (Color: TGLcolor; mult: TGLdouble): TGLcolor;
  61.   procedure MatrixMultiply(M1, M2:TArrMatrix; var M3: TArrMatrix);
  62.   function MakeVector(X,Y,Z:TGLFloat):TArrVector;overload;
  63.   function MakeVector(X,Y,Z,W:TGLFloat):TArrVector;overload;
  64.   procedure Normalize(aVector:TArrVector;var RVec:TArrVector);overload;
  65.   procedure Normalize(aVector:TGLVector;var RVec:TGLVector);overload;
  66.   function GetIdentity:TMatrix;
  67.   function GetArrIdentity:TArrMatrix;
  68.   function MatrixTranspose(const M:TMatrix):TMatrix;register;
  69.   function VectorRotateX(v:TArrVector;a:TGLFloat):TArrVector;overload;
  70.   function VectorRotateY(v:TArrVector;a:TGLFloat):TArrVector;overload;
  71.   function VectorRotateZ(v:TArrVector;a:TGLFloat):TArrVector;overload;
  72.   function VectorRotateX(v:TGLVector;a:TGLFloat):TGLVector;overload;
  73.   function VectorRotateY(v:TGLVector;a:TGLFloat):TGLVector;overload;
  74.   function VectorRotateZ(v:TGLVector;a:TGLFloat):TGLVector;overload;
  75.  
  76.   function GL2GKVector (V: TGLVector): TGKVector;
  77.   function GK2GLVector (V: TGKVector): TGLVector;
  78.   function GL2WinColor (GLcol: TGLcolor): TColor;
  79.   function Win2GLColor (WinCol: Tcolor): TGLcolor;
  80.   function CalcNormale (V1, V2, V3: TGLVector): TGLVector;
  81.   function CrossProduct(V1, V2: TGLVector): TGLVector;
  82.   function DotProduct (V1, V2: TGLVector): GLdouble;
  83.   function LoadTexture(Filename: String; var Texture: GLuint): Boolean;
  84.   function Magnitude(V1 : TGLVector) : GLfloat;
  85.   function MultiplyVektor (V1, V2: TGLVector): TGLVector;
  86.   function ScalarProduct (V1, V2: TGLVector): GLdouble;
  87.   function SubtractVector (Vec1, Vec2: TGLVector): TGLVector;overload;
  88.   function SubtractVector (Vec: TGLVector; X, Y, Z: TGLdouble): TGLVector;overload;
  89.   function AddVector (Vec1, Vec2: TGLVector): TGLVector;overload;
  90.   function AddVector (Vec: TGLVector; X, Y, Z: TGLdouble): TGLVector;overload;
  91.   procedure CopyVector (FromVektor: TGLVector; var ToVektor: TGLVector);
  92.   procedure InitVector (var V1: TGLVector; x, y, z: TGLdouble);overload;
  93.   procedure InitVector (var V1: TGKVector; x, y, z: TGLdouble);overload;
  94.   procedure InitVector (var V1: TArrVector; x, y, z: TGLdouble);overload;
  95.   procedure InitScale (var S1: TScale; x, y, z: TGLdouble);
  96.   procedure LoadBitmap(Filename: String;
  97.                        out Width: Cardinal;
  98.                        out Height: Cardinal;
  99.                        out pData: Pointer);
  100.   procedure GetRotation (V1, V2: TGLVector;
  101.                          var Rotation: TRotation;
  102.                          var normale: TGLVector);
  103.   function MakeTextureFromBitmap (Bitmap: string; var BitmapList: TTextureList): GLenum;
  104.   procedure EnableTexture (Texture: GLenum; TextureTiled: boolean);
  105.   procedure DisableTexture;
  106.   function TextToGLVector (VTxt: string): TGLVector;
  107.   function TextToGKVector (VTxt: string): TGKVector;
  108.   function GKVectorToText (V1: TGKVector): string;
  109.   function GLVectorToText (V1: TGLVector): string;
  110.   function MyCone (Start, Ende: TGLVector;
  111.                    RadiusStart, RadiusEnde: TGLfloat;
  112.                    Slices: Integer): boolean;
  113.   function InvertMatrix (src: TArrMatrix; var inverse: TArrMatrix): boolean;
  114.  
  115. const
  116.   C_X = 0;
  117.   C_Y = 1;
  118.   C_Z = 2;
  119.   C_W = 3;
  120.   C_EPS:TGLFloat=0.01;
  121.   C_DEGTORAD:TGLFloat=3.1412/180;
  122.   C_RADTODEG:TGLFloat=180/3.1412;
  123.   C_LAMBDA_INCREMENT:TGLFloat=0.01;
  124.  
  125.  
  126. implementation
  127.  
  128. function MyPower (Base: extended; Exp: integer): extended;
  129. // ist nicht ausprogrammiert, funktioniert nur für eine
  130. // einfache zweierpotenz
  131. begin
  132.   result := Base * Base;
  133. end;
  134.  
  135. procedure CopyVector (FromVektor: TGLVector; var ToVektor: TGLVector);
  136. begin
  137.   ToVektor.X := FromVektor.X;
  138.   ToVektor.Y := FromVektor.Y;
  139.   ToVektor.Z := FromVektor.Z;
  140. end;
  141.  
  142. function SubtractVector (Vec1, Vec2: TGLVector): TGLVector;
  143. // subtrahiert Vec2 von vec1 und gibt das ergebnis in vec3 zurück
  144. var
  145.   Vec3: TGLVector;
  146. begin
  147.   Vec3 .X := Vec1.X - Vec2.X;
  148.   Vec3 .Y := Vec1.Y - Vec2.Y;
  149.   Vec3 .Z := Vec1.Z - Vec2.Z;
  150.   result := Vec3;
  151. end;
  152.  
  153. function SubtractVector (Vec: TGLVector; X, Y, Z: TGLdouble): TGLVector;
  154. // subtrahiert X, Y, Z von vec.x, vec.y, vec.z  und gibt das
  155. // ergebnis zurück
  156. begin
  157.   Vec .X := Vec.X - X;
  158.   Vec .Y := Vec.Y - Y;
  159.   Vec .Z := Vec.Z - Z;
  160.   result := Vec;
  161. end;
  162.  
  163. function AddVector (Vec1, Vec2: TGLVector): TGLVector;
  164. // addiert Vec2 auf vec1 und gibt das ergebnis in vec3 zurück
  165. var
  166.   Vec3: TGLVector;
  167. begin
  168.   Vec3 .X := Vec1.X + Vec2.X;
  169.   Vec3 .Y := Vec1.Y + Vec2.Y;
  170.   Vec3 .Z := Vec1.Z + Vec2.Z;
  171.   result := Vec3;
  172. end;
  173.  
  174. function AddVector (Vec: TGLVector; X, Y, Z: TGLdouble): TGLVector;
  175. // addiert X, Y, Z auf vec.x, vec.y, vec.z  und gibt das
  176. // ergebnis zurück
  177. begin
  178.   Vec .X := Vec.X + X;
  179.   Vec .Y := Vec.Y + Y;
  180.   Vec .Z := Vec.Z + Z;
  181.   result := Vec;
  182. end;
  183.  
  184. function Magnitude(V1 : TGLVector) : GLfloat;
  185. var
  186.   Ergebnis: GLdouble;
  187. begin
  188. // gibt die länge des vektors zurück
  189.   Ergebnis := MyPower(V1.X,2)+MyPower(V1.Y,2)+MyPower(V1.Z,2);
  190.   try
  191.     result := sqrt(Ergebnis);
  192.   except
  193.     result := 0;
  194.   end;
  195. end;
  196.  
  197. function DotProduct (V1, V2: TGLVector): GLdouble;
  198. var
  199.   len1, len2: GLdouble;
  200.   Ergebnis: GLdouble;
  201. begin
  202.   len1 := Magnitude (V1);
  203.   len2 := Magnitude (V2);
  204.   Ergebnis := ScalarProduct (V1, V2);
  205.   Ergebnis := arccos (Ergebnis / (len1 * len2));
  206.   result := radtodeg (Ergebnis) * 2.0;
  207. end;
  208.  
  209. function CrossProduct(V1, V2: TGLVector): TGLVector;
  210. var
  211.   CrossVec: TGLVector;
  212. begin
  213.   CrossVec.X := ((V1.Y*V2.Z) - (V1.Z*V2.Y));
  214.   CrossVec.Y := ((V1.Z*V2.X) - (V1.X*V2.Z));
  215. CrossVec.Z := ((V1.X*V2.Y) - (V1.Y*V2.X));
  216.   result := CrossVec;
  217.  end;
  218.  
  219. function CalcNormale (V1, V2, V3: TGLVector): TGLVector;
  220. var
  221.   Kreuz: TGLvector;
  222.   V1V2, V1V3: TGLvector;
  223. begin
  224.   // gibt die normale von 3 vektoren zurück (die senkrechte auf die
  225.   // durch die drei vektoren gebildete ebene)
  226.   V1V2 := SubtractVector (V2, V1);
  227.   V1V3 := SubtractVector (V3, V1);
  228.  
  229.   Kreuz := CrossProduct (V1V2, V1V3);
  230.  
  231.   Normalize (Kreuz, result);
  232. end;
  233.  
  234. procedure InitVector (var V1: TGLVector; x, y, z: TGLdouble);
  235. begin
  236.   V1.x := x;
  237.   V1.y := y;
  238.   V1.z := z;
  239. end;
  240.  
  241. procedure InitVector (var V1: TGKVector; x, y, z: TGLdouble);
  242. begin
  243.   V1.x := x;
  244.   V1.y := y;
  245.   V1.z := z;
  246. end;
  247.  
  248. procedure InitVector (var V1: TArrVector; x, y, z: TGLdouble);
  249. begin
  250.   V1[C_X] := x;
  251.   V1[C_Y] := y;
  252.   V1[C_Z] := z;
  253. end;
  254.  
  255. procedure InitScale (var S1: TScale; x, y, z: TGLdouble);
  256. begin
  257.   S1.x := x;
  258.   S1.y := y;
  259.   S1.z := z;
  260. end;
  261.  
  262. function MultiplyVektor (V1, V2: TGLVector): TGLVector;
  263. var
  264.   multVec: TGLVector;
  265. begin
  266. // zwei vektoren miteinander multiplizieren
  267.   multVec.X := V1.X * V2.X;
  268.   multVec.Y := V1.Y * V2.Y;
  269.   multVec.Z := V1.Z * V2.Z;
  270.   result := multvec;
  271. end;
  272.  
  273. function ScalarProduct (V1, V2: TGLVector): GLdouble;
  274. begin
  275. // die summe der potenzen der einzelnen achsen von zwei vektoren errechnen
  276.   result := (V1.X*V2.X +
  277.              V1.Y*V2.Y +
  278.              V1.Z*V2.Z);
  279. end;
  280.  
  281. function LoadTexture(Filename: String; var Texture: GLuint): Boolean;
  282. var
  283.   pData: Pointer;
  284.   Width: Cardinal;
  285.   Height: Cardinal;
  286. begin
  287.   pData :=nil;
  288.   LoadBitmap(Filename, Width, Height, pData);
  289.  
  290.   if (Assigned(pData)) then
  291.     Result := True
  292.   else
  293.   begin
  294.     Result := False;
  295.     MessageBox(0, PChar('Unable to load ' + filename), 'Loading Textures', MB_OK);
  296.     Halt(1);
  297.   end;
  298.  
  299.   glGenTextures(1, @Texture);
  300.   glBindTexture(GL_TEXTURE_2D, Texture);
  301.   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);  {Texture blends with object background}
  302.  
  303.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); { only first two can be used }
  304.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); { all of the above can be used }
  305.  
  306.   gluBuild2DMipmaps(GL_TEXTURE_2D, 3, Width, Height, GL_RGB, GL_UNSIGNED_BYTE, pData);
  307. end;
  308.  
  309. procedure LoadBitmap(Filename: String;
  310.                      out Width: Cardinal;
  311.                      out Height: Cardinal;
  312.                      out pData: Pointer);
  313. var
  314.   FileHeader: BITMAPFILEHEADER;
  315.   InfoHeader: BITMAPINFOHEADER;
  316.   Palette: array of RGBQUAD;
  317.   BitmapFile: THandle;
  318.   BitmapLength: Cardinal;
  319.   PaletteLength: Cardinal;
  320.   ReadBytes: Cardinal;
  321.   Front: ^Byte;
  322.   Back: ^Byte;
  323.   Temp: Byte;
  324.   I : Cardinal;
  325. begin
  326.   BitmapFile := CreateFile(PChar(Filename), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
  327.   if (BitmapFile = INVALID_HANDLE_VALUE) then begin
  328.     MessageBox(0, PChar('Error opening \"' + Filename), PChar('BMP Unit'), MB_OK);
  329.     Exit;
  330.   end;
  331.  
  332.   // Get header information
  333.   ReadFile(BitmapFile, FileHeader, SizeOf(FileHeader), ReadBytes, nil);
  334.   ReadFile(BitmapFile, InfoHeader, SizeOf(InfoHeader), ReadBytes, nil);
  335.  
  336.   // Get palette
  337.   PaletteLength := InfoHeader.biClrUsed;
  338.   SetLength(Palette, PaletteLength);
  339.   ReadFile(BitmapFile, Palette, PaletteLength, ReadBytes, nil);
  340.   if (ReadBytes <> PaletteLength) then begin
  341.     MessageBox(0, PChar('Error reading palette'), PChar('BMP Unit'), MB_OK);
  342.     Exit;
  343.   end;
  344.  
  345.   Width := InfoHeader.biWidth;
  346.   Height := InfoHeader.biHeight;
  347.   BitmapLength := InfoHeader.biSizeImage;
  348.   if BitmapLength = 0 then
  349.     BitmapLength := Width * Height * InfoHeader.biBitCount Div 8;
  350.  
  351.   // Get the actual pixel data
  352.   GetMem(pData, BitmapLength);
  353.   ReadFile(BitmapFile, pData^, BitmapLength, ReadBytes, nil);
  354.   if (ReadBytes <> BitmapLength) then begin
  355.     MessageBox(0, PChar('Error reading bitmap data'), PChar('BMP Unit'), MB_OK);
  356.     Exit;
  357.   end;
  358.   CloseHandle(BitmapFile);
  359.  
  360.   // Bitmaps are stored BGR and not RGB, so swap the R and B bytes.
  361.   for I :=0 to Width * Height - 1 do
  362.   begin
  363.     Front := Pointer(Cardinal(pData) + I*3);
  364.     Back := Pointer(Cardinal(pData) + I*3 + 2);
  365.     Temp := Front^;
  366.     Front^ := Back^;
  367.     Back^ := Temp;
  368.   end;
  369. end;
  370.  
  371. function GK2GLVector (V: TGKVector): TGLVector;
  372. // ändert Gauss-Krüger Koordinaten in OpenGL Koordinaten um
  373. begin
  374.   result.X := V.X;
  375.   result.Y := V.Z;
  376.   result.Z := V.Y;
  377. end;
  378.  
  379. function GL2GKVector (V: TGLVector): TGKVector;
  380. // ändert OpenGL Koordinaten in Gauss-Krüger Koordinaten um
  381. begin
  382.   result.X := V.X;
  383.   result.Y := V.Z;
  384.   result.Z := V.Y;
  385. end;
  386.  
  387. function Win2GLColor (WinCol: TColor): TGLcolor;
  388. begin
  389.   result.Red := GetRValue (WinCol);
  390.   result.Green := GetGValue (WinCol);
  391.   result.Blue := GetBValue (WinCol);
  392.   result.Alpha := 1.0;
  393. end;
  394.  
  395. function GL2WinColor (GLcol: TGLcolor): TColor;
  396. begin
  397.   result := Rgb (StrToInt (FloatToStr (int (GLcol.Red))),
  398.                  StrToInt (FloatToStr (int (GLcol.Green))),
  399.                  StrToInt (FloatToStr (int (GLcol.Blue))));
  400. end;
  401.  
  402. procedure GetRotation (V1, V2: TGLVector;
  403.                        var Rotation: TRotation;
  404.                        var normale: TGLVector);
  405. var
  406.   tmpCyl, tmpZiel, nullVec: TGLVector;
  407.   ResultLen: TGLVector;
  408.   VectorLength: GLfloat;
  409. begin
  410.   // temporäre vektoren initialisieren
  411.   InitVector (nullVec, 0,0,0);
  412.   InitVector (tmpCyl, 0,0,0);
  413.  
  414.   // länge des zu drehenden objekts ermitteln
  415.   ResultLen := SubtractVector (V2, V1);
  416.   VectorLength := Magnitude (ResultLen);
  417.  
  418.   // vektoren zur bildung der dreiecksfläche bilden.
  419.   // die schenkel schneiden sich im nullpunkt
  420.   // der Cylinder läuft immer entlang der Z-Achse
  421.   tmpCyl.Z := VectorLength;
  422.   tmpZiel := SubtractVector (V2, V1);
  423.   tmpZiel.Z := tmpZiel.Z + VectorLength;
  424.  
  425.   // senkrechte zu den beiden vektoren bilden
  426.   // (um diese achse soll nachher gedreht werden)
  427.   // drehachse für späteren gebrauch speichern
  428.   normale := CalcNormale (tmpCyl, tmpZiel, nullVec);
  429.  
  430.   // um \"Angle\" Grad soll nachher gedreht werden
  431.   Rotation.Angle := DotProduct(tmpCyl, tmpZiel);
  432.   Rotation.X     := normale.X;
  433.   Rotation.Y     := normale.Y;
  434.   Rotation.Z     := normale.Z;
  435. end;
  436.  
  437. function MakeTextureFromBitmap (Bitmap: string; var BitmapList: TTextureList): GLenum;
  438. // die funktion lädt die in Bitmap übergebene Grafik und gibt die Textturnummer
  439. // zurück. ist das bitmap schon im array BitmapList enthalten, wird die bereits
  440. // vergeben nummer zurückgegeben.
  441. var
  442.   i, Laenge: integer;
  443. begin
  444.   result := 0;
  445.   if length (trim (Bitmap)) = 0 then
  446.     exit;
  447.   Bitmap := trim (uppercase (Bitmap));
  448.   // suchen, ob die textur schon geladen wurde
  449.   Laenge := length (BitmapList);
  450.   if Laenge > 0 then
  451.     for i := 0 to Laenge-1 do
  452.     begin
  453.       if (BitmapList[i].BitmapName = Bitmap) and
  454.          (BitmapList[i].TextureNum > 0) then
  455.         result := BitmapList[i].TextureNum;
  456.     end;
  457.  
  458.   if (result = 0) then
  459.   begin
  460.     setlength (BitmapList, Laenge+1);
  461.     BitmapList[Laenge].BitmapName := Bitmap;
  462.     BitmapList[Laenge].TextureNum := 0;
  463.     if LoadTexture (Bitmap, BitmapList[Laenge].TextureNum) then
  464.       result := BitmapList[Laenge].TextureNum;
  465.   end;
  466. end;
  467.  
  468. procedure EnableTexture (Texture: GLenum; TextureTiled: boolean);
  469. begin
  470.   glEnable(GL_TEXTURE_2D);
  471.   glBindTexture(GL_TEXTURE_2D, Texture);
  472.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  473.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  474.   if TextureTiled then
  475.   begin
  476.     glTexparameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  477.     glTexparameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  478.   end
  479.   else
  480.   begin
  481.     glTexparameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  482.     glTexparameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  483.   end;
  484. end;
  485.  
  486. procedure DisableTexture;
  487. begin
  488.   glDisable(GL_TEXTURE_2D);
  489. end;
  490.  
  491. function TextToGLVector (VTxt: string): TGLVector;
  492. const
  493.   subdelim: char = '/';
  494. var
  495.   posi: integer;
  496.   V1: TGLVector;
  497. begin
  498.   InitVector (V1,0,0,0);
  499.   posi := pos (subdelim, VTxt);
  500.   if posi > 0 then
  501.   begin
  502.     V1.X := StrToFloat (copy (VTxt, 1, posi-1));
  503.     VTxt := copy (VTxt, posi+1, length (VTxt));
  504.     posi := pos (subdelim, VTxt);
  505.   end;
  506.   if posi > 0 then
  507.   begin
  508.     V1.Y := StrToFloat (copy (VTxt, 1, posi-1));
  509.     VTxt := copy (VTxt, posi+1, length (VTxt));
  510.   end;
  511.   if length (VTxt) > 0 then V1.Z := StrToFloat (VTxt);
  512.  
  513.   result := V1;
  514. end;
  515.  
  516. function TextToGKVector (VTxt: string): TGKVector;
  517. const
  518.   subdelim: char = '/';
  519. var
  520.   posi: integer;
  521.   V1: TGKVector;
  522. begin
  523.   InitVector (V1,0,0,0);
  524.   posi := pos (subdelim, VTxt);
  525.   if posi > 0 then
  526.   begin
  527.     V1.X := StrToFloat (copy (VTxt, 1, posi-1));
  528.     VTxt := copy (VTxt, posi+1, length (VTxt));
  529.     posi := pos (subdelim, VTxt);
  530.   end;
  531.   if posi > 0 then
  532.   begin
  533.     V1.Y := StrToFloat (copy (VTxt, 1, posi-1));
  534.     VTxt := copy (VTxt, posi+1, length (VTxt));
  535.   end;
  536.   if length (VTxt) > 0 then V1.Z := StrToFloat (VTxt);
  537.  
  538.   result := V1;
  539. end;
  540.  
  541. function GKVectorToText (V1: TGKVector): string;
  542. const
  543.   subdelim: char = '/';
  544. var
  545.   VTxt: string;
  546. begin
  547.   VTxt := FloatToStr (V1.X) + subdelim;
  548.   VTxt := VTxt + FloatToStr (V1.Y) + subdelim;
  549.   VTxt := VTxt + FloatToStr (V1.Z);
  550.   result := VTxt;
  551. end;
  552.  
  553. function GLVectorToText (V1: TGLVector): string;
  554. const
  555.   subdelim: char = '/';
  556. var
  557.   VTxt: string;
  558. begin
  559.   VTxt := FloatToStr (V1.X) + subdelim;
  560.   VTxt := VTxt + FloatToStr (V1.Y) + subdelim;
  561.   VTxt := VTxt + FloatToStr (V1.Z);
  562.   result := VTxt;
  563. end;
  564.  
  565. function MyCone (Start, Ende: TGLVector;
  566.                  RadiusStart, RadiusEnde: TGLfloat;
  567.                  Slices: Integer): boolean;
  568. var
  569.   Slice: Integer;
  570.   Laenge, xdelta, zdelta: TGLfloat;
  571.   V1, V2, V3, V4: TGLvector;
  572.   A, B: Single;
  573.   tmpVec: TGLvector;
  574. begin
  575.   result := true;
  576.   // laenge des kegels berechnen
  577.   // hierbei wird davon ausgegangen, dass der kegel senkrecht steht
  578.   // Laenge := Ende.y - Start.y;
  579.   tmpVec := SubtractVector (Start, Ende);
  580.   Laenge := Magnitude (tmpVec);
  581.   // radiusdifferenz berechnen
  582.   xdelta := Start.x - Ende.x;
  583.   zdelta := Start.z - Ende.z;
  584.   xdelta := -xdelta;
  585.   //zdelta := zdelta;
  586.   glBegin (GL_TRIANGLE_STRIP);
  587.   // der kegel wird entlang der z-achse gezeichnet
  588.   V1.z := 0;
  589.   V2.z := 0;
  590.   V3.z := Laenge;
  591.   V4.z := Laenge;
  592.   for Slice := 1 to Slices do begin
  593.     A := 2 * PI * Slice / Slices;
  594.     B := 2 * PI * (Slice+1) / Slices;
  595.     V1.x := sin(A)*RadiusStart;
  596.     V1.y := cos(A)*RadiusStart;
  597.     V2.x := sin(B)*RadiusStart;
  598.     V2.y := cos(B)*RadiusStart;
  599.     // umsetzung von y nach z-achse
  600.     V3.x := (sin(B)*RadiusEnde)+xdelta;
  601.     V3.y := (cos(B)*RadiusEnde)+zdelta;
  602.     V4.x := (sin(A)*RadiusEnde)+xdelta;
  603.     V4.y := (cos(A)*RadiusEnde)+zdelta;
  604.     //Normale := CalcNormale (V1, V3, V2);
  605.     //glNormal3fv(@Normale);
  606.     if Slice = 1 then
  607.     begin
  608.       glTexCoord2f(1,0); glVertex3fv(@V1);
  609.       glTexCoord2f(1,1); glVertex3fv(@V4);
  610.       glTexCoord2f(1-Slice/Slices,0); glVertex3fv(@V2);
  611.       glTexCoord2f(1-Slice/Slices,1); glVertex3fv(@V3);
  612.     end
  613.     else
  614.     begin
  615.       glTexCoord2f(1-Slice/Slices,0); glVertex3fv(@V2);
  616.       glTexCoord2f(1-Slice/Slices,1); glVertex3fv(@V3);
  617.     end;
  618.     // aktuellen und nächsten punkt des kreises (oben und unten)
  619.     // nehmen und ein rechteck zeichnen. alle rechtecke zusammen sollten
  620.     // einen geschlossenen kegel ergeben.
  621.     //glBegin(GL_QUADS);
  622.     //  glNormal3fv(@Normale);
  623.     //  glTexCoord2f(0,0); glVertex3fv(@V2);
  624.     //  glTexCoord2f(1,0); glVertex3fv(@V1);
  625.     //  glTexCoord2f(1,1); glVertex3fv(@V4);
  626.     //  glTexCoord2f(0,1); glVertex3fv(@V3);
  627.     //glEnd;
  628.   end;
  629.   glEnd;  // (GL_TRIANGLE_STRIP)
  630. end;
  631.  
  632. {-----------------------------------------------------------------------------}
  633. {----------------------------- für TRUVCamera --------------------------------}
  634. {-----------------------------------------------------------------------------}
  635.  
  636. procedure MatrixMultiply(M1, M2: TArrMatrix; var M3: TArrMatrix);
  637. // multiplies two 4x4 matrices
  638. begin  
  639.   glPushMatrix();
  640.   glLoadMatrixf(@M1);
  641.   glMultMatrixf(@M2);
  642.   glGetFloatv(GL_MODELVIEW_MATRIX,@M3);
  643.   glPopMatrix();
  644. end;
  645.  
  646. function MakeVector(X,Y,Z:TGLFloat):TArrVector;
  647. begin
  648.   result[0]:=x;
  649.   result[1]:=y;
  650.   result[2]:=z;
  651. end;
  652.  
  653. function MakeVector(X,Y,Z,W:TGLFloat):TArrVector;
  654. begin
  655.   result[0]:=x;
  656.   result[1]:=y;
  657.   result[2]:=z;
  658.   result[3]:=w;
  659. end;
  660.  
  661. procedure Normalize(aVector:TArrVector;var RVec:TArrVector);
  662. var
  663.    d:double;
  664. begin
  665.   InitVector (RVec,1,1,1);
  666.   d:=Sqrt(Sqr(aVector[C_X])+Sqr(aVector[C_Y])+Sqr(aVector[C_Z]));
  667.   if d=0 then
  668.   begin
  669.     //raise exception.Create('Zero length vector(Normalize 1)');
  670.     exit;
  671.   end;
  672.   RVec[C_X]:=aVector[C_X]/d;
  673.   RVec[C_Y]:=aVector[C_Y]/d;
  674.   RVec[C_Z]:=aVector[C_Z]/d;
  675. end;
  676.  
  677. procedure Normalize(aVector:TGLVector; var RVec:TGLVector);
  678. var
  679.    d:double;
  680. begin
  681.   InitVector (RVec,1,1,1);
  682.   d:=Sqrt(Sqr(aVector.X)+Sqr(aVector.Y)+Sqr(aVector.Z));
  683.   if d=0 then
  684.   begin
  685.     //raise exception.Create('Zero length vector(Normalize 2)');
  686.     exit;
  687.   end;
  688.   RVec.X:=aVector.X/d;
  689.   RVec.Y:=aVector.Y/d;
  690.   RVec.Z:=aVector.Z/d;
  691. end;
  692.  
  693. function GetIdentity:TMatrix;
  694. begin
  695.   result[0,0]:=1.0;result[0,1]:=0.0;result[0,2]:=0.0;result[0,3]:=0.0;
  696.   result[1,0]:=0.0;result[1,1]:=1.0;result[1,2]:=0.0;result[1,3]:=0.0;
  697.   result[2,0]:=0.0;result[2,1]:=0.0;result[2,2]:=1.0;result[2,3]:=0.0;
  698.   result[3,0]:=0.0;result[3,1]:=0.0;result[3,2]:=0.0;result[3,3]:=1.0;
  699. end;
  700.  
  701. function GetArrIdentity:TArrMatrix;
  702. begin
  703.   result[0]:=1.0;result[1]:=0.0;result[2]:=0.0;result[3]:=0.0;
  704.   result[4]:=0.0;result[5]:=1.0;result[6]:=0.0;result[7]:=0.0;
  705.   result[8]:=0.0;result[9]:=0.0;result[10]:=1.0;result[11]:=0.0;
  706.   result[12]:=0.0;result[13]:=0.0;result[14]:=0.0;result[15]:=1.0;
  707. end;
  708.  
  709. function MatrixTranspose(const M:TMatrix):TMatrix;register;
  710. var
  711.    i,j:integer;
  712. begin
  713.      for i:=0 to 3 do
  714.          for j:=0 to 3 do
  715.              result[i,j]:=M[j,i];
  716. end;
  717.  
  718. function VectorRotateX(v:TArrVector;a:TGLFloat):TArrVector;
  719. var
  720.    temp: TArrVector;
  721.    sine,cosine:TGLFloat;
  722. begin
  723.      a:=a*C_DEGTORAD;
  724.      sine:=Sin(a);
  725.      cosine:=Cos(a);
  726.  
  727.      temp[C_X] := v[C_x];
  728.      temp[C_Y] := (v[C_Y] * cosine) + (v[C_Z] * -sine);
  729.      temp[C_Z] := (v[C_Y] * sine) + (v[C_Z] * cosine);
  730.      result := temp;
  731. end;
  732.  
  733. function VectorRotateY(v: TArrVector;a:TGLFloat):TArrVector;
  734. var
  735.    temp: TArrVector;
  736.    sine,cosine:TGLFloat;
  737. begin
  738.      a:=a*C_DEGTORAD;
  739.      sine:=Sin(a);
  740.      cosine:=Cos(a);
  741.  
  742.      temp[C_x] := (v[C_x] * cosine) + (v[C_z] * sine);
  743.      temp[C_y] := v[C_y];
  744.      temp[C_z] := (v[C_x] * -sine) + (v[C_z] * cosine);
  745.      result := temp;
  746. end;
  747.  
  748. function VectorRotateZ(v: TArrVector; a: TGLFloat):TArrVector;
  749. var
  750.   temp: TArrVector;
  751.    sine,cosine:TGLFloat;
  752. begin
  753.      a:=a*C_DEGTORAD;
  754.      sine:=Sin(a);
  755.      cosine:=Cos(a);
  756.      temp[C_x] := (v[C_x] * cosine) + (v[C_y] * -sine);
  757.      temp[C_y] := (v[C_x] * sin(a)) + (v[C_y] * cosine);
  758.      temp[C_z] := v[C_z];
  759.      result := temp;
  760. end;
  761.  
  762. function VectorRotateX(v:TGLVector;a:TGLFloat):TGLVector;
  763. var
  764.    temp: TGLVector;
  765.    sine,cosine:TGLFloat;
  766. begin
  767.      a:=a*C_DEGTORAD;
  768.      sine:=Sin(a);
  769.      cosine:=Cos(a);
  770.  
  771.      temp.X := v.x;
  772.      temp.Y := (v.Y * cosine) + (v.Z * -sine);
  773.      temp.Z := (v.Y * sine) + (v.Z * cosine);
  774.      result := temp;
  775. end;
  776.  
  777. function VectorRotateY(v: TGLVector;a:TGLFloat):TGLVector;
  778. var
  779.    temp: TGLVector;
  780.    sine,cosine:TGLFloat;
  781. begin
  782.      a:=a*C_DEGTORAD;
  783.      sine:=Sin(a);
  784.      cosine:=Cos(a);
  785.  
  786.      temp.x := (v.x * cosine) + (v.z * sine);
  787.      temp.y := v.y;
  788.      temp.z := (v.X * -sine) + (v.z * cosine);
  789.      result := temp;
  790. end;
  791.  
  792. function VectorRotateZ(v: TGLVector; a: TGLFloat):TGLVector;
  793. var
  794.   temp: TGLVector;
  795.    sine,cosine:TGLFloat;
  796. begin
  797.      a:=a*C_DEGTORAD;
  798.      sine:=Sin(a);
  799.      cosine:=Cos(a);
  800.      temp.x := (v.x * cosine) + (v.y * -sine);
  801.      temp.y := (v.x * sin(a)) + (v.y * cosine);
  802.      temp.z := v.z;
  803.      result := temp;
  804. end;
  805.  
  806. {-----------------------------------------------------------------------------}
  807. {-------------------------------- allgemein ----------------------------------}
  808. {-----------------------------------------------------------------------------}
  809.  
  810. function InvertMatrix (src: TArrMatrix; var inverse: TArrMatrix): boolean;
  811. var
  812.   t: TGLdouble;
  813.   i, j, k, swap: integer;
  814.   tmp: TMatrix;
  815. begin
  816.   result := false;
  817.   inverse := GetArrIdentity;
  818.  
  819.   for i := 0 to 3 do
  820.   begin
  821.     for j := 0 to 3 do
  822.     begin
  823.       tmp[i][j] := src[i*4+j];
  824.     end;
  825.   end;
  826.  
  827.   for i := 0 to 3 do
  828.   begin
  829.     // look for largest element in column.
  830.     swap := i;
  831.     for j := i+1 to 3 do
  832.     begin
  833.       if abs(tmp[j][i]) > abs(tmp[i][i]) then
  834.       begin
  835.         swap := j;
  836.       end;
  837.     end;
  838.  
  839.     if not (swap = i) then
  840.     begin
  841.       // swap rows.
  842.       for k := 0 to 3 do
  843.       begin
  844.         t := tmp[i][k];
  845.         tmp[i][k] := tmp[swap][k];
  846.         tmp[swap][k] := t;
  847.  
  848.         t := inverse[i*4+k];
  849.         inverse[i*4+k] := inverse[swap*4+k];
  850.         inverse[swap*4+k] := t;
  851.       end;
  852.     end;
  853.  
  854.     if tmp[i][i] = 0 then
  855.     begin
  856.     { no non-zero pivot.  the matrix is singular, which
  857.       shouldn't happen.  This means the user gave us a bad
  858.       matrix. }
  859.       exit;
  860.     end;
  861.  
  862.     t := tmp[i][i];
  863.     for k := 0 to 3 do
  864.     begin
  865.       tmp[i][k] := tmp[i][k]/t;
  866.       inverse[i*4+k] := inverse[i*4+k]/t;
  867.     end;
  868.  
  869.     for j := 0 to 3 do
  870.     begin
  871.       if not (j = i) then
  872.       begin
  873.         t := tmp[j][i];
  874.         for k := 0 to 3 do
  875.         begin
  876.           tmp[j][k] := tmp[j][k]-tmp[i][k]*t;
  877.           inverse[j*4+k] := inverse[j*4+k]-inverse[i*4+k]*t;
  878.         end;
  879.       end;
  880.     end;
  881.   end;
  882.   result := true;
  883. end;
  884.  
  885. function Multiply (Color: TGLcolor; mult: TGLdouble): TGLcolor;
  886. begin
  887.   Color.red := Color.red * mult;
  888.   Color.green := Color.green * mult;
  889.   Color.blue := Color.blue * mult;
  890. end;
  891.  
  892. end.
  893.  


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast


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.015s | 16 Queries | GZIP : On ]