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

Aktuelle Zeit: Sa Jul 19, 2025 21:12

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:10 
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.

Ich habe versucht die beiden Dateien als Attachment hinzuzufügen aber die Erweiterung PAS wird immer abgelehnt. Also füge ich die Module hier ein.

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.  
  285. unit OpenGLUtil;
  286.  
  287. interface
  288.  
  289. uses DglOpenGL, Math, Windows, Graphics, SysUtils, Dialogs;
  290.  
  291. type
  292.   TProjection=(Frustum, Orthographic, Perspective);
  293.  
  294.   TGLPlace=packed record
  295.     X,Y,Z: glFloat;
  296.   end;
  297.  
  298.   TScale=packed record
  299.     X,Y,Z: glFloat;
  300.   end;
  301.  
  302.   TGLPosition=packed record
  303.     X,Y,Z,W: glFloat;
  304.   end;
  305.  
  306.   TPosition = packed record
  307.     X,Y,Z,W: GLdouble;
  308.   end;
  309.  
  310.   TGLVector = packed record
  311.     X,Y,Z: GLfloat;
  312.   end;
  313.   TGLVectorArray = array of TGLvector;
  314.   TGLfloatArray = array of TGLfloat;
  315.  
  316.   TGKVector = packed record
  317.     X,Y,Z: GLfloat;
  318.   end;
  319.  
  320.   TAngle = packed record
  321.     X,Y,Z: GLdouble;
  322.   end;
  323.  
  324.   TGLColor=record
  325.     red,green,blue,alpha: GLclampf;
  326.   end;
  327.  
  328.   TRotation = packed record
  329.     angle, x, y, z: GLfloat;
  330.   end;
  331.  
  332.   TTextureInfo = packed record
  333.     BitmapName: string;
  334.     TextureNum: GLUint;
  335.   end;
  336.   TTextureList = array of TTextureInfo;
  337.  
  338.   TMatrix = array [0..3,0..3] of TGLFloat;
  339.   TArrMatrix = array [0..15] of TGLFloat;
  340.   TFrustum = array [0..5,0..3] of TGLFloat;
  341.   TArrVector = array [0..3] of TGLFloat;
  342.  
  343.   function Multiply (Color: TGLcolor; mult: TGLdouble): TGLcolor;
  344.   procedure MatrixMultiply(M1, M2:TArrMatrix; var M3: TArrMatrix);
  345.   function MakeVector(X,Y,Z:TGLFloat):TArrVector;overload;
  346.   function MakeVector(X,Y,Z,W:TGLFloat):TArrVector;overload;
  347.   procedure Normalize(aVector:TArrVector;var RVec:TArrVector);overload;
  348.   procedure Normalize(aVector:TGLVector;var RVec:TGLVector);overload;
  349.   function GetIdentity:TMatrix;
  350.   function GetArrIdentity:TArrMatrix;
  351.   function MatrixTranspose(const M:TMatrix):TMatrix;register;
  352.   function VectorRotateX(v:TArrVector;a:TGLFloat):TArrVector;overload;
  353.   function VectorRotateY(v:TArrVector;a:TGLFloat):TArrVector;overload;
  354.   function VectorRotateZ(v:TArrVector;a:TGLFloat):TArrVector;overload;
  355.   function VectorRotateX(v:TGLVector;a:TGLFloat):TGLVector;overload;
  356.   function VectorRotateY(v:TGLVector;a:TGLFloat):TGLVector;overload;
  357.   function VectorRotateZ(v:TGLVector;a:TGLFloat):TGLVector;overload;
  358.  
  359.   function GL2GKVector (V: TGLVector): TGKVector;
  360.   function GK2GLVector (V: TGKVector): TGLVector;
  361.   function GL2WinColor (GLcol: TGLcolor): TColor;
  362.   function Win2GLColor (WinCol: Tcolor): TGLcolor;
  363.   function CalcNormale (V1, V2, V3: TGLVector): TGLVector;
  364.   function CrossProduct(V1, V2: TGLVector): TGLVector;
  365.   function DotProduct (V1, V2: TGLVector): GLdouble;
  366.   function LoadTexture(Filename: String; var Texture: GLuint): Boolean;
  367.   function Magnitude(V1 : TGLVector) : GLfloat;
  368.   function MultiplyVektor (V1, V2: TGLVector): TGLVector;
  369.   function ScalarProduct (V1, V2: TGLVector): GLdouble;
  370.   function SubtractVector (Vec1, Vec2: TGLVector): TGLVector;overload;
  371.   function SubtractVector (Vec: TGLVector; X, Y, Z: TGLdouble): TGLVector;overload;
  372.   function AddVector (Vec1, Vec2: TGLVector): TGLVector;overload;
  373.   function AddVector (Vec: TGLVector; X, Y, Z: TGLdouble): TGLVector;overload;
  374.   procedure CopyVector (FromVektor: TGLVector; var ToVektor: TGLVector);
  375.   procedure InitVector (var V1: TGLVector; x, y, z: TGLdouble);overload;
  376.   procedure InitVector (var V1: TGKVector; x, y, z: TGLdouble);overload;
  377.   procedure InitVector (var V1: TArrVector; x, y, z: TGLdouble);overload;
  378.   procedure InitScale (var S1: TScale; x, y, z: TGLdouble);
  379.   procedure LoadBitmap(Filename: String;
  380.                        out Width: Cardinal;
  381.                        out Height: Cardinal;
  382.                        out pData: Pointer);
  383.   procedure GetRotation (V1, V2: TGLVector;
  384.                          var Rotation: TRotation;
  385.                          var normale: TGLVector);
  386.   function MakeTextureFromBitmap (Bitmap: string; var BitmapList: TTextureList): GLenum;
  387.   procedure EnableTexture (Texture: GLenum; TextureTiled: boolean);
  388.   procedure DisableTexture;
  389.   function TextToGLVector (VTxt: string): TGLVector;
  390.   function TextToGKVector (VTxt: string): TGKVector;
  391.   function GKVectorToText (V1: TGKVector): string;
  392.   function GLVectorToText (V1: TGLVector): string;
  393.   function MyCone (Start, Ende: TGLVector;
  394.                    RadiusStart, RadiusEnde: TGLfloat;
  395.                    Slices: Integer): boolean;
  396.   function InvertMatrix (src: TArrMatrix; var inverse: TArrMatrix): boolean;
  397.  
  398. const
  399.   C_X = 0;
  400.   C_Y = 1;
  401.   C_Z = 2;
  402.   C_W = 3;
  403.   C_EPS:TGLFloat=0.01;
  404.   C_DEGTORAD:TGLFloat=3.1412/180;
  405.   C_RADTODEG:TGLFloat=180/3.1412;
  406.   C_LAMBDA_INCREMENT:TGLFloat=0.01;
  407.  
  408.  
  409. implementation
  410.  
  411. function MyPower (Base: extended; Exp: integer): extended;
  412. // ist nicht ausprogrammiert, funktioniert nur für eine
  413. // einfache zweierpotenz
  414. begin
  415.   result := Base * Base;
  416. end;
  417.  
  418. procedure CopyVector (FromVektor: TGLVector; var ToVektor: TGLVector);
  419. begin
  420.   ToVektor.X := FromVektor.X;
  421.   ToVektor.Y := FromVektor.Y;
  422.   ToVektor.Z := FromVektor.Z;
  423. end;
  424.  
  425. function SubtractVector (Vec1, Vec2: TGLVector): TGLVector;
  426. // subtrahiert Vec2 von vec1 und gibt das ergebnis in vec3 zurück
  427. var
  428.   Vec3: TGLVector;
  429. begin
  430.   Vec3 .X := Vec1.X - Vec2.X;
  431.   Vec3 .Y := Vec1.Y - Vec2.Y;
  432.   Vec3 .Z := Vec1.Z - Vec2.Z;
  433.   result := Vec3;
  434. end;
  435.  
  436. function SubtractVector (Vec: TGLVector; X, Y, Z: TGLdouble): TGLVector;
  437. // subtrahiert X, Y, Z von vec.x, vec.y, vec.z  und gibt das
  438. // ergebnis zurück
  439. begin
  440.   Vec .X := Vec.X - X;
  441.   Vec .Y := Vec.Y - Y;
  442.   Vec .Z := Vec.Z - Z;
  443.   result := Vec;
  444. end;
  445.  
  446. function AddVector (Vec1, Vec2: TGLVector): TGLVector;
  447. // addiert Vec2 auf vec1 und gibt das ergebnis in vec3 zurück
  448. var
  449.   Vec3: TGLVector;
  450. begin
  451.   Vec3 .X := Vec1.X + Vec2.X;
  452.   Vec3 .Y := Vec1.Y + Vec2.Y;
  453.   Vec3 .Z := Vec1.Z + Vec2.Z;
  454.   result := Vec3;
  455. end;
  456.  
  457. function AddVector (Vec: TGLVector; X, Y, Z: TGLdouble): TGLVector;
  458. // addiert X, Y, Z auf vec.x, vec.y, vec.z  und gibt das
  459. // ergebnis zurück
  460. begin
  461.   Vec .X := Vec.X + X;
  462.   Vec .Y := Vec.Y + Y;
  463.   Vec .Z := Vec.Z + Z;
  464.   result := Vec;
  465. end;
  466.  
  467. function Magnitude(V1 : TGLVector) : GLfloat;
  468. var
  469.   Ergebnis: GLdouble;
  470. begin
  471. // gibt die länge des vektors zurück
  472.   Ergebnis := MyPower(V1.X,2)+MyPower(V1.Y,2)+MyPower(V1.Z,2);
  473.   try
  474.     result := sqrt(Ergebnis);
  475.   except
  476.     result := 0;
  477.   end;
  478. end;
  479.  
  480. function DotProduct (V1, V2: TGLVector): GLdouble;
  481. var
  482.   len1, len2: GLdouble;
  483.   Ergebnis: GLdouble;
  484. begin
  485.   len1 := Magnitude (V1);
  486.   len2 := Magnitude (V2);
  487.   Ergebnis := ScalarProduct (V1, V2);
  488.   Ergebnis := arccos (Ergebnis / (len1 * len2));
  489.   result := radtodeg (Ergebnis) * 2.0;
  490. end;
  491.  
  492. function CrossProduct(V1, V2: TGLVector): TGLVector;
  493. var
  494.   CrossVec: TGLVector;
  495. begin
  496.   CrossVec.X := ((V1.Y*V2.Z) - (V1.Z*V2.Y));
  497.   CrossVec.Y := ((V1.Z*V2.X) - (V1.X*V2.Z));
  498. CrossVec.Z := ((V1.X*V2.Y) - (V1.Y*V2.X));
  499.   result := CrossVec;
  500.  end;
  501.  
  502. function CalcNormale (V1, V2, V3: TGLVector): TGLVector;
  503. var
  504.   Kreuz: TGLvector;
  505.   V1V2, V1V3: TGLvector;
  506. begin
  507.   // gibt die normale von 3 vektoren zurück (die senkrechte auf die
  508.   // durch die drei vektoren gebildete ebene)
  509.   V1V2 := SubtractVector (V2, V1);
  510.   V1V3 := SubtractVector (V3, V1);
  511.  
  512.   Kreuz := CrossProduct (V1V2, V1V3);
  513.  
  514.   Normalize (Kreuz, result);
  515. end;
  516.  
  517. procedure InitVector (var V1: TGLVector; x, y, z: TGLdouble);
  518. begin
  519.   V1.x := x;
  520.   V1.y := y;
  521.   V1.z := z;
  522. end;
  523.  
  524. procedure InitVector (var V1: TGKVector; x, y, z: TGLdouble);
  525. begin
  526.   V1.x := x;
  527.   V1.y := y;
  528.   V1.z := z;
  529. end;
  530.  
  531. procedure InitVector (var V1: TArrVector; x, y, z: TGLdouble);
  532. begin
  533.   V1[C_X] := x;
  534.   V1[C_Y] := y;
  535.   V1[C_Z] := z;
  536. end;
  537.  
  538. procedure InitScale (var S1: TScale; x, y, z: TGLdouble);
  539. begin
  540.   S1.x := x;
  541.   S1.y := y;
  542.   S1.z := z;
  543. end;
  544.  
  545. function MultiplyVektor (V1, V2: TGLVector): TGLVector;
  546. var
  547.   multVec: TGLVector;
  548. begin
  549. // zwei vektoren miteinander multiplizieren
  550.   multVec.X := V1.X * V2.X;
  551.   multVec.Y := V1.Y * V2.Y;
  552.   multVec.Z := V1.Z * V2.Z;
  553.   result := multvec;
  554. end;
  555.  
  556. function ScalarProduct (V1, V2: TGLVector): GLdouble;
  557. begin
  558. // die summe der potenzen der einzelnen achsen von zwei vektoren errechnen
  559.   result := (V1.X*V2.X +
  560.              V1.Y*V2.Y +
  561.              V1.Z*V2.Z);
  562. end;
  563.  
  564. function LoadTexture(Filename: String; var Texture: GLuint): Boolean;
  565. var
  566.   pData: Pointer;
  567.   Width: Cardinal;
  568.   Height: Cardinal;
  569. begin
  570.   pData :=nil;
  571.   LoadBitmap(Filename, Width, Height, pData);
  572.  
  573.   if (Assigned(pData)) then
  574.     Result := True
  575.   else
  576.   begin
  577.     Result := False;
  578.     MessageBox(0, PChar('Unable to load ' + filename), 'Loading Textures', MB_OK);
  579.     Halt(1);
  580.   end;
  581.  
  582.   glGenTextures(1, @Texture);
  583.   glBindTexture(GL_TEXTURE_2D, Texture);
  584.   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);  {Texture blends with object background}
  585.  
  586.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); { only first two can be used }
  587.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); { all of the above can be used }
  588.  
  589.   gluBuild2DMipmaps(GL_TEXTURE_2D, 3, Width, Height, GL_RGB, GL_UNSIGNED_BYTE, pData);
  590. end;
  591.  
  592. procedure LoadBitmap(Filename: String;
  593.                      out Width: Cardinal;
  594.                      out Height: Cardinal;
  595.                      out pData: Pointer);
  596. var
  597.   FileHeader: BITMAPFILEHEADER;
  598.   InfoHeader: BITMAPINFOHEADER;
  599.   Palette: array of RGBQUAD;
  600.   BitmapFile: THandle;
  601.   BitmapLength: Cardinal;
  602.   PaletteLength: Cardinal;
  603.   ReadBytes: Cardinal;
  604.   Front: ^Byte;
  605.   Back: ^Byte;
  606.   Temp: Byte;
  607.   I : Cardinal;
  608. begin
  609.   BitmapFile := CreateFile(PChar(Filename), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
  610.   if (BitmapFile = INVALID_HANDLE_VALUE) then begin
  611.     MessageBox(0, PChar('Error opening \"' + Filename), PChar('BMP Unit'), MB_OK);
  612.     Exit;
  613.   end;
  614.  
  615.   // Get header information
  616.   ReadFile(BitmapFile, FileHeader, SizeOf(FileHeader), ReadBytes, nil);
  617.   ReadFile(BitmapFile, InfoHeader, SizeOf(InfoHeader), ReadBytes, nil);
  618.  
  619.   // Get palette
  620.   PaletteLength := InfoHeader.biClrUsed;
  621.   SetLength(Palette, PaletteLength);
  622.   ReadFile(BitmapFile, Palette, PaletteLength, ReadBytes, nil);
  623.   if (ReadBytes <> PaletteLength) then begin
  624.     MessageBox(0, PChar('Error reading palette'), PChar('BMP Unit'), MB_OK);
  625.     Exit;
  626.   end;
  627.  
  628.   Width := InfoHeader.biWidth;
  629.   Height := InfoHeader.biHeight;
  630.   BitmapLength := InfoHeader.biSizeImage;
  631.   if BitmapLength = 0 then
  632.     BitmapLength := Width * Height * InfoHeader.biBitCount Div 8;
  633.  
  634.   // Get the actual pixel data
  635.   GetMem(pData, BitmapLength);
  636.   ReadFile(BitmapFile, pData^, BitmapLength, ReadBytes, nil);
  637.   if (ReadBytes <> BitmapLength) then begin
  638.     MessageBox(0, PChar('Error reading bitmap data'), PChar('BMP Unit'), MB_OK);
  639.     Exit;
  640.   end;
  641.   CloseHandle(BitmapFile);
  642.  
  643.   // Bitmaps are stored BGR and not RGB, so swap the R and B bytes.
  644.   for I :=0 to Width * Height - 1 do
  645.   begin
  646.     Front := Pointer(Cardinal(pData) + I*3);
  647.     Back := Pointer(Cardinal(pData) + I*3 + 2);
  648.     Temp := Front^;
  649.     Front^ := Back^;
  650.     Back^ := Temp;
  651.   end;
  652. end;
  653.  
  654. function GK2GLVector (V: TGKVector): TGLVector;
  655. // ändert Gauss-Krüger Koordinaten in OpenGL Koordinaten um
  656. begin
  657.   result.X := V.X;
  658.   result.Y := V.Z;
  659.   result.Z := V.Y;
  660. end;
  661.  
  662. function GL2GKVector (V: TGLVector): TGKVector;
  663. // ändert OpenGL Koordinaten in Gauss-Krüger Koordinaten um
  664. begin
  665.   result.X := V.X;
  666.   result.Y := V.Z;
  667.   result.Z := V.Y;
  668. end;
  669.  
  670. function Win2GLColor (WinCol: TColor): TGLcolor;
  671. begin
  672.   result.Red := GetRValue (WinCol);
  673.   result.Green := GetGValue (WinCol);
  674.   result.Blue := GetBValue (WinCol);
  675.   result.Alpha := 1.0;
  676. end;
  677.  
  678. function GL2WinColor (GLcol: TGLcolor): TColor;
  679. begin
  680.   result := Rgb (StrToInt (FloatToStr (int (GLcol.Red))),
  681.                  StrToInt (FloatToStr (int (GLcol.Green))),
  682.                  StrToInt (FloatToStr (int (GLcol.Blue))));
  683. end;
  684.  
  685. procedure GetRotation (V1, V2: TGLVector;
  686.                        var Rotation: TRotation;
  687.                        var normale: TGLVector);
  688. var
  689.   tmpCyl, tmpZiel, nullVec: TGLVector;
  690.   ResultLen: TGLVector;
  691.   VectorLength: GLfloat;
  692. begin
  693.   // temporäre vektoren initialisieren
  694.   InitVector (nullVec, 0,0,0);
  695.   InitVector (tmpCyl, 0,0,0);
  696.  
  697.   // länge des zu drehenden objekts ermitteln
  698.   ResultLen := SubtractVector (V2, V1);
  699.   VectorLength := Magnitude (ResultLen);
  700.  
  701.   // vektoren zur bildung der dreiecksfläche bilden.
  702.   // die schenkel schneiden sich im nullpunkt
  703.   // der Cylinder läuft immer entlang der Z-Achse
  704.   tmpCyl.Z := VectorLength;
  705.   tmpZiel := SubtractVector (V2, V1);
  706.   tmpZiel.Z := tmpZiel.Z + VectorLength;
  707.  
  708.   // senkrechte zu den beiden vektoren bilden
  709.   // (um diese achse soll nachher gedreht werden)
  710.   // drehachse für späteren gebrauch speichern
  711.   normale := CalcNormale (tmpCyl, tmpZiel, nullVec);
  712.  
  713.   // um \"Angle\" Grad soll nachher gedreht werden
  714.   Rotation.Angle := DotProduct(tmpCyl, tmpZiel);
  715.   Rotation.X     := normale.X;
  716.   Rotation.Y     := normale.Y;
  717.   Rotation.Z     := normale.Z;
  718. end;
  719.  
  720. function MakeTextureFromBitmap (Bitmap: string; var BitmapList: TTextureList): GLenum;
  721. // die funktion lädt die in Bitmap übergebene Grafik und gibt die Textturnummer
  722. // zurück. ist das bitmap schon im array BitmapList enthalten, wird die bereits
  723. // vergeben nummer zurückgegeben.
  724. var
  725.   i, Laenge: integer;
  726. begin
  727.   result := 0;
  728.   if length (trim (Bitmap)) = 0 then
  729.     exit;
  730.   Bitmap := trim (uppercase (Bitmap));
  731.   // suchen, ob die textur schon geladen wurde
  732.   Laenge := length (BitmapList);
  733.   if Laenge > 0 then
  734.     for i := 0 to Laenge-1 do
  735.     begin
  736.       if (BitmapList[i].BitmapName = Bitmap) and
  737.          (BitmapList[i].TextureNum > 0) then
  738.         result := BitmapList[i].TextureNum;
  739.     end;
  740.  
  741.   if (result = 0) then
  742.   begin
  743.     setlength (BitmapList, Laenge+1);
  744.     BitmapList[Laenge].BitmapName := Bitmap;
  745.     BitmapList[Laenge].TextureNum := 0;
  746.     if LoadTexture (Bitmap, BitmapList[Laenge].TextureNum) then
  747.       result := BitmapList[Laenge].TextureNum;
  748.   end;
  749. end;
  750.  
  751. procedure EnableTexture (Texture: GLenum; TextureTiled: boolean);
  752. begin
  753.   glEnable(GL_TEXTURE_2D);
  754.   glBindTexture(GL_TEXTURE_2D, Texture);
  755.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  756.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  757.   if TextureTiled then
  758.   begin
  759.     glTexparameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  760.     glTexparameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  761.   end
  762.   else
  763.   begin
  764.     glTexparameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  765.     glTexparameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  766.   end;
  767. end;
  768.  
  769. procedure DisableTexture;
  770. begin
  771.   glDisable(GL_TEXTURE_2D);
  772. end;
  773.  
  774. function TextToGLVector (VTxt: string): TGLVector;
  775. const
  776.   subdelim: char = '/';
  777. var
  778.   posi: integer;
  779.   V1: TGLVector;
  780. begin
  781.   InitVector (V1,0,0,0);
  782.   posi := pos (subdelim, VTxt);
  783.   if posi > 0 then
  784.   begin
  785.     V1.X := StrToFloat (copy (VTxt, 1, posi-1));
  786.     VTxt := copy (VTxt, posi+1, length (VTxt));
  787.     posi := pos (subdelim, VTxt);
  788.   end;
  789.   if posi > 0 then
  790.   begin
  791.     V1.Y := StrToFloat (copy (VTxt, 1, posi-1));
  792.     VTxt := copy (VTxt, posi+1, length (VTxt));
  793.   end;
  794.   if length (VTxt) > 0 then V1.Z := StrToFloat (VTxt);
  795.  
  796.   result := V1;
  797. end;
  798.  
  799. function TextToGKVector (VTxt: string): TGKVector;
  800. const
  801.   subdelim: char = '/';
  802. var
  803.   posi: integer;
  804.   V1: TGKVector;
  805. begin
  806.   InitVector (V1,0,0,0);
  807.   posi := pos (subdelim, VTxt);
  808.   if posi > 0 then
  809.   begin
  810.     V1.X := StrToFloat (copy (VTxt, 1, posi-1));
  811.     VTxt := copy (VTxt, posi+1, length (VTxt));
  812.     posi := pos (subdelim, VTxt);
  813.   end;
  814.   if posi > 0 then
  815.   begin
  816.     V1.Y := StrToFloat (copy (VTxt, 1, posi-1));
  817.     VTxt := copy (VTxt, posi+1, length (VTxt));
  818.   end;
  819.   if length (VTxt) > 0 then V1.Z := StrToFloat (VTxt);
  820.  
  821.   result := V1;
  822. end;
  823.  
  824. function GKVectorToText (V1: TGKVector): string;
  825. const
  826.   subdelim: char = '/';
  827. var
  828.   VTxt: string;
  829. begin
  830.   VTxt := FloatToStr (V1.X) + subdelim;
  831.   VTxt := VTxt + FloatToStr (V1.Y) + subdelim;
  832.   VTxt := VTxt + FloatToStr (V1.Z);
  833.   result := VTxt;
  834. end;
  835.  
  836. function GLVectorToText (V1: TGLVector): string;
  837. const
  838.   subdelim: char = '/';
  839. var
  840.   VTxt: string;
  841. begin
  842.   VTxt := FloatToStr (V1.X) + subdelim;
  843.   VTxt := VTxt + FloatToStr (V1.Y) + subdelim;
  844.   VTxt := VTxt + FloatToStr (V1.Z);
  845.   result := VTxt;
  846. end;
  847.  
  848. function MyCone (Start, Ende: TGLVector;
  849.                  RadiusStart, RadiusEnde: TGLfloat;
  850.                  Slices: Integer): boolean;
  851. var
  852.   Slice: Integer;
  853.   Laenge, xdelta, zdelta: TGLfloat;
  854.   V1, V2, V3, V4: TGLvector;
  855.   A, B: Single;
  856.   tmpVec: TGLvector;
  857. begin
  858.   result := true;
  859.   // laenge des kegels berechnen
  860.   // hierbei wird davon ausgegangen, dass der kegel senkrecht steht
  861.   // Laenge := Ende.y - Start.y;
  862.   tmpVec := SubtractVector (Start, Ende);
  863.   Laenge := Magnitude (tmpVec);
  864.   // radiusdifferenz berechnen
  865.   xdelta := Start.x - Ende.x;
  866.   zdelta := Start.z - Ende.z;
  867.   xdelta := -xdelta;
  868.   //zdelta := zdelta;
  869.   glBegin (GL_TRIANGLE_STRIP);
  870.   // der kegel wird entlang der z-achse gezeichnet
  871.   V1.z := 0;
  872.   V2.z := 0;
  873.   V3.z := Laenge;
  874.   V4.z := Laenge;
  875.   for Slice := 1 to Slices do begin
  876.     A := 2 * PI * Slice / Slices;
  877.     B := 2 * PI * (Slice+1) / Slices;
  878.     V1.x := sin(A)*RadiusStart;
  879.     V1.y := cos(A)*RadiusStart;
  880.     V2.x := sin(B)*RadiusStart;
  881.     V2.y := cos(B)*RadiusStart;
  882.     // umsetzung von y nach z-achse
  883.     V3.x := (sin(B)*RadiusEnde)+xdelta;
  884.     V3.y := (cos(B)*RadiusEnde)+zdelta;
  885.     V4.x := (sin(A)*RadiusEnde)+xdelta;
  886.     V4.y := (cos(A)*RadiusEnde)+zdelta;
  887.     //Normale := CalcNormale (V1, V3, V2);
  888.     //glNormal3fv(@Normale);
  889.     if Slice = 1 then
  890.     begin
  891.       glTexCoord2f(1,0); glVertex3fv(@V1);
  892.       glTexCoord2f(1,1); glVertex3fv(@V4);
  893.       glTexCoord2f(1-Slice/Slices,0); glVertex3fv(@V2);
  894.       glTexCoord2f(1-Slice/Slices,1); glVertex3fv(@V3);
  895.     end
  896.     else
  897.     begin
  898.       glTexCoord2f(1-Slice/Slices,0); glVertex3fv(@V2);
  899.       glTexCoord2f(1-Slice/Slices,1); glVertex3fv(@V3);
  900.     end;
  901.     // aktuellen und nächsten punkt des kreises (oben und unten)
  902.     // nehmen und ein rechteck zeichnen. alle rechtecke zusammen sollten
  903.     // einen geschlossenen kegel ergeben.
  904.     //glBegin(GL_QUADS);
  905.     //  glNormal3fv(@Normale);
  906.     //  glTexCoord2f(0,0); glVertex3fv(@V2);
  907.     //  glTexCoord2f(1,0); glVertex3fv(@V1);
  908.     //  glTexCoord2f(1,1); glVertex3fv(@V4);
  909.     //  glTexCoord2f(0,1); glVertex3fv(@V3);
  910.     //glEnd;
  911.   end;
  912.   glEnd;  // (GL_TRIANGLE_STRIP)
  913. end;
  914.  
  915. {-----------------------------------------------------------------------------}
  916. {----------------------------- für TRUVCamera --------------------------------}
  917. {-----------------------------------------------------------------------------}
  918.  
  919. procedure MatrixMultiply(M1, M2: TArrMatrix; var M3: TArrMatrix);
  920. // multiplies two 4x4 matrices
  921. begin  
  922.   glPushMatrix();
  923.   glLoadMatrixf(@M1);
  924.   glMultMatrixf(@M2);
  925.   glGetFloatv(GL_MODELVIEW_MATRIX,@M3);
  926.   glPopMatrix();
  927. end;
  928.  
  929. function MakeVector(X,Y,Z:TGLFloat):TArrVector;
  930. begin
  931.   result[0]:=x;
  932.   result[1]:=y;
  933.   result[2]:=z;
  934. end;
  935.  
  936. function MakeVector(X,Y,Z,W:TGLFloat):TArrVector;
  937. begin
  938.   result[0]:=x;
  939.   result[1]:=y;
  940.   result[2]:=z;
  941.   result[3]:=w;
  942. end;
  943.  
  944. procedure Normalize(aVector:TArrVector;var RVec:TArrVector);
  945. var
  946.    d:double;
  947. begin
  948.   InitVector (RVec,1,1,1);
  949.   d:=Sqrt(Sqr(aVector[C_X])+Sqr(aVector[C_Y])+Sqr(aVector[C_Z]));
  950.   if d=0 then
  951.   begin
  952.     //raise exception.Create('Zero length vector(Normalize 1)');
  953.     exit;
  954.   end;
  955.   RVec[C_X]:=aVector[C_X]/d;
  956.   RVec[C_Y]:=aVector[C_Y]/d;
  957.   RVec[C_Z]:=aVector[C_Z]/d;
  958. end;
  959.  
  960. procedure Normalize(aVector:TGLVector; var RVec:TGLVector);
  961. var
  962.    d:double;
  963. begin
  964.   InitVector (RVec,1,1,1);
  965.   d:=Sqrt(Sqr(aVector.X)+Sqr(aVector.Y)+Sqr(aVector.Z));
  966.   if d=0 then
  967.   begin
  968.     //raise exception.Create('Zero length vector(Normalize 2)');
  969.     exit;
  970.   end;
  971.   RVec.X:=aVector.X/d;
  972.   RVec.Y:=aVector.Y/d;
  973.   RVec.Z:=aVector.Z/d;
  974. end;
  975.  
  976. function GetIdentity:TMatrix;
  977. begin
  978.   result[0,0]:=1.0;result[0,1]:=0.0;result[0,2]:=0.0;result[0,3]:=0.0;
  979.   result[1,0]:=0.0;result[1,1]:=1.0;result[1,2]:=0.0;result[1,3]:=0.0;
  980.   result[2,0]:=0.0;result[2,1]:=0.0;result[2,2]:=1.0;result[2,3]:=0.0;
  981.   result[3,0]:=0.0;result[3,1]:=0.0;result[3,2]:=0.0;result[3,3]:=1.0;
  982. end;
  983.  
  984. function GetArrIdentity:TArrMatrix;
  985. begin
  986.   result[0]:=1.0;result[1]:=0.0;result[2]:=0.0;result[3]:=0.0;
  987.   result[4]:=0.0;result[5]:=1.0;result[6]:=0.0;result[7]:=0.0;
  988.   result[8]:=0.0;result[9]:=0.0;result[10]:=1.0;result[11]:=0.0;
  989.   result[12]:=0.0;result[13]:=0.0;result[14]:=0.0;result[15]:=1.0;
  990. end;
  991.  
  992. function MatrixTranspose(const M:TMatrix):TMatrix;register;
  993. var
  994.    i,j:integer;
  995. begin
  996.      for i:=0 to 3 do
  997.          for j:=0 to 3 do
  998.              result[i,j]:=M[j,i];
  999. end;
  1000.  
  1001. function VectorRotateX(v:TArrVector;a:TGLFloat):TArrVector;
  1002. var
  1003.    temp: TArrVector;
  1004.    sine,cosine:TGLFloat;
  1005. begin
  1006.      a:=a*C_DEGTORAD;
  1007.      sine:=Sin(a);
  1008.      cosine:=Cos(a);
  1009.  
  1010.      temp[C_X] := v[C_x];
  1011.      temp[C_Y] := (v[C_Y] * cosine) + (v[C_Z] * -sine);
  1012.      temp[C_Z] := (v[C_Y] * sine) + (v[C_Z] * cosine);
  1013.      result := temp;
  1014. end;
  1015.  
  1016. function VectorRotateY(v: TArrVector;a:TGLFloat):TArrVector;
  1017. var
  1018.    temp: TArrVector;
  1019.    sine,cosine:TGLFloat;
  1020. begin
  1021.      a:=a*C_DEGTORAD;
  1022.      sine:=Sin(a);
  1023.      cosine:=Cos(a);
  1024.  
  1025.      temp[C_x] := (v[C_x] * cosine) + (v[C_z] * sine);
  1026.      temp[C_y] := v[C_y];
  1027.      temp[C_z] := (v[C_x] * -sine) + (v[C_z] * cosine);
  1028.      result := temp;
  1029. end;
  1030.  
  1031. function VectorRotateZ(v: TArrVector; a: TGLFloat):TArrVector;
  1032. var
  1033.   temp: TArrVector;
  1034.    sine,cosine:TGLFloat;
  1035. begin
  1036.      a:=a*C_DEGTORAD;
  1037.      sine:=Sin(a);
  1038.      cosine:=Cos(a);
  1039.      temp[C_x] := (v[C_x] * cosine) + (v[C_y] * -sine);
  1040.      temp[C_y] := (v[C_x] * sin(a)) + (v[C_y] * cosine);
  1041.      temp[C_z] := v[C_z];
  1042.      result := temp;
  1043. end;
  1044.  
  1045. function VectorRotateX(v:TGLVector;a:TGLFloat):TGLVector;
  1046. var
  1047.    temp: TGLVector;
  1048.    sine,cosine:TGLFloat;
  1049. begin
  1050.      a:=a*C_DEGTORAD;
  1051.      sine:=Sin(a);
  1052.      cosine:=Cos(a);
  1053.  
  1054.      temp.X := v.x;
  1055.      temp.Y := (v.Y * cosine) + (v.Z * -sine);
  1056.      temp.Z := (v.Y * sine) + (v.Z * cosine);
  1057.      result := temp;
  1058. end;
  1059.  
  1060. function VectorRotateY(v: TGLVector;a:TGLFloat):TGLVector;
  1061. var
  1062.    temp: TGLVector;
  1063.    sine,cosine:TGLFloat;
  1064. begin
  1065.      a:=a*C_DEGTORAD;
  1066.      sine:=Sin(a);
  1067.      cosine:=Cos(a);
  1068.  
  1069.      temp.x := (v.x * cosine) + (v.z * sine);
  1070.      temp.y := v.y;
  1071.      temp.z := (v.X * -sine) + (v.z * cosine);
  1072.      result := temp;
  1073. end;
  1074.  
  1075. function VectorRotateZ(v: TGLVector; a: TGLFloat):TGLVector;
  1076. var
  1077.   temp: TGLVector;
  1078.    sine,cosine:TGLFloat;
  1079. begin
  1080.      a:=a*C_DEGTORAD;
  1081.      sine:=Sin(a);
  1082.      cosine:=Cos(a);
  1083.      temp.x := (v.x * cosine) + (v.y * -sine);
  1084.      temp.y := (v.x * sin(a)) + (v.y * cosine);
  1085.      temp.z := v.z;
  1086.      result := temp;
  1087. end;
  1088.  
  1089. {-----------------------------------------------------------------------------}
  1090. {-------------------------------- allgemein ----------------------------------}
  1091. {-----------------------------------------------------------------------------}
  1092.  
  1093. function InvertMatrix (src: TArrMatrix; var inverse: TArrMatrix): boolean;
  1094. var
  1095.   t: TGLdouble;
  1096.   i, j, k, swap: integer;
  1097.   tmp: TMatrix;
  1098. begin
  1099.   result := false;
  1100.   inverse := GetArrIdentity;
  1101.  
  1102.   for i := 0 to 3 do
  1103.   begin
  1104.     for j := 0 to 3 do
  1105.     begin
  1106.       tmp[i][j] := src[i*4+j];
  1107.     end;
  1108.   end;
  1109.  
  1110.   for i := 0 to 3 do
  1111.   begin
  1112.     // look for largest element in column.
  1113.     swap := i;
  1114.     for j := i+1 to 3 do
  1115.     begin
  1116.       if abs(tmp[j][i]) > abs(tmp[i][i]) then
  1117.       begin
  1118.         swap := j;
  1119.       end;
  1120.     end;
  1121.  
  1122.     if not (swap = i) then
  1123.     begin
  1124.       // swap rows.
  1125.       for k := 0 to 3 do
  1126.       begin
  1127.         t := tmp[i][k];
  1128.         tmp[i][k] := tmp[swap][k];
  1129.         tmp[swap][k] := t;
  1130.  
  1131.         t := inverse[i*4+k];
  1132.         inverse[i*4+k] := inverse[swap*4+k];
  1133.         inverse[swap*4+k] := t;
  1134.       end;
  1135.     end;
  1136.  
  1137.     if tmp[i][i] = 0 then
  1138.     begin
  1139.     { no non-zero pivot.  the matrix is singular, which
  1140.       shouldn't happen.  This means the user gave us a bad
  1141.       matrix. }
  1142.       exit;
  1143.     end;
  1144.  
  1145.     t := tmp[i][i];
  1146.     for k := 0 to 3 do
  1147.     begin
  1148.       tmp[i][k] := tmp[i][k]/t;
  1149.       inverse[i*4+k] := inverse[i*4+k]/t;
  1150.     end;
  1151.  
  1152.     for j := 0 to 3 do
  1153.     begin
  1154.       if not (j = i) then
  1155.       begin
  1156.         t := tmp[j][i];
  1157.         for k := 0 to 3 do
  1158.         begin
  1159.           tmp[j][k] := tmp[j][k]-tmp[i][k]*t;
  1160.           inverse[j*4+k] := inverse[j*4+k]-inverse[i*4+k]*t;
  1161.         end;
  1162.       end;
  1163.     end;
  1164.   end;
  1165.   result := true;
  1166. end;
  1167.  
  1168. function Multiply (Color: TGLcolor; mult: TGLdouble): TGLcolor;
  1169. begin
  1170.   Color.red := Color.red * mult;
  1171.   Color.green := Color.green * mult;
  1172.   Color.blue := Color.blue * mult;
  1173. end;
  1174.  
  1175. end.
  1176.  


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 13 Gäste


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.016s | 14 Queries | GZIP : On ]