unit GameUtils;

interface
uses Windows, Variables, OpenGl;

function Bounds(X,Y,Width,Height : integer):TRect;
function BoundsS(X,Y,Width,Height : single):TSingleRect;
function RectInRect(r:Trect;r2:Trect):boolean; overload;
function RectInRect(r:TSingleRect;r2:TSingleRect):boolean; overload;
function PointInRect(const Point: TPoint; const Rect: TRect): Boolean; overload;
function PointInRect(X,Y : Double; Rx,Ry,Rw,Rh : single):boolean; overload;
function PointInRect(X,Y : Double; R : TsingleRect):boolean; overload;
function GetOpenGLPos(X, Y: Integer): TGLVectord3;
function GetOpenGLProject(obj : TGLVectord3): TPoint;

implementation
function GetOpenGLPos(X, Y: Integer): TGLVectord3;
var
	viewport:   TGLVectori4;
	modelview:  TGLMatrixd4;
	projection: TGLMatrixd4;
	winZ,winY:  Single;
begin
	glGetDoublev(GL_MODELVIEW_MATRIX, @modelview );
	glGetDoublev(GL_PROJECTION_MATRIX, @projection );
	glGetIntegerv(GL_VIEWPORT, @viewport );

  winY := viewport[3] - y;

	glReadPixels(X, Round(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, @winZ );
	gluUnProject(X, winY, winZ,
              @modelview, @projection, @viewport,
			        Result[0], Result[1], Result[2]);
end;
//------------------------------------------------------------------------------
function GetOpenGLProject(obj : TGLVectord3): TPoint;
var
	viewport:   TGLVectori4;
	modelview:  TGLMatrixd4;
	projection: TGLMatrixd4;
	winX, winY, winZ : Double;
begin
	glGetDoublev(GL_MODELVIEW_MATRIX, @modelview );
	glGetDoublev(GL_PROJECTION_MATRIX, @projection );
	glGetIntegerv(GL_VIEWPORT, @viewport );

	gluProject(obj[0],obj[1],obj[2],
              @modelview, @projection, @viewport,
			        winX,winY,winZ);
 result.X:=round(WinX);
 result.Y:=round(WinY);
end;
//------------------------------------------------------------------------------
function Bounds(X,Y,Width,Height : integer):TRect;
begin
result.Left:=X;
result.Top:=Y;
result.Right:=X+Width;
result.Bottom:=Y+Height;
end;
function BoundsS(X,Y,Width,Height : single):TSingleRect;
begin
result.X:=X;
result.Y:=Y;
result.Width:=Width;
result.Height:=Height;
end;
//------------------------------------------------------------------------------
function PointInRect(X,Y : Double; Rx,Ry,Rw,Rh : single):boolean; overload;
begin
result:= (x>rx) and (x<rx+Rw) and (Y>ry) and (y<ry+rh);
end;

function PointInRect(X,Y : Double; R : TsingleRect):boolean; overload;
begin
result:= (x>R.X) and (x<R.X+R.Width) and (Y>R.Y) and (y<R.Y+R.Height);
end;

function PointInRect(const Point: TPoint; const Rect: TRect): Boolean; overload;
begin
  Result := (Point.X >= Rect.Left) and
            (Point.X <= Rect.Right) and
            (Point.Y >= Rect.Top) and
            (Point.Y <= Rect.Bottom);
end;
//------------------------------------------------------------------------------
function RectInRect(r:Trect;r2:Trect):boolean; overload;
begin
result:=
  (R.Left < R2.Right) and
  (R.Right > R2.Left) and
  (R.Top < R2.Bottom) and
  (R.Bottom > R2.Top) or
  (R2.Left < R.Right) and
  (R2.Right > R.Left) and
  (R2.Top < R.Bottom) and
  (R2.Bottom > R.Top);
end;

function RectInRect(r:TSingleRect;r2:TSingleRect):boolean; overload;
begin
result:=
  (R.X < R2.X+R2.Width) and
  (R.X+R.Width > R2.X) and
  (R.Y < R2.Y+R2.Height) and
  (R.Y+R.Height > R2.Y) or
  (R2.X < R.X+R.Width) and
  (R2.X+R2.Width > R.X) and
  (R2.Y < R.Y+R.Height) and
  (R2.Y+R2.Height > R.Y);
end;

end.
