unit GMUtilite;

interface
      uses Windows,OpenGl,GMVars,SysUtils;


procedure Enable2d(A:boolean);
procedure glBlend(ID: Byte);
procedure VBL2(vsync : TVSyncMode);
procedure FreeSystemFont2D(font: DWORD); stdcall;
function GetTimer: integer;
function ExtractFileDir(const FileName: string): string;
function CreateSystemFont2D(AD:hDC;Face: PChar; W, H: integer): DWORD; stdcall;
procedure SText2D(font: DWORD; const str: string; X, Y, color: integer; Alpha : byte); stdcall;
procedure DrawRectangle2D(X, Y, Width, Height, Color:integer; Alpha : byte=255;Angle:integer=0; Fill : boolean = false;Center:boolean=false);
function IntToStr(x: integer): string;
function StrToInt(const S: string): Integer;
procedure DrawTextureBox(x,y,w,h:integer;textId:cardinal;center:boolean=false;angle:integer=0;FlipV:boolean=false);
procedure DrawLine2D(X1, Y1, X2, Y2, Color : integer; Alpha : integer = 255; LineWidth : real = 1.0; Smooth : boolean = true);
implementation


procedure DrawLine2D(X1, Y1, X2, Y2, Color : integer; Alpha : integer = 255; LineWidth : real = 1.0; Smooth : boolean = true);
begin

glDisable(GL_TEXTURE_2D);
if Smooth then
begin
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
end;
glLineWidth(LineWidth);
   glBegin(GL_LINES);
   glcolor4ub(GetRValue(Color1),GetGValue(Color1),GetBValue(Color1),Alpha);
   glVertex2f(X1,Y1);
   glcolor4ub(GetRValue(Color1),GetGValue(Color1),GetBValue(Color1),Alpha);
   glVertex2f(X2,Y2);
  glEnd;

if Smooth then
begin
glDisable(GL_LINE_SMOOTH);
glDisable(GL_BLEND);
end;
glLineWidth(1);

end;


procedure DrawTextureBox(x,y,w,h:integer;textId:cardinal;center:boolean=false;angle:integer=0;FlipV:boolean=false);
var
rx,ry:single;
FlipN:array[0..3] of record
                          x,y:byte;
                          end;
begin
   glColor3f(1,1,1);
  glEnable( GL_TEXTURE_2D );
  glPushMatrix();
  glTranslatef(X,Y,0);
  if Angle<>0 then glrotatef(Angle,0,0,1);
  glBindTexture(GL_TEXTURE_2D, textId); // use floor

 FlipN[0].x:=0;FlipN[0].y:=1;
 FlipN[1].x:=1;FlipN[1].y:=1;
 FlipN[2].x:=1;FlipN[2].y:=0;
 FlipN[3].x:=0;FlipN[3].y:=0;

 if flipv then
 begin
 FlipN[0].x:=0;FlipN[0].y:=0;
 FlipN[1].x:=1;FlipN[1].y:=0;
 FlipN[2].x:=1;FlipN[2].y:=1;
 FlipN[3].x:=0;FlipN[3].y:=1;
 end;

 glBegin(GL_QUADS);
 if center then
  begin
      Rx:=W/2;
      Ry:=H/2;
  glTexCoord2f(FlipN[0].x,FlipN[0].y);  glVertex2f(-rx,-ry);
  glTexCoord2f(FlipN[1].x,FlipN[1].y);  glVertex2f(rx,-ry);
  glTexCoord2f(FlipN[2].x,FlipN[2].y);  glVertex2f(rx,ry);
  glTexCoord2f(FlipN[3].x,FlipN[3].y);  glVertex2f(-rx,ry);
   end
   else
   begin
  glTexCoord2f(FlipN[0].x,FlipN[0].y);  glVertex2f(0, 0);
  glTexCoord2f(FlipN[1].x,FlipN[1].y);  glVertex2f(0+w,0);
  glTexCoord2f(FlipN[2].x,FlipN[2].y);  glVertex2f(0+w, 0+h);
  glTexCoord2f(FlipN[3].x,FlipN[3].y);  glVertex2f(0,0+h);
   end;

  glEnd();
  glPopMatrix();
  glDisable( GL_TEXTURE_2D );
end;


// целое в строку
function IntToStr(x: integer): string;
begin
Str(x, Result);
end;

function StrToInt(const S: string): Integer;
var
  E: Integer;
begin
  Val(S, Result, E);
end;


procedure DrawRectangle2D(X, Y, Width, Height, Color:integer; Alpha : byte=255;Angle:integer=0; Fill : boolean = false;Center:boolean=false);
var
Rx,Ry:real;
begin

glPushMatrix;

glTranslatef(X,Y,0);

if Angle<>0 then glrotatef(Angle,0,0,1);
if Alpha<>255 then glEnable(GL_BLEND);

 if fill then
 begin

  glcolor4ub(GetRValue(Color),GetGValue(Color),GetBValue(Color),Alpha);
   glBegin(GL_QUADS);
  if center then
  begin
      Rx:=Width/2;
      Ry:=Height/2;
    glVertex2f(-rx,-ry);
    glVertex2f(rx,-ry);
    glVertex2f(rx,ry);
    glVertex2f(-rx,ry);
 end
 else
 begin
    glVertex2f(0,0);
    glVertex2f(0+Width,0);
    glVertex2f(0+Width,0+Height);
    glVertex2f(0,0+Height);
 end;

   glEnd;

 end else
 begin

  glcolor4ub(GetRValue(Color),GetGValue(Color),GetBValue(Color),Alpha);
   glBegin(GL_LINE_STRIP);
     if center then
  begin
      Rx:=Width/2;
      Ry:=Height/2;

    glVertex2f(-rx,-ry);
    glVertex2f(rx,-ry);
    glVertex2f(rx,ry);
    glVertex2f(-rx,ry);
    glVertex2f(-rx,-ry);
   end
   else
   begin

    glVertex2f(0,0);
    glVertex2f(0+Width,0);
    glVertex2f(0+Width,0+Height);
    glVertex2f(0,0+Height);
    glVertex2f(0,0-1);

   end;

   glEnd;

 end;
 glPopMatrix;

if Alpha<>255 then glDisable(GL_BLEND);
end;

procedure SText2D(font: DWORD; const str: string; X, Y, color: integer; Alpha : byte); stdcall;
begin
glPushMatrix();

if Alpha<>255 then
  glEnable(GL_BLEND);
 glcolor4ub(GetRValue(Color),GetGValue(Color),GetBValue(Color),Alpha);
 glRasterPos2f(X, Y);
 glListBase(font);
 glCallLists(Length(str), GL_UNSIGNED_BYTE, PChar(str));
if Alpha<>255 then
  glDisable(GL_BLEND);
glPopMatrix();
end;



function CreateSystemFont2D(AD:hDC;Face: PChar; W, H: integer): DWORD; stdcall;
var
 font : HFONT;
begin
Result := glGenLists(256);
font := CreateFont(H, W, 0, 0, 0, 0, 0, 0,RUSSIAN_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS,
                   ANTIALIASED_QUALITY, FW_BOLD {or FF_DONTCARE or DEFAULT_PITCH}, Face);
SelectObject(AD, font);
wglUseFontBitmaps(AD, 0, 256, Result);
DeleteObject(font);
end;


function ExtractFileDir(const FileName: string): string;
var
  I: Integer;
begin
  I := LastDelimiter(PathDelim + DriveDelim,Filename);
  if (I > 1) and (FileName[I] = PathDelim) and
    (((FileName[I - 1] <> PathDelim) and (FileName[I-1] <> DriveDelim)) or
    (ByteType(FileName, I-1) = mbTrailByte)) then Dec(I);
  while (ByteType(FileName, I-1) = mbTrailByte) and (I > 0) do Dec(I);
  Result := Copy(FileName, 1, I);
end;


function GetTimer: integer;
var
T : LARGE_INTEGER;
F : LARGE_INTEGER;
begin
QueryPerformanceFrequency(Int64(F));
QueryPerformanceCounter(Int64(T));
result := round(1000 * T.QuadPart / F.QuadPart);
end;



procedure FreeSystemFont2D(font: DWORD); stdcall;
begin
glDeleteLists(font, 256);
end;


procedure VBL2(vsync : TVSyncMode);
var
   i : Integer;
begin
   if WGL_EXT_swap_control then
   begin
      i := wglGetSwapIntervalEXT;
      case VSync of
         vsmSync    : if i<>1 then wglSwapIntervalEXT(1);
         vsmNoSync  : if i<>0 then wglSwapIntervalEXT(0);
      else
         Assert(False);
      end;
   end;

end;


// Прочие функции //
procedure glBlend(ID: Byte);
begin
if ID = 0 then
 glDisable(GL_BLEND)
else
 begin
 glEnable(GL_BLEND);
  case ID of
   1 : glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
   2 : glBlendFunc(GL_SRC_ALPHA, GL_ONE);
   3 : glBlendFunc(GL_ZERO, GL_SRC_COLOR);
  end;
 end;
end;

procedure Enable2d(A:boolean);
begin
 if A then
 begin
  glDisable(GL_DEPTH_TEST);
  glMatrixMode(GL_PROJECTION);
  glPushMatrix;
  glLoadIdentity;
  gluOrtho2D(0,SCRW,SCRH,0);
  glMatrixMode(GL_MODELVIEW);
  glPushMatrix;
  glLoadIdentity;
 end
 else
 begin
  glPopMatrix;
  glMatrixMode(GL_PROJECTION);
  glPopMatrix;
  glMatrixMode(GL_MODELVIEW);
  glEnable(GL_DEPTH_TEST);
 end;

 end;



end.
