DEADSOFTWARE

gl: properly free memory
[d2df-sdl.git] / src / game / renders / opengl / r_textures.pas
index 062f76bdcebe373f1ecc231c88ba127b7724d476..24ea1642e7aa37ec447a509ed4ce2c02627f7bbf 100644 (file)
@@ -82,7 +82,6 @@ interface
     TGLMultiTexture = class
       private
         mTexture: array of TGLTexture;
-        mBackanim: Boolean;
 
       public
         destructor Destroy; override;
@@ -95,7 +94,6 @@ interface
         property width: Integer read GetWidth;
         property height: Integer read GetHeight;
         property count: Integer read GetCount;
-        property backAnim: Boolean read mBackanim; (* this property must be located at TAnimState? *)
     end;
 
     TGLTextureArray = array of TGLTexture;
@@ -122,27 +120,32 @@ interface
       anim: TAnimInfo;
     end;
 
+    TConvProc = function (x: Integer): Integer;
+
   procedure r_Textures_Initialize;
   procedure r_Textures_Finalize;
 
   function r_Textures_LoadFromFile (const filename: AnsiString; log: Boolean = True): TGLTexture;
   function r_Textures_LoadMultiFromFile (const filename: AnsiString; log: Boolean = True): TGLMultiTexture;
-  function r_Textures_LoadMultiFromFileAndInfo (const filename: AnsiString; w, h, count: Integer; backanim: Boolean; log: Boolean = True): TGLMultiTexture;
+  function r_Textures_LoadMultiFromFileAndInfo (const filename: AnsiString; w, h, count: Integer; log: Boolean = True): TGLMultiTexture;
   function r_Textures_LoadMultiTextFromFile (const filename: AnsiString; var txt: TAnimTextInfo; log: Boolean = True): TGLMultiTexture;
 
   function r_Textures_LoadStreamFromFile (const filename: AnsiString; w, h, count, cw: Integer; st: TGLTextureArray; rs: TRectArray; log: Boolean = True): Boolean;
 
-  function r_Textures_LoadFontFromFile (const filename: AnsiString; constref f: TFontInfo; skipch: Integer; log: Boolean = true): TGLFont;
+  function r_Textures_LoadFontFromFile (const filename: AnsiString; constref f: TFontInfo; font2enc: TConvProc; log: Boolean = true): TGLFont;
 
 implementation
 
   uses
     SysUtils, Classes,
+    r_common,
     e_log, e_res, WADReader, Config,
+    g_console, // cvar declaration
     Imaging, ImagingTypes, ImagingUtility
   ;
 
   var
+    r_GL_MaxTexSize: WORD;
     maxTileSize: Integer;
     atl: array of TGLAtlas;
 
@@ -329,8 +332,8 @@ implementation
     var i: Integer;
   begin
     for i := 0 to self.count - 1 do
-      self.mTexture[i].Free;
-    self.mTexture := nil;
+      r_Common_FreeAndNil(self.mTexture[i]);
+    SetLength(self.mTexture, 0);
     inherited;
   end;
 
@@ -359,19 +362,47 @@ implementation
 
   (* --------- Init / Fin --------- *)
 
+  function IsPOT (v: LongWord): Boolean;
+  begin
+    result := (v <> 0) and ((v and (v - 1)) = 0)
+  end;
+
+  function NextPOT (v: LongWord): LongWord;
+  begin
+    DEC(v);
+    v := v or (v >> 1);
+    v := v or (v >> 2);
+    v := v or (v >> 4);
+    v := v or (v >> 8);
+    v := v or (v >> 16);
+    INC(v);
+    result := v;
+  end;
+
   function r_Textures_GetMaxHardwareSize (): Integer;
     var size: GLint = 0;
   begin
-    glGetIntegerv(GL_MAX_TEXTURE_SIZE, @size);
-    if size < 64 then size := 64;
-    //if size > 512 then size := 512;
-    //size := 64; // !!!
+    if r_GL_MaxTexSize <= 0 then
+    begin
+      // auto, max possible reccomended by driver
+      glGetIntegerv(GL_MAX_TEXTURE_SIZE, @size);
+      if size < 1 then size := 64;
+    end
+    else
+    begin
+      // selected by user
+      if IsPOT(r_GL_MaxTexSize) then
+        size := r_GL_MaxTexSize
+      else
+        size := NextPOT(r_GL_MaxTexSize);
+    end;
     result := size;
   end;
 
   procedure r_Textures_Initialize;
   begin
     maxTileSize := r_Textures_GetMaxHardwareSize();
+    e_LogWritefln('TEXTURE SIZE: %s', [maxTileSize]);
   end;
 
   procedure r_Textures_Finalize;
@@ -383,10 +414,10 @@ implementation
       begin
         glDeleteTextures(1, @atl[i].id);
         atl[i].id := 0;
-        atl[i].Free;
+        r_Common_FreeAndNil(atl[i]);
       end;
-      atl := nil;
     end;
+    SetLength(atl, 0);
   end;
 
   function r_Textures_FixImageData (var img: TImageData): Boolean;
@@ -458,7 +489,7 @@ implementation
     end
   end;
 
-  function r_Textures_LoadMultiFromImageAndInfo (var img: TImageData; w, h, c: Integer; b: Boolean): TGLMultiTexture;
+  function r_Textures_LoadMultiFromImageAndInfo (var img: TImageData; w, h, c: Integer): TGLMultiTexture;
     var t: TImageData; a: array of TGLTexture; i: Integer; m: TGLMultiTexture;
   begin
     ASSERT(w >= 0);
@@ -477,12 +508,11 @@ implementation
     end;
     m := TGLMultiTexture.Create();
     m.mTexture := a;
-    m.mBackanim := b;
     ASSERT(m.mTexture <> nil);
     result := m;
   end;
 
-  function r_Textures_LoadMultiFromDataAndInfo (data: Pointer; size: LongInt; w, h, c: Integer; b: Boolean): TGLMultiTexture;
+  function r_Textures_LoadMultiFromDataAndInfo (data: Pointer; size: LongInt; w, h, c: Integer): TGLMultiTexture;
     var img: TImageData;
   begin
     ASSERT(w > 0);
@@ -495,7 +525,7 @@ implementation
       try
         if LoadImageFromMemory(data, size, img) then
           if r_Textures_FixImageData(img) then
-            result := r_Textures_LoadMultiFromImageAndInfo(img, w, h, c, b)
+            result := r_Textures_LoadMultiFromImageAndInfo(img, w, h, c)
       except
       end;
       FreeImage(img);
@@ -540,7 +570,7 @@ implementation
           try
             if LoadImageFromMemory(data, size, img) then
               if r_Textures_FixImageData(img) then
-                result := r_Textures_LoadMultiFromImageAndInfo(img, txt.w, txt.h, txt.anim.frames, txt.anim.back);
+                result := r_Textures_LoadMultiFromImageAndInfo(img, txt.w, txt.h, txt.anim.frames);
           finally
             FreeMem(data);
           end;
@@ -564,7 +594,6 @@ implementation
         m := TGLMultiTexture.Create();
         SetLength(m.mTexture, 1);
         m.mTexture[0] := t;
-        m.mBackanim := false;
         txt.name := '';
         txt.w := m.width;
         txt.h := m.height;
@@ -610,7 +639,7 @@ implementation
     result := r_Textures_LoadMultiTextFromFile(filename, txt, log);
   end;
 
-  function r_Textures_LoadMultiFromFileAndInfo (const filename: AnsiString; w, h, count: Integer; backanim: Boolean; log: Boolean = True): TGLMultiTexture;
+  function r_Textures_LoadMultiFromFileAndInfo (const filename: AnsiString; w, h, count: Integer; log: Boolean = True): TGLMultiTexture;
     var wad: TWADFile; wadName, resName: AnsiString; data: Pointer; size: Integer;
   begin
     ASSERT(w > 0);
@@ -624,7 +653,7 @@ implementation
       resName := g_ExtractFilePathName(filename);
       if wad.GetResource(resName, data, size, log) then
       begin
-        result := r_Textures_LoadMultiFromDataAndInfo(data, size, w, h, count, backanim);
+        result := r_Textures_LoadMultiFromDataAndInfo(data, size, w, h, count);
         FreeMem(data);
       end;
       wad.Free
@@ -771,26 +800,28 @@ implementation
 
   (* --------- TGLFont --------- *)
 
-  function r_Textures_LoadFontFromFile (const filename: AnsiString; constref f: TFontInfo; skipch: Integer; log: Boolean = true): TGLFont;
-    var i: Integer; st: TGLTextureArray; font: TGLFont; t: TGLTexture;
+  function r_Textures_LoadFontFromFile (const filename: AnsiString; constref f: TFontInfo; font2enc: TConvProc; log: Boolean = true): TGLFont;
+    var i, ch: Integer; st, stch: TGLTextureArray; font: TGLFont;
   begin
-    ASSERT(skipch >= 0);
     result := nil;
     SetLength(st, 256);
     if r_Textures_LoadStreamFromFile(filename, f.w, f.h, 256, 16, st, nil, log) then
     begin
-      if skipch > 0 then
+      font := TGLFont.Create();
+      font.info := f;
+      font.ch := st;
+      if Assigned(font2enc) then
       begin
+        SetLength(stch, 256);
         for i := 0 to 255 do
         begin
-          t := st[i];
-          st[i] := st[(i + skipch) mod 256];
-          st[(i + skipch) mod 256] := t;
+          ch := font2enc(i);
+          ASSERT((ch >= 0) and (ch <= 255));
+          stch[ch] := st[i];
         end;
+        font.ch := stch;
+        SetLength(st, 0);
       end;
-      font := TGLFont.Create();
-      font.info := f;
-      font.ch := st;
       result := font;
     end;
   end;
@@ -835,4 +866,7 @@ implementation
     result := self.info.kern;
   end;
 
+initialization
+  conRegVar('r_gl_maxtexsize', @r_GL_MaxTexSize, '', '');
+  r_GL_MaxTexSize := 0; // default is automatic value
 end.