Advertisement
Guest User

Font4

a guest
Mar 29th, 2010
302
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 23.06 KB | None | 0 0
  1. // ---------------------
  2. // Unit: Font4.pas
  3. //
  4. // FontObjs now load data and images separately
  5. // Uses proper ABC font widths
  6. // Supports Unicode Widestrings. (not Win 98 and earlier compatible?)
  7. //
  8. // Can Load JPG (separate RGB and Alpha) and 32bit TGAs
  9. // Can Load Binary Fnt Data which has been combined with another file or separately.
  10. //
  11. // 17/08/08 - Added support for .fnt files.
  12. //
  13. // Author: Michael Pote
  14. // Date: 30 April 2007
  15. // -------------------
  16. unit Font4;
  17.  
  18. interface
  19.  
  20. Uses GL,GLU; //Use either OpenGL, OpenGL12 or dglOpenGl, they are all compatible here.
  21.  
  22. const
  23.       MAX_CHARS = high(Word);
  24.       USE_MIPMAP = false; //if you dont want mipmaps set this to false.
  25.       USE_INVERTED = false; //Use this if you use inverted GL coordinates
  26.                             //where (0,0) is the top left corner.
  27.       USE_AUTOTEXTURESWITCH = true; //Use this to change the GL texture
  28.                                     //every time you draw text, saving you
  29.                                     //from having to manually change to the
  30.                                     //font texture every time you want
  31.                                     //to write something to screen.
  32.  
  33. type  FontInfo = record
  34.         A, C: integer;
  35.         Wid, Hgt: cardinal;
  36.         char: WideChar;
  37.         x1,y1,x2,y2: double;
  38.       end;
  39.  
  40.   TFontObj = class
  41.                  private
  42.                   CharLookup: array[0..MAX_CHARS] of integer;
  43.                  public
  44.  
  45.                   F: array of FontInfo;
  46.                   NumFonts: cardinal;
  47.                   TexInd: glUInt;
  48.  
  49.                   SpaceWidth, MaxHeight: cardinal;
  50.  
  51.                   constructor Create; overload;
  52.  
  53.                   function LoadFnt(const Path: string): boolean;
  54.                   function LoadTGAComp(const Path: string): boolean;
  55.                   function LoadJPEGs(const rgb, alpha: string): boolean;
  56.                   function LoadData(const Filename: string; MergedFile: boolean): boolean;
  57.  
  58.                   function TextLen(const Txt: widestring): integer;
  59.                   function TextLenEx(const Txt: widestring; Size: single): single;
  60.  
  61.                   Procedure Draw(Const X,Y: single;Const Txt: widestring; Lev:single); Overload;
  62.                   function GetXPos(Const X: single;Const Txt: widestring; const charindex: integer): single;
  63.  
  64.                   Procedure DrawEx(Const X,Y: single;Const Txt: widestring; Size:single);
  65.                 end;
  66.  
  67. Procedure DrawQuadRT(X, Y, Wid, Hgt, Lev, Tu, Tu2, Tv,Tv2: single);
  68. Procedure DrawQuadRTI(X, Y, Wid, Hgt, Lev, Tu, Tu2, Tv,Tv2: single);
  69.  
  70. implementation
  71.  
  72. Uses Classes, {Windows,} {JPEG, Graphics,} SysUtils;
  73.  
  74. const
  75.     MajorVersion: byte = 4;
  76.     MinorVersion: byte = 0;
  77.  
  78. type QuadDrawingFunction = procedure(X, Y, Wid, Hgt, Lev, Tu, Tu2, Tv,Tv2: single);
  79.  
  80. function LoadJPGs(Filename1, Filename2: String; var Texture: GLuint): Boolean; forward;
  81. function LoadTGA( filename : string; var TexId: glUint; MipMap: boolean) : boolean; forward;        // Loads A TGA File Into Memory
  82.  
  83. var DrawQuad: QuadDrawingFunction;
  84.  
  85. ////////////////////////////////////////////////////////////////////////////////
  86. //  TFONTOBJ
  87. ////////////////////////////////////////////////////////////////////////////////
  88.  
  89. constructor TFontObj.Create;
  90. begin
  91.   inherited Create;
  92.   NumFonts := 0;
  93. end;
  94.  
  95. function TFontObj.TextLen(const Txt: widestring): integer;
  96. var CurX: integer;
  97.     Ch: Widechar;
  98.     Chaar, I, Ind: integer;
  99. begin
  100.    CurX := 0;
  101.  
  102.    for I := 1 to length(Txt) do
  103.    begin
  104.        Ch := Txt[I];
  105.        Chaar := integer(ch);
  106.  
  107.        if Chaar = 32 then
  108.        begin
  109.          Ind := -1;
  110.          CurX := CurX + SpaceWidth;
  111.        end
  112.        else
  113.        begin
  114.          Ind := CharLookup[Chaar];
  115.        end;
  116.  
  117.        if ind > -1 then
  118.        begin
  119.          CurX := CurX + F[Ind].A;
  120.  
  121.          //DrawQuadRT(CurX, Y, F[ind].Wid, F[ind].Hgt, 0, F[ind].x1,F[ind].x2,F[ind].y1,F[ind].y2);
  122.  
  123.          CurX := CurX + F[Ind].C;
  124.        end;
  125.    end;
  126.  
  127.    result := CurX;
  128.  
  129. end;
  130.  
  131.  
  132. function TFontObj.TextLenEx(const Txt: widestring; Size: single): single;
  133. var CurX: single;
  134.     Ch: Widechar;
  135.     Chaar, I, Ind: integer;
  136. begin
  137.    CurX := 0;
  138.  
  139.    for I := 1 to length(Txt) do
  140.    begin
  141.        Ch := Txt[I];
  142.        Chaar := integer(ch);
  143.  
  144.        if Chaar = 32 then
  145.        begin
  146.          Ind := -1;
  147.          CurX := CurX + SpaceWidth*Size;
  148.        end
  149.        else
  150.        begin
  151.          Ind := CharLookup[Chaar];
  152.        end;
  153.  
  154.        if ind > -1 then
  155.        begin
  156.          CurX := CurX + F[Ind].A*Size;
  157.  
  158.          //DrawQuadRT(CurX, Y, F[ind].Wid, F[ind].Hgt, 0, F[ind].x1,F[ind].x2,F[ind].y1,F[ind].y2);
  159.  
  160.          CurX := CurX + F[Ind].C*Size;
  161.        end;
  162.    end;
  163.  
  164.    result := CurX;
  165.  
  166.  
  167. end;
  168.  
  169. procedure TFontObj.Draw(const X, Y: single; const Txt: widestring; Lev: single);
  170. var CurX: single;
  171.     Ch: Widechar;
  172.     Chaar, I, Ind: integer;
  173. begin
  174.    CurX := X;
  175.  
  176.    if USE_AUTOTEXTURESWITCH then glBindTexture(GL_TEXTURE_2D, TexInd);
  177.  
  178.    for I := 1 to length(Txt) do
  179.    begin
  180.        Ch := Txt[I];
  181.        Chaar := integer(ch);
  182.  
  183.        if Chaar = 32 then
  184.        begin
  185.          Ind := -1;
  186.          CurX := CurX + SpaceWidth;
  187.        end
  188.        else
  189.        begin
  190.          Ind := CharLookup[Chaar];
  191.        end;
  192.  
  193.        if ind > -1 then
  194.        begin
  195.          CurX := CurX + F[Ind].A;
  196.  
  197.  
  198.          DrawQuad(CurX, Y, F[ind].Wid, F[ind].Hgt, lev, F[ind].x1,F[ind].x2,F[ind].y1,F[ind].y2);
  199.  
  200.          CurX := CurX + F[Ind].C;
  201.        end;
  202.    end;
  203.  
  204. end;
  205.  
  206. procedure TFontObj.DrawEx(const X, Y: single; const Txt: widestring;
  207.   Size: single);
  208. var CurX: single;
  209.     Ch: Widechar;
  210.     Chaar, I, Ind: integer;
  211. begin
  212.    CurX := X;
  213.  
  214.    if USE_AUTOTEXTURESWITCH then glBindTexture(GL_TEXTURE_2D, TexInd);
  215.  
  216.    for I := 1 to length(Txt) do
  217.    begin
  218.        Ch := Txt[I];
  219.        Chaar := integer(ch);
  220.  
  221.        if Chaar = 32 then
  222.        begin
  223.          Ind := -1;
  224.          CurX := CurX + SpaceWidth*Size;
  225.        end
  226.        else
  227.        begin
  228.          Ind := CharLookup[Chaar];
  229.        end;
  230.  
  231.        if ind > -1 then
  232.        begin
  233.          CurX := CurX + F[Ind].A*Size;
  234.  
  235.  
  236.          DrawQuad(CurX, Y, F[ind].Wid*Size, F[ind].Hgt*Size, 0, F[ind].x1,F[ind].x2,F[ind].y1,F[ind].y2);
  237.  
  238.          CurX := CurX + F[Ind].C*Size;
  239.        end;
  240.    end;
  241.  
  242. end;
  243.  
  244. function TFontObj.GetXPos(const X: single; const Txt: widestring; const charindex: integer): single;
  245. var CurX: single;
  246.     Ch: Widechar;
  247.     Chaar, I, Ind: integer;
  248. begin
  249.    CurX := X;
  250.  
  251.  
  252.  
  253.    for I := 1 to CharIndex do
  254.    if I <= Length(Txt) then
  255.    begin
  256.        Ch := Txt[I];
  257.        Chaar := integer(ch);
  258.  
  259.        if (Chaar = 32) then
  260.        begin
  261.          Ind := -1;
  262.          if I < CharIndex then
  263.             CurX := CurX + SpaceWidth;
  264.        end
  265.        else
  266.        begin
  267.          Ind := CharLookup[Chaar];
  268.        end;
  269.  
  270.        if ind > -1 then
  271.        begin
  272.          CurX := CurX + F[Ind].A;
  273.  
  274.  
  275.          //DrawQuad(CurX, Y, F[ind].Wid*Size, F[ind].Hgt*Size, 0, F[ind].x1,F[ind].x2,F[ind].y1,F[ind].y2);
  276.          if I < CharIndex then
  277.             CurX := CurX + F[Ind].C;
  278.        end;
  279.    end
  280.    else
  281.     if I < CharIndex then
  282.      CurX := CurX + self.SpaceWidth;
  283.  
  284.    result := CurX;
  285.  
  286. end;
  287.  
  288. //Loads the data part of the font.
  289. //Use MergedFile if you saved the data into the graphic composite in Font Studio.
  290. //Can only load binary font data (.Fnt filetype)
  291. function TFontObj.LoadData(const Filename: string; MergedFile: boolean): boolean;
  292. var Fs: TFileStream;
  293.     Pos: int64;
  294.     I: integer;
  295.     Header: array[0..3] of char;
  296. begin
  297.    Fs := nil;
  298.    try
  299.       Fs := TFileStream.Create(filename, fmOpenRead);
  300.  
  301.       if MergedFile then
  302.       begin
  303.         Fs.Seek(-10, soFromEnd);
  304.         Fs.Read(Header[0], 2);
  305.         if (header[0] <> 'F') or (header[1] <> 'S') then
  306.         begin
  307. //          Messagebox(0, 'TFontObj.LoadData: This is not a valid Merged file.', 'Error', MB_OK);
  308.           result := false; //Not a valid merged file.
  309.           exit;
  310.         end;
  311.  
  312.         Fs.Read(Pos, sizeof(int64));
  313.         Fs.Seek(Pos, soFromBeginning); //Move to the correct position.
  314.       end;
  315.  
  316.     Fs.Read(Header[0], 4);
  317.     if (header[0] <> 'F') or (header[1] <> 'S') then
  318.     begin
  319. //          Messagebox(0, 'TFontObj.LoadData: This is not a valid font file (must be .fnt format).', 'Error', MB_OK);
  320.           result := false; //Not a valid file.
  321.           exit;
  322.     end;
  323.     //if (byte(header[2]) <> MajorVersion) or (byte(header[3]) <> MinorVersion) then
  324.     if (header[2] <> 't') or (header[3] <> 'd') then
  325.     begin
  326. //      Messagebox(0, 'TFontObj.LoadData: Warning! Version Mismatch!', 'Error', MB_OK);
  327.     end;
  328.  
  329.  
  330.     Fs.Read(NumFonts, sizeof(Cardinal));
  331.     Fs.Read(SpaceWidth, sizeof(Cardinal));
  332.  
  333.     setlength(F, NumFonts);
  334.  
  335.     for I := 0 to MAX_CHARS-1 do
  336.        CharLookup[I] := -1;
  337.  
  338.  
  339.     MaxHeight := 0;
  340.     for I := 0 to NumFonts-1 do
  341.     begin
  342.        fs.Read(F[I].char, sizeof(WideChar));
  343.        fs.Read(F[I].A, sizeof(integer));
  344.        fs.Read(F[I].C, sizeof(integer));
  345.        fs.Read(F[I].Wid, sizeof(cardinal));
  346.        fs.Read(F[I].Hgt, sizeof(cardinal));
  347.        fs.Read(F[I].X1, sizeof(double));
  348.        fs.Read(F[I].Y1, sizeof(double));
  349.        fs.Read(F[I].X2, sizeof(double));
  350.        fs.Read(F[I].Y2, sizeof(double));
  351.  
  352.        if F[I].Hgt > MaxHeight Then MaxHeight := F[I].Hgt;
  353.  
  354.        if (integer(F[I].char) >= 0) and (integer(F[I].char) < MAX_CHARS) then
  355.           CharLookup[integer(F[I].char)] := I;
  356.     end;
  357.  
  358.     Result := true;
  359.  
  360.    finally
  361.       if assigned(Fs) then Fs.Free;
  362.    end;
  363. end;
  364.  
  365.  
  366. function TFontObj.LoadFnt(const Path: string): boolean;
  367. begin
  368.    //fnt files are just TGA composites.
  369.    result := LoadTGAComp(Path) and LoadData(path, true);
  370.  
  371. end;
  372.  
  373. // Loads two jpeg images as the font texture.
  374. function TFontObj.LoadJPEGs(const rgb, alpha: string): boolean;
  375. begin
  376.   LoadJpgs(rgb, alpha, TexInd);
  377. end;
  378.  
  379. // Loads a 32bit TGA image as the font texture.
  380. function TFontObj.LoadTGAComp(const Path: string): boolean;
  381. begin
  382.   result := LoadTGA(path, TexInd, USE_MIPMAP);
  383. end;
  384.  
  385.  
  386.  
  387. ////////////////////////////////////////////////////////////////////////////////
  388.  
  389.  
  390. function CreateTexture(Width, Height, Format : Word; pData : Pointer; Mipmap: boolean) : Integer;
  391. var
  392.   Texture : GLuint;
  393. begin
  394.   glGenTextures(1, @Texture);
  395.   glBindTexture(GL_TEXTURE_2D, Texture);
  396.   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);  {Texture blends with object background}
  397.  
  398.   { Select a filtering type. BiLinear filtering produces very good results with little performance impact
  399.     GL_NEAREST               - Basic texture (grainy looking texture)
  400.     GL_LINEAR                - BiLinear filtering
  401.     GL_LINEAR_MIPMAP_NEAREST - Basic mipmapped texture
  402.     GL_LINEAR_MIPMAP_LINEAR  - BiLinear Mipmapped texture
  403.   }
  404.  
  405.   if Mipmap then
  406.   begin
  407.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); { only first two can be used }
  408.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); { all of the above can be used }
  409.   end
  410.   else
  411.   begin
  412.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); { only first two can be used }
  413.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); { all of the above can be used }
  414.   end;
  415.  
  416.   if Format = GL_RGBA then
  417.     gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, pData)
  418.   else
  419.     gluBuild2DMipmaps(GL_TEXTURE_2D, format, Width, Height, format, GL_UNSIGNED_BYTE, pData);
  420.  
  421.   result :=Texture;
  422. end;
  423.  
  424.  
  425. function LoadJPGs(Filename1, Filename2: String; var Texture: GLuint): Boolean;
  426. {var
  427.   Data : Array of Byte;
  428.   W, Width : Integer;
  429.   H, Height : Integer;
  430.   BMP : TBitmap;
  431.   JPG: TJPEGImage;
  432.   C : LongWord;
  433.   Line : PByteArray;
  434.  
  435.   MaxSize: integer;
  436.   TD: Array of LongWord;
  437.   ScaleF: single;
  438.   OldW, OldH, X, Y, I: integer;}
  439.  
  440. begin
  441. {  result :=FALSE;
  442.   JPG:=TJPEGImage.Create;
  443.  
  444.     try
  445.       JPG.LoadFromFile(Filename1);
  446.     except
  447.       MessageBox(0, PChar('Couldn''t load JPG - "'+ Filename1 +'"'), PChar('BMP Unit'), MB_OK);
  448.       Exit;
  449.     end;
  450.  
  451.   // Create Bitmap
  452.   BMP:=TBitmap.Create;
  453.   BMP.pixelformat:=pf24bit;
  454.   BMP.width:=JPG.width;
  455.   BMP.height:=JPG.height;
  456.   BMP.canvas.draw(0,0,JPG);        // Copy the JPEG onto the Bitmap
  457.  
  458.   Width :=BMP.Width;
  459.   Height :=BMP.Height;
  460.   SetLength(Data, Width*Height*4);
  461.  
  462.   For H:=0 to Height-1 do
  463.   Begin
  464.     Line :=BMP.scanline[Height-H-1];   // flip JPEG
  465.     For W:=0 to Width-1 do
  466.     Begin
  467.  
  468.       Data[(W*4)+(H*Width*4)] := Line[W*3+2];
  469.       Data[(W*4)+1+(H*Width*4)] := Line[W*3+1];
  470.       Data[(W*4)+2+(H*Width*4)] := Line[W*3];
  471.  
  472.     End;
  473.   End;
  474.  
  475.     try
  476.       JPG.LoadFromFile(Filename2);
  477.     except
  478.       MessageBox(0, PChar('Couldn''t load JPG - "'+ Filename2 +'"'), PChar('BMP Unit'), MB_OK);
  479.       Exit;
  480.     end;
  481.   BMP.canvas.draw(0,0,JPG);        // Copy the JPEG onto the Bitmap
  482.  
  483.   For H:=0 to Height-1 do
  484.   Begin
  485.     Line :=BMP.scanline[Height-H-1];   // flip JPEG
  486.     For W:=0 to Width-1 do
  487.     Begin
  488.  
  489.       Data[(W*4)+3+(H*Width*4)] := Line[W*3];
  490.    
  491.  
  492.     End;
  493.   End;
  494.  
  495.   BMP.free;
  496.   JPG.free;
  497.  
  498.  glGetIntegerv(GL_MAX_TEXTURE_SIZE, @MaxSize);
  499.  
  500.   OldW := -1;
  501.  
  502.   if width > Height then
  503.   begin
  504.    if width > Maxsize then
  505.    begin
  506.  
  507.      ScaleF := MaxSize / width;
  508.      OldW := width;
  509.      OldH := Height;
  510.      width := Maxsize;
  511.      Height := round(Height*ScaleF);
  512.    end;
  513.   end
  514.   else
  515.   begin
  516.    if height > Maxsize then
  517.    begin
  518.      ScaleF := MaxSize / height;
  519.      OldW := width;
  520.      OldH := Height;
  521.      height := Maxsize;
  522.      width := round(width*ScaleF);
  523.    end;
  524.   end;
  525.  
  526.   if OldW > -1 then
  527.   begin
  528.      ScaleF := 1/ScaleF;
  529.      SetLength(TD, Width*Height);
  530.      For X := 0 to Width-1 do
  531.      For Y := 0 to Height-1 do
  532.      begin
  533.         TD[(Y*Width+X)] := data[
  534.                         round(((Y*OldW)*ScaleF+(X*ScaleF)))
  535.                         ];
  536.      end;
  537.      SetLength(Data, Width*Height);
  538.      For Y := 0 to high(Td) do
  539.       Data[Y] := Td[Y];
  540.      SetLength(TD, 0);
  541.  
  542.   end;
  543.  
  544.  
  545.  
  546.  
  547.   Texture :=CreateTexture(Width, Height, GL_RGBA, addr(Data[0]), USE_MIPMAP);}
  548.   result :=TRUE;
  549. end;
  550.  
  551.  
  552. Procedure DrawQuadRT(X, Y, Wid, Hgt, Lev, Tu, Tu2, Tv,Tv2: single);
  553. begin
  554.    Tv := 1-Tv;
  555.   Tv2 := 1-Tv2;
  556.   glBegin(GL_QUADS);
  557.     glTexCoord2f(Tu,  Tv); glVertex3f(X,     Y, -lev);
  558.     glTexCoord2f(Tu2, Tv); glVertex3f(X+Wid, Y, -lev);
  559.     glTexCoord2f(Tu2,Tv2); glVertex3f(X+Wid, Y-Hgt, -lev);
  560.     glTexCoord2f(Tu, Tv2); glVertex3f(X,     Y-Hgt, -lev);
  561.   glEnd;
  562. end;
  563.  
  564. Procedure DrawQuadRTI(X, Y, Wid, Hgt, Lev, Tu, Tu2, Tv,Tv2: single);
  565. begin
  566.    Tv := 1-Tv;
  567.   Tv2 := 1-Tv2;
  568.   glBegin(GL_QUADS);
  569.     glTexCoord2f(Tu,  Tv) ;  glVertex3f(X,     Y    , -lev);
  570.     glTexCoord2f(Tu2, Tv) ;  glVertex3f(X+Wid, Y    , -lev);
  571.     glTexCoord2f(Tu2, Tv2);  glVertex3f(X+Wid, Y+Hgt, -lev);
  572.     glTexCoord2f(Tu,  Tv2);  glVertex3f(X,     Y+Hgt, -lev);
  573.   glEnd;
  574. end;
  575.  
  576.  
  577.  
  578. function LoadTGA( filename : string; var TexId: glUint; MipMap: boolean) : boolean;         // Loads A TGA File Into Memory
  579. const
  580.   TGAheader : array [0..11] of GLubyte = (0,0,2,0,0,0,0,0,0,0,0,0); // Uncompressed TGA Header
  581. TGAComheader : array [0..11] of GLubyte = (0,0,10,0,0,0,0,0,0,0,0,0);   // Compressed TGA Header
  582.  
  583. type TextureImage = record                                      // Structure Name
  584.     imageData : PChar;                                      // Image Data (Up To 32 Bits)
  585.     bpp : GLuint;                                           // Image Color Depth In Bits Per Pixel.
  586.     width : GLuint;                                         // Image Width
  587.     height : GLuint;                                            // Image Height
  588.     texID : GLuint;
  589.      end;
  590.  
  591. var
  592.   TGAcompare : array [0..11] of GLubyte;                                // Used To Compare TGA Header
  593.   header : array [0..5] of GLubyte;                                 // First 6 Useful Bytes From The Header
  594.   bytesPerPixel : GLuint;                   // Holds Number Of Bytes Per Pixel Used In The TGA File
  595.   imageSize : GLuint;                                   // Used To Store The Image Size When Setting Aside Ram
  596.   i : GLuint;                                       // Temporary Variable
  597.   gltype : GLuint;                              // Set The Default GL Mode To RBGA (32 BPP)
  598.   Compressed:boolean;
  599.  
  600.   Tm: Char;
  601.   Texture:  TextureImage;
  602.   tgafile : integer;
  603.   TD: pchar;
  604.   ScaleF: single;
  605.   OldW, OldH, X, Y: integer;
  606.  
  607.   PixelCount, CurrentPixel, CurrentByte: gluInt;
  608.   ColorBuffer: Pchar;
  609.   ChunkHeader: gluByte;
  610.   Counter, Ret: integer;
  611. begin
  612.   tgafile := FileOpen(filename, fmOpenReadWrite);
  613.  
  614.   Ret := FileRead(tgafile, TGAcompare, sizeof(TGAcompare));
  615.  
  616.   if (
  617.       (tgafile = -1) or                             // Does File Even Exist?
  618.       (Ret <> sizeof(TGAcompare))   // Are There 12 Bytes To Read?
  619.      )
  620.   then
  621.   begin
  622.     //ShowError(10, 'TGATexture.LoadTGA', False);
  623.     if (tgafile = -1) then                                  // Did The File Even Exist? *Added Jim Strong*
  624.     begin
  625.       result := false;                                  // Return False
  626.       exit;
  627.     end
  628.     else
  629.     begin
  630.       fileclose(tgafile);                                   // If Anything Failed, Close The File
  631.       result := false;                                  // Return False
  632.       exit;
  633.     end;
  634.   end;
  635.  
  636.   if (CompareMem(@TGAheader, @TGAcompare, sizeof(TGAheader)) = false)                   // Does The Header Match What We Want?
  637.   Then
  638.   begin //File is not uncompressed...
  639.  
  640.    if (CompareMem(@TGAComheader, @TGAcompare, sizeof(TGAComheader)) = True)                 // Does The Header Match What We Want?
  641.    Then
  642.    Begin
  643.       Compressed := True;
  644.    end
  645.    else
  646.    Begin
  647.      i := 0;
  648.      //ShowError(17, 'TGATexture.LoadTGA', False);
  649.      if (tgafile = -1) then                                 // Did The File Even Exist? *Added Jim Strong*
  650.      begin
  651.        result := false;                                 // Return False
  652.        exit;
  653.      end
  654.      else
  655.      begin
  656.        fileclose(tgafile);                                  // If Anything Failed, Close The File
  657.        result := false;                                 // Return False
  658.        exit;
  659.      end;
  660.     end;
  661.  
  662.   end
  663.   else
  664.   begin
  665.    Compressed := False;
  666.   end;
  667.  
  668.    if (FileRead(tgafile, header, sizeof(header)) <> sizeof(header)) then
  669.    begin
  670.      //ShowError(10, 'TGATexture.LoadTGA', False);
  671.      if (tgafile = -1) then                                 // Did The File Even Exist? *Added Jim Strong*
  672.      begin
  673.        result := false;                                 // Return False
  674.        exit;
  675.      end
  676.      else
  677.      begin
  678.        fileclose(tgafile);                                  // If Anything Failed, Close The File
  679.        result := false;                                 // Return False
  680.        exit;
  681.      end;
  682.    end;
  683.  
  684.   texture.width  := header[1] * 256 + header[0];            // Determine The TGA Width  (highbyte*256+lowbyte)
  685.   texture.height := header[3] * 256 + header[2];            // Determine The TGA Height (highbyte*256+lowbyte)
  686.  
  687.   if (texture.width <= 0)   or                              // Is The Width Less Than Or Equal To Zero
  688.      (texture.height <= 0)  or                              // Is The Height Less Than Or Equal To Zero
  689.      ((header[4] <> 24) and (header[4] <> 32)) then                 // Is The TGA 24 or 32 Bit?
  690.   begin
  691.     //ShowError(11, 'TGATexture.LoadTGA', False);
  692.     fileclose(tgafile);                                     // If Anything Failed, Close The File
  693.     result := false;                                        // Return False
  694.     exit;
  695.   end;
  696.  
  697.   texture.bpp   := header[4];                           // Grab The TGA's Bits Per Pixel (24 or 32)
  698.   bytesPerPixel := texture.bpp div 8;                       // Divide By 8 To Get The Bytes Per Pixel
  699.   imageSize := texture.width * texture.height * bytesPerPixel;  // Calculate The Memory Required For The TGA Data
  700.   If BytesPerPixel = 4 then glType := GL_RGBA else
  701.   glType := GL_RGB;
  702.  
  703.   GetMem(texture.imageData, imageSize);     // Reserve Memory To Hold The TGA Data
  704.   //Setlength(texture.imagedata, imagesize);
  705.   if Not Compressed then
  706.   begin
  707.    if (texture.imageData = nil) or         // Does The Storage Memory Exist?
  708.       (fileread(tgafile, texture.imageData^, integer(imageSize)) <> imageSize)  // Does The Image Size Match The Memory Reserved?
  709.       then
  710.       begin
  711.         if (texture.imageData <> nil)                       // Was Image Data Loaded
  712.            then freemem(texture.imageData);                     // If So, Release The Image Data
  713.  
  714.         fileclose(tgafile);                                     // Close The File
  715.         //ShowError(10, 'TGATexture.LoadTGA', False);
  716.         result := false;                                        // Return False
  717.         exit;
  718.       end;
  719.  
  720.     i := 0;
  721.     while i < imageSize do
  722.     with texture do
  723.     begin
  724.      Tm := ImageData[I+2];
  725.      imageData[i+2] := imageData[i];                    // Set The 3rd Byte To The Value In 'temp' (1st Byte Value)
  726.      imageData[i] := Tm;                          // Set The 1st Byte To The Value Of The 3rd Byte
  727.  
  728.      i := i + bytesPerPixel;
  729.     end;
  730.  
  731.  end
  732.  else  //COMPRESSED TGA'S
  733.  begin
  734.    PixelCount := texture.width * Texture.Height;
  735.    CurrentPixel := 0;
  736.    CurrentByte := 0;
  737.    GetMem(ColorBuffer, BytesPerPixel);
  738.  
  739.    Repeat
  740.       ChunkHeader := 0;
  741.       if FileRead(tgaFile, ChunkHeader, sizeof(gluByte)) = 0 then
  742.       begin
  743.         //ERROR reading Chunk!
  744.         fileclose(tgafile);                                     // Close The File
  745.         result := false;                                        // Return False
  746.         exit;
  747.       end;
  748.  
  749.  
  750.       if ChunkHeader < 128 then
  751.       begin
  752.          ChunkHeader := ChunkHeader + 1;
  753.          For Counter := 0 to ChunkHeader-1 do
  754.          begin
  755.             if fileRead(tgafile, ColorBuffer^, BytesPerPixel) <> BytesPerPixel then
  756.             begin
  757.              fileclose(tgafile);                                        // Close The File
  758.              result := false;                                       // Return False
  759.              exit;
  760.             end;
  761.  
  762.             Texture.imageData[CurrentByte] := (ColorBuffer[2]);
  763.             Texture.imageData[CurrentByte+1] := (ColorBuffer[1]);
  764.             Texture.imageData[CurrentByte+2] := (ColorBuffer[0]);
  765.             if BytesPerPixel = 4 then
  766.             Texture.imageData[CurrentByte+3] := (ColorBuffer[3]);
  767.  
  768.             CurrentByte := CurrentByte + bytesPerPixel;
  769.             inc(CurrentPixel);
  770.             if CurrentPixel > PixelCount then
  771.             begin
  772.              fileclose(tgafile);                                        // Close The File
  773.              result := false;                                       // Return False
  774.              exit;
  775.             end;
  776.          end;
  777.       end
  778.       else //Chunkheader > 128
  779.       begin
  780.          ChunkHeader := ChunkHeader - 128;
  781.          if fileRead(tgafile, ColorBuffer^, BytesPerPixel) <> BytesPerPixel then
  782.          begin
  783.           fileclose(tgafile);                                       // Close The File
  784.           result := false;                                      // Return False
  785.           exit;
  786.          end;
  787.          For Counter := 0 to ChunkHeader do
  788.          begin
  789.             Texture.imageData[CurrentByte] := ColorBuffer[2];
  790.             Texture.imageData[CurrentByte+1] := ColorBuffer[1];
  791.             Texture.imageData[CurrentByte+2] := ColorBuffer[0];
  792.             if BytesPerPixel = 4 then
  793.             Texture.imageData[CurrentByte+3] := ColorBuffer[3];
  794.  
  795.             CurrentByte := CurrentByte + bytesPerPixel;
  796.             inc(CurrentPixel);
  797.          end;
  798.  
  799.       end;
  800.    Until CurrentPixel >= PixelCount;
  801.    FreeMem(ColorBuffer);
  802.  end;
  803.  fileclose (tgafile);                                           // Close The File
  804.  
  805.  
  806.  
  807.   // Build A Texture From The Data
  808.  Texture.texId := CreateTexture(Texture.Width, Texture.Height, glType, Texture.Imagedata, Mipmap);
  809.  FreeMem(Texture.ImageData);
  810.  
  811.   TexId := Texture.texID;
  812.   result := true;                                           // Texture Building Went Ok, Return True
  813. end;
  814.  
  815. procedure SetupInversion;
  816. begin
  817.   if USE_INVERTED then
  818.   begin
  819.     DrawQuad := @DrawQuadRTI;
  820.   end
  821.   else
  822.   begin
  823.     DrawQuad := @DrawQuadRT;
  824.   end;
  825. end;
  826.  
  827. initialization
  828.   SetupInversion;
  829.  
  830.  
  831. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement