////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TglcFrustum = class(TObject)
private
+ fProjMatrix: TgluMatrix4f;
+ function GetProjMatrixPtr: Pointer;
function GetWidth: Single;
function GetHeight: Single;
function GetFOVAngle: Single;
function GetAspectRatio: Single;
+ procedure UpdateProjMatrix;
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;
+ 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;
+ property ProjMatrix: TgluMatrix4f read fProjMatrix;
+ property ProjMatrixPtr: Pointer read GetProjMatrixPtr;
procedure Frustum(const aLeft, aRight, aBottom, aTop, aNear, aFar: Single);
procedure Perspective(const aFOVAngle, aAspectRatio, aNear, aFar: Single);
TglcCamera = class(TglcFrustum)
private
fPosition: TgluMatrix4f;
+ function GetPositionPtr: Pointer;
public
- property Position: TgluMatrix4f read fPosition write fPosition;
+ property Position: TgluMatrix4f read fPosition write fPosition;
+ property PositionPtr: Pointer read GetPositionPtr;
procedure Move(const aVec: TgluVector3f);
procedure Tilt(const aAngle: Single);
uses
Math, {$IFNDEF OPENGL_ES}dglOpenGL{$ELSE}dglOpenGLES{$ENDIF};
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TglcFrustum///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglcFrustum.UpdateProjMatrix;
+begin
+ if fIsOrthogonal then begin
+ fProjMatrix[maAxisX] := gluVector4f(
+ 2 / (fRight - fLeft),
+ 0,
+ 0,
+ 0);
+ fProjMatrix[maAxisY] := gluVector4f(
+ 0,
+ 2 / (fTop - fBottom),
+ 0,
+ 0);
+ fProjMatrix[maAxisZ] := gluVector4f(
+ 0,
+ 0,
+ -2 / (fFar - fNear),
+ 0);
+ fProjMatrix[maPos] := gluVector4f(
+ -(fRight + fLeft) / (fRight - fLeft),
+ -(fTop + fBottom) / (fTop - fBottom),
+ -(fFar + fNear) / (fFar - fNear),
+ 1);
+ end else begin
+ fProjMatrix[maAxisX] := gluVector4f(
+ 2 * fNear / (fRight - fLeft),
+ 0,
+ 0,
+ 0);
+ fProjMatrix[maAxisY] := gluVector4f(
+ 0,
+ 2 * fNear / (fTop - fBottom),
+ 0,
+ 0);
+ fProjMatrix[maAxisZ] := gluVector4f(
+ (fRight + fLeft) / (fRight - fLeft),
+ (fTop + fBottom) / (fTop - fBottom),
+ -(fFar + fNear) / (fFar - fNear),
+ -1);
+ fProjMatrix[maPos] := gluVector4f(
+ 0,
+ 0,
+ -2 * fFar * fNear / (fFar - fNear),
+ 0);
+ end;
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TglcFrustum.GetWidth: Single;
begin
result := (fRight - fLeft);
end;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglcFrustum.GetProjMatrixPtr: Pointer;
+begin
+ result := @fProjMatrix[0, 0];
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TglcFrustum.GetHeight: Single;
begin
result := (fTop - fBottom);
fRight := aTop;
fNear := aNear;
fFar := aFar;
+ UpdateProjMatrix;
end;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
fBottom := -fTop;
fRight := aAspectRatio * fTop;
fLeft := -fRight;
+ UpdateProjMatrix;
end;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
fBottom := aBottom;
fNear := aNear;
fFar := aFar;
+ UpdateProjMatrix;
end;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TglcCamera////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglcCamera.GetPositionPtr: Pointer;
+begin
+ result := @fPosition[0, 0];
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TglcCamera.Move(const aVec: TgluVector3f);
begin
fPosition := gluMatrixMult(gluMatrixTranslate(aVec), fPosition);