unit MyUnit;

interface

Uses
  Windows, Messages, SysUtils, OpenGL;

Type
  TextureImage = record                                 // Struktura textury
    imageData: ^GLubyte;                                // Ukazatel na data
    bpp: GLuint;                                        // Barevna hloubka
    width: GLuint;                                      // Sirka
    height: GLuint;                                     // Vyska
    texID: GLuint;                                      // cislo textury
    end;

var
  //global
  WndWidth:Integer=800;
  WndHeight:Integer=600;

function IntToStr(Num:Integer): String;
function ArcCos(const X:Extended): Extended;
function ReadBitmap(const FileName:String; Mask:Cardinal; var sWidth,tHeight:Integer; var BitCount: Word): pointer;
function LoadTGA(var texture: TextureImage; filename: string): boolean;

implementation

{var}
//local

//********************************************************************
function IntToStr(Num:Integer):String;
begin
  Str(Num, result);
end;

function ArcCos(const X:Extended):Extended;
asm
  //Result:= ArcTan2(Sqrt((1+X) * (1-X)), X)
  FLD   X
  FLD1
  FADD  ST(0), ST(1)
  FLD1
  FSUB  ST(0), ST(2)
  FMULP ST(1), ST(0)
  FSQRT
  FXCH
  FPATAN
end;

function ReadBitmap(const FileName:String; Mask:DWord; var sWidth,tHeight:Integer; var BitCount:Word): pointer;
const
  szh = SizeOf(TBitmapFileHeader);
  szi = SizeOf(TBitmapInfoHeader);
type
  TRGB = record
    r, g, b: Byte;
  end;
  TRGBArr = array[Word] of TRGB;
  PRGBArr = ^TRGBArr;
  TRGBA = record
    r, g, b, a: Byte;
  end;
  TRGBAArr = array[Word] of TRGBA;
  PRGBAArr = ^TRGBAArr;
var
  BmpFile : File;
  bfh : TBitmapFileHeader;
  bmi : TBitmapInfoHeader;
  x, size: Integer;
  tmp: Shortint;
begin
  AssignFile (BmpFile, FileName);
  Reset (BmpFile, 1);
  Blockread(BmpFile, bfh, szh);
  BlockRead (BmpFile, bmi, szi);
  If Bfh.bfType <> $4D42 then begin
    MessageBox(0, 'Invalid Bitmap', 'Error', MB_OK);
    Result := nil;
    Exit;
  end;
  sWidth := bmi.biWidth;
  tHeight := bmi.biHeight;
  BitCount := bmi.biBitCount;
  Size := bmi.biWidth * bmi.biHeight * (bmi.biBitCount div 8);
  GetMem (Result, Size);
  BlockRead(BmpFile, Result^, Size);
  case bmi.biBitCount of
    24:
    begin
      for x := 0 to sWidth * tHeight - 1 do
      with PRGBArr(result)^[x] do
      begin
        tmp := r;
        r := b;
        b := tmp;
      end;
    end;
    32:
    begin
      for x := 0 to sWidth * tHeight - 1 do
      with PRGBAArr(result)^[x] do
      begin
        tmp := r;
        r := b;
        b := tmp;
        if PDWord(@PRGBAArr(result)^[x])^ <> Mask then a := 255;
      end;
    end;
  end;
end;

function LoadTGA(var texture: TextureImage; filename: string): boolean;
var
  TGAheader: array [0..11] of byte;                                   // Nekomprimovana TGA hlavicka  {0,0,2,0,0,0,0,0,0,0,0,0}
  TGAcompare: array [0..11] of byte;                                  // Pro porovnani TGA hlavicky
  Header: array [0..5] of byte;                                       // Prvnich 6 u?itecn?ch byt? z hlavicky
  BytesPerPixel: GLuint;                                              // Pocet byt? na pixel pou?it? v TGA souboru
  ImageSize: GLuint;                                                  // Uklada velikost obrazku pri alokovani RAM
  temp: GLubyte;                                                      // Pomocna promenna
  TypeMode: GLuint;                                                   // GL m?d
  f: file;                                                            // Soubor TGA
  precteno: Gluint;                                                   // Pocet precten?ch byt?
  i: integer;                                                         // Cyklus
  B, R: PGLubyte;                                                     // Ukazatel na prohazovan? slo?ky barev
begin
  ZeroMemory(@TGAheader,sizeof(TGAheader));                           // Nulovani prvk? pole
  TGAheader[2] := 2;                                                  // Treti prvek hlavicky je 2 - viz deklarace
  TypeMode := GL_RGBA;                                                // Implicitnim GL m?dem je RGBA (32 BPP)
  if not FileExists(filename) then                                    // Existuje soubor?
    begin
    Result := false;                                                  // Konec funkce
    exit;
    end;
  AssignFile(f,filename);                                             // Prirazeni souboru
  Reset(f,1);                                                         // Otevre TGA soubor
  BlockRead(f,TGAcompare,Sizeof(TGAcompare),precteno);                // Nacte hlavicku
  if (precteno <> Sizeof(TGAcompare)) or                              // Podarilo se nacist 12 byt??
    (not CompareMem(@TGAcompare,@TGAHeader,sizeof(TGAheader))) then   // Maji potrebn? hodnoty?
    begin
    Result := false;                                                  // Konec funkce
    CloseFile(f);                                                     // Zavre soubor
    exit;
    end;
  BlockRead(f,Header,Sizeof(Header),precteno);                        // Pokud ano, nacte dal?ich ?est byt?
  if precteno <> sizeof(Header) then                                  // Podarilo se nacist 6 byt??
    begin
    Result := false;                                                  // Konec funkce
    CloseFile(f);                                                     // Zavre soubor
    exit;
    end;
  texture.width := Header[1] * 256 + Header[0];                       // Ziska ?irku obrazku
  texture.height := Header[3] * 256 + Header[2];                      // Ziska v??ku obrazku
  if (texture.width <= 0) or (texture.height <= 0)                    // Platna ?irka? Platna v??ka?
    or ((Header[4] <> 24) and (Header[4] <> 32)) then                 // Platna barevna hloubka?
    begin
    Result := false;                                                  // Konec funkce
    CloseFile(f);                                                     // Zavre soubor
    exit;
    end;
  texture.bpp := Header[4];                                           // Bity na pixel (24 nebo 32)
  BytesPerPixel := texture.bpp div 8;                                 // Byty na pixel
  ImageSize := texture.width * texture.height * BytesPerPixel;        // Velikost pameti pro data obrazku
  texture.imageData := AllocMem(ImageSize);                           // Alokace pameti pro data obrazku
  if texture.imageData = nil then                                     // Podarilo se pame? alokovat?
    begin
    Result := false;                                                  // Konec funkce
    CloseFile(f);                                                     // Zavre soubor
    exit;
    end;
  BlockRead(f,texture.imageData^,ImageSize,precteno);                 // Kopirovani dat
  if precteno <> ImageSize then                                       // Podarilo se kopirovani dat?
    begin
    Result := false;                                                  // Konec funkce
    FreeMem(texture.imageData);                                       // Uvolni pame?
    CloseFile(f);                                                     // Zavre soubor
    exit;
    end;
  for i := 0 to (texture.width * texture.height) - 1 do               // Prochazi data obrazku
    begin
    B := Pointer(Integer(texture.imageData) + i * BytesPerPixel);     // Ukazatel na B
    R := Pointer(Integer(texture.imageData) + i * BytesPerPixel+2);   // Ukazatel na R
    temp := B^;                                                       // B ulo?ime do pomocn? promenn?
    B^ := R^;                                                         // R je na spravn?m miste
    R^ := temp;                                                       // B je na spravn?m miste
    end;
  CloseFile(f);
  texture.texID:= glGenLists(1);
  glNewList(texture.texID, GL_COMPILE);                                                       // Zavre glNewList();
  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);     // Linearni filtrovani
  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);     // Linearni filtrovani
  if texture.bpp = 24 then TypeMode := GL_RGB;                        // Je obrazek 24 bitov?? Nastavi typ na GL_RGB
  glTexImage2D(GL_TEXTURE_2D,0,TypeMode,texture.width,texture.height,0,TypeMode,GL_UNSIGNED_BYTE,texture.imageData);  // Vytvori texturu
  glEndList;
  FreeMem(texture.imageData);                                         // Uvolni pame?
  Result := true;
end;

end.
 