|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- unit uglcCamera;
-
- { Package: OpenGLCore
- Prefix: glc - OpenGL Core
- Beschreibung: diese Unit enthält eine Klassen-Kapselung für OpenGL Frustum und Kamera }
-
- {$mode objfpc}{$H+}
-
- interface
-
- uses
- Classes, SysUtils,
- ugluVector, ugluMatrix;
-
- type
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- TglcFrustum = class(TObject)
- private
- function GetWidth: Single;
- function GetHeight: Single;
- function GetFOVAngle: Single;
- function GetAspectRatio: Single;
- protected
- fIsOrthogonal: Boolean;
- fTop, fBottom, fLeft, fRight, fNear, fFar: Single;
- public
- property Top : Single read fTop;
- property Bottom : Single read fBottom;
- property Left : Single read fLeft;
- property Right : Single read fRight;
- property Near : Single read fNear;
- property Far : Single read fFar;
- property Width : Single read GetWidth;
- property Height : Single read GetHeight;
- property FOVAngle : Single read GetFOVAngle;
- property AspectRatio : Single read GetAspectRatio;
- property IsOrthogonal: Boolean read fIsOrthogonal;
-
- procedure Frustum(const aLeft, aRight, aBottom, aTop, aNear, aFar: Single);
- procedure Perspective(const aFOVAngle, aAspectRatio, aNear, aFar: Single);
- procedure Ortho(const aLeft, aRight, aBottom, aTop, aNear, aFar: Single);
- procedure Activate;
- procedure Render;
-
- constructor Create;
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- TglcCamera = class(TglcFrustum)
- private
- fPosition: TgluMatrix4f;
- public
- property Position: TgluMatrix4f read fPosition write fPosition;
-
- procedure Move(const aVec: TgluVector3f);
- procedure Tilt(const aAngle: Single);
- procedure Turn(const aAngle: Single);
- procedure Roll(const aAngle: Single);
- procedure Activate;
- function GetRay(const aPos: TgluVector2f): TgluRayf;
-
- constructor Create;
- end;
-
- implementation
-
- uses
- Math, dglOpenGL;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //TglcFrustum///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TglcFrustum.GetWidth: Single;
- begin
- result := (fRight - fLeft);
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TglcFrustum.GetHeight: Single;
- begin
- result := (fTop - fBottom);
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TglcFrustum.GetFOVAngle: Single;
- begin
- result := arctan2(Height/2, fNear)/Pi*360;
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TglcFrustum.GetAspectRatio: Single;
- begin
- result := Height / Width;
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- procedure TglcFrustum.Frustum(const aLeft, aRight, aBottom, aTop, aNear, aFar: Single);
- begin
- fIsOrthogonal := false;
- fTop := aRight;
- fBottom := aLeft;
- fLeft := aBottom;
- fRight := aTop;
- fNear := aNear;
- fFar := aFar;
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- procedure TglcFrustum.Perspective(const aFOVAngle, aAspectRatio, aNear, aFar: Single);
- begin
- fIsOrthogonal := false;
- fNear := aNear;
- fFar := aFar;
- fTop := fNear * tan(aFOVAngle / 360 * Pi);
- fBottom := -fTop;
- fRight := aAspectRatio * fTop;
- fLeft := -fRight;
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- procedure TglcFrustum.Ortho(const aLeft, aRight, aBottom, aTop, aNear, aFar: Single);
- begin
- fIsOrthogonal := true;
- fLeft := aLeft;
- fRight := aRight;
- fTop := aTop;
- fBottom := aBottom;
- fNear := aNear;
- fFar := aFar;
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- procedure TglcFrustum.Activate;
- begin
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity;
- if fIsOrthogonal then
- glOrtho(fLeft, fRight, fBottom, fTop, fNear, fFar)
- else
- glFrustum(fLeft, fRight, fBottom, fTop, fNear, fFar);
- glMatrixMode(GL_MODELVIEW);
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- procedure TglcFrustum.Render;
- var
- min, max: TgluVector2f;
- begin
- min[0] := fLeft / fNear * fFar;
- min[1] := fBottom / fNear * fFar;
- max[0] := fRight / fNear * fFar;
- max[1] := fTop / fNear * fFar;
-
- glBegin(GL_LINE_LOOP);
- glVertex3f(fLeft, fTop, -fNear);
- glVertex3f(fLeft, fBottom, -fNear);
- glVertex3f(fRight, fBottom, -fNear);
- glVertex3f(fRight, fTop, -fNear);
- glEnd;
-
- glBegin(GL_LINE_LOOP);
- glVertex3f(min[0], min[0], -fFar);
- glVertex3f(min[0], max[0], -fFar);
- glVertex3f(max[0], max[0], -fFar);
- glVertex3f(max[0], min[0], -fFar);
- glEnd;
-
- glBegin(GL_LINES);
- glVertex3f(0, 0, 0); glVertex3f(min[0], min[0], -fFar);
- glVertex3f(0, 0, 0); glVertex3f(min[0], max[0], -fFar);
- glVertex3f(0, 0, 0); glVertex3f(max[0], max[0], -fFar);
- glVertex3f(0, 0, 0); glVertex3f(max[0], min[0], -fFar);
- glEnd;
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- constructor TglcFrustum.Create;
- begin
- inherited Create;
- fTop := 0;
- fBottom := 0;
- fLeft := 0;
- fRight := 0;
- fNear := 0;
- fFar := 0;
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //TglcCamera////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- procedure TglcCamera.Move(const aVec: TgluVector3f);
- begin
- fPosition := gluMatrixMult(gluMatrixTranslate(aVec), fPosition);
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- procedure TglcCamera.Tilt(const aAngle: Single);
- begin
- fPosition := gluMatrixMult(gluMatrixRotate(gluVector3f(1,0,0), aAngle), fPosition);
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- procedure TglcCamera.Turn(const aAngle: Single);
- begin
- fPosition := gluMatrixMult(gluMatrixRotate(gluVector3f(0,1,0), aAngle), fPosition);
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- procedure TglcCamera.Roll(const aAngle: Single);
- begin
- fPosition := gluMatrixMult(gluMatrixRotate(gluVector3f(0,0,1), aAngle), fPosition);
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- procedure TglcCamera.Activate;
- begin
- inherited Activate;
- glLoadMatrixf(@fPosition[0, 0]);
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TglcCamera.GetRay(const aPos: TgluVector2f): TgluRayf;
- var
- p: TgluVector3f;
- begin
- if (aPos[0] < 0) then
- p[0] := -aPos[0] * fLeft
- else
- p[0] := aPos[0] * fRight;
- if (aPos[1] < 0) then
- p[1] := -aPos[1] * fBottom
- else
- p[1] := aPos[1] * fTop;
- if (fIsOrthogonal) then begin
- p[2] := 0;
- result.p := fPosition * p;
- result.v := fPosition * gluVector3f(0, 0, -1);
- end else begin
- p[2] := -fNear;
- result.p := gluVector3f(0, 0, 0);
- result.v := fPosition * p;
- end;
- result := gluRayNormalize(result);
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- constructor TglcCamera.Create;
- begin
- inherited Create;
- fPosition := gluMatrixIdentity;
- end;
-
- end.
-
|