* refactoring nearly completed; now testing
authorBergmann89 <bergmann89@muo-game.de>
Mon, 28 Oct 2013 18:37:43 +0000 (19:37 +0100)
committerBergmann89 <bergmann89@muo-game.de>
Mon, 28 Oct 2013 18:37:43 +0000 (19:37 +0100)
glBitmap.pas

index 04f4a9f..12e84af 100644 (file)
@@ -168,9 +168,9 @@ History
 - function MoveMemory replaced with function Move (little speed change)
 - several calculations stored in variables (little speed change)
 29-09-2003
-- property BuildMipsMaps added (default = True)
+- property BuildMipsMaps added (default = true)
   if BuildMipMaps isn't set GenTextures uses glTexImage[12]D else it use gluBuild[12]dMipmaps
-- property FreeDataAfterGenTexture added (default = True)
+- property FreeDataAfterGenTexture added (default = true)
   if FreeDataAfterGenTexture is set the texturedata were deleted after the texture was generated.
 - parameter DisableOtherTextureUnits of Bind removed
 - parameter FreeDataAfterGeneration of GenTextures removed
@@ -600,6 +600,7 @@ type
     AlphaRange: Cardinal;
     AlphaShift: Shortint;
   end;
+  PglBitmapPixelDesc = ^TglBitmapPixelDesc;
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
   TglBitmapPixelData = packed record
@@ -628,12 +629,12 @@ type
 ////////////////////////////////////////////////////////////////////////////////////////////////////
   TglBitmap = class;
   TglBitmapFunctionRec = record
-    Sender : TglBitmap;
-    Size: TglBitmapPixelPosition;
+    Sender:   TglBitmap;
+    Size:     TglBitmapPixelPosition;
     Position: TglBitmapPixelPosition;
-    Source: TglBitmapPixelData;
-    Dest: TglBitmapPixelData;
-    CustomData: Pointer;
+    Source:   TglBitmapPixelData;
+    Dest:     TglBitmapPixelData;
+    Args:     PtrInt;
   end;
   TglBitmapFunction = procedure(var FuncRec: TglBitmapFunctionRec);
 
@@ -659,51 +660,63 @@ type
 
   TglBitmapFormat = (
     tfEmpty = 0,
-    TODO
-    tfAlpha4,
-    tfAlpha8,
-    tfAlpha12,
-    tfAlpha16,
+    //TODO
+    //tfAlpha4,
+    //tfAlpha8,
+    //tfAlpha12,
+    //tfAlpha16,
 
-    tfLuminance4, }
+    //tfLuminance4,
     tfLuminance8,
-{    tfLuminance12,
-    tfLuminance16,
-
-    tfuminance4Alpha4,
-    tfLuminance6Alpha2,}
+    //tfLuminance12,
+    //tfLuminance16,
+    //
+    //tfuminance4Alpha4,
+    //tfLuminance6Alpha2,
     tfLuminance8Alpha8,
-{    tfLuminance12Alpha4,
-    tfLuminance12Alpha12,
-    tfLuminance16Alpha16,
+    //tfLuminance12Alpha4,
+    //tfLuminance12Alpha12,
+    //tfLuminance16Alpha16,
 
-    tfR3G3B2,
-    tfRGB4,
-    tfRGB5, }
+    //tfR3G3B2,
+    //tfRGB4,
+    tfRGB5,
     tfRGB8,
-{    tfRGB10,
-    tfRGB12,
-    tfRGB16,
+    //tfRGB10,
+    //tfRGB12,
+    //tfRGB16,
 
-    tfRGBA2,
-    tfRGBA4,
-    tfRGB5A1, }
+    //tfRGBA2,
+    //tfRGBA4,
+    tfRGB5A1,
     tfRGBA8,
-{    tfRGB10A2,
-    tfRGBA12,
-    tfRGBA16,
-    }
+    //tfRGB10A2,
+    //tfRGBA12,
+    //tfRGBA16,
+
+    //tfBGR4,
+    //tfBGR5,
     tfBGR8,
-    tfBGRA8,
-    {
-    tfDepth16,
-    tfDepth24,
-    tfDepth32 }
+    //tfBGR10,
+    //tfBGR12,
+    //tfBGR16,
+
+    //tfBGRA2,
+    //tfBGRA4,
+    //tfBGR5A1,
+    tfBGRA8
+    //tfBGR10A2,
+    //tfBGRA12,
+    //tfBGRA16,
+
+    //tfDepth16,
+    //tfDepth24,
+    //tfDepth32
   );
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
-  TglBitmapGetPixel  = procedure(const Pos: TglBitmapPixelPosition; var   Pixel: TglBitmapPixelData) of object;
-  TglBitmapSetPixel  = procedure(const Pos: TglBitmapPixelPosition; const Pixel: TglBitmapPixelData) of object;
+  TglBitmapGetPixel  = procedure(const aPos: TglBitmapPixelPosition; var   aPixel: TglBitmapPixelData) of object;
+  TglBitmapSetPixel  = procedure(const aPos: TglBitmapPixelPosition; const aPixel: TglBitmapPixelData) of object;
 
   TglBitmapMapFunc   = procedure(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte);
   TglBitmapUnMapFunc = procedure(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData);
@@ -716,13 +729,17 @@ type
     class function GetPixelDesc:  TglBitmapPixelDesc;  virtual; abstract;
     class function GetFormatDesc: TglBitmapFormatDesc; virtual; abstract;
 
-    class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte); virtual; abstract;
-    class procedure Unmap(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData); virtual; abstract;
+    class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); virtual; abstract;
+    class procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); virtual; abstract;
 
     //virtual
     class function WithoutAlpha: TglBitmapFormat; virtual;
     class function WithAlpha:    TglBitmapFormat; virtual;
 
+    class function GetSize: Single; virtual; overload;
+    class function GetSize(const aSize: TglBitmapPixelPosition): Integer; virtual; overload;
+    class function GetColorCompCount: Integer; virtual;
+
     class function IsEmpty:  Boolean; virtual;
     class function HasAlpha: Boolean; virtual;
     class function MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: UInt64): Boolean; virtual;
@@ -739,11 +756,11 @@ type
   end;
   TglBitmapFormatDescClass = class of TglBitmapFormatDescriptor;
 
-  // Base Class
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   TglBitmap = class
   protected
-    fID: Cardinal;
-    fTarget: Cardinal;
+    fID: GLuint;
+    fTarget: GLuint;
     fAnisotropic: Integer;
     fDeleteTextureOnFree: Boolean;
     fFreeDataAfterGenTexture: Boolean;
@@ -758,8 +775,8 @@ type
     // Mapping
     fPixelSize: Integer;
     fRowSize: Integer;
-    fUnmapFunc: TglBitmapUnMapFunc;
-    fMapFunc: TglBitmapMapFunc;
+    //TODO delete? fUnmapFunc: TglBitmapUnMapFunc;
+    //TODO delete? fMapFunc: TglBitmapMapFunc;
 
     // Filtering
     fFilterMin: Cardinal;
@@ -770,8 +787,8 @@ type
     fWrapT: Cardinal;
     fWrapR: Cardinal;
 
-    fGetPixelFunc: TglBitmapGetPixel;
-    fSetPixelFunc: TglBitmapSetPixel;
+    //TODO delete? fGetPixelFunc: TglBitmapGetPixel;
+    //TODO delete? fSetPixelFunc: TglBitmapSetPixel;
 
     // CustomData
     fFilename: String;
@@ -780,8 +797,11 @@ type
     fCustomData: Pointer;
 
     //Getter
-    function GetHeight: Integer; virtual;
     function GetWidth:  Integer; virtual;
+    function GetHeight: Integer; virtual;
+
+    function GetFileWidth:  Integer; virtual;
+    function GetFileHeight: Integer; virtual;
 
     //Setter
     procedure SetCustomData(const aValue: Pointer);
@@ -795,41 +815,22 @@ type
     procedure SetTarget(const aValue: Cardinal);
     procedure SetAnisotropic(const aValue: Integer);
 
-    //Load
-    {$IFDEF GLB_SUPPORT_PNG_READ}
-    function LoadPNG(Stream: TStream): Boolean; virtual;
-    {$ENDIF}
-    {$IFDEF GLB_SUPPORT_JPEG_READ}
-    function LoadJPEG(Stream: TStream): Boolean; virtual;
-    {$ENDIF}
-    function LoadDDS(Stream: TStream): Boolean; virtual;
-    function LoadTGA(Stream: TStream): Boolean; virtual;
-    function LoadBMP(Stream: TStream): Boolean; virtual;
-
-    //Save
-    {$IFDEF GLB_SUPPORT_PNG_WRITE}
-    procedure SavePNG(Stream: TStream); virtual;
-    {$ENDIF}
-    {$IFDEF GLB_SUPPORT_JPEG_WRITE}
-    procedure SaveJPEG(Stream: TStream); virtual;
-    {$ENDIF}
-    procedure SaveDDS(Stream: TStream); virtual;
-    procedure SaveTGA(Stream: TStream); virtual;
-    procedure SaveBMP(Stream: TStream); virtual;
-
     procedure CreateID;
     procedure SetupParameters(var aBuildWithGlu: Boolean);
-    procedure SelectFormat(const aFormat: TglBitmapFormat; var glFormat, glInternalFormat, glType: Cardinal);
-
-    procedure SetDataPointer(NewData: pByte; Format: TglBitmapFormat; Width: Integer = -1; Height: Integer = -1); virtual;
-    procedure GenTexture(TestTextureSize: Boolean = True); virtual; abstract;
+    procedure SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
+      const aWidth: Integer = -1; const aHeight: Integer = -1); virtual;
+    procedure GenTexture(const aTestTextureSize: Boolean = true); virtual; abstract;
 
     function FlipHorz: Boolean; virtual;
     function FlipVert: Boolean; virtual;
 
     property Width:  Integer read GetWidth;
     property Height: Integer read GetHeight;
+
+    property FileWidth:  Integer read GetFileWidth;
+    property FileHeight: Integer read GetFileHeight;
   public
+    //Properties
     property ID:           Cardinal        read fID          write SetID;
     property Target:       Cardinal        read fTarget      write SetTarget;
     property Format:       TglBitmapFormat read fFormat      write SetFormat;
@@ -844,29 +845,33 @@ type
     property DeleteTextureOnFree:     Boolean read fDeleteTextureOnFree     write SetDeleteTextureOnFree;
     property FreeDataAfterGenTexture: Boolean read fFreeDataAfterGenTexture write SetFreeDataAfterGenTexture;
 
-    property Dimension:      TglBitmapPixelPosition  read fDimension;
-    property Data:           PByte                   read fData;
-    property IsResident:     Boolean                 read fIsResident;
+    property Dimension:  TglBitmapPixelPosition  read fDimension;
+    property Data:       PByte                   read fData;
+    property IsResident: Boolean                 read fIsResident;
 
     procedure AfterConstruction; override;
     procedure BeforeDestruction; override;
 
-    //Loading
-    procedure LoadFromFile(const aFileName: String);
+    //Load
+    procedure LoadFromFile(const aFilename: String);
     procedure LoadFromStream(const aStream: TStream); virtual;
     procedure LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
       const aFormat: TglBitmapFormat; const aArgs: PtrInt = 0);
     {$IFDEF GLB_DELPHI}
-    procedure LoadFromResource(const aInstance: Cardinal; aResource: String; const aResType: PChar = nil);
-    procedure LoadFromResourceID(const sInstance: Cardinal; aResourceID: Integer; const aResType: PChar);
+    procedure LoadFromResource(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil);
+    procedure LoadFromResourceID(const sInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
     {$ENDIF}
 
+    //Save
     procedure SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
     procedure SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType); virtual;
 
-    //function AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; Format: TglBitmapFormat; CustomData: Pointer = nil): boolean; overload;
-    //function AddFunc(const aFunc: TglBitmapFunction; CreateTemp: Boolean; CustomData: Pointer = nil): boolean; overload;
-(* TODO
+    //Convert
+    function AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: PtrInt = 0): Boolean; overload;
+    function AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
+      const aFormat: TglBitmapFormat; const aArgs: PtrInt = 0): Boolean; overload;
+  public
+    //Alpha & Co
     {$IFDEF GLB_SDL}
     function AssignToSurface(out aSurface: PSDL_Surface): Boolean;
     function AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
@@ -881,19 +886,17 @@ type
     function AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
     function AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction = nil;
       const aArgs: PtrInt = 0): Boolean;
-    {$ENDIF}
-
-    function AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: PtrInt = 0): Boolean; virtual;
-    function AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
-    function AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
-    function AddAlphaFromGlBitmap(const aBitmap: TglBitmap; const aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
-    {$IFDEF GLB_DELPHI}
     function AddAlphaFromResource(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil;
       const aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
     function AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
       const aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
     {$ENDIF}
 
+    function AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: PtrInt = 0): Boolean; virtual;
+    function AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
+    function AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
+    function AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
+
     function AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte = 0): Boolean;
     function AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal = 0): Boolean;
     function AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single = 0): Boolean;
@@ -903,71 +906,96 @@ type
     function AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
 
     function RemoveAlpha: Boolean; virtual;
+  public
+    //Common
     function Clone: TglBitmap;
-    function ConvertTo(const aFormat: TglBitmapFormat; const aInternalFormat: TglBitmapFormat): Boolean; virtual;
-    procedure SetBorderColor(Red, Green, Blue, Alpha: Single);
-    procedure Invert(const aUseRGB: Boolean = true; aUseAlpha: Boolean = false);
+    function ConvertTo(const aFormat: TglBitmapFormat): Boolean; virtual;
+    procedure Invert(const aUseRGB: Boolean = true; const aUseAlpha: Boolean = false);
+    procedure SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
     procedure FreeData;
 
-    procedure FillWithColor(const aRed, aGreen, aBlue: aByte; Alpha: Byte = 255);
+    //ColorFill
+    procedure FillWithColor(const aRed, aGreen, aBlue: Byte; const aAlpha: Byte = 255);
     procedure FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal = $FFFFFFFF);
     procedure FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha : Single = 1);
-*)
+
+    //TexParameters
     procedure SetFilter(const aMin, aMag: Cardinal);
     procedure SetWrap(
       const S: Cardinal = GL_CLAMP_TO_EDGE;
       const T: Cardinal = GL_CLAMP_TO_EDGE;
       const R: Cardinal = GL_CLAMP_TO_EDGE);
 
-    procedure GetPixel(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);   virtual;
-    procedure SetPixel(const Pos: TglBitmapPixelPosition; const Pixel: TglBitmapPixelData); virtual;
+    procedure GetPixel(const aPos: TglBitmapPixelPosition; var aPixel: TglBitmapPixelData);   virtual;
+    procedure SetPixel(const aPos: TglBitmapPixelPosition; const aPixel: TglBitmapPixelData); virtual;
 
-    procedure Unbind(DisableTextureUnit: Boolean = True); virtual;
-    procedure Bind(EnableTextureUnit: Boolean = True); virtual;
+    procedure Bind(const aEnableTextureUnit: Boolean = true); virtual;
+    procedure Unbind(const aDisableTextureUnit: Boolean = true); virtual;
 
+    //Constructors
     constructor Create; overload;
-    constructor Create(FileName: String); overload;
-    constructor Create(Stream: TStream); overload;
+    constructor Create(const aFileName: String); overload;
+    constructor Create(const aStream: TStream); overload;
+    constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat); overload;
+    constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: PtrInt = 0); overload;
     {$IFDEF GLB_DELPHI}
-    constructor CreateFromResourceName(Instance: Cardinal; Resource: String; ResType: PChar = nil);
-    constructor Create(Instance: Cardinal; Resource: String; ResType: PChar = nil); overload;
-    constructor Create(Instance: Cardinal; ResourceID: Integer; ResType: PChar); overload;
+    constructor Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil); overload;
+    constructor Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar); overload;
     {$ENDIF}
-    constructor Create(Size: TglBitmapPixelPosition; Format: TglBitmapFormat); overload;
-    constructor Create(Size: TglBitmapPixelPosition; Format: TglBitmapFormat; Func: TglBitmapFunction; CustomData: Pointer = nil); overload;
-  end;
+  private
+    {$IFDEF GLB_SUPPORT_PNG_READ}
+    function LoadPNG(const aStream: TStream): Boolean; virtual;
+    procedure SavePNG(const aStream: TStream); virtual;
+    {$ENDIF}
+    {$IFDEF GLB_SUPPORT_JPEG_READ}
+    function LoadJPEG(const aStream: TStream): Boolean; virtual;
+    procedure SaveJPEG(const aStream: TStream); virtual;
+    {$ENDIF}
+    function LoadBMP(const aStream: TStream): Boolean; virtual;
+    procedure SaveBMP(const aStream: TStream); virtual;
 
+    function LoadTGA(const aStream: TStream): Boolean; virtual;
+    procedure SaveTGA(const aStream: TStream); virtual;
 
+    function LoadDDS(const aStream: TStream): Boolean; virtual;
+    procedure SaveDDS(const aStream: TStream); virtual;
+  end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   TglBitmap2D = class(TglBitmap)
   protected
     // Bildeinstellungen
     fLines: array of PByte;
 
+    (* TODO
     procedure GetDXTColorBlock(pData: pByte; relX, relY: Integer; var Pixel: TglBitmapPixelData);
     procedure GetPixel2DDXT1(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
     procedure GetPixel2DDXT3(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
     procedure GetPixel2DDXT5(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
     procedure GetPixel2DUnmap(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
-    function GetScanline(Index: Integer): Pointer;
-
     procedure SetPixel2DUnmap(const Pos: TglBitmapPixelPosition; const Pixel: TglBitmapPixelData);
+    *)
 
-    procedure SetDataPointer(Data: pByte; Format: TglBitmapFormat; Width: Integer = -1; Height: Integer = -1); override;
-    procedure UploadData (Target, Format, InternalFormat, Typ: Cardinal; BuildWithGlu: Boolean);
+    function GetScanline(const aIndex: Integer): Pointer;
+    procedure SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
+      const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
+    procedure UploadData(const aTarget: Cardinal; const aBuildWithGlu: Boolean);
   public
     property Width;
     property Height;
-    property Scanline[Index: Integer]: Pointer read GetScanline;
+    property Scanline[const aIndex: Integer]: Pointer read GetScanline;
 
     procedure AfterConstruction; override;
 
     procedure GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
     procedure GetDataFromTexture;
-    procedure ToNormalMap(const aFunc: TglBitmapNormalMapFunc = nm3x3; const aScale: Single = 2; const aUseAlpha: Boolean = False);
-    procedure GenTexture(TestTextureSize: Boolean = True); override;
+    procedure GenTexture(const aTestTextureSize: Boolean = true); override;
 
     function FlipHorz: Boolean; override;
     function FlipVert: Boolean; override;
+
+    procedure ToNormalMap(const aFunc: TglBitmapNormalMapFunc = nm3x3;
+      const aScale: Single = 2; const aUseAlpha: Boolean = false);
   end;
 
 (* TODO
@@ -976,14 +1004,14 @@ type
     fGenMode: Integer;
 
     // Hide GenTexture
-    procedure GenTexture(TestTextureSize: Boolean = True); reintroduce;
+    procedure GenTexture(TestTextureSize: Boolean = true); reintroduce;
   public
     procedure AfterConstruction; override;
 
     procedure GenerateCubeMap(CubeTarget: Cardinal; TestTextureSize: Boolean = true);
 
-    procedure Unbind(DisableTexCoordsGen: Boolean = true; DisableTextureUnit: Boolean = True); reintroduce; virtual;
-    procedure Bind(EnableTexCoordsGen: Boolean = true; EnableTextureUnit: Boolean = True); reintroduce; virtual;
+    procedure Unbind(DisableTexCoordsGen: Boolean = true; DisableTextureUnit: Boolean = true); reintroduce; virtual;
+    procedure Bind(EnableTexCoordsGen: Boolean = true; EnableTextureUnit: Boolean = true); reintroduce; virtual;
   end;
 
 
@@ -1011,7 +1039,7 @@ type
     function FlipHorz: Boolean; override;
 
     // Generation
-    procedure GenTexture(TestTextureSize: Boolean = True); override;
+    procedure GenTexture(TestTextureSize: Boolean = true); override;
   end;
 *)
 
@@ -1037,9 +1065,6 @@ procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
 
 function glBitmapPosition(X: Integer = -1; Y: Integer = -1): TglBitmapPixelPosition;
 
-// Formatfunctions
-function FormatGetSize(const aFormat: TglBitmapFormat): Single;
-
 var
   glBitmapDefaultDeleteTextureOnFree: Boolean;
   glBitmapDefaultFreeDataAfterGenTextures: Boolean;
@@ -1062,14 +1087,69 @@ uses
 
 type
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+  TBitfieldFormat = class(TObject)
+  private
+    fRedShift: ShortInt;
+    fGreenShift: ShortInt;
+    fBlueShift: ShortInt;
+    fAlphaShift: ShortInt;
+
+    fRedRange: Cardinal;
+    fGreenRange: Cardinal;
+    fBlueRange: Cardinal;
+    fAlphaRange: Cardinal;
+
+    fRedMask: UInt64;
+    fGreenMask: UInt64;
+    fBlueMask: UInt64;
+    fAlphaMask: UInt64;
+    function GetSize: Integer;
+    procedure SetAlphaMask(aValue: UInt64);
+    procedure SetAlphaRange(aValue: Cardinal);
+    procedure SetAlphaShift(aValue: ShortInt);
+    procedure SetBlueMask(aValue: UInt64);
+    procedure SetBlueRange(aValue: Cardinal);
+    procedure SetBlueShift(aValue: ShortInt);
+    procedure SetGreenMask(aValue: UInt64);
+    procedure SetGreenRange(aValue: Cardinal);
+    procedure SetGreenShift(aValue: ShortInt);
+    procedure SetRedMask(aValue: UInt64);
+    procedure SetRedRange(aValue: Cardinal);
+    procedure SetRedShift(aValue: ShortInt);
+
+    procedure CalcShiftAndRange(aMask: UInt64; out aRange: Cardinal; out aShift: ShortInt);
+  public
+    property RedShift:   ShortInt read fRedShift   write SetRedShift;
+    property GreenShift: ShortInt read fGreenShift write SetGreenShift;
+    property BlueShift:  ShortInt read fBlueShift  write SetBlueShift;
+    property AlphaShift: ShortInt read fAlphaShift write SetAlphaShift;
+
+    property RedRange:   Cardinal read fRedRange   write SetRedRange;
+    property GreenRange: Cardinal read fGreenRange write SetGreenRange;
+    property BlueRange:  Cardinal read fBlueRange  write SetBlueRange;
+    property AlphaRange: Cardinal read fAlphaRange write SetAlphaRange;
+
+    property RedMask:   UInt64 read fRedMask   write SetRedMask;
+    property GreenMask: UInt64 read fGreenMask write SetGreenMask;
+    property BlueMask:  UInt64 read fBlueMask  write SetBlueMask;
+    property AlphaMask: UInt64 read fAlphaMask write SetAlphaMask;
+
+    property Size: Integer read GetSize;
+
+    procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte);
+    procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); overload;
+    procedure Unmap(const aData: UInt64; var aPixel: TglBitmapPixelData); overload;
+  end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   TfdEmpty = class(TglBitmapFormatDescriptor)
   public
     class function GetFormat: TglBitmapFormat; override;
     class function GetPixelDesc: TglBitmapPixelDesc; override;
     class function GetFormatDesc: TglBitmapFormatDesc; override;
 
-    class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte); override;
-    class procedure Unmap(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData); override;
+    class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); override;
+    class procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); override;
   end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1080,8 +1160,8 @@ type
     class function GetFormatDesc: TglBitmapFormatDesc; override;
     class function WithAlpha: TglBitmapFormat; override;
 
-    class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte); override;
-    class procedure Unmap(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData); override;
+    class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); override;
+    class procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); override;
   end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1092,11 +1172,23 @@ type
       class function GetFormatDesc: TglBitmapFormatDesc; override;
       class function WithoutAlpha: TglBitmapFormat; override;
 
-      class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte); override;
-      class procedure Unmap(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData); override;
+      class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); override;
+      class procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); override;
     end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+  TfdRGB5 = class(TglBitmapFormatDescriptor)
+  public
+    class function GetFormat: TglBitmapFormat; override;
+    class function GetPixelDesc: TglBitmapPixelDesc; override;
+    class function GetFormatDesc: TglBitmapFormatDesc; override;
+    class function WithAlpha: TglBitmapFormat; override;
+
+    class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); override;
+    class procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); override;
+  end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   TfdRGB8 = class(TglBitmapFormatDescriptor)
   public
     class function GetFormat: TglBitmapFormat; override;
@@ -1104,8 +1196,20 @@ type
     class function GetFormatDesc: TglBitmapFormatDesc; override;
     class function WithAlpha: TglBitmapFormat; override;
 
-    class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte); override;
-    class procedure Unmap(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData); override;
+    class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); override;
+    class procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); override;
+  end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+  TfdRGB5A1 = class(TglBitmapFormatDescriptor)
+  public
+    class function GetFormat: TglBitmapFormat; override;
+    class function GetPixelDesc: TglBitmapPixelDesc; override;
+    class function GetFormatDesc: TglBitmapFormatDesc; override;
+    class function WithoutAlpha: TglBitmapFormat; override;
+
+    class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); override;
+    class procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); override;
   end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1116,8 +1220,8 @@ type
     class function GetFormatDesc: TglBitmapFormatDesc; override;
     class function WithoutAlpha: TglBitmapFormat; override;
 
-    class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte); override;
-    class procedure Unmap(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData); override;
+    class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); override;
+    class procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); override;
   end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1128,8 +1232,8 @@ type
     class function GetFormatDesc: TglBitmapFormatDesc; override;
     class function WithAlpha: TglBitmapFormat; override;
 
-    class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte); override;
-    class procedure Unmap(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData); override;
+    class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); override;
+    class procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); override;
   end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1140,46 +1244,59 @@ type
     class function GetFormatDesc: TglBitmapFormatDesc; override;
     class function WithoutAlpha: TglBitmapFormat; override;
 
-    class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte); override;
-    class procedure Unmap(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData); override;
+    class procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte); override;
+    class procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData); override;
   end;
 
 const
   LUMINANCE_WEIGHT_R = 0.30;
   LUMINANCE_WEIGHT_G = 0.59;
   LUMINANCE_WEIGHT_B = 0.11;
-  UNSUPPORTED_INTERNAL_FORMAT = 'the given format isn''t supported by this function.';
+
+  ALPHA_WEIGHT_R = 0.30;
+  ALPHA_WEIGHT_G = 0.59;
+  ALPHA_WEIGHT_B = 0.11;
+
+  UNSUPPORTED_FORMAT = 'the given format isn''t supported by this function.';
+
+  FORMAT_DESCRIPTORS: array[TglBitmapFormat] of TglBitmapFormatDescClass = (
+    TfdEmpty,
+
+    TfdLuminance8,
+    TfdLuminance8Alpha8,
+
+    TfdRGB5,
+    TfdRGB8,
+
+    TfdRGB5A1,
+    TfdRGBA8,
+
+    TfdBGR8,
+    TfdBGRA8
+  );
+
 
 {$REGION Private Helper}
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 function glBitmapPosition(X, Y: Integer): TglBitmapPixelPosition;
 begin
-  Result.Fields := [];
+  result.Fields := [];
 
   if X >= 0 then
-    Result.Fields := Result.Fields + [ffX];
+    result.Fields := result.Fields + [ffX];
   if Y >= 0 then
-    Result.Fields := Result.Fields + [ffY];
+    result.Fields := result.Fields + [ffY];
 
-  Result.X := Max(0, X);
-  Result.Y := Max(0, Y);
-end;
-
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-function FormatGetImageSize(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat): Integer;
-begin
-  if (aSize.X = 0) and (aSize.Y = 0) then
-    Result := 0
-  else
-    Result := Ceil(Max(aSize.Y, 1) * Max(aSize.X, 1) * FormatGetSize(aFormat));
+  result.X := Max(0, X);
+  result.Y := Max(0, Y);
 end;
 
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes;
 begin
-  //TODO check Formats!
-  result := [];
-
+  //TODO Supported File Formats!
+  result := [ftDDS, ftTGA, ftBMP];
+  (*
   {$IFDEF GLB_SUPPORT_PNG_WRITE}
   if aFormat in [
     tfAlpha4, tfAlpha8, tfAlpha12, tfAlpha16,
@@ -1211,6 +1328,7 @@ begin
     tfDepth16, tfDepth24, tfDepth32]
   then
     result := result + [ftDDS, ftTGA, ftBMP];
+  *)
 end;
 
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1222,7 +1340,17 @@ begin
 end;
 
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-function GetBitSize(aBitSet: Cardinal): Integer;
+function GetTopMostBit(aBitSet: UInt64): Integer;
+begin
+  result := 0;
+  while aBitSet > 0 do begin
+    inc(result);
+    aBitSet := aBitSet shr 1;
+  end;
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function CountSetBits(aBitSet: UInt64): Integer;
 begin
   result := 0;
   while aBitSet > 0 do begin
@@ -1233,6 +1361,8 @@ begin
 end;
 {$ENDREGION}
 
+//TODO check _ARB functions and constants
+
 (* GLB_NO_NATIVE_GL
 {$IFNDEF GLB_NO_NATIVE_GL}
 procedure ReadOpenGLExtensions;
@@ -1281,19 +1411,19 @@ var
     ExtPos: Integer;
   begin
     ExtPos := Pos(Extension, Buffer);
-    Result := ExtPos > 0;
+    result := ExtPos > 0;
 
-    if Result then
-      Result := ((ExtPos + Length(Extension) - 1) = Length(Buffer)) or not (Buffer[ExtPos + Length(Extension)] in ['_', 'A'..'Z', 'a'..'z']);
+    if result then
+      result := ((ExtPos + Length(Extension) - 1) = Length(Buffer)) or not (Buffer[ExtPos + Length(Extension)] in ['_', 'A'..'Z', 'a'..'z']);
   end;
 
 
   function glLoad (aFunc: pAnsiChar): pointer;
   begin
     {$IFDEF LINUX}
-      Result := glXGetProcAddress(aFunc);
+      result := glXGetProcAddress(aFunc);
     {$else}
-      Result := wglGetProcAddress(aFunc);
+      result := wglGetProcAddress(aFunc);
     {$ENDIF}
   end;
 
@@ -1310,29 +1440,29 @@ begin
     Buffer := glGetString(GL_VERSION);
     TrimVersionString(Buffer, MajorVersion, MinorVersion);
 
-    GL_VERSION_1_2 := False;
-    GL_VERSION_1_3 := False;
-    GL_VERSION_1_4 := False;
-    GL_VERSION_2_0 := False;
+    GL_VERSION_1_2 := false;
+    GL_VERSION_1_3 := false;
+    GL_VERSION_1_4 := false;
+    GL_VERSION_2_0 := false;
 
     if MajorVersion = 1 then begin
       if MinorVersion >= 1 then begin
         if MinorVersion >= 2 then
-          GL_VERSION_1_2 := True;
+          GL_VERSION_1_2 := true;
 
         if MinorVersion >= 3 then
-          GL_VERSION_1_3 := True;
+          GL_VERSION_1_3 := true;
 
         if MinorVersion >= 4 then
-          GL_VERSION_1_4 := True;
+          GL_VERSION_1_4 := true;
       end;
     end;
 
     if MajorVersion >= 2 then begin
-      GL_VERSION_1_2 := True;
-      GL_VERSION_1_3 := True;
-      GL_VERSION_1_4 := True;
-      GL_VERSION_2_0 := True;
+      GL_VERSION_1_2 := true;
+      GL_VERSION_1_3 := true;
+      GL_VERSION_1_4 := true;
+      GL_VERSION_2_0 := true;
     end;
 
     // Extensions
@@ -1403,7 +1533,7 @@ begin
     {$R+}
   {$ENDIF}
 
-  Result := CreatePalette(Pal^);
+  result := CreatePalette(Pal^);
 
   FreeMem(Pal);
 end;
@@ -1414,36 +1544,36 @@ end;
 {$IFDEF GLB_SDL_IMAGE}
 function glBitmapRWseek(context: PSDL_RWops; offset: Integer; whence: Integer): Integer; cdecl;
 begin
-  Result := TStream(context^.unknown.data1).Seek(offset, whence);
+  result := TStream(context^.unknown.data1).Seek(offset, whence);
 end;
 
 function glBitmapRWread(context: PSDL_RWops; Ptr: Pointer; size: Integer; maxnum : Integer): Integer; cdecl;
 begin
-  Result := TStream(context^.unknown.data1).Read(Ptr^, size * maxnum);
+  result := TStream(context^.unknown.data1).Read(Ptr^, size * maxnum);
 end;
 
 function glBitmapRWwrite(context: PSDL_RWops; Ptr: Pointer; size: Integer; num: Integer): Integer; cdecl;
 begin
-  Result := TStream(context^.unknown.data1).Write(Ptr^, size * num);
+  result := TStream(context^.unknown.data1).Write(Ptr^, size * num);
 end;
 
 function glBitmapRWclose(context: PSDL_RWops): Integer; cdecl;
 begin
-  Result := 0;
+  result := 0;
 end;
 
 function glBitmapCreateRWops(Stream: TStream): PSDL_RWops;
 begin
-  Result := SDL_AllocRW;
+  result := SDL_AllocRW;
 
-  if Result = nil then
+  if result = nil then
     raise EglBitmapException.Create('glBitmapCreateRWops - SDL_AllocRW failed.');
 
-  Result^.seek := glBitmapRWseek;
-  Result^.read := glBitmapRWread;
-  Result^.write := glBitmapRWwrite;
-  Result^.close := glBitmapRWclose;
-  Result^.unknown.data1 := Stream;
+  result^.seek := glBitmapRWseek;
+  result^.read := glBitmapRWread;
+  result^.write := glBitmapRWwrite;
+  result^.close := glBitmapRWclose;
+  result^.unknown.data1 := Stream;
 end;
 {$ENDIF}
 *)
@@ -1453,7 +1583,7 @@ function LoadTexture(Filename: String; var Texture: Cardinal{$IFDEF GLB_DELPHI};
 var
   glBitmap: TglBitmap2D;
 begin
-  Result := false;
+  result := false;
   Texture := 0;
 
   {$IFDEF GLB_DELPHI}
@@ -1467,12 +1597,12 @@ begin
     glBitmap := TglBitmap2D.Create(FileName);
 
   try
-    glBitmap.DeleteTextureOnFree := False;
-    glBitmap.FreeDataAfterGenTexture := False;
-    glBitmap.GenTexture(True);
+    glBitmap.DeleteTextureOnFree := false;
+    glBitmap.FreeDataAfterGenTexture := false;
+    glBitmap.GenTexture(true);
     if (glBitmap.ID > 0) then begin
       Texture := glBitmap.ID;
-      Result := True;
+      result := true;
     end;
   finally
     glBitmap.Free;
@@ -1492,7 +1622,7 @@ begin
 
   CM := TglBitmapCubeMap.Create;
   try
-    CM.DeleteTextureOnFree := False;
+    CM.DeleteTextureOnFree := false;
 
     // Maps
     {$IFDEF GLB_DELPHI}
@@ -1544,7 +1674,7 @@ begin
     CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
 
     Texture := CM.ID;
-    Result := True;
+    result := true;
   finally
     CM.Free;
   end;
@@ -1558,11 +1688,11 @@ begin
 
   NM := TglBitmapNormalMap.Create;
   try
-    NM.DeleteTextureOnFree := False;
+    NM.DeleteTextureOnFree := false;
     NM.GenerateNormalMap(Size);
 
     Texture := NM.ID;
-    Result := True;
+    result := true;
   finally
     NM.Free;
   end;
@@ -1649,6 +1779,188 @@ begin
 end;
 {$ENDREGION}
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TCustomFormat///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.SetAlphaMask(aValue: UInt64);
+begin
+  if fAlphaMask = aValue then Exit;
+  fAlphaMask := aValue;
+  CalcShiftAndRange(fAlphaMask, fAlphaRange, fAlphaShift);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TBitfieldFormat.GetSize: Integer;
+var
+  tmp: UInt64;
+begin
+  tmp :=
+    (fRedRange   shl fRedShift)   or
+    (fGreenRange shl fGreenShift) or
+    (fBlueRange  shl fBlueShift)  or
+    (fAlphaRange shl fAlphaShift);
+  result := Trunc(GetTopMostBit(tmp) / 8);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.SetAlphaRange(aValue: Cardinal);
+begin
+  if fAlphaRange = aValue then Exit;
+  fAlphaRange := aValue;
+  fAlphaMask := fAlphaRange shl fAlphaShift;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.SetAlphaShift(aValue: ShortInt);
+begin
+  if fAlphaShift = aValue then Exit;
+  fAlphaShift := aValue;
+  fAlphaMask := fAlphaRange shl fAlphaShift;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.SetBlueMask(aValue: UInt64);
+begin
+  if fBlueMask = aValue then Exit;
+  fBlueMask := aValue;
+  CalcShiftAndRange(fBlueMask, fBlueRange, fBlueShift);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.SetBlueRange(aValue: Cardinal);
+begin
+  if fBlueRange = aValue then Exit;
+  fBlueRange := aValue;
+  fBlueMask := fBlueRange shl fBlueShift;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.SetBlueShift(aValue: ShortInt);
+begin
+  if fBlueShift = aValue then Exit;
+  fBlueShift := aValue;
+  fBlueMask := fBlueRange shl fBlueShift;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.SetGreenMask(aValue: UInt64);
+begin
+  if fGreenMask = aValue then Exit;
+  fGreenMask := aValue;
+  CalcShiftAndRange(fGreenMask, fGreenRange, fGreenShift);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.SetGreenRange(aValue: Cardinal);
+begin
+  if fGreenRange = aValue then Exit;
+  fGreenRange := aValue;
+  fGreenMask := fGreenRange shl fGreenShift;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.SetGreenShift(aValue: ShortInt);
+begin
+  if fGreenShift = aValue then Exit;
+  fGreenShift := aValue;
+  fGreenMask := fGreenRange shl fGreenShift;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.SetRedMask(aValue: UInt64);
+begin
+  if fRedMask = aValue then Exit;
+  fRedMask := aValue;
+  CalcShiftAndRange(fRedMask, fRedRange, fRedShift);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.SetRedRange(aValue: Cardinal);
+begin
+  if fRedRange = aValue then Exit;
+  fRedRange := aValue;
+  fRedMask := fRedRange shl fRedShift;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.SetRedShift(aValue: ShortInt);
+begin
+  if fRedShift = aValue then Exit;
+  fRedShift := aValue;
+  fRedMask := fRedRange shl fRedShift;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.CalcShiftAndRange(aMask: UInt64; out aRange: Cardinal;
+  out aShift: ShortInt);
+begin
+  aShift := 0;
+  aRange := 0;
+  if (aMask = 0) then
+    exit;
+  while (aMask > 0) and ((aMask and 1) = 0) do begin
+    inc(aShift);
+    aMask := aMask shr 1;
+  end;
+  aRange := 1;
+  while (aMask > 0) do begin
+    aRange := aRange shl 1;
+    aMask  := aMask  shr 1;
+  end;
+  dec(aRange);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte);
+var
+  data: UInt64;
+  s: Integer;
+type
+  PUInt64 = ^UInt64;
+begin
+  data :=
+    ((aPixel.Red   and fRedRange)   shl fRedShift)  or
+    ((aPixel.Green and fGreenRange) shl fGreenShift) or
+    ((aPixel.Blue  and fBlueRange)  shl fBlueShift)  or
+    ((aPixel.Alpha and fAlphaRange) shl fAlphaShift);
+  s := Size;
+  case s of
+    1:           aData^  := data;
+    2:     PWord(aData)^ := data;
+    4: PCardinal(aData)^ := data;
+    8:   PUInt64(aData)^ := data;
+  end;
+  inc(aData, s);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData);
+var
+  data: UInt64;
+  s: Integer;
+type
+  PUInt64 = ^UInt64;
+begin
+  s := Size;
+  case s of
+    1: data :=           aData^;
+    2: data :=     PWord(aData)^;
+    4: data := PCardinal(aData)^;
+    8: data :=   PUInt64(aData)^;
+  end;
+  Unmap(data, aPixel);
+  inc(aData, s);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TBitfieldFormat.Unmap(const aData: UInt64; var aPixel: TglBitmapPixelData);
+begin
+  aPixel.Red   := (aData shr fRedShift)   and fRedRange;
+  aPixel.Green := (aData shr fGreenShift) and fGreenRange;
+  aPixel.Blue  := (aData shr fBlueShift)  and fBlueRange;
+  aPixel.Alpha := (aData shr fAlphaShift) and fAlphaRange;
+end;
+
 {$REGION TglBitmapFormatDescriptor}
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //TglBitmapFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1671,6 +1983,50 @@ begin
 end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+class function TglBitmapFormatDescriptor.GetSize: Single;
+var
+  tmp: UInt64;
+begin
+  with GetPixelDesc do begin
+    tmp :=
+      (RedRange   shl RedShift)   or
+      (GreenRange shl GreenShift) or
+      (BlueRange  shl BlueShift)  or
+      (AlphaRange shl AlphaShift);
+  end;
+  result := Trunc(GetTopMostBit(tmp) / 4) / 2;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+class function TglBitmapFormatDescriptor.GetSize(const aSize: TglBitmapPixelPosition): Integer;
+var
+  w, h: Integer;
+begin
+  if (ffX in aSize.Fields) or (ffY in aSize.Fields) then begin
+    w := Max(1, aSize.X);
+    h := Max(1, aSize.Y);
+    result := Ceil(w * h * GetSize);
+  end else
+    result := 0;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+class function TglBitmapFormatDescriptor.GetColorCompCount: Integer;
+begin
+  result := 0;
+  with GetPixelDesc do begin
+    if (RedRange > 0) then
+      inc(result);
+    if (GreenRange > 0) then
+      inc(result);
+    if (BlueRange > 0) then
+      inc(result);
+    if (AlphaRange > 0) then
+      inc(result);
+  end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 class function TglBitmapFormatDescriptor.IsEmpty: Boolean;
 begin
   result := (GetFormat = tfEmpty);
@@ -1687,7 +2043,7 @@ class function TglBitmapFormatDescriptor.MaskMatch(const aRedMask, aGreenMask, a
 var
   PixelDesc: TglBitmapPixelDesc;
 begin
-  result := False;
+  result := false;
 
   if (aRedMask = 0) and (aGreenMask = 0) and (aBlueMask = 0) and (aAlphaMask = 0) then
     raise EglBitmapException.Create('FormatCheckFormat - All Masks are 0');
@@ -1703,14 +2059,15 @@ begin
     if (aAlphaMask <> 0) and (aAlphaMask <> (AlphaRange shl AlphaShift)) then
       exit;
   end;
-  result := True;
+  result := true;
 end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 class procedure TglBitmapFormatDescriptor.PreparePixel(var aPixel: TglBitmapPixelData);
 begin
   FillChar(aPixel, SizeOf(aPixel), 0);
-  with GetPixelDesc do begin
+  aPixel.PixelDesc := GetPixelDesc;
+  with aPixel.PixelDesc do begin
     aPixel.Red   := RedRange;
     aPixel.Green := GreenRange;
     aPixel.Blue  := BlueRange;
@@ -1747,12 +2104,12 @@ begin
   end;
 end;
 
-class procedure TfdEmpty.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte);
+class procedure TfdEmpty.Map(const aPixel: TglBitmapPixelData; var aData: PByte  );
 begin
   raise EglBitmapException.Create('format does not support mapping');
 end;
 
-class procedure TfdEmpty.Unmap(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData);
+class procedure TfdEmpty.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData);
 begin
   raise EglBitmapException.Create('format does not support unmapping');
 end;
@@ -1791,7 +2148,7 @@ begin
   result := tfLuminance8Alpha8;
 end;
 
-class procedure TfdLuminance8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte);
+class procedure TfdLuminance8.Map(const aPixel: TglBitmapPixelData; var aData: PByte);
 begin
   aData^ := Trunc(
     aPixel.Red   * LUMINANCE_WEIGHT_R +
@@ -1800,7 +2157,7 @@ begin
   inc(aData);
 end;
 
-class procedure TfdLuminance8.Unmap(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData);
+class procedure TfdLuminance8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData);
 begin
   aPixel.Red   := aData^;
   aPixel.Green := aData^;
@@ -1843,7 +2200,7 @@ begin
   result := tfLuminance8;
 end;
 
-class procedure TfdLuminance8Alpha8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte);
+class procedure TfdLuminance8Alpha8.Map(const aPixel: TglBitmapPixelData; var aData: PByte);
 begin
   aData^ := Trunc(
     aPixel.Red   * LUMINANCE_WEIGHT_R +
@@ -1855,7 +2212,7 @@ begin
   inc(aData);
 end;
 
-class procedure TfdLuminance8Alpha8.Unmap(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData);
+class procedure TfdLuminance8Alpha8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData);
 begin
   aPixel.Red   := aData^;
   aPixel.Green := aData^;
@@ -1867,6 +2224,56 @@ begin
 end;
 {$ENDREGION}
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TfdRGB5/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+class function TfdRGB5.GetFormat: TglBitmapFormat;
+begin
+  result := tfRGB5;
+end;
+
+class function TfdRGB5.GetPixelDesc: TglBitmapPixelDesc;
+begin
+  with result do begin
+    RedRange   := $0000001F; RedShift   := 0;
+    GreenRange := $0000001F; GreenShift := 5;
+    BlueRange  := $0000001F; BlueShift  := 10;
+    AlphaRange := $00000000; AlphaShift := 0;
+  end;
+end;
+
+class function TfdRGB5.GetFormatDesc: TglBitmapFormatDesc;
+begin
+  with result do begin
+    Format         := GL_RGB;
+    InternalFormat := GL_RGB5;
+    DataType       := GL_UNSIGNED_SHORT_5_5_5_1;
+  end;
+end;
+
+class function TfdRGB5.WithAlpha: TglBitmapFormat;
+begin
+  result := tfRGB5A1;
+end;
+
+class procedure TfdRGB5.Map(const aPixel: TglBitmapPixelData; var aData: PByte);
+begin
+  PWord(aData)^ :=
+    ((aPixel.Red   and aPixel.PixelDesc.RedRange)   shl aPixel.PixelDesc.RedShift)   or
+    ((aPixel.Green and aPixel.PixelDesc.GreenRange) shl aPixel.PixelDesc.GreenShift) or
+    ((aPixel.Blue  and aPixel.PixelDesc.BlueRange)  shl aPixel.PixelDesc.BlueShift);
+  inc(aData, 2);
+end;
+
+class procedure TfdRGB5.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData);
+begin
+  aPixel.Red   := (PWord(aData)^ shr aPixel.PixelDesc.RedShift)   and aPixel.PixelDesc.RedRange;
+  aPixel.Green := (PWord(aData)^ shr aPixel.PixelDesc.GreenShift) and aPixel.PixelDesc.GreenRange;
+  aPixel.Blue  := (PWord(aData)^ shr aPixel.PixelDesc.BlueShift)  and aPixel.PixelDesc.BlueRange;
+  aPixel.Alpha := 0;
+  inc(aData, 2);
+end;
+
 {$REGION TfdRGB8}
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //TfdRGB8/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1900,7 +2307,7 @@ begin
   result := tfRGBA8;
 end;
 
-class procedure TfdRGB8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte);
+class procedure TfdRGB8.Map(const aPixel: TglBitmapPixelData; var aData: PByte);
 begin
   aData^ := aPixel.Red;
   inc(aData);
@@ -1910,7 +2317,7 @@ begin
   inc(aData);
 end;
 
-class procedure TfdRGB8.Unmap(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData);
+class procedure TfdRGB8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData);
 begin
   aPixel.Red := aData^;
   inc(aData);
@@ -1922,52 +2329,103 @@ begin
 end;
 {$ENDREGION}
 
-{$REGION TfdRGBA8}
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//TfdRGBA8////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TfdRGB5A1///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-class function TfdRGBA8.GetFormat: TglBitmapFormat;
+class function TfdRGB5A1.GetFormat: TglBitmapFormat;
 begin
-  result := tfRGBA8;
+  result := tfRGB5A1;
 end;
 
-class function TfdRGBA8.GetPixelDesc: TglBitmapPixelDesc;
+class function TfdRGB5A1.GetPixelDesc: TglBitmapPixelDesc;
 begin
   with result do begin
-    RedRange   := $000000FF; RedShift   := 0;
-    GreenRange := $000000FF; GreenShift := 8;
-    BlueRange  := $000000FF; BlueShift  := 16;
-    AlphaRange := $000000FF; AlphaShift := 24;
+    RedRange   := $0000001F; RedShift   := 0;
+    GreenRange := $0000001F; GreenShift := 5;
+    BlueRange  := $0000001F; BlueShift  := 10;
+    AlphaRange := $00000001; AlphaShift := 15;
   end;
 end;
 
-class function TfdRGBA8.GetFormatDesc: TglBitmapFormatDesc;
+class function TfdRGB5A1.GetFormatDesc: TglBitmapFormatDesc;
 begin
   with result do begin
-    Format         := GL_RGB;
-    InternalFormat := GL_RGB8;
-    DataType       := GL_UNSIGNED_BYTE;
+    Format         := GL_RGBA;
+    InternalFormat := GL_RGB5_A1;
+    DataType       := GL_UNSIGNED_SHORT_5_5_5_1;
   end;
 end;
 
-class function TfdRGBA8.WithoutAlpha: TglBitmapFormat;
+class function TfdRGB5A1.WithoutAlpha: TglBitmapFormat;
 begin
-  result := tfRGB8;
+  //TODO result := tfRGB5;
 end;
 
-class procedure TfdRGBA8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte);
+class procedure TfdRGB5A1.Map(const aPixel: TglBitmapPixelData; var aData: PByte);
 begin
-  aData^ := aPixel.Red;
-  inc(aData);
-  aData^ := aPixel.Green;
-  inc(aData);
-  aData^ := aPixel.Blue;
+  PWord(aData)^ :=
+    ((aPixel.Red   and aPixel.PixelDesc.RedRange)   shl aPixel.PixelDesc.RedShift)   or
+    ((aPixel.Green and aPixel.PixelDesc.GreenRange) shl aPixel.PixelDesc.GreenShift) or
+    ((aPixel.Blue  and aPixel.PixelDesc.BlueRange)  shl aPixel.PixelDesc.BlueShift)  or
+    ((aPixel.Alpha and aPixel.PixelDesc.AlphaRange) shl aPixel.PixelDesc.AlphaShift);
+  inc(aData, 2);
+end;
+
+class procedure TfdRGB5A1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData);
+begin
+  aPixel.Red   := (PWord(aData)^ shr aPixel.PixelDesc.RedShift)   and aPixel.PixelDesc.RedRange;
+  aPixel.Green := (PWord(aData)^ shr aPixel.PixelDesc.GreenShift) and aPixel.PixelDesc.GreenRange;
+  aPixel.Blue  := (PWord(aData)^ shr aPixel.PixelDesc.BlueShift)  and aPixel.PixelDesc.BlueRange;
+  aPixel.Alpha := (PWord(aData)^ shr aPixel.PixelDesc.AlphaShift) and aPixel.PixelDesc.AlphaRange;
+  inc(aData, 2);
+end;
+
+{$REGION TfdRGBA8}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TfdRGBA8////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+class function TfdRGBA8.GetFormat: TglBitmapFormat;
+begin
+  result := tfRGBA8;
+end;
+
+class function TfdRGBA8.GetPixelDesc: TglBitmapPixelDesc;
+begin
+  with result do begin
+    RedRange   := $000000FF; RedShift   := 0;
+    GreenRange := $000000FF; GreenShift := 8;
+    BlueRange  := $000000FF; BlueShift  := 16;
+    AlphaRange := $000000FF; AlphaShift := 24;
+  end;
+end;
+
+class function TfdRGBA8.GetFormatDesc: TglBitmapFormatDesc;
+begin
+  with result do begin
+    Format         := GL_RGB;
+    InternalFormat := GL_RGB8;
+    DataType       := GL_UNSIGNED_BYTE;
+  end;
+end;
+
+class function TfdRGBA8.WithoutAlpha: TglBitmapFormat;
+begin
+  result := tfRGB8;
+end;
+
+class procedure TfdRGBA8.Map(const aPixel: TglBitmapPixelData; var aData: PByte);
+begin
+  aData^ := aPixel.Red;
+  inc(aData);
+  aData^ := aPixel.Green;
+  inc(aData);
+  aData^ := aPixel.Blue;
   inc(aData);
   aData^ := aPixel.Alpha;
   inc(aData);
 end;
 
-class procedure TfdRGBA8.Unmap(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData);
+class procedure TfdRGBA8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData);
 begin
   aPixel.Red := aData^;
   inc(aData);
@@ -2013,7 +2471,7 @@ begin
   result := tfBGRA8;
 end;
 
-class procedure TfdBGR8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte);
+class procedure TfdBGR8.Map(const aPixel: TglBitmapPixelData; var aData: PByte);
 begin
   aData^ := aPixel.Blue;
   inc(aData);
@@ -2023,7 +2481,7 @@ begin
   inc(aData);
 end;
 
-class procedure TfdBGR8.Unmap(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData);
+class procedure TfdBGR8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData);
 begin
   aPixel.Blue := aData^;
   inc(aData);
@@ -2067,7 +2525,7 @@ begin
   result := tfBGR8;
 end;
 
-class procedure TfdBGRA8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aBitOffset: Byte);
+class procedure TfdBGRA8.Map(const aPixel: TglBitmapPixelData; var aData: PByte);
 begin
   aData^ := aPixel.Blue;
   inc(aData);
@@ -2079,7 +2537,7 @@ begin
   inc(aData);
 end;
 
-class procedure TfdBGRA8.Unmap(var aData: PByte; var aBitOffset: Byte; var aPixel: TglBitmapPixelData);
+class procedure TfdBGRA8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData);
 begin
   aPixel.Blue := aData^;
   inc(aData);
@@ -2092,19 +2550,163 @@ begin
 end;
 {$ENDREGION}
 
-{$REGION TglBitmap }
+{$REGION TglBitmap}
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//TglBitmap///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TglBitmap - Helper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-function TglBitmap.GetHeight: Integer;
+procedure glBitmapConvertCopyFunc(var aFuncRec: TglBitmapFunctionRec);
 begin
-  if (ffY in fDimension.Fields) then
-    result := fDimension.Y
-  else
-    result := -1;
+  with aFuncRec do begin
+    if (Source.PixelDesc.RedRange   > 0) then
+      Dest.Red   := Source.Red;
+    if (Source.PixelDesc.GreenRange > 0) then
+      Dest.Green := Source.Green;
+    if (Source.PixelDesc.BlueRange  > 0) then
+      Dest.Blue  := Source.Blue;
+    if (Source.PixelDesc.AlphaRange > 0) then
+      Dest.Alpha := Source.Alpha;
+  end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure glBitmapConvertCalculateRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
+begin
+  with aFuncRec do begin
+    if (Source.PixelDesc.RedRange   > 0) then
+      Dest.Red   := Round(Dest.PixelDesc.RedRange   * Source.Red   / Source.PixelDesc.RedRange);
+    if (Source.PixelDesc.GreenRange > 0) then
+      Dest.Green := Round(Dest.PixelDesc.GreenRange * Source.Green / Source.PixelDesc.GreenRange);
+    if (Source.PixelDesc.BlueRange  > 0) then
+      Dest.Blue  := Round(Dest.PixelDesc.BlueRange  * Source.Blue  / Source.PixelDesc.BlueRange);
+    if (Source.PixelDesc.AlphaRange > 0) then
+      Dest.Alpha := Round(Dest.PixelDesc.AlphaRange * Source.Alpha / Source.PixelDesc.AlphaRange);
+  end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure glBitmapConvertShiftRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
+begin
+  with aFuncRec do
+    with PglBitmapPixelDesc(Args)^ do begin
+      if (Source.PixelDesc.RedRange   > 0) then
+        Dest.Red   := Source.Red   shr RedShift;
+      if (Source.PixelDesc.GreenRange > 0) then
+        Dest.Green := Source.Green shr GreenShift;
+      if (Source.PixelDesc.BlueRange  > 0) then
+        Dest.Blue  := Source.Blue  shr BlueShift;
+      if (Source.PixelDesc.AlphaRange > 0) then
+        Dest.Alpha := Source.Alpha shr AlphaShift;
+    end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure glBitmapInvertFunc(var aFuncRec: TglBitmapFunctionRec);
+begin
+  with aFuncRec do begin
+    Dest.Red   := Source.Red;
+    Dest.Green := Source.Green;
+    Dest.Blue  := Source.Blue;
+    Dest.Alpha := Source.Alpha;
+    if (Args and $1 > 0) then begin
+      Dest.Red   := Dest.Red   xor Dest.PixelDesc.RedRange;
+      Dest.Green := Dest.Green xor Dest.PixelDesc.GreenRange;
+      Dest.Blue  := Dest.Blue  xor Dest.PixelDesc.BlueRange;
+    end;
+    if (Args and $2 > 0) then begin
+      Dest.Alpha := Dest.Alpha xor Dest.PixelDesc.AlphaRange;
+    end;
+  end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure glBitmapFillWithColorFunc(var aFuncRec: TglBitmapFunctionRec);
+type
+  PglBitmapPixelData = ^TglBitmapPixelData;
+begin
+  with aFuncRec do begin
+    Dest.Red   := PglBitmapPixelData(Args)^.Red;
+    Dest.Green := PglBitmapPixelData(Args)^.Green;
+    Dest.Blue  := PglBitmapPixelData(Args)^.Blue;
+    Dest.Alpha := PglBitmapPixelData(Args)^.Alpha;
+  end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure glBitmapAlphaFunc(var FuncRec: TglBitmapFunctionRec);
+var
+  Temp: Single;
+begin
+  with FuncRec do begin
+    if (FuncRec.Args = 0) then begin //source has no alpha
+      Temp :=
+        Source.Red   / Source.PixelDesc.RedRange   * ALPHA_WEIGHT_R +
+        Source.Green / Source.PixelDesc.GreenRange * ALPHA_WEIGHT_G +
+        Source.Blue  / Source.PixelDesc.BlueRange  * ALPHA_WEIGHT_B;
+      Dest.Alpha := Round(Dest.PixelDesc.AlphaRange * Temp);
+    end else
+      Dest.Alpha := Round(Source.Alpha / Source.PixelDesc.AlphaRange * Dest.PixelDesc.AlphaRange);
+  end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure glBitmapColorKeyAlphaFunc(var FuncRec: TglBitmapFunctionRec);
+type
+  PglBitmapPixelData = ^TglBitmapPixelData;
+begin
+  with FuncRec do begin
+    Dest.Red   := Source.Red;
+    Dest.Green := Source.Green;
+    Dest.Blue  := Source.Blue;
+
+    with PglBitmapPixelData(Args)^ do
+      if ((Dest.Red   <= Red  ) and (Dest.Red   >= PixelDesc.RedRange  ) and
+          (Dest.Green <= Green) and (Dest.Green >= PixelDesc.GreenRange) and
+          (Dest.Blue  <= Blue ) and (Dest.Blue  >= PixelDesc.BlueRange )) then
+        Dest.Alpha := 0
+      else
+        Dest.Alpha := Dest.PixelDesc.AlphaRange;
+  end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure glBitmapValueAlphaFunc(var FuncRec: TglBitmapFunctionRec);
+type
+  PglBitmapPixelData = ^TglBitmapPixelData;
+begin
+  with FuncRec do begin
+    Dest.Red   := Source.Red;
+    Dest.Green := Source.Green;
+    Dest.Blue  := Source.Blue;
+    with PglBitmapPixelData(Args)^ do
+      Dest.Alpha := Alpha;
+  end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure SwapRGB(aData: PByte; aWidth: Integer; const aHasAlpha: Boolean);
+type
+  PRGBPix = ^TRGBPix;
+  TRGBPix = array [0..2] of byte;
+var
+  Temp: Byte;
+begin
+  while aWidth > 0 do begin
+    Temp := PRGBPix(aData)^[0];
+    PRGBPix(aData)^[0] := PRGBPix(aData)^[2];
+    PRGBPix(aData)^[2] := Temp;
+
+    if aHasAlpha then
+      Inc(aData, 4)
+    else
+      Inc(aData, 3);
+    dec(aWidth);
+  end;
 end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TglBitmap - PROTECTED///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+{$REGION Getter}
 function TglBitmap.GetWidth: Integer;
 begin
   if (ffX in fDimension.Fields) then
@@ -2113,6 +2715,28 @@ begin
     result := -1;
 end;
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.GetHeight: Integer;
+begin
+  if (ffY in fDimension.Fields) then
+    result := fDimension.Y
+  else
+    result := -1;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.GetFileWidth: Integer;
+begin
+  result := Max(1, Width);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.GetFileHeight: Integer;
+begin
+  result := Max(1, Height);
+end;
+{$ENDREGION}
+
 {$REGION Setter}
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 procedure TglBitmap.SetCustomData(const aValue: Pointer);
@@ -2151,7 +2775,9 @@ procedure TglBitmap.SetFormat(const aValue: TglBitmapFormat);
 begin
   if fFormat = aValue then
     exit;
-  fFormat := aValue;
+  if (FORMAT_DESCRIPTORS[Format].GetSize <> FORMAT_DESCRIPTORS[aValue].GetSize) then
+    raise EglBitmapUnsupportedFormatFormat.Create('SetInternalFormat - ' + UNSUPPORTED_FORMAT);
+  SetDataPointer(Data, aValue, Width, Height);
 end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -2191,11 +2817,11 @@ procedure TglBitmap.SetAnisotropic(const aValue: Integer);
 var
   MaxAnisotropic: Integer;
 begin
-  fAnisotropic := Value;
+  fAnisotropic := aValue;
   if (ID > 0) then begin
     if GL_EXT_texture_filter_anisotropic then begin
       if fAnisotropic > 0 then begin
-        Bind(False);
+        Bind(false);
         glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @MaxAnisotropic);
         if aValue > MaxAnisotropic then
           fAnisotropic := MaxAnisotropic;
@@ -2208,38 +2834,12 @@ begin
 end;
 {$ENDREGION}
 
-procedure TglBitmap.AfterConstruction;
-begin
-  inherited AfterConstruction;
-
-  fID         := 0;
-  fTarget     := 0;
-  fIsResident := False;
-
-  fFormat                  := glBitmapGetDefaultFormat;
-  fMipMap                  := glBitmapDefaultMipmap;
-  fFreeDataAfterGenTexture := glBitmapGetDefaultFreeDataAfterGenTexture;
-  fDeleteTextureOnFree     := glBitmapGetDefaultDeleteTextureOnFree;
-
-  glBitmapGetDefaultFilter     (fFilterMin, fFilterMag);
-  glBitmapGetDefaultTextureWrap(fWrapS, fWrapT, fWrapR);
-end;
-
-//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TglBitmap.BeforeDestruction;
-begin
-  SetDataPointer(nil, ifEmpty);
-  if (ID > 0) and fDeleteTextureOnFree then
-    glDeleteTextures(1, @ID);
-  inherited BeforeDestruction;
-end;
-
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 procedure TglBitmap.CreateID;
 begin
-  if ID <> 0 then
-    glDeleteTextures(1, @ID);
-  glGenTextures(1, @ID);
+  if (ID <> 0) then
+    glDeleteTextures(1, @fID);
+  glGenTextures(1, @fID);
   Bind(false);
 end;
 
@@ -2253,657 +2853,406 @@ begin
   SetBorderColor(fBorderColor[0], fBorderColor[1], fBorderColor[2], fBorderColor[3]);
 
   // Mip Maps Generation Mode
-  aBuildWithGlu := False;
+  aBuildWithGlu := false;
   if (MipMap = mmMipmap) then begin
     if (GL_VERSION_1_4 or GL_SGIS_generate_mipmap) then
       glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE)
     else
-      BuildWithGlu := True;
+      aBuildWithGlu := true;
   end else if (MipMap = mmMipmapGlu) then
-    BuildWithGlu := True;
+    aBuildWithGlu := true;
 end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TglBitmap.SelectFormat(const aFormat: TglBitmapFormat; var glFormat, glInternalFormat, glType: Cardinal);
+procedure TglBitmap.SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
+  const aWidth: Integer; const aHeight: Integer);
+var
+  s: Single;
+begin
+  if (Data <> aData) then begin
+    if (Assigned(Data)) then
+      FreeMem(Data);
+    fData := aData;
+  end;
 
-  procedure Check12;
-  begin
-    if not GL_VERSION_1_2 then
-      raise EglBitmapUnsupportedFormatFormat.Create('SelectFormat - You need at least OpenGL 1.2 to support these format.');
+  FillChar(fDimension, SizeOf(fDimension), 0);
+  if not Assigned(fData) then begin
+    fFormat    := tfEmpty;
+    fPixelSize := 0;
+    fRowSize   := 0;
+  end else begin
+    if aWidth <> -1 then begin
+      fDimension.Fields := fDimension.Fields + [ffX];
+      fDimension.X := aWidth;
+    end;
+
+    if aHeight <> -1 then begin
+      fDimension.Fields := fDimension.Fields + [ffY];
+      fDimension.Y := aHeight;
+    end;
+
+    s := FORMAT_DESCRIPTORS[aFormat].GetSize;
+    fFormat    := aFormat;
+    fPixelSize := Ceil(s);
+    fRowSize   := Ceil(s * aWidth);
   end;
+end;
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.FlipHorz: Boolean;
 begin
-  PIXEL_DESC_ALPHA12;
-  glType := GL_UNSIGNED_BYTE;
-  glInternalFormat := Cardinal(aFormat);
+  result := false;
+end;
 
-  case aFormat of
-    tfAlpha4, tfAlpha8, tfAlpha12, tfAlpha16:
-      glFormat := GL_ALPHA;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.FlipVert: Boolean;
+begin
+  result := false;
+end;
 
-    tfLuminance4, tfLuminance8, tfLuminance12, tfLuminance16:
-      glFormat := GL_LUMINANCE;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TglBitmap - PUBLIC//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.AfterConstruction;
+begin
+  inherited AfterConstruction;
 
-    tfuminance4Alpha4, tfLuminance6Alpha2, tfLuminance8Alpha8,
-    tfLuminance12Alpha4, tfLuminance12Alpha12, tfLuminance16Alpha16:
-      glFormat := GL_LUMINANCE_ALPHA;
+  fID         := 0;
+  fTarget     := 0;
+  fIsResident := false;
 
-    tfR3G3B2, tfRGB4, tfRGB5, tfRGB8, tfRGB10, tfRGB12, tfRGB16:
-      glFormat := GL_RGB;
+  fFormat                  := glBitmapGetDefaultFormat;
+  fMipMap                  := glBitmapDefaultMipmap;
+  fFreeDataAfterGenTexture := glBitmapGetDefaultFreeDataAfterGenTexture;
+  fDeleteTextureOnFree     := glBitmapGetDefaultDeleteTextureOnFree;
 
-    tfRGBA2, tfRGBA4, tfRGB5A1, tfRGBA8, tfRGB10A2, tfRGBA12, tfRGBA16:
-      glFormat := GL_RGBA;
+  glBitmapGetDefaultFilter     (fFilterMin, fFilterMag);
+  glBitmapGetDefaultTextureWrap(fWrapS, fWrapT, fWrapR);
+end;
 
-    tfDepth16, tfDepth24, tfDepth32:
-      glFormat := GL_DEPTH_COMPONENT;
-  else
-    glFormat := 0;
-  end;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.BeforeDestruction;
+begin
+  SetDataPointer(nil, tfEmpty);
+  if (fID > 0) and fDeleteTextureOnFree then
+    glDeleteTextures(1, @fID);
+  inherited BeforeDestruction;
+end;
 
-  case aFormat of
-    tfRGBA4:
-      glType := GL_UNSIGNED_SHORT_4_4_4_4;
-    tfRGB5A1:
-      glType := GL_UNSIGNED_SHORT_5_5_5_1;
-    tfRG
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.LoadFromFile(const aFilename: String);
+var
+  fs: TFileStream;
+begin
+  fFilename := aFilename;
+  fs := TFileStream.Create(fFilename, fmOpenRead);
+  try
+    fs.Position := 0;
+    LoadFromStream(fs);
+  finally
+    fs.Free;
   end;
+end;
 
-
-  // selecting Format
-  case DataFormat of
-    ifAlpha:
-      glFormat := GL_ALPHA;
-    ifLuminance:
-      glFormat := GL_LUMINANCE;
-    ifDepth8:
-      glFormat := GL_DEPTH_COMPONENT;
-    ifLuminanceAlpha:
-      glFormat := GL_LUMINANCE_ALPHA;
-    ifBGR8:
-      begin
-        if (GL_VERSION_1_2 or GL_EXT_bgra) then begin
-          glFormat := GL_BGR;
-        end else begin
-          if CanConvertImage then
-            ConvertTo(tfRGB8);
-          glFormat := GL_RGB;
-        end;
-      end;
-    ifBGRA8:
-      begin
-        if (GL_VERSION_1_2 or GL_EXT_bgra) then begin
-          glFormat := GL_BGRA;
-        end else begin
-          if CanConvertImage then
-            ConvertTo(tfRGBA8);
-          glFormat := GL_RGBA;
-        end;
-      end;
-    tfRGB8:
-      glFormat := GL_RGB;
-    tfRGBA8:
-      glFormat := GL_RGBA;
-    tfRGBA4:
-      begin
-        Check12;
-        glFormat := GL_BGRA;
-        glType := GL_UNSIGNED_SHORT_4_4_4_4_REV;
-      end;
-    tfRGB5A1:
-      begin
-        Check12;
-        glFormat := GL_BGRA;
-        glType := GL_UNSIGNED_SHORT_1_5_5_5_REV;
-      end;
-    tfRGB10A2:
-      begin
-        Check12;
-        glFormat := GL_BGRA;
-        glType := GL_UNSIGNED_INT_2_10_10_10_REV;
-      end;
-    ifR5G6B5:
-      begin
-        Check12;
-        glFormat := GL_RGB;
-        glType := GL_UNSIGNED_SHORT_5_6_5;
-      end;
-    else
-      glFormat := 0;
-  end;
-
-  // Selecting InternalFormat
-  case DataFormat of
-    ifDXT1, ifDXT3, ifDXT5:
-      begin
-        if GL_EXT_texture_compression_s3tc then begin
-          case DataFormat of
-            ifDXT1:
-              glInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
-            ifDXT3:
-              glInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
-            ifDXT5:
-              glInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
-          end;
-        end else begin
-          // Compression isn't supported so convert to RGBA
-          if CanConvertImage then
-            ConvertTo(tfRGBA8);
-          glFormat := GL_RGBA;
-          glInternalFormat := GL_RGBA8;
-        end;
-      end;
-    ifAlpha:
-      begin
-        case Format of
-          tf4BitsPerChanel:
-            glInternalFormat := GL_ALPHA4;
-          tf8BitsPerChanel:
-            glInternalFormat := GL_ALPHA8;
-          tfCompressed:
-            begin
-              if (GL_ARB_texture_compression or GL_VERSION_1_3) then
-                glInternalFormat := GL_COMPRESSED_ALPHA
-              else
-                glInternalFormat := GL_ALPHA;
-            end;
-          else
-            glInternalFormat := GL_ALPHA;
-        end;
-      end;
-    ifLuminance:
-      begin
-        case Format of
-          tf4BitsPerChanel:
-            glInternalFormat := GL_LUMINANCE4;
-          tf8BitsPerChanel:
-            glInternalFormat := GL_LUMINANCE8;
-          tfCompressed:
-            begin
-              if (GL_ARB_texture_compression or GL_VERSION_1_3) then
-                glInternalFormat := GL_COMPRESSED_LUMINANCE
-              else
-                glInternalFormat := GL_LUMINANCE;
-            end;
-          else
-            glInternalFormat := GL_LUMINANCE;
-        end;
-      end;
-    ifDepth8:
-      begin
-        glInternalFormat := GL_DEPTH_COMPONENT;
-      end;
-    ifLuminanceAlpha:
-      begin
-        case Format of
-          tf4BitsPerChanel:
-            glInternalFormat := GL_LUMINANCE4_ALPHA4;
-          tf8BitsPerChanel:
-            glInternalFormat := GL_LUMINANCE8_ALPHA8;
-          tfCompressed:
-            begin
-              if (GL_ARB_texture_compression or GL_VERSION_1_3) then
-                glInternalFormat := GL_COMPRESSED_LUMINANCE_ALPHA
-              else
-                glInternalFormat := GL_LUMINANCE_ALPHA;
-            end;
-          else
-            glInternalFormat := GL_LUMINANCE_ALPHA;
-        end;
-      end;
-    ifBGR8, tfRGB8:
-      begin
-        case Format of
-          tf4BitsPerChanel:
-            glInternalFormat := GL_RGB4;
-          tf8BitsPerChanel:
-            glInternalFormat := GL_RGB8;
-          tfCompressed:
-            begin
-              if (GL_ARB_texture_compression or GL_VERSION_1_3) then begin
-                glInternalFormat := GL_COMPRESSED_RGB
-              end else begin
-                if (GL_EXT_texture_compression_s3tc) then
-                  glInternalFormat := GL_COMPRESSED_RGB_S3TC_DXT1_EXT
-                else
-                  glInternalFormat := GL_RGB;
-              end;
-            end;
-          else
-            glInternalFormat := GL_RGB;
-        end;
-      end;
-    ifBGRA8, tfRGBA8, tfRGBA4, tfRGB5A1, tfRGB10A2, ifR5G6B5:
-      begin
-        case Format of
-          tf4BitsPerChanel:
-            glInternalFormat := GL_RGBA4;
-          tf8BitsPerChanel:
-            glInternalFormat := GL_RGBA8;
-          tfCompressed:
-            begin
-              if (GL_ARB_texture_compression or GL_VERSION_1_3) then begin
-                glInternalFormat := GL_COMPRESSED_RGBA
-              end else begin
-                if (GL_EXT_texture_compression_s3tc) then
-                  glInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
-                else
-                  glInternalFormat := GL_RGBA;
-              end;
-            end;
-          else
-            glInternalFormat := GL_RGBA;
-        end;
-      end;
-  end;
-end;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.LoadFromStream(const aStream: TStream);
+begin
+  {$IFDEF GLB_SUPPORT_PNG_READ}
+  if not LoadPNG(aStream) then
+  {$ENDIF}
+  {$IFDEF GLB_SUPPORT_JPEG_READ}
+  if not LoadJPEG(aStream) then
+  {$ENDIF}
+  if not LoadDDS(aStream) then
+  if not LoadTGA(aStream) then
+  if not LoadBMP(aStream) then
+    raise EglBitmapException.Create('LoadFromStream - Couldn''t load Stream. It''s possible to be an unknow Streamtype.');
+end;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-constructor TglBitmap.Create;
-begin
-  {$IFNDEF GLB_NO_NATIVE_GL}
-    ReadOpenGLExtensions;
-  {$ENDIF}
-
-  if (ClassType = TglBitmap) then
-    raise EglBitmapException.Create('Don''t create TglBitmap directly. Use one of the deviated classes (TglBitmap2D) instead.');
-
-  inherited Create;
-end;
-
-
-constructor TglBitmap.Create(FileName: String);
-begin
-  Create;
-  LoadFromFile(FileName);
-end;
-
-
-constructor TglBitmap.Create(Stream: TStream);
-begin
-  Create;
-  LoadFromStream(Stream);
-end;
-
-
-{$IFDEF GLB_DELPHI}
-constructor TglBitmap.CreateFromResourceName(Instance: Cardinal; Resource: String; ResType: PChar);
-begin
-  Create;
-  LoadFromResource(Instance, Resource, ResType);
-end;
-
-
-constructor TglBitmap.Create(Instance: Cardinal; Resource: String; ResType: PChar);
-begin
-  Create;
-  LoadFromResource(Instance, Resource, ResType);
-end;
-
-
-
-constructor TglBitmap.Create(Instance: Cardinal; ResourceID: Integer; ResType: PChar);
-begin
-  Create;
-  LoadFromResourceID(Instance, ResourceID, ResType);
-end;
-{$ENDIF}
-
-
-constructor TglBitmap.Create(Size: TglBitmapPixelPosition;
-  Format: TglBitmapFormat);
-var
-  Image: pByte;
-  ImageSize: Integer;
-begin
-  Create;
-
-  ImageSize := FormatGetImageSize(Size, Format);
-  GetMem(Image, ImageSize);
-  try
-    FillChar(Image^, ImageSize, #$FF);
-
-    SetDataPointer(Image, Format, Size.X, Size.Y);
-  except
-    FreeMem(Image);
-    raise;
-  end;
-end;
-
-
-constructor TglBitmap.Create(Size: TglBitmapPixelPosition;
-  Format: TglBitmapFormat; Func: TglBitmapFunction; CustomData: Pointer);
-begin
-  Create;
-  LoadFromFunc(Size, Func, Format, CustomData);
-end;
-
-
-function TglBitmap.Clone: TglBitmap;
+procedure TglBitmap.LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
+  const aFormat: TglBitmapFormat; const aArgs: PtrInt);
 var
-  Temp: TglBitmap;
-  TempPtr: pByte;
-  Size: Integer;
+  tmpData: PByte;
+  size: Integer;
 begin
-  Temp := ClassType.Create as TglBitmap;
+  size := FORMAT_DESCRIPTORS[aFormat].GetSize(aSize);
+  GetMem(tmpData, size);
   try
-    // copy texture data if assigned
-    if Assigned(Data) then begin
-      Size := FormatGetImageSize(glBitmapPosition(Width, Height), InternalFormat);
-
-      GetMem(TempPtr, Size);
-      try
-        Move(Data^, TempPtr^, Size);
-        Temp.SetDataPointer(TempPtr, InternalFormat, Width, Height);
-      except
-        FreeMem(TempPtr);
-        raise;
-      end;
-    end else
-      Temp.SetDataPointer(nil, InternalFormat, Width, Height);
-
-       // copy properties
-    Temp.fID := ID;
-    Temp.fTarget := Target;
-    Temp.fFormat := Format;
-    Temp.fMipMap := MipMap;
-    Temp.fAnisotropic := Anisotropic;
-    Temp.fBorderColor := fBorderColor;
-    Temp.fDeleteTextureOnFree := DeleteTextureOnFree;
-    Temp.fFreeDataAfterGenTexture := FreeDataAfterGenTexture;
-    Temp.fFilterMin := fFilterMin;
-    Temp.fFilterMag := fFilterMag;
-    Temp.fWrapS := fWrapS;
-    Temp.fWrapT := fWrapT;
-    Temp.fWrapR := fWrapR;
-    Temp.fFilename := fFilename;
-    Temp.fCustomName := fCustomName;
-    Temp.fCustomNameW := fCustomNameW;
-    Temp.fCustomDataPointer := fCustomDataPointer;
-
-    Result := Temp;
+    FillChar(tmpData^, size, #$FF);
+    SetDataPointer(tmpData, aFormat, aSize.X, aSize.Y);
   except
-    FreeAndNil(Temp);
+    FreeMem(tmpData);
     raise;
   end;
+  AddFunc(Self, aFunc, false, Format, aArgs);
 end;
 
-
-procedure TglBitmap.LoadFromFile(const aFileName: String);
-var
-  FS: TFileStream;
-begin
-  fFilename := FileName;
-
-  FS := TFileStream.Create(FileName, fmOpenRead);
-  try
-    FS.Position := 0;
-    
-    LoadFromStream(FS);
-  finally
-    FS.Free;
-  end;
-end;
-
-
-procedure TglBitmap.LoadFromStream(const aStream: TStream);
-begin
-  {$IFDEF GLB_SUPPORT_PNG_READ}
-  if not LoadPNG(Stream) then
-  {$ENDIF}
-  {$IFDEF GLB_SUPPORT_JPEG_READ}
-  if not LoadJPEG(Stream) then
-  {$ENDIF}
-  if not LoadDDS(Stream) then
-  if not LoadTGA(Stream) then
-  if not LoadBMP(Stream) then
-    raise EglBitmapException.Create('LoadFromStream - Couldn''t load Stream. It''s possible to be an unknow Streamtype.');
-end;
-
-
 {$IFDEF GLB_DELPHI}
-procedure TglBitmap.LoadFromResource(Instance: Cardinal; Resource: String; ResType: PChar);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.LoadFromResource(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil);
 var
-  RS: TResourceStream;
+  rs: TResourceStream;
   TempPos: Integer;
   ResTypeStr: String;
   TempResType: PChar;
 begin
-  if Assigned(ResType) then
+  if not Assigned(ResType) then begin
+    TempPos     := Pos('.', Resource);
+    ResTypeStr  := UpperCase(Copy(Resource, TempPos + 1, Length(Resource) - TempPos));
+    Resource    := UpperCase(Copy(Resource, 0, TempPos -1));
+    TempResType := PChar(ResTypeStr);
+  end else
     TempResType := ResType
-  else
-    begin
-      TempPos := Pos('.', Resource);
-      ResTypeStr := UpperCase(Copy(Resource, TempPos + 1, Length(Resource) - TempPos));
-      Resource   := UpperCase(Copy(Resource, 0, TempPos -1));
-      TempResType := PChar(ResTypeStr);
-    end;
 
-  RS := TResourceStream.Create(Instance, Resource, TempResType);
+  rs := TResourceStream.Create(Instance, Resource, TempResType);
   try
-    LoadFromStream(RS);
+    LoadFromStream(rs);
   finally
-    RS.Free;
+    rs.Free;
   end;
 end;
 
-
-procedure TglBitmap.LoadFromResourceID(Instance: Cardinal; ResourceID: Integer; ResType: PChar);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.LoadFromResourceID(const sInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
 var
-  RS: TResourceStream;
+  rs: TResourceStream;
 begin
-  RS := TResourceStream.CreateFromID(Instance, ResourceID, ResType);
+  rs := TResourceStream.CreateFromID(Instance, ResourceID, ResType);
   try
-    LoadFromStream(RS);
+    LoadFromStream(rs);
   finally
-    RS.Free;
+    rs.Free;
   end;
 end;
 {$ENDIF}
 
-
-
-procedure TglBitmap.LoadFromFunc(const aSize: TglBitmapPixelPosition;
-  const aFunc: TglBitmapFunction; const aFormat: TglBitmapFormat;
-  const aArgs: PtrInt);
-var
-  Image: pByte;
-  ImageSize: Integer;
-begin
-  ImageSize := FormatGetImageSize(Size, Format);
-  GetMem(Image, ImageSize);
-  try
-    FillChar(Image^, ImageSize, #$FF);
-
-    SetDataPointer(Image, Format, Size.X, Size.Y);
-  except
-    FreeMem(Image);
-    raise;
-  end;
-
-  AddFunc(Self, Func, False, Format, CustomData)
-end;
-
-
-procedure TglBitmap.SaveToFile(const aFileName: String;
-  const aFileType: TglBitmapFileType);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
 var
-  FS: TFileStream;
+  fs: TFileStream;
 begin
-  FS := TFileStream.Create(FileName, fmCreate);
+  fs := TFileStream.Create(aFileName, fmCreate);
   try
-    FS.Position := 0;
-    SaveToStream(FS, FileType);
+    fs.Position := 0;
+    SaveToStream(fs, aFileType);
   finally
-    FS.Free;
+    fs.Free;
   end;
 end;
 
-
-procedure TglBitmap.SaveToStream(const aStream: TStream;
-  const aFileType: TglBitmapFileType);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType);
 begin
-  case FileType of
+  case aFileType of
     {$IFDEF GLB_SUPPORT_PNG_WRITE}
-    ftPNG:  SavePng(Stream);
+    ftPNG:  SavePng(aStream);
     {$ENDIF}
     {$IFDEF GLB_SUPPORT_JPEG_WRITE}
-    ftJPEG: SaveJPEG(Stream);
+    ftJPEG: SaveJPEG(aStream);
     {$ENDIF}
-    ftDDS:  SaveDDS(Stream);
-    ftTGA:  SaveTGA(Stream);
-    ftBMP:  SaveBMP(Stream);
+    ftDDS:  SaveDDS(aStream);
+    ftTGA:  SaveTGA(aStream);
+    ftBMP:  SaveBMP(aStream);
   end;
 end;
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: PtrInt): Boolean;
+begin
+  result := AddFunc(Self, aFunc, aCreateTemp, Format, aArgs);
+end;
 
-{$IFDEF GLB_SDL}
-function TglBitmap.AssignToSurface(out Surface: PSDL_Surface): boolean;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
+  const aFormat: TglBitmapFormat; const aArgs: PtrInt): Boolean;
 var
-  Row, RowSize: Integer;
-  pSource, pData: PByte;
-  TempDepth: Integer;
-  Pix: TglBitmapPixelData;
-
-  function GetRowPointer(Row: Integer): pByte;
-  begin
-    Result := Surface.pixels;
-    Inc(Result, Row * RowSize);
-  end;
+  DestData, TmpData, SourceData: pByte;
+  TempHeight, TempWidth: Integer;
+  SourceFD, DestFD: TglBitmapFormatDescClass;
 
+  FuncRec: TglBitmapFunctionRec;
 begin
-  Result := False;
-
-  if not FormatIsUncompressed(InternalFormat) then 
-    raise EglBitmapUnsupportedInternalFormat.Create('AssignToSurface - ' + UNSUPPORTED_INTERNAL_FORMAT);
-
-  if Assigned(Data) then begin
-    case Trunc(FormatGetSize(InternalFormat)) of
-      1: TempDepth :=  8;
-      2: TempDepth := 16;
-      3: TempDepth := 24;
-      4: TempDepth := 32;
-      else
-        raise EglBitmapException.Create('AssignToSurface - ' + UNSUPPORTED_INTERNAL_FORMAT);
-    end;
-
-    FormatPreparePixel(Pix, InternalFormat);
+  Assert(Assigned(Data));
+  Assert(Assigned(aSource));
+  Assert(Assigned(aSource.Data));
 
-    with Pix.PixelDesc do
-      Surface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, TempDepth, RedRange shl RedShift, GreenRange shl GreenShift, BlueRange shl BlueShift, AlphaRange shl AlphaShift);
+  result := false;
+  if Assigned(aSource.Data) and ((aSource.Height > 0) or (aSource.Width > 0)) then begin
+    SourceFD := FORMAT_DESCRIPTORS[aSource.Format];
+    DestFD   := FORMAT_DESCRIPTORS[aFormat];
 
-    pSource := Data;
-    RowSize := Trunc(FileWidth * FormatGetSize(InternalFormat));
+    // inkompatible Formats so CreateTemp
+    if (SourceFD.GetSize <> DestFD.GetSize) then
+      aCreateTemp := true;
 
-    for Row := 0 to FileHeight -1 do begin
-      pData := GetRowPointer(Row);
+    // Values
+    TempHeight := Max(1, aSource.Height);
+    TempWidth  := Max(1, aSource.Width);
 
-      if Assigned(pData) then begin
-        Move(pSource^, pData^, RowSize);
-        Inc(pSource, RowSize);
-      end;
-    end;
+    FuncRec.Sender := Self;
+    FuncRec.Args   := aArgs;
 
-    Result := True;
-  end;
-end;
+    TmpData := nil;
+    if aCreateTemp then begin
+      GetMem(TmpData, Ceil(FORMAT_DESCRIPTORS[aFormat].GetSize * TempHeight * TempWidth));
+      DestData := TmpData;
+    end else
+      DestData := Data;
 
+    try
+      SourceFD.PreparePixel(FuncRec.Source);
+      DestFD.PreparePixel  (FuncRec.Dest);
 
-function TglBitmap.AssignFromSurface(const Surface: PSDL_Surface): boolean;
-var
-  pSource, pData, pTempData: PByte;
-  Row, RowSize, TempWidth, TempHeight: Integer;
-  IntFormat: TglBitmapInternalFormat;
+      FuncRec.Size            := aSource.Dimension;
+      FuncRec.Position.Fields := FuncRec.Size.Fields;
 
-  function GetRowPointer(Row: Integer): pByte;
-  begin
-    Result := Surface^.pixels;
-    Inc(Result, Row * RowSize);
-  end;
+      if {FormatIsUncompressed(Source.InternalFormat)} true then begin
+        SourceData := aSource.Data;
+        FuncRec.Position.Y := 0;
+        while FuncRec.Position.Y < TempHeight do begin
+          FuncRec.Position.X := 0;
+          while FuncRec.Position.X < TempWidth do begin
+            SourceFD.Unmap(SourceData, FuncRec.Source);
+            aFunc(FuncRec);
+            DestFD.Map(FuncRec.Dest, DestData);
+            inc(FuncRec.Position.X);
+          end;
+          inc(FuncRec.Position.Y);
+        end;
+      end else begin
+        (* TODO
+        // Compressed Images
+        FuncRec.Position.Y := 0;
+        while FuncRec.Position.Y < TempHeight do begin
+          FuncRec.Position.X := 0;
+          while FuncRec.Position.X < TempWidth do begin
+            // Get Data
+            fGetPixelFunc(FuncRec.Position, FuncRec.Source);
+            // Func
+            Func(FuncRec);
+            // Set Data
+            MapFunc(FuncRec.Dest, dest);
+            Inc(FuncRec.Position.X);
+          end;
+          Inc(FuncRec.Position.Y);
+        end;
+        *)
+      end;
 
-begin
-  Result := False;
+      // Updating Image or InternalFormat
+      if aCreateTemp then
+        SetDataPointer(TmpData, aFormat, aSource.Width, aSource.Height)
+      else if (aFormat <> fFormat) then
+        Format := aFormat;
 
-  if (Assigned(Surface)) then begin
-    with Surface^.format^ do begin
-      if FormatCheckFormat(RMask, GMask, BMask, AMask, ifLuminance) then
-        IntFormat := ifLuminance
-      else
+      result := true;
+    except
+      if aCreateTemp then
+        FreeMem(TmpData);
+      raise;
+    end;
+  end;
+end;
 
-      if FormatCheckFormat(RMask, GMask, BMask, AMask, ifLuminanceAlpha) then
-        IntFormat := ifLuminanceAlpha
-      else
+{$IFDEF GLB_SDL}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AssignToSurface(out aSurface: PSDL_Surface): Boolean;
+var
+  Row, RowSize: Integer;
+  SourceData, TmpData: PByte;
+  TempDepth: Integer;
+  Pix: TglBitmapPixelData;
+  FormatDesc: TglBitmapFormatDescriptor;
 
-      if FormatCheckFormat(RMask, GMask, BMask, AMask, ifRGBA4) then
-        IntFormat := ifRGBA4
-      else
+  function GetRowPointer(Row: Integer): pByte;
+  begin
+    result := Surface.pixels;
+    Inc(result, Row * RowSize);
+  end;
 
-      if FormatCheckFormat(RMask, GMask, BMask, AMask, ifR5G6B5) then
-        IntFormat := ifR5G6B5
-      else
+begin
+  result := false;
 
-      if FormatCheckFormat(RMask, GMask, BMask, AMask, ifRGB5A1) then
-        IntFormat := ifRGB5A1
-      else
+  (* TODO
+  if not FormatIsUncompressed(InternalFormat) then
+    raise EglBitmapUnsupportedInternalFormat.Create('AssignToSurface - ' + UNSUPPORTED_INTERNAL_FORMAT);
+  *)
 
-      if FormatCheckFormat(RMask, GMask, BMask, AMask, ifBGR8) then
-        IntFormat := ifBGR8
-      else
+  FormatDesc := FORMAT_DESCRIPTORS[Format];
+  if Assigned(Data) then begin
+    case Trunc(FormatDesc.GetSize) of
+      1: TempDepth :=  8;
+      2: TempDepth := 16;
+      3: TempDepth := 24;
+      4: TempDepth := 32;
+    else
+      raise EglBitmapException.Create('AssignToSurface - ' + UNSUPPORTED_INTERNAL_FORMAT);
+    end;
+    FormatDesc.PreparePixel(Pix);
+    with Pix.PixelDesc do
+      Surface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, TempDepth,
+        RedRange shl RedShift, GreenRange shl GreenShift, BlueRange shl BlueShift, AlphaRange shl AlphaShift);
 
-      if FormatCheckFormat(RMask, GMask, BMask, AMask, ifRGB8) then
-        IntFormat := ifRGB8
-      else
+    SourceData := Data;
+    RowSize    := Ceil(FileWidth * FormatDesc.GetSize);
 
-      if FormatCheckFormat(RMask, GMask, BMask, AMask, ifBGRA8) then
-        IntFormat := ifBGRA8
-      else
+    for Row := 0 to FileHeight -1 do begin
+      TmpData := GetRowPointer(Row);
+      if Assigned(TmpData) then begin
+        Move(SourceData^, TmpData^, RowSize);
+        inc(SourceData, RowSize);
+      end;
+    end;
+    result := true;
+  end;
+end;
 
-      if FormatCheckFormat(RMask, GMask, BMask, AMask, ifRGBA8) then
-        IntFormat := ifRGBA8
-      else
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
+var
+  pSource, pData, pTempData: PByte;
+  Row, RowSize, TempWidth, TempHeight: Integer;
+  IntFormat, f: TglBitmapInternalFormat;
+  FormatDesc: TglBitmapFormatDescriptor;
 
-      if FormatCheckFormat(RMask, GMask, BMask, AMask, ifRGB10A2) then
-        IntFormat := ifRGB10A2
-      else
+  function GetRowPointer(Row: Integer): pByte;
+  begin
+    result := Surface^.pixels;
+    Inc(result, Row * RowSize);
+  end;
+
+begin
+  result := false;
+  if (Assigned(Surface)) then begin
+    with Surface^.format^ do begin
+      IntFormat := tfEmpty;
+      for f := Low(f) to High(f) do begin
+        if FORMAT_DESCRIPTORS[f].MaskMatch(RMask, GMask, BMask, AMask) then begin
+          IntFormat := f;
+          break;
+        end;
+      end;
+      if (IntFormat = tfEmpty) then
         raise EglBitmapException.Create('AssignFromSurface - Invalid Pixelformat.');
     end;
 
-    TempWidth := Surface^.w;
+    FormatDesc := FORMAT_DESCRIPTORS[IntFormat];
+    TempWidth  := Surface^.w;
     TempHeight := Surface^.h;
-
-    RowSize := Trunc(TempWidth * FormatGetSize(IntFormat));
-
+    RowSize := Trunc(TempWidth * FormatDesc.GetSize);
     GetMem(pData, TempHeight * RowSize);
     try
       pTempData := pData;
-
       for Row := 0 to TempHeight -1 do begin
         pSource := GetRowPointer(Row);
-
         if (Assigned(pSource)) then begin
           Move(pSource^, pTempData^, RowSize);
           Inc(pTempData, RowSize);
         end;
       end;
-
       SetDataPointer(pData, IntFormat, TempWidth, TempHeight);
-
-      Result := True;
+      result := true;
     except
       FreeMem(pData);
       raise;
@@ -2911,40 +3260,35 @@ begin
   end;
 end;
 
-
-function TglBitmap.AssignAlphaToSurface(out Surface: PSDL_Surface): boolean;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
 var
   Row, Col, AlphaInterleave: Integer;
   pSource, pDest: PByte;
 
   function GetRowPointer(Row: Integer): pByte;
   begin
-    Result := Surface.pixels;
-    Inc(Result, Row * Width);
+    result := aSurface.pixels;
+    Inc(result, Row * Width);
   end;
 
 begin
-  Result := False;
-
+  result := false;
   if Assigned(Data) then begin
-    if InternalFormat in [ifAlpha, ifLuminanceAlpha, ifBGRA8, ifRGBA8] then begin
-      Surface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, 8, $FF, $FF, $FF, 0);
+    if Format in [tfAlpha8, tfLuminance8Alpha8, tfBGRA8, tfRGBA8] then begin
+      aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, 8, $FF, $FF, $FF, 0);
 
-      case InternalFormat of
-        ifLuminanceAlpha:
+      AlphaInterleave := 0;
+      case Format of
+        ifLuminance8Alpha8:
           AlphaInterleave := 1;
         ifBGRA8, ifRGBA8:
           AlphaInterleave := 3;
-        else
-          AlphaInterleave := 0;
       end;
 
-      // Copy Data
       pSource := Data;
-
       for Row := 0 to Height -1 do begin
         pDest := GetRowPointer(Row);
-
         if Assigned(pDest) then begin
           for Col := 0 to Width -1 do begin
             Inc(pSource, AlphaInterleave);
@@ -2954,37 +3298,83 @@ begin
           end;
         end;
       end;
-
-      Result := True;
+      result := true;
     end;
   end;
 end;
 
-
-function TglBitmap.AddAlphaFromSurface(Surface: PSDL_Surface; Func: TglBitmapFunction; CustomData: Pointer): boolean;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
 var
-  glBitmap: TglBitmap2D;
+  bmp: TglBitmap2D;
 begin
-  glBitmap := TglBitmap2D.Create;
+  bmp := TglBitmap2D.Create;
   try
-    glBitmap.AssignFromSurface(Surface);
-
-    Result := AddAlphaFromglBitmap(glBitmap, Func, CustomData);
+    bmp.AssignFromSurface(Surface);
+    result := AddAlphaFromGlBitmap(bmp, Func, CustomData);
   finally
-    glBitmap.Free;
+    bmp.Free;
   end;
 end;
 {$ENDIF}
 
-
 {$IFDEF GLB_DELPHI}
-function TglBitmap.AssignFromBitmap(const Bitmap: TBitmap): boolean;
+//TODO rework & test
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AssignToBitmap(const aBitmap: TBitmap): Boolean;
+var
+  Row: Integer;
+  pSource, pData: PByte;
+begin
+  result := false;
+  if Assigned(Data) then begin
+    if Assigned(aBitmap) then begin
+      aBitmap.Width  := Width;
+      aBitmap.Height := Height;
+
+      case Format of
+        tfAlpha8, ifLuminance, ifDepth8:
+          begin
+            Bitmap.PixelFormat := pf8bit;
+            Bitmap.Palette := CreateGrayPalette;
+          end;
+        ifRGB5A1:
+          Bitmap.PixelFormat := pf15bit;
+        ifR5G6B5:
+          Bitmap.PixelFormat := pf16bit;
+        ifRGB8, ifBGR8:
+          Bitmap.PixelFormat := pf24bit;
+        ifRGBA8, ifBGRA8:
+          Bitmap.PixelFormat := pf32bit;
+        else
+          raise EglBitmapException.Create('AssignToBitmap - Invalid Pixelformat.');
+      end;
+
+      pSource := Data;
+      for Row := 0 to FileHeight -1 do begin
+        pData := Bitmap.Scanline[Row];
+
+        Move(pSource^, pData^, fRowSize);
+        Inc(pSource, fRowSize);
+
+        // swap RGB(A) to BGR(A)
+        if InternalFormat in [ifRGB8, ifRGBA8] then
+          SwapRGB(pData, FileWidth, InternalFormat = ifRGBA8);
+      end;
+
+      result := true;
+    end;
+  end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AssignFromBitmap(const aBitmap: TBitmap): Boolean;
 var
   pSource, pData, pTempData: PByte;
   Row, RowSize, TempWidth, TempHeight: Integer;
   IntFormat: TglBitmapInternalFormat;
 begin
-  Result := False;
+  result := false;
 
   if (Assigned(Bitmap)) then begin
     case Bitmap.PixelFormat of
@@ -3022,7 +3412,7 @@ begin
 
       SetDataPointer(pData, IntFormat, TempWidth, TempHeight);
 
-      Result := True;
+      result := true;
     except
       FreeMem(pData);
       raise;
@@ -3030,61 +3420,13 @@ begin
   end;
 end;
 
-
-function TglBitmap.AssignToBitmap(const Bitmap: TBitmap): boolean;
-var
-  Row: Integer;
-  pSource, pData: PByte;
-begin
-  Result := False;
-
-  if Assigned(Data) then begin
-    if Assigned(Bitmap) then begin
-      Bitmap.Width := Width;
-      Bitmap.Height := Height;
-
-      case InternalFormat of
-        ifAlpha, ifLuminance, ifDepth8:
-          begin
-            Bitmap.PixelFormat := pf8bit;
-            Bitmap.Palette := CreateGrayPalette;
-          end;
-        ifRGB5A1:
-          Bitmap.PixelFormat := pf15bit;
-        ifR5G6B5:
-          Bitmap.PixelFormat := pf16bit;
-        ifRGB8, ifBGR8:
-          Bitmap.PixelFormat := pf24bit;
-        ifRGBA8, ifBGRA8:
-          Bitmap.PixelFormat := pf32bit;
-        else
-          raise EglBitmapException.Create('AssignToBitmap - Invalid Pixelformat.');
-      end;
-
-      pSource := Data;
-      for Row := 0 to FileHeight -1 do begin
-        pData := Bitmap.Scanline[Row];
-
-        Move(pSource^, pData^, fRowSize);
-        Inc(pSource, fRowSize);
-
-        // swap RGB(A) to BGR(A)
-        if InternalFormat in [ifRGB8, ifRGBA8] then
-          SwapRGB(pData, FileWidth, InternalFormat = ifRGBA8);
-      end;
-
-      Result := True;
-    end;
-  end;
-end;
-
-
-function TglBitmap.AssignAlphaToBitmap(const Bitmap: TBitmap): boolean;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
 var
   Row, Col, AlphaInterleave: Integer;
   pSource, pDest: PByte;
 begin
-  Result := False;
+  result := false;
 
   if Assigned(Data) then begin
     if InternalFormat in [ifAlpha, ifLuminanceAlpha, ifRGBA8, ifBGRA8] then begin
@@ -3119,58 +3461,29 @@ begin
           end;
         end;
 
-        Result := True;
+        result := true;
       end;
     end;
   end;
 end;
 
-
-function TglBitmap.AddAlphaFromBitmap(Bitmap: TBitmap; Func: TglBitmapFunction; CustomData: Pointer): boolean;
-var
-  glBitmap: TglBitmap2D;
-begin
-  glBitmap := TglBitmap2D.Create;
-  try
-    glBitmap.AssignFromBitmap(Bitmap);
-
-    Result := AddAlphaFromglBitmap(glBitmap, Func, CustomData);
-  finally
-    glBitmap.Free;
-  end;
-end;
-{$ENDIF}
-
-
-function TglBitmap.AddAlphaFromFile(FileName: String; Func: TglBitmapFunction; CustomData: Pointer): boolean;
-var
-  FS: TFileStream;
-begin
-  FS := TFileStream.Create(FileName, fmOpenRead);
-  try
-    Result := AddAlphaFromStream(FS, Func, CustomData);
-  finally
-    FS.Free;
-  end;
-end;
-
-
-function TglBitmap.AddAlphaFromStream(Stream: TStream; Func: TglBitmapFunction; CustomData: Pointer): boolean;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
 var
-  glBitmap: TglBitmap2D;
+  tex: TglBitmap2D;
 begin
-  glBitmap := TglBitmap2D.Create(Stream);
+  tex := TglBitmap2D.Create;
   try
-    Result := AddAlphaFromglBitmap(glBitmap, Func, CustomData);
+    tex.AssignFromBitmap(Bitmap);
+    result := AddAlphaFromglBitmap(tex, Func, CustomData);
   finally
-    glBitmap.Free;
+    tex.Free;
   end;
 end;
 
-
-{$IFDEF GLB_DELPHI}
-function TglBitmap.AddAlphaFromResource(Instance: Cardinal; Resource: String;
-  ResType: PChar; Func: TglBitmapFunction; CustomData: Pointer): boolean;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddAlphaFromResource(const aInstance: Cardinal; const aResource: String; const aResType: PChar;
+  const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
 var
   RS: TResourceStream;
   TempPos: Integer;
@@ -3189,167 +3502,373 @@ begin
 
   RS := TResourceStream.Create(Instance, Resource, TempResType);
   try
-    Result := AddAlphaFromStream(RS, Func, CustomData);
+    result := AddAlphaFromStream(RS, Func, CustomData);
   finally
     RS.Free;
   end;
 end;
 
-
-function TglBitmap.AddAlphaFromResourceID(Instance: Cardinal; ResourceID: Integer;
-  ResType: PChar; Func: TglBitmapFunction; CustomData: Pointer): boolean;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
+  const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
 var
   RS: TResourceStream;
 begin
   RS := TResourceStream.CreateFromID(Instance, ResourceID, ResType);
   try
-    Result := AddAlphaFromStream(RS, Func, CustomData);
+    result := AddAlphaFromStream(RS, Func, CustomData);
   finally
     RS.Free;
   end;
 end;
 {$ENDIF}
 
-
-procedure glBitmapColorKeyAlphaFunc(var FuncRec: TglBitmapFunctionRec);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
 begin
-  with FuncRec do begin
-    Dest.Red   := Source.Red;
-    Dest.Green := Source.Green;
-    Dest.Blue  := Source.Blue;
+  (* TODO
+  if not FormatIsUncompressed(InternalFormat) then
+    raise EglBitmapUnsupportedFormatFormat.Create('AddAlphaFromFunc - ' + UNSUPPORTED_FORMAT);
+  *)
+  result := AddFunc(Self, aFunc, false, FORMAT_DESCRIPTORS[Format].WithAlpha, aArgs);
+end;
 
-    with TglBitmapPixelData(CustomData^) do
-      if ((Dest.Red   <= Red  ) and (Dest.Red   >= PixelDesc.RedRange  ) and
-          (Dest.Green <= Green) and (Dest.Green >= PixelDesc.GreenRange) and
-          (Dest.Blue  <= Blue ) and (Dest.Blue  >= PixelDesc.BlueRange )) then
-        Dest.Alpha := 0
-      else
-        Dest.Alpha := Dest.PixelDesc.AlphaRange;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
+var
+  FS: TFileStream;
+begin
+  FS := TFileStream.Create(FileName, fmOpenRead);
+  try
+    result := AddAlphaFromStream(FS, aFunc, aArgs);
+  finally
+    FS.Free;
   end;
 end;
 
-
-function TglBitmap.AddAlphaFromColorKey(Red, Green, Blue: Byte; Deviation: Byte
-  ): Boolean;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
+var
+  tex: TglBitmap2D;
 begin
-  Result := AddAlphaFromColorKeyFloat(Red / $FF, Green / $FF, Blue / $FF, Deviation / $FF);
+  tex := TglBitmap2D.Create(aStream);
+  try
+    result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
+  finally
+    tex.Free;
+  end;
 end;
 
-
-function TglBitmap.AddAlphaFromColorKeyRange(Red, Green, Blue: Cardinal; Deviation: Cardinal = 0): Boolean;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
 var
-  PixelData: TglBitmapPixelData;
+  DestData, DestData2, SourceData: pByte;
+  TempHeight, TempWidth: Integer;
+  SourceFD, DestFD: TglBitmapFormatDescClass;
+
+  FuncRec: TglBitmapFunctionRec;
 begin
-  FormatPreparePixel(PixelData, FormatGetWithAlpha(InternalFormat));
+  result := false;
 
-  Result := AddAlphaFromColorKeyFloat(
-    Red   / PixelData.PixelDesc.RedRange,
-    Green / PixelData.PixelDesc.GreenRange,
-    Blue  / PixelData.PixelDesc.BlueRange,
-    Deviation / Max(PixelData.PixelDesc.RedRange, Max(PixelData.PixelDesc.GreenRange, PixelData.PixelDesc.BlueRange)));
-end;
+  Assert(Assigned(Data));
+  Assert(Assigned(aBitmap));
+  Assert(Assigned(aBitmap.Data));
 
+  if ((aBitmap.Width = Width) and (aBitmap.Height = Height)) then begin
+    result := ConvertTo(FORMAT_DESCRIPTORS[Format].WithAlpha);
+    if not Assigned(aFunc) then
+      aFunc := glBitmapAlphaFunc;
 
-function TglBitmap.AddAlphaFromColorKeyFloat(Red, Green, Blue: Single; Deviation: Single = 0): Boolean;
-var
-  TempR, TempG, TempB: Cardinal;
-  PixelData: TglBitmapPixelData;
-begin
-  FormatPreparePixel(PixelData, FormatGetWithAlpha(InternalFormat));
+    SourceFD := FORMAT_DESCRIPTORS[aBitmap.Format];
+    DestFD   := FORMAT_DESCRIPTORS[Format];
 
-  // Calculate Colorrange
-  with PixelData.PixelDesc do begin
-    TempR := Trunc(RedRange   * Deviation);
-    TempG := Trunc(GreenRange * Deviation);
-    TempB := Trunc(BlueRange  * Deviation);
-
-    PixelData.Red   := Min(RedRange,   Trunc(RedRange   * Red)   + TempR);
-    RedRange        := Max(0,          Trunc(RedRange   * Red)   - TempR);
-    PixelData.Green := Min(GreenRange, Trunc(GreenRange * Green) + TempG);
-    GreenRange      := Max(0,          Trunc(GreenRange * Green) - TempG);
-    PixelData.Blue  := Min(BlueRange,  Trunc(BlueRange  * Blue)  + TempB);
-    BlueRange       := Max(0,          Trunc(BlueRange  * Blue)  - TempB);
-    PixelData.Alpha := 0;
-    AlphaRange      := 0;
-  end;
+    // Values
+    TempHeight := aBitmap.FileHeight;
+    TempWidth  := aBitmap.FileWidth;
 
-  Result := AddAlphaFromFunc(glBitmapColorKeyAlphaFunc, @PixelData);
-end;
+    FuncRec.Sender          := Self;
+    FuncRec.Args            := aArgs;
+    FuncRec.Size            := Dimension;
+    FuncRec.Position.Fields := FuncRec.Size.Fields;
+    FuncRec.Args            := PtrInt(SourceFD.HasAlpha) and 1;
 
+    DestData   := Data;
+    DestData2  := Data;
+    SourceData := aBitmap.Data;
 
-procedure glBitmapValueAlphaFunc(var FuncRec: TglBitmapFunctionRec);
-begin
-  with FuncRec do begin
-    Dest.Red   := Source.Red;
-    Dest.Green := Source.Green;
-    Dest.Blue  := Source.Blue;
+    // Mapping
+    SourceFD.PreparePixel(FuncRec.Source);
+    DestFD.PreparePixel  (FuncRec.Dest);
 
-    with TglBitmapPixelData(CustomData^) do
-      Dest.Alpha := Alpha;
+    FuncRec.Position.Y := 0;
+    while FuncRec.Position.Y < TempHeight do begin
+      FuncRec.Position.X := 0;
+      while FuncRec.Position.X < TempWidth do begin
+        SourceFD.Unmap(SourceData, FuncRec.Source);
+        DestFD.Unmap  (DestData,   FuncRec.Dest);
+        aFunc(FuncRec);
+        DestFD.Map(FuncRec.Dest, DestData2);
+        inc(FuncRec.Position.X);
+      end;
+      inc(FuncRec.Position.Y);
+    end;
   end;
 end;
 
 
-function TglBitmap.AddAlphaFromValue(Alpha: Byte): Boolean;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte): Boolean;
 begin
-  Result := AddAlphaFromValueFloat(Alpha / $FF);
+  result := AddAlphaFromColorKeyFloat(aRed / $FF, aGreen / $FF, aBlue / $FF, aDeviation / $FF);
 end;
 
-
-function TglBitmap.AddAlphaFromValueFloat(Alpha: Single): Boolean;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal): Boolean;
 var
   PixelData: TglBitmapPixelData;
 begin
-  FormatPreparePixel(PixelData, FormatGetWithAlpha(InternalFormat));
-
-  with PixelData.PixelDesc do
-    PixelData.Alpha := Min(AlphaRange, Max(0, Round(AlphaRange * Alpha)));
+  FORMAT_DESCRIPTORS[FORMAT_DESCRIPTORS[Format].WithAlpha].PreparePixel(PixelData);
+  result := AddAlphaFromColorKeyFloat(
+    aRed   / PixelData.PixelDesc.RedRange,
+    aGreen / PixelData.PixelDesc.GreenRange,
+    aBlue  / PixelData.PixelDesc.BlueRange,
+    aDeviation / Max(PixelData.PixelDesc.RedRange, Max(PixelData.PixelDesc.GreenRange, PixelData.PixelDesc.BlueRange)));
+end;
 
-  Result := AddAlphaFromFunc(glBitmapValueAlphaFunc, @PixelData);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single): Boolean;
+var
+  TempR, TempG, TempB: Cardinal;
+  PixelData: TglBitmapPixelData;
+begin
+  FORMAT_DESCRIPTORS[FORMAT_DESCRIPTORS[Format].WithAlpha].PreparePixel(PixelData);
+  with PixelData.PixelDesc do begin
+    TempR := Trunc(RedRange   * aDeviation);
+    TempG := Trunc(GreenRange * aDeviation);
+    TempB := Trunc(BlueRange  * aDeviation);
+
+    PixelData.Red   := Min(RedRange,   Trunc(RedRange   * aRed)   + TempR);
+    RedRange        := Max(0,          Trunc(RedRange   * aRed)   - TempR);
+    PixelData.Green := Min(GreenRange, Trunc(GreenRange * aGreen) + TempG);
+    GreenRange      := Max(0,          Trunc(GreenRange * aGreen) - TempG);
+    PixelData.Blue  := Min(BlueRange,  Trunc(BlueRange  * aBlue)  + TempB);
+    BlueRange       := Max(0,          Trunc(BlueRange  * aBlue)  - TempB);
+    PixelData.Alpha := 0;
+    AlphaRange      := 0;
+  end;
+  result := AddAlphaFromFunc(glBitmapColorKeyAlphaFunc, PtrInt(@PixelData));
 end;
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddAlphaFromValue(const aAlpha: Byte): Boolean;
+begin
+  result := AddAlphaFromValueFloat(aAlpha / $FF);
+end;
 
-function TglBitmap.AddAlphaFromValueRange(Alpha: Cardinal): Boolean;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
 var
   PixelData: TglBitmapPixelData;
 begin
-  FormatPreparePixel(PixelData, FormatGetWithAlpha(InternalFormat));
+  FORMAT_DESCRIPTORS[FORMAT_DESCRIPTORS[Format].WithAlpha].PreparePixel(PixelData);
+  result := AddAlphaFromValueFloat(aAlpha / PixelData.PixelDesc.AlphaRange);
+end;
 
-  Result := AddAlphaFromValueFloat(Alpha / PixelData.PixelDesc.AlphaRange);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
+var
+  PixelData: TglBitmapPixelData;
+begin
+  FORMAT_DESCRIPTORS[FORMAT_DESCRIPTORS[Format].WithAlpha].PreparePixel(PixelData);
+  with PixelData.PixelDesc do
+    PixelData.Alpha := Min(AlphaRange, Max(0, Round(AlphaRange * aAlpha)));
+  result := AddAlphaFromFunc(glBitmapValueAlphaFunc, PtrInt(@PixelData));
 end;
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.RemoveAlpha: Boolean;
+var
+  FormatDesc: TglBitmapFormatDescClass;
+begin
+  result := false;
+  FormatDesc := FORMAT_DESCRIPTORS[Format];
+  if Assigned(Data) then begin
+    if not ({FormatDesc.IsUncompressed or }FormatDesc.HasAlpha) then
+      raise EglBitmapUnsupportedFormatFormat.Create('RemoveAlpha - ' + UNSUPPORTED_FORMAT);
+    result := ConvertTo(FormatDesc.WithoutAlpha);
+  end;
+end;
 
-procedure glBitmapInvertFunc(var FuncRec: TglBitmapFunctionRec);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.Clone: TglBitmap;
+var
+  Temp: TglBitmap;
+  TempPtr: PByte;
+  Size: Integer;
 begin
-  with FuncRec do begin
-    Dest.Red   := Source.Red;
-    Dest.Green := Source.Green;
-    Dest.Blue  := Source.Blue;
-    Dest.Alpha := Source.Alpha;
+  result := nil;
+  Temp := (ClassType.Create as TglBitmap);
+  try
+    // copy texture data if assigned
+    if Assigned(Data) then begin
+      Size := FORMAT_DESCRIPTORS[Format].GetSize(fDimension);
+      GetMem(TempPtr, Size);
+      try
+        Move(Data^, TempPtr^, Size);
+        Temp.SetDataPointer(TempPtr, Format, Width, Height);
+      except
+        FreeMem(TempPtr);
+        raise;
+      end;
+    end else
+      Temp.SetDataPointer(nil, Format, Width, Height);
 
-    if (Integer(CustomData) and $1 > 0) then begin
-      Dest.Red   := Dest.Red   xor Dest.PixelDesc.RedRange;
-      Dest.Green := Dest.Green xor Dest.PixelDesc.GreenRange;
-      Dest.Blue  := Dest.Blue  xor Dest.PixelDesc.BlueRange;
-    end;
+       // copy properties
+    Temp.fID                      := ID;
+    Temp.fTarget                  := Target;
+    Temp.fFormat                  := Format;
+    Temp.fMipMap                  := MipMap;
+    Temp.fAnisotropic             := Anisotropic;
+    Temp.fBorderColor             := fBorderColor;
+    Temp.fDeleteTextureOnFree     := DeleteTextureOnFree;
+    Temp.fFreeDataAfterGenTexture := FreeDataAfterGenTexture;
+    Temp.fFilterMin               := fFilterMin;
+    Temp.fFilterMag               := fFilterMag;
+    Temp.fWrapS                   := fWrapS;
+    Temp.fWrapT                   := fWrapT;
+    Temp.fWrapR                   := fWrapR;
+    Temp.fFilename                := fFilename;
+    Temp.fCustomName              := fCustomName;
+    Temp.fCustomNameW             := fCustomNameW;
+    Temp.fCustomData              := fCustomData;
+
+    result := Temp;
+  except
+    FreeAndNil(Temp);
+    raise;
+  end;
+end;
 
-    if (Integer(CustomData) and $2 > 0) then begin
-      Dest.Alpha := Dest.Alpha xor Dest.PixelDesc.AlphaRange;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.ConvertTo(const aFormat: TglBitmapFormat): Boolean;
+var
+  SourceFD, DestFD: TglBitmapFormatDescClass;
+  SourcePD, DestPD: TglBitmapPixelData;
+  PixelDesc: TglBitmapPixelDesc;
+
+  function CanCopyDirect: Boolean;
+  begin
+    result :=
+      ((SourcePD.PixelDesc.RedRange   = DestPD.PixelDesc.RedRange)   or (SourcePD.PixelDesc.RedRange   = 0) or (DestPD.PixelDesc.RedRange   = 0)) and
+      ((SourcePD.PixelDesc.GreenRange = DestPD.PixelDesc.GreenRange) or (SourcePD.PixelDesc.GreenRange = 0) or (DestPD.PixelDesc.GreenRange = 0)) and
+      ((SourcePD.PixelDesc.BlueRange  = DestPD.PixelDesc.BlueRange)  or (SourcePD.PixelDesc.BlueRange  = 0) or (DestPD.PixelDesc.BlueRange  = 0)) and
+      ((SourcePD.PixelDesc.AlphaRange = DestPD.PixelDesc.AlphaRange) or (SourcePD.PixelDesc.AlphaRange = 0) or (DestPD.PixelDesc.AlphaRange = 0));
+  end;
+
+  function CanShift: Boolean;
+  begin
+    result :=
+      ((SourcePD.PixelDesc.RedRange   >= DestPD.PixelDesc.RedRange  ) or (SourcePD.PixelDesc.RedRange   = 0) or (DestPD.PixelDesc.RedRange   = 0)) and
+      ((SourcePD.PixelDesc.GreenRange >= DestPD.PixelDesc.GreenRange) or (SourcePD.PixelDesc.GreenRange = 0) or (DestPD.PixelDesc.GreenRange = 0)) and
+      ((SourcePD.PixelDesc.BlueRange  >= DestPD.PixelDesc.BlueRange ) or (SourcePD.PixelDesc.BlueRange  = 0) or (DestPD.PixelDesc.BlueRange  = 0)) and
+      ((SourcePD.PixelDesc.AlphaRange >= DestPD.PixelDesc.AlphaRange) or (SourcePD.PixelDesc.AlphaRange = 0) or (DestPD.PixelDesc.AlphaRange = 0));
+  end;
+
+  function GetShift(aSource, aDest: Cardinal) : ShortInt;
+  begin
+    result := 0;
+    while (aSource > aDest) and (aSource > 0) do begin
+      inc(result);
+      aSource := aSource shr 1;
     end;
   end;
+
+begin
+  if aFormat <> fFormat then begin
+    SourceFD := FORMAT_DESCRIPTORS[Format];
+    DestFD   := FORMAT_DESCRIPTORS[aFormat];
+
+    SourceFD.PreparePixel(SourcePD);
+    DestFD.PreparePixel  (DestPD);
+
+    if CanCopyDirect then
+      result := AddFunc(Self, glBitmapConvertCopyFunc, false, aFormat)
+    else if CanShift then begin
+      PixelDesc.RedShift   := GetShift(SourcePD.PixelDesc.RedRange,   DestPD.PixelDesc.RedRange);
+      PixelDesc.GreenShift := GetShift(SourcePD.PixelDesc.GreenRange, DestPD.PixelDesc.GreenRange);
+      PixelDesc.BlueShift  := GetShift(SourcePD.PixelDesc.BlueRange,  DestPD.PixelDesc.BlueRange);
+      PixelDesc.AlphaShift := GetShift(SourcePD.PixelDesc.AlphaRange, DestPD.PixelDesc.AlphaRange);
+      result := AddFunc(Self, glBitmapConvertShiftRGBAFunc, false, aFormat, PtrInt(@PixelDesc));
+    end else
+      result := AddFunc(Self, glBitmapConvertCalculateRGBAFunc, false, aFormat);
+  end else
+    result := true;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.Invert(const aUseRGB: Boolean; const aUseAlpha: Boolean);
+begin
+  if aUseRGB or aUseAlpha then
+    AddFunc(glBitmapInvertFunc, false, ((PtrInt(aUseAlpha) and 1) shl 1) or (PtrInt(aUseRGB) and 1));
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
+begin
+  fBorderColor[0] := aRed;
+  fBorderColor[1] := aGreen;
+  fBorderColor[2] := aBlue;
+  fBorderColor[3] := aAlpha;
+  if (ID > 0) then begin
+    Bind(false);
+    glTexParameterfv(Target, GL_TEXTURE_BORDER_COLOR, @fBorderColor[0]);
+  end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.FreeData;
+begin
+  SetDataPointer(nil, tfEmpty);
 end;
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.FillWithColor(const aRed, aGreen, aBlue: Byte;
+  const aAlpha: Byte);
+begin
+  FillWithColorFloat(aRed/$FF, aGreen/$FF, aBlue/$FF, aAlpha/$FF);
+end;
 
-procedure TglBitmap.Invert(UseRGB: Boolean; UseAlpha: Boolean);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal);
+var
+  PixelData: TglBitmapPixelData;
 begin
-  if ((UseRGB) or (UseAlpha)) then
-    AddFunc(glBitmapInvertFunc, False, Pointer(Integer(UseAlpha) shl 1 or Integer(UseRGB)));
+  FORMAT_DESCRIPTORS[FORMAT_DESCRIPTORS[Format].WithAlpha].PreparePixel(PixelData);
+  FillWithColorFloat(
+    aRed   / PixelData.PixelDesc.RedRange,
+    aGreen / PixelData.PixelDesc.GreenRange,
+    aBlue  / PixelData.PixelDesc.BlueRange,
+    aAlpha / PixelData.PixelDesc.AlphaRange);
 end;
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single);
+var
+  PixelData: TglBitmapPixelData;
+begin
+  FORMAT_DESCRIPTORS[Format].PreparePixel(PixelData);
+  PixelData.Red   := Max(0, Min(PixelData.PixelDesc.RedRange,   Trunc(PixelData.PixelDesc.RedRange   * aRed)));
+  PixelData.Green := Max(0, Min(PixelData.PixelDesc.GreenRange, Trunc(PixelData.PixelDesc.GreenRange * aGreen)));
+  PixelData.Blue  := Max(0, Min(PixelData.PixelDesc.BlueRange,  Trunc(PixelData.PixelDesc.BlueRange  * aBlue)));
+  PixelData.Alpha := Max(0, Min(PixelData.PixelDesc.AlphaRange, Trunc(PixelData.PixelDesc.AlphaRange * aAlpha)));
+  AddFunc(glBitmapFillWithColorFunc, false, PtrInt(@PixelData));
+end;
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 procedure TglBitmap.SetFilter(const aMin, aMag: Cardinal);
 begin
-  case Min of
+  //check MIN filter
+  case aMin of
     GL_NEAREST:
       fFilterMin := GL_NEAREST;
     GL_LINEAR:
@@ -3363,25 +3882,25 @@ begin
     GL_LINEAR_MIPMAP_LINEAR:
       fFilterMin := GL_LINEAR_MIPMAP_LINEAR;
     else
-      raise EglBitmapException.Create('SetFilter - Unknow Minfilter.');
+      raise EglBitmapException.Create('SetFilter - Unknow MIN filter.');
   end;
 
-  case Mag of
+  //check MAG filter
+  case aMag of
     GL_NEAREST:
       fFilterMag := GL_NEAREST;
     GL_LINEAR:
       fFilterMag := GL_LINEAR;
     else
-      raise EglBitmapException.Create('SetFilter - Unknow Magfilter.');
+      raise EglBitmapException.Create('SetFilter - Unknow MAG filter.');
   end;
 
-  // If texture is created then assign filter
-  if ID > 0 then begin
-    Bind(False);
-
+  //apply filter
+  if (ID > 0) then begin
+    Bind(false);
     glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, fFilterMag);
 
-    if (MipMap = mmNone) or (Target = GL_TEXTURE_RECTANGLE_ARB) then begin
+    if (MipMap = mmNone) or (Target = GL_TEXTURE_RECTANGLE) then begin
       case fFilterMin of
         GL_NEAREST, GL_LINEAR:
           glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
@@ -3395,180 +3914,199 @@ begin
   end;
 end;
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SetWrap(const S: Cardinal; const T: Cardinal; const R: Cardinal);
 
-procedure TglBitmap.SetWrap(const S: Cardinal; const T: Cardinal;
-  const R: Cardinal);
-begin
-  case S of
-    GL_CLAMP:
-      fWrapS := GL_CLAMP;
-    GL_REPEAT:
-      fWrapS := GL_REPEAT;
-    GL_CLAMP_TO_EDGE:
-      begin
+  procedure CheckAndSetWrap(const aValue: Cardinal; var aTarget: Cardinal);
+  begin
+    case aValue of
+      GL_CLAMP:
+        aTarget := GL_CLAMP;
+
+      GL_REPEAT:
+        aTarget := GL_REPEAT;
+
+      GL_CLAMP_TO_EDGE: begin
         if GL_VERSION_1_2 or GL_EXT_texture_edge_clamp then
-          fWrapS := GL_CLAMP_TO_EDGE
+          aTarget := GL_CLAMP_TO_EDGE
         else
-          fWrapS := GL_CLAMP;
+          aTarget := GL_CLAMP;
       end;
-    GL_CLAMP_TO_BORDER:
-      begin
+
+      GL_CLAMP_TO_BORDER: begin
         if GL_VERSION_1_3 or GL_ARB_texture_border_clamp then
-          fWrapS := GL_CLAMP_TO_BORDER
+          aTarget := GL_CLAMP_TO_BORDER
         else
-          fWrapS := GL_CLAMP;
+          aTarget := GL_CLAMP;
       end;
-    GL_MIRRORED_REPEAT:
-      begin
+
+      GL_MIRRORED_REPEAT: begin
         if GL_VERSION_1_4 or GL_ARB_texture_mirrored_repeat or GL_IBM_texture_mirrored_repeat then
-          fWrapS := GL_MIRRORED_REPEAT
+          aTarget := GL_MIRRORED_REPEAT
         else
           raise EglBitmapException.Create('SetWrap - Unsupported Texturewrap GL_MIRRORED_REPEAT (S).');
       end;
     else
       raise EglBitmapException.Create('SetWrap - Unknow Texturewrap (S).');
+    end;
   end;
 
-  case T of
-    GL_CLAMP:
-      fWrapT := GL_CLAMP;
-    GL_REPEAT:
-      fWrapT := GL_REPEAT;
-    GL_CLAMP_TO_EDGE:
-      begin
-        if GL_VERSION_1_2 or GL_EXT_texture_edge_clamp then
-          fWrapT := GL_CLAMP_TO_EDGE
-        else
-          fWrapT := GL_CLAMP;
-      end;
-    GL_CLAMP_TO_BORDER:
-      begin
-        if GL_VERSION_1_3 or GL_ARB_texture_border_clamp then
-          fWrapT := GL_CLAMP_TO_BORDER
-        else
-          fWrapT := GL_CLAMP;
-      end;
-    GL_MIRRORED_REPEAT:
-      begin
-        if GL_VERSION_1_4 or GL_ARB_texture_mirrored_repeat or GL_IBM_texture_mirrored_repeat then
-          fWrapT := GL_MIRRORED_REPEAT
-        else
-          raise EglBitmapException.Create('SetWrap - Unsupported Texturewrap GL_MIRRORED_REPEAT (T).');
-      end;
-    else
-      raise EglBitmapException.Create('SetWrap - Unknow Texturewrap (T).');
-  end;
-
-  case R of
-    GL_CLAMP:
-      fWrapR := GL_CLAMP;
-    GL_REPEAT:
-      fWrapR := GL_REPEAT;
-    GL_CLAMP_TO_EDGE:
-      begin
-        if GL_VERSION_1_2 or GL_EXT_texture_edge_clamp then
-          fWrapR := GL_CLAMP_TO_EDGE
-        else
-          fWrapR := GL_CLAMP;
-      end;
-    GL_CLAMP_TO_BORDER:
-      begin
-        if GL_VERSION_1_3 or GL_ARB_texture_border_clamp then
-          fWrapR := GL_CLAMP_TO_BORDER
-        else
-          fWrapR := GL_CLAMP;
-      end;
-    GL_MIRRORED_REPEAT:
-      begin
-        if GL_VERSION_1_4 or GL_ARB_texture_mirrored_repeat or GL_IBM_texture_mirrored_repeat then
-          fWrapR := GL_MIRRORED_REPEAT
-        else
-          raise EglBitmapException.Create('SetWrap - Unsupported Texturewrap GL_MIRRORED_REPEAT (R).');
-      end;
-    else
-      raise EglBitmapException.Create('SetWrap - Unknow Texturewrap (R).');
-  end;
+begin
+  CheckAndSetWrap(S, fWrapS);
+  CheckAndSetWrap(T, fWrapT);
+  CheckAndSetWrap(R, fWrapR);
 
-  if ID > 0 then begin
-    Bind (False);
+  if (ID > 0) then begin
+    Bind(false);
     glTexParameteri(Target, GL_TEXTURE_WRAP_S, fWrapS);
     glTexParameteri(Target, GL_TEXTURE_WRAP_T, fWrapT);
     glTexParameteri(Target, GL_TEXTURE_WRAP_R, fWrapR);
   end;
 end;
 
-
-procedure TglBitmap.SetDataPointer(NewData: pByte;
-  Format: TglBitmapFormat; Width: Integer; Height: Integer);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.GetPixel(const aPos: TglBitmapPixelPosition; var aPixel: TglBitmapPixelData);
 begin
-  // Data
-  if Data <> NewData then begin
-    if (Assigned(Data))
-      then FreeMem(Data);
+  { TODO delete?
+  if Assigned (fGetPixelFunc) then
+    fGetPixelFunc(aPos, aPixel);
+    }
+end;
 
-    fData := NewData;
-  end;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SetPixel(const aPos: TglBitmapPixelPosition; const aPixel: TglBitmapPixelData);
+begin
+  {TODO delete?
+  if Assigned (fSetPixelFunc) then
+    fSetPixelFuc(aPos, aPixel);
+    }
+end;
 
-  if Data = nil then begin
-    fInternalFormat := ifEmpty;
-    fPixelSize := 0;
-    fRowSize := 0;
-  end else begin
-    if Width <> -1 then begin
-      fDimension.Fields := fDimension.Fields + [ffX];
-      fDimension.X := Width;
-    end;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.Bind(const aEnableTextureUnit: Boolean);
+begin
+  if aEnableTextureUnit then
+    glEnable(Target);
+  if (ID > 0) then
+    glBindTexture(Target, ID);
+end;
 
-    if Height <> -1 then begin
-      fDimension.Fields := fDimension.Fields + [ffY];
-      fDimension.Y := Height;
-    end;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.Unbind(const aDisableTextureUnit: Boolean);
+begin
+  if aDisableTextureUnit then
+    glDisable(Target);
+  glBindTexture(Target, 0);
+end;
 
-    fInternalFormat := Format;
-    fPixelSize := Trunc(FormatGetSize(InternalFormat));
-    fRowSize :=  Trunc(FormatGetSize(InternalFormat) * Self.Width);
-  end;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TglBitmap.Create;
+begin
+{$IFNDEF GLB_NO_NATIVE_GL}
+  ReadOpenGLExtensions;
+{$ENDIF}
+  if (ClassType = TglBitmap) then
+    raise EglBitmapException.Create('Don''t create TglBitmap directly. Use one of the deviated classes (TglBitmap2D) instead.');
+  inherited Create;
 end;
 
-{$IFDEF GLB_SUPPORT_PNG_READ}
-{$IFDEF GLB_LIB_PNG}
-procedure glBitmap_libPNG_read_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TglBitmap.Create(const aFileName: String);
 begin
-  TStream(png_get_io_ptr(png)).Read(buffer^, size);
+  Create;
+  LoadFromFile(FileName);
 end;
-{$ENDIF}
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TglBitmap.Create(const aStream: TStream);
+begin
+  Create;
+  LoadFromStream(aStream);
+end;
 
-function TglBitmap.LoadPNG(Stream: TStream): Boolean;
-{$IFDEF GLB_SDL_IMAGE}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat);
 var
-  Surface: PSDL_Surface;
-  RWops: PSDL_RWops;
+  Image: PByte;
+  ImageSize: Integer;
 begin
-  Result := False;
-
-  RWops := glBitmapCreateRWops(Stream);
+  Create;
+  ImageSize := FORMAT_DESCRIPTORS[aFormat].GetSize(aSize);
+  GetMem(Image, ImageSize);
   try
-    if IMG_isPNG(RWops) > 0 then begin
-      Surface := IMG_LoadPNG_RW(RWops);
-      try
-        AssignFromSurface(Surface);
-        Result := True;
-      finally
-        SDL_FreeSurface(Surface);
-      end;
-    end;
-  finally
-    SDL_FreeRW(RWops);
+    FillChar(Image^, ImageSize, #$FF);
+    SetDataPointer(Image, aFormat, aSize.X, aSize.Y);
+  except
+    FreeMem(Image);
+    raise;
   end;
 end;
-{$ENDIF}
-{$IFDEF GLB_LIB_PNG}
-var
-  StreamPos: Int64;
-  signature: array [0..7] of byte;
-  png: png_structp;
-  png_info: png_infop;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat;
+  const aFunc: TglBitmapFunction; const aArgs: PtrInt);
+begin
+  Create;
+  LoadFromFunc(aSize, aFunc, aFormat, aArgs);
+end;
+
+{$IFDEF GLB_DELPHI}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TglBitmap.Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar);
+begin
+  Create;
+  LoadFromResource(aInstance, aResource, aResType);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TglBitmap.Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
+begin
+  Create;
+  LoadFromResourceID(aInstance, aResourceID, aResType);
+end;
+{$ENDIF}
+
+{$IFDEF GLB_SUPPORT_PNG_READ}
+{$IF DEFINED(GLB_SDL_IMAGE)}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//PNG/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
+var
+  Surface: PSDL_Surface;
+  RWops: PSDL_RWops;
+begin
+  result := false;
+  RWops := glBitmapCreateRWops(aStream);
+  try
+    if IMG_isPNG(RWops) > 0 then begin
+      Surface := IMG_LoadPNG_RW(RWops);
+      try
+        AssignFromSurface(Surface);
+        Rresult := true;
+      finally
+        SDL_FreeSurface(Surface);
+      end;
+    end;
+  finally
+    SDL_FreeRW(RWops);
+  end;
+end;
+
+{$ELSEIF DEFINED(GLB_LIB_PNG)}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure glBitmap_libPNG_read_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
+begin
+  TStream(png_get_io_ptr(png)).Read(buffer^, size);
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
+var
+  StreamPos: Int64;
+  signature: array [0..7] of byte;
+  png: png_structp;
+  png_info: png_infop;
 
   TempHeight, TempWidth: Integer;
   Format: TglBitmapInternalFormat;
@@ -3577,7 +4115,7 @@ var
   png_rows: array of pByte;
   Row, LineSize: Integer;
 begin
-  Result := False;
+  result := false;
 
   if not init_libPNG then
     raise Exception.Create('LoadPNG - unable to initialize libPNG.');
@@ -3614,13 +4152,13 @@ begin
       // format
       case png_get_color_type(png, png_info) of
         PNG_COLOR_TYPE_GRAY:
-          Format := ifLuminance;
+          Format := tfLuminance8;
         PNG_COLOR_TYPE_GRAY_ALPHA:
-          Format := ifLuminanceAlpha;
+          Format := tfLuminance8Alpha8;
         PNG_COLOR_TYPE_RGB:
-          Format := ifRGB8;
+          Format := tfRGB8;
         PNG_COLOR_TYPE_RGB_ALPHA:
-          Format := ifRGBA8;
+          Format := tfRGBA8;
         else
           raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
       end;
@@ -3657,7 +4195,7 @@ begin
         // set new data
         SetDataPointer(png_data, Format, TempWidth, TempHeight);
 
-        Result := True;
+        result := true;
       except
         FreeMem(png_data);
         raise;
@@ -3667,8 +4205,10 @@ begin
     quit_libPNG;
   end;
 end;
-{$ENDIF}
-{$IFDEF GLB_PNGIMAGE}
+
+{$ELSEIF DEFINED(GLB_PNGIMAGE)}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
 var
   StreamPos: Int64;
   Png: TPNGObject;
@@ -3681,7 +4221,7 @@ const
   PngHeader: Array[0..7] of Byte = (#137, #80, #78, #71, #13, #10, #26, #10);
 
 begin
-  Result := False;
+  result := false;
 
   StreamPos := Stream.Position;
   Stream.Read(Header[0], SizeOf(Header));
@@ -3746,7 +4286,7 @@ begin
 
         SetDataPointer(NewImage, Format, Png.Header.Width, Png.Header.Height);
 
-        Result := True;
+        result := true;
       except
         FreeMem(NewImage);
         raise;
@@ -3756,10 +4296,175 @@ begin
     end;
   end;
 end;
+{$IFEND}
 {$ENDIF}
+
+{$IFDEF GLB_SUPPORT_PNG_WRITE}
+{$IFDEF GLB_LIB_PNG}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure glBitmap_libPNG_write_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
+begin
+  TStream(png_get_io_ptr(png)).Write(buffer^, size);
+end;
 {$ENDIF}
 
+{$IF DEFINED(GLB_LIB_PNG)}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SavePNG(const aStream: TStream);
+var
+  png: png_structp;
+  png_info: png_infop;
+  png_rows: array of pByte;
+  LineSize: Integer;
+  ColorType: Integer;
+  Row: Integer;
+begin
+  if not (ftPNG in FormatGetSupportedFiles (InternalFormat)) then
+    raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
+
+  if not init_libPNG then
+    raise Exception.Create('SavePNG - unable to initialize libPNG.');
+
+  try
+    case FInternalFormat of
+      ifAlpha, ifLuminance, ifDepth8:
+        ColorType := PNG_COLOR_TYPE_GRAY;
+      ifLuminanceAlpha:
+        ColorType := PNG_COLOR_TYPE_GRAY_ALPHA;
+      ifBGR8, ifRGB8:
+        ColorType := PNG_COLOR_TYPE_RGB;
+      ifBGRA8, ifRGBA8:
+        ColorType := PNG_COLOR_TYPE_RGBA;
+      else
+        raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
+    end;
+    LineSize := Trunc(FormatGetSize(FInternalFormat) * Width);
+
+    // creating array for scanline
+    SetLength(png_rows, Height);
+    try
+      for Row := 0 to Height - 1 do begin
+        png_rows[Row] := Data;
+        Inc(png_rows[Row], Row * LineSize)
+      end;
+
+      // write struct
+      png := png_create_write_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
+      if png = nil then
+        raise EglBitmapException.Create('SavePng - couldn''t create write struct.');
+
+      // create png info
+      png_info := png_create_info_struct(png);
+      if png_info = nil then begin
+        png_destroy_write_struct(@png, nil);
+        raise EglBitmapException.Create('SavePng - couldn''t create info struct.');
+      end;
+
+      // set read callback
+      png_set_write_fn(png, stream, glBitmap_libPNG_write_func, nil);
+
+      // set compression
+      png_set_compression_level(png, 6);
+
+      if InternalFormat in [ifBGR8, ifBGRA8] then
+        png_set_bgr(png);
+
+      png_set_IHDR(png, png_info, Width, Height, 8, ColorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+      png_write_info(png, png_info);
+      png_write_image(png, @png_rows[0]);
+      png_write_end(png, png_info);
+      png_destroy_write_struct(@png, @png_info);
+    finally
+      SetLength(png_rows, 0);
+    end;
+  finally
+    quit_libPNG;
+  end;
+end;
+
+{$ELSEIF DEFINED(GLB_PNGIMAGE)}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SavePNG(const aStream: TStream);
+var
+  Png: TPNGObject;
+
+  pSource, pDest: pByte;
+  X, Y, PixSize: Integer;
+  ColorType: Cardinal;
+  Alpha: Boolean;
+
+  pTemp: pByte;
+  Temp: Byte;
+begin
+  if not (ftPNG in FormatGetSupportedFiles (InternalFormat)) then
+    raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
+
+  case FInternalFormat of
+    ifAlpha, ifLuminance, ifDepth8: begin
+      ColorType := COLOR_GRAYSCALE;
+      PixSize := 1;
+      Alpha := false;
+    end;
+    ifLuminanceAlpha: begin
+      ColorType := COLOR_GRAYSCALEALPHA;
+      PixSize := 1;
+      Alpha := true;
+    end;
+    ifBGR8, ifRGB8: begin
+      ColorType := COLOR_RGB;
+      PixSize := 3;
+      Alpha := false;
+    end;
+    ifBGRA8, ifRGBA8: begin
+      ColorType := COLOR_RGBALPHA;
+      PixSize := 3;
+      Alpha := true
+    end;
+  else
+    raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
+  end;
+
+  Png := TPNGObject.CreateBlank(ColorType, 8, Width, Height);
+  try
+    // Copy ImageData
+    pSource := Data;
+    for Y := 0 to Height -1 do begin
+      pDest := png.ScanLine[Y];
+      for X := 0 to Width -1 do begin
+        Move(pSource^, pDest^, PixSize);
+        Inc(pDest, PixSize);
+        Inc(pSource, PixSize);
+        if Alpha then begin
+          png.AlphaScanline[Y]^[X] := pSource^;
+          Inc(pSource);
+        end;
+      end;
+
+      // convert RGB line to BGR
+      if InternalFormat in [ifRGB8, ifRGBA8] then begin
+        pTemp := png.ScanLine[Y];
+        for X := 0 to Width -1 do begin
+          Temp := pByteArray(pTemp)^[0];
+          pByteArray(pTemp)^[0] := pByteArray(pTemp)^[2];
+          pByteArray(pTemp)^[2] := Temp;
+          Inc(pTemp, 3);
+        end;
+      end;
+    end;
+
+    // Save to Stream
+    Png.CompressionLevel := 6;
+    Png.SaveToStream(Stream);
+  finally
+    FreeAndNil(Png);
+  end;
+end;
+{$IFEND}
+{$ENDIF}
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//JPEG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 {$IFDEF GLB_LIB_JPEG}
 type
   glBitmap_libJPEG_source_mgr_ptr = ^glBitmap_libJPEG_source_mgr;
@@ -3770,7 +4475,6 @@ type
     SrcBuffer: array [1..4096] of byte;
   end;
 
-
   glBitmap_libJPEG_dest_mgr_ptr = ^glBitmap_libJPEG_dest_mgr;
   glBitmap_libJPEG_dest_mgr = record
     pub: jpeg_destination_mgr;
@@ -3779,41 +4483,41 @@ type
     DestBuffer: array [1..4096] of byte;
   end;
 
-
-
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+{
 procedure glBitmap_libJPEG_error_exit(cinfo: j_common_ptr); cdecl;
-//var
-//  Msg: String;
+var
+  Msg: String;
 begin
-//  SetLength(Msg, 256);
-//  cinfo^.err^.format_message(cinfo, pChar(Msg));
-
-//  Writeln('ERROR [' + IntToStr(cinfo^.err^.msg_code) + '] ' + Msg);
-
-//  cinfo^.global_state := 0;
-
-//  jpeg_abort(cinfo);
+  SetLength(Msg, 256);
+  cinfo^.err^.format_message(cinfo, pChar(Msg));
+  Writeln('ERROR [' + IntToStr(cinfo^.err^.msg_code) + '] ' + Msg);
+  cinfo^.global_state := 0;
+  jpeg_abort(cinfo);
 end;
+}
 
-
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+{
 procedure glBitmap_libJPEG_output_message(cinfo: j_common_ptr); cdecl;
-//var
-//  Msg: String;
+var
+  Msg: String;
 begin
-//  SetLength(Msg, 256);
-//  cinfo^.err^.format_message(cinfo, pChar(Msg));
-
-//  Writeln('OUTPUT [' + IntToStr(cinfo^.err^.msg_code) + '] ' + Msg);
-
-//  cinfo^.global_state := 0;
+  SetLength(Msg, 256);
+  cinfo^.err^.format_message(cinfo, pChar(Msg));
+  Writeln('OUTPUT [' + IntToStr(cinfo^.err^.msg_code) + '] ' + Msg);
+  cinfo^.global_state := 0;
 end;
+}
 
-
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+{
 procedure glBitmap_libJPEG_init_source(cinfo: j_decompress_ptr); cdecl;
 begin
 end;
+}
 
-
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 function glBitmap_libJPEG_fill_input_buffer(cinfo: j_decompress_ptr): boolean; cdecl;
 var
   src: glBitmap_libJPEG_source_mgr_ptr;
@@ -3834,7 +4538,7 @@ begin
   result := true;
 end;
 
-
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 procedure glBitmap_libJPEG_skip_input_data(cinfo: j_decompress_ptr; num_bytes: Longint); cdecl;
 var
   src: glBitmap_libJPEG_source_mgr_ptr;
@@ -3854,17 +4558,21 @@ begin
   end;
 end;
 
-
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+{
 procedure glBitmap_libJPEG_term_source(cinfo: j_decompress_ptr); cdecl;
 begin
 end;
+}
 
-
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+{
 procedure glBitmap_libJPEG_init_destination(cinfo: j_compress_ptr); cdecl;
 begin
 end;
+}
 
-
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 function glBitmap_libJPEG_empty_output_buffer(cinfo: j_compress_ptr): boolean; cdecl;
 var
   dest: glBitmap_libJPEG_dest_mgr_ptr;
@@ -3880,10 +4588,10 @@ begin
     dest^.pub.free_in_buffer := Length(dest^.DestBuffer);
   end;
 
-  Result := True;
+  result := true;
 end;
 
-
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 procedure glBitmap_libJPEG_term_destination(cinfo: j_compress_ptr); cdecl;
 var
   Idx: Integer;
@@ -3898,22 +4606,22 @@ begin
       dest^.DestStream.Write(dest^.DestBuffer[Idx], 2);
 
       // leave
-      Break;
+      break;
     end else
       dest^.DestStream.Write(dest^.DestBuffer[Idx], 1);
   end;
 end;
 {$ENDIF}
 
-
 {$IFDEF GLB_SUPPORT_JPEG_READ}
-function TglBitmap.LoadJPEG(Stream: TStream): Boolean;
-{$IFDEF GLB_SDL_IMAGE}
+{$IF DEFINED(GLB_SDL_IMAGE)}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
 var
   Surface: PSDL_Surface;
   RWops: PSDL_RWops;
 begin
-  Result := False;
+  result := false;
 
   RWops := glBitmapCreateRWops(Stream);
   try
@@ -3921,7 +4629,7 @@ begin
       Surface := IMG_LoadJPG_RW(RWops);
       try
         AssignFromSurface(Surface);
-        Result := True;
+        result := true;
       finally
         SDL_FreeSurface(Surface);
       end;
@@ -3930,8 +4638,10 @@ begin
     SDL_FreeRW(RWops);
   end;
 end;
-{$ENDIF}
-{$IFDEF GLB_LIB_JPEG}
+
+{$ELSEIF DEFINED(GLB_LIB_JPEG)}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
 var
   StreamPos: Int64;
   Temp: array[0..1]of Byte;
@@ -3946,7 +4656,7 @@ var
   pTemp: pByte;
   Row: Integer;
 begin
-  Result := False;
+  result := false;
 
   if not init_libJPEG then
     raise Exception.Create('LoadJPG - unable to initialize libJPEG.');
@@ -3991,7 +4701,7 @@ begin
       jpeg.global_state := DSTATE_START;
 
       // read header of jpeg
-      jpeg_read_header(@jpeg, False);
+      jpeg_read_header(@jpeg, false);
 
       // setting output parameter
       case jpeg.jpeg_color_space of
@@ -4029,7 +4739,7 @@ begin
 
         SetDataPointer(pImage, IntFormat, TempWidth, TempHeight);
 
-        Result := True;
+        result := true;
       except
         FreeMem(pImage);
         raise;
@@ -4039,15 +4749,17 @@ begin
     quit_libJPEG;
   end;
 end;
-{$ENDIF}
-{$IFDEF GLB_DELPHI_JPEG}
+
+{$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
 var
   bmp: TBitmap;
   jpg: TJPEGImage;
   StreamPos: Int64;
   Temp: array[0..1]of Byte;
 begin
-  Result := False;
+  result := false;
 
   // reading first two bytes to test file and set cursor back to begin
   StreamPos := Stream.Position;
@@ -4062,7 +4774,7 @@ begin
       try
         jpg.LoadFromStream(Stream);
         bmp.Assign(jpg);
-        Result := AssignFromBitmap(bmp);
+        result := AssignFromBitmap(bmp);
       finally
         jpg.Free;
       end;
@@ -4071,20 +4783,159 @@ begin
     end;
   end;
 end;
+{$IFEND}
 {$ENDIF}
-{$ENDIF}
-
-
-const
-  BMP_MAGIC          = $4D42;
 
-  BMP_COMP_RGB       = 0;
-  BMP_COMP_RLE8      = 1;
-  BMP_COMP_RLE4      = 2;
-  BMP_COMP_BITFIELDS = 3;
+{$IFDEF GLB_SUPPORT_JPEG_WRITE}
+{$IF DEFEFINED(GLB_LIB_JPEG)}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SaveJPEG(Stream: TStream);
+var
+  jpeg: jpeg_compress_struct;
+  jpeg_err: jpeg_error_mgr;
+  Row: Integer;
+  pTemp, pTemp2: pByte;
 
-type
-  TBMPHeader = packed record
+  procedure CopyRow(pDest, pSource: pByte);
+  var
+    X: Integer;
+  begin
+    for X := 0 to Width - 1 do begin
+      pByteArray(pDest)^[0] := pByteArray(pSource)^[2];
+      pByteArray(pDest)^[1] := pByteArray(pSource)^[1];
+      pByteArray(pDest)^[2] := pByteArray(pSource)^[0];
+      Inc(pDest, 3);
+      Inc(pSource, 3);
+    end;
+  end;
+
+begin
+  if not (ftJPEG in FormatGetSupportedFiles(Format)) then
+    raise EglBitmapUnsupportedInternalFormat.Create('SaveJpg - ' + UNSUPPORTED_INTERNAL_FORMAT);
+
+  if not init_libJPEG then
+    raise Exception.Create('SaveJPG - unable to initialize libJPEG.');
+
+  try
+    FillChar(jpeg, SizeOf(jpeg_compress_struct), $00);
+    FillChar(jpeg_err, SizeOf(jpeg_error_mgr), $00);
+
+    // error managment
+    jpeg.err := jpeg_std_error(@jpeg_err);
+    jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
+    jpeg_err.output_message := glBitmap_libJPEG_output_message;
+
+    // compression struct
+    jpeg_create_compress(@jpeg);
+
+    // allocation space for streaming methods
+    jpeg.dest := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_dest_mgr));
+
+    // seeting up custom functions
+    with glBitmap_libJPEG_dest_mgr_ptr(jpeg.dest)^ do begin
+      pub.init_destination    := glBitmap_libJPEG_init_destination;
+      pub.empty_output_buffer := glBitmap_libJPEG_empty_output_buffer;
+      pub.term_destination    := glBitmap_libJPEG_term_destination;
+
+      pub.next_output_byte  := @DestBuffer[1];
+      pub.free_in_buffer    := Length(DestBuffer);
+
+      DestStream := Stream;
+    end;
+
+    // very important state
+    jpeg.global_state := CSTATE_START;
+    jpeg.image_width  := Width;
+    jpeg.image_height := Height;
+    case InternalFormat of
+      ifAlpha, ifLuminance, ifDepth8: begin
+        jpeg.input_components := 1;
+        jpeg.in_color_space := JCS_GRAYSCALE;
+      end;
+      ifRGB8, ifBGR8: begin
+        jpeg.input_components := 3;
+        jpeg.in_color_space := JCS_RGB;
+      end;
+    end;
+
+    jpeg_set_defaults(@jpeg);
+    jpeg_set_quality(@jpeg, 95, true);
+    jpeg_start_compress(@jpeg, true);
+    pTemp := Data;
+
+    if InternalFormat = ifBGR8 then
+      GetMem(pTemp2, fRowSize)
+    else
+      pTemp2 := pTemp;
+
+    try
+      for Row := 0 to jpeg.image_height -1 do begin
+        // prepare row
+        if InternalFormat = ifBGR8 then
+          CopyRow(pTemp2, pTemp)
+        else
+          pTemp2 := pTemp;
+
+        // write row
+        jpeg_write_scanlines(@jpeg, @pTemp2, 1);
+        inc(pTemp, fRowSize);
+      end;
+    finally
+      // free memory
+      if InternalFormat = ifBGR8 then
+        FreeMem(pTemp2);
+    end;
+    jpeg_finish_compress(@jpeg);
+    jpeg_destroy_compress(@jpeg);
+  finally
+    quit_libJPEG;
+  end;
+end;
+
+{$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SaveJPEG(Stream: TStream);
+var
+  Bmp: TBitmap;
+  Jpg: TJPEGImage;
+begin
+  if not (ftJPEG in FormatGetSupportedFiles (InternalFormat)) then
+    raise EglBitmapUnsupportedInternalFormat.Create('SaveJpg - ' + UNSUPPORTED_INTERNAL_FORMAT);
+
+  Bmp := TBitmap.Create;
+  try
+    Jpg := TJPEGImage.Create;
+    try
+      AssignToBitmap(Bmp);
+      if FInternalFormat in [ifAlpha, ifLuminance, ifDepth8] then begin
+        Jpg.Grayscale := true;
+        Jpg.PixelFormat := jf8Bit;
+      end;
+      Jpg.Assign(Bmp);
+      Jpg.SaveToStream(Stream);
+    finally
+      FreeAndNil(Jpg);
+    end;
+  finally
+    FreeAndNil(Bmp);
+  end;
+end;
+{$ENDIF}
+{$ENDIF}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//BMP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+const
+  BMP_MAGIC          = $4D42;
+
+  BMP_COMP_RGB       = 0;
+  BMP_COMP_RLE8      = 1;
+  BMP_COMP_RLE4      = 2;
+  BMP_COMP_BITFIELDS = 3;
+
+type
+  TBMPHeader = packed record
     bfType: Word;
     bfSize: Cardinal;
     bfReserved1: Word;
@@ -4116,357 +4967,356 @@ type
 
 //  TBMPPalette = record
 //    case Boolean of
-//      True : (Colors: array[Byte] of TRGBQUAD);
-//      False: (redMask, greenMask, blueMask: Cardinal);
+//      true : (Colors: array[Byte] of TRGBQUAD);
+//      false: (redMask, greenMask, blueMask: Cardinal);
 //  end;
 
-function TglBitmap.LoadBMP(Stream: TStream): Boolean;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.LoadBMP(const aStream: TStream): Boolean;
+type
+  TMaskValues = packed record
+    Red: Cardinal;
+    Green: Cardinal;
+    Blue: Cardinal;
+    Alpha: Cardinal;
+  end;
+
 var
-  StreamPos: Int64;
-  Header: TBMPHeader;
-  Info: TBMPInfo;
-  NewImage, pData: pByte;
+  StartPos: Int64;
 
-  Format: TglBitmapFormat;
-  LineSize, Padding, LineIdx: Integer;
-  RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
+  //////////////////////////////////////////////////////////////////////////////////////////////////
+  function ReadInfo(var aInfo: TBMPInfo; var aMask: TMaskValues): TglBitmapFormat;
+  begin
+    result := tfEmpty;
+    aStream.Read(aInfo, SizeOf(aInfo));
+    FillChar(aMask, SizeOf(aMask), 0);
 
-  PaddingBuff: Cardinal;
+    //Read Compression
+    if aInfo.biCompression <> BMP_COMP_RGB then begin
+      if aInfo.biCompression = BMP_COMP_BITFIELDS then begin
+        // Read Bitmasks for 16 or 32 Bit (24 Bit dosn't support Bitmasks!)
+        if (aInfo.biBitCount = 16) or (aInfo.biBitCount = 32) then begin
+          aStream.Read(aMask.Red,   SizeOf(Cardinal));
+          aStream.Read(aMask.Green, SizeOf(Cardinal));
+          aStream.Read(aMask.Blue,  SizeOf(Cardinal));
+          aStream.Read(aMask.Alpha, SizeOf(Cardinal));
+        end else
+          raise EglBitmapException.Create('Bitmask is not supported for 24bit formats');
+      end else begin
+        aStream.Position := StartPos;
+        raise EglBitmapException.Create('RLE compression is not supported');
+      end;
+    end;
 
+    //get suitable format
+    case aInfo.biBitCount of
+       8: result := tfLuminance8;
+      16: result := tfRGB5A1;
+      24: result := tfBGR8;
+      32: result := tfBGRA8;
+    end;
+  end;
 
-  function GetLineWidth : Integer;
+  //////////////////////////////////////////////////////////////////////////////////////////////////
+  function CheckBitfields(var aFormat: TglBitmapFormat; const aMask: TMaskValues): TBitfieldFormat;
+  var
+    TmpFormat: TglBitmapFormat;
+    FormatDesc: TglBitmapFormatDescClass;
   begin
-    Result := ((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3;
-  end;
+    result := nil;
+    if (aMask.Red <> 0) or (aMask.Green <> 0) or (aMask.Blue <> 0) or (aMask.Alpha <> 0) then begin
+      for TmpFormat := High(FORMAT_DESCRIPTORS) downto Low(FORMAT_DESCRIPTORS) do begin
+        FormatDesc := FORMAT_DESCRIPTORS[TmpFormat];
+        if FormatDesc.MaskMatch(aMask.Red, aMask.Green, aMask.Blue, aMask.Alpha) then begin
+          aFormat := FormatDesc.GetFormat;
+          exit;
+        end;
+      end;
 
-  
-begin
-  Result := False;
+      if (aMask.Alpha = 0) then
+        aFormat := FORMAT_DESCRIPTORS[aFormat].WithoutAlpha;
 
-  RedMask := 0;
-  GreenMask := 0;
-  BlueMask := 0;
-  Format := ifEmpty;
+      result := TBitfieldFormat.Create;
+      result.RedMask   := aMask.Red;
+      result.GreenMask := aMask.Green;
+      result.BlueMask  := aMask.Blue;
+      result.AlphaMask := aMask.Alpha;
+    end;
+  end;
 
-  // Header
-  StreamPos := Stream.Position;
-  Stream.Read(Header, SizeOf(Header));
+var
+  //simple types
+  ImageSize, rbLineSize, wbLineSize, Padding, i: Integer;
+  PaddingBuff: Cardinal;
+  LineBuf, ImageData, TmpData: PByte;
+  BmpFormat: TglBitmapFormat;
 
-  if Header.bfType = BMP_MAGIC then begin
-    Stream.Read(Info, SizeOf(Info));
+  //records
+  Mask: TMaskValues;
+  Header: TBMPHeader;
+  Info: TBMPInfo;
 
-    // Check for Compression
-    if Info.biCompression <> BMP_COMP_RGB then begin
-      if Info.biCompression = BMP_COMP_BITFIELDS then begin
-        // Read Bitmasks for 16 or 32 Bit (24 Bit dosn't support Bitmasks!)
-        if (Info.biBitCount = 16) or (Info.biBitCount = 32) then begin
-          Stream.Read(RedMask,   SizeOf(Cardinal));
-          Stream.Read(GreenMask, SizeOf(Cardinal));
-          Stream.Read(BlueMask,  SizeOf(Cardinal));
-          Stream.Read(AlphaMask, SizeOf(Cardinal));
-        end;
-      end else begin
-        // RLE compression is unsupported
-        Stream.Position := StreamPos;
+  //classes
+  BitfieldFormat: TBitfieldFormat;
+  FormatDesc: TglBitmapFormatDescClass;
 
-        Exit;
-      end;
-    end;
 
-    // Skip palette
-    if Info.biBitCount < 16 then
-      Stream.Position := Stream.Position + Info.biClrUsed * 4;
+  Tick: QWord;
+{
 
-    // Jump to the data
-    Stream.Position := StreamPos + Header.bfOffBits;
 
-    // Select Format
-    case Info.biBitCount of
-      8 : Format := ifLuminance;
-      16:
-        begin
-          if (RedMask = 0) and (GreenMask = 0) and (BlueMask = 0) then begin
-              Format := tfRGB5A1;
-          end else begin
-            if FormatCheckFormat(RedMask, GreenMask, BlueMask, AlphaMask, ifLuminanceAlpha) then
-              Format := ifLuminanceAlpha;
+  ImageData, pData, pTmp, LineBuf, TmpData: PByte;
+  BitOffset: Byte;
+  BmpFormat: TglBitmapFormat;
+  LineSize, Padding, LineIdx, PixelIdx: Integer;
+  RedMask, GreenMask, BlueMask, AlphaMask, FormatSize: Cardinal;
 
-            if FormatCheckFormat(RedMask, GreenMask, BlueMask, AlphaMask, tfRGBA4) then
-              Format := tfRGBA4;
 
-            if FormatCheckFormat(RedMask, GreenMask, BlueMask, 0, tfRGB5A1) then
-              Format := tfRGB5A1;
+  Pixel: TglBitmapPixelData;
+  PaddingBuff: Cardinal;
 
-            if FormatCheckFormat(RedMask, GreenMask, BlueMask, 0, ifR5G6B5) then
-              Format := ifR5G6B5;
-          end;
-        end;
-      24: Format := ifBGR8;
-      32:
-        begin
-          if (RedMask = 0) and (GreenMask = 0) and (BlueMask = 0) then begin
-            Format := ifBGRA8;
-          end else begin
-            if FormatCheckFormat(RedMask, GreenMask, BlueMask, AlphaMask, tfRGBA8) then
-              Format := tfRGBA8;
-
-            if FormatCheckFormat(RedMask, GreenMask, BlueMask, AlphaMask, ifBGRA8) then
-              Format := ifBGRA8;
-
-            if FormatCheckFormat(RedMask, GreenMask, BlueMask, AlphaMask, tfRGB10A2) then
-              Format := tfRGB10A2;
-          end;
-        end;
-    end;
 
-    if Format <> ifEmpty then begin
-       LineSize := Trunc(Info.biWidth * FormatGetSize(Format));
-      Padding := GetLineWidth - LineSize;
 
-      // copying data
-      GetMem(NewImage, Info.biHeight * LineSize);
-      try
-        FillChar(NewImage^, Info.biHeight * LineSize, $FF);
+  }
 
-        // Set pData to last Line
-        pData := NewImage;
-        Inc(pData, LineSize * (Info.biHeight -1));
+  //////////////////////////////////////////////////////////////////////////////////////////////////
+  procedure ReadBitfieldLine(aData: PByte; aLineBuf: PByte);
+  var
+    i: Integer;
+    Pixel: TglBitmapPixelData;
 
-        // Copy Image Data
-        for LineIdx := 0 to Info.biHeight - 1 do begin
-          Stream.Read(pData^, LineSize);
-          Dec(pData, LineSize);
+    ////////////////////////////////////////////////////////////////////////////////////////////////
+    procedure ChangeRange(var aValue: Cardinal; const aOldRange, aNewRange: Cardinal);
+    begin
+      if (aOldRange = aNewRange) then
+        exit;
+      if (aOldRange > 0) then
+        aValue := Round(aValue / aOldRange * aNewRange)
+      else
+        aValue := 0;
+    end;
 
-          Stream.Read(PaddingBuff, Padding);
-        end;
+  begin
+    aStream.Read(aLineBuf^, rbLineSize);
+    for i := 0 to Info.biWidth-1 do begin
+      BitfieldFormat.Unmap(PCardinal(aLineBuf)^, Pixel); //if is 16bit Bitfield only 2 last significant Bytes are taken from Cardinal
+      inc(aLineBuf, Info.biBitCount shr 3);
+      with FormatDesc.GetPixelDesc do begin
+        ChangeRange(Pixel.Red,   BitfieldFormat.RedRange,   RedRange);
+        ChangeRange(Pixel.Green, BitfieldFormat.GreenRange, GreenRange);
+        ChangeRange(Pixel.Blue,  BitfieldFormat.BlueRange,  BlueRange);
+        ChangeRange(Pixel.Alpha, BitfieldFormat.AlphaRange, AlphaRange);
+      end;
+      FormatDesc.Map(Pixel, aData);
+    end;
+  end;
 
-        // Set new Image
-        SetDataPointer(NewImage, Format, Info.biWidth, Info.biHeight);
+begin
+  result         := false;
+  BmpFormat      := tfEmpty;
+  BitfieldFormat := nil;
+  LineBuf        := nil;
 
-        Result := True;
-      except
-        FreeMem(NewImage);
-        raise;
-      end;
+  // Header
+  StartPos := aStream.Position;
+  aStream.Read(Header, SizeOf(Header));
+
+  if Header.bfType = BMP_MAGIC then begin
+    BmpFormat      := ReadInfo(Info, Mask);
+    BitfieldFormat := CheckBitfields(BmpFormat, Mask);
+    try
+      if (Info.biBitCount < 16) then
+        aStream.Position := aStream.Position + Info.biClrUsed * 4;
+      aStream.Position := StartPos + Header.bfOffBits;
+
+      if (BmpFormat <> tfEmpty) then begin
+        FormatDesc := FORMAT_DESCRIPTORS[BmpFormat];
+        rbLineSize := Info.biWidth * (Info.biBitCount shr 3); //ReadBuffer LineSize
+        wbLineSize := Trunc(Info.biWidth * FormatDesc.GetSize);
+        Padding    := (((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3) - rbLineSize;
+
+        //get Memory
+        ImageSize := FormatDesc.GetSize(glBitmapPosition(Info.biWidth, Info.biHeight));
+        GetMem(ImageData, ImageSize);
+        if Assigned(BitfieldFormat) then
+          GetMem(LineBuf, rbLineSize); //tmp Memory for converting Bitfields
+
+        //read Data
+        try try
+          FillChar(ImageData^, ImageSize, $FF);
+          TmpData := ImageData;
+          Inc(TmpData, wbLineSize * (Info.biHeight -1));
+          for i := 0 to Info.biHeight-1 do begin
+            if Assigned(BitfieldFormat) then
+              ReadBitfieldLine(TmpData, LineBuf)  //if is bitfield format read and convert data
+            else
+              aStream.Read(TmpData^, wbLineSize);   //else only read data
+            Dec(TmpData, wbLineSize);
+            aStream.Read(PaddingBuff, Padding);
+          end;
+          SetDataPointer(ImageData, BmpFormat, Info.biWidth, Info.biHeight);
+          result := true;
+        finally
+          if Assigned(LineBuf) then
+            FreeMem(LineBuf);
+        end;
+        except
+          FreeMem(ImageData);
+          raise;
+        end;
+      end else
+        raise EglBitmapException.Create('LoadBMP - No suitable format found');
+    finally
+      FreeAndNil(BitfieldFormat);
     end;
   end
-    else Stream.Position := StreamPos;
+    else aStream.Position := StartPos;
 end;
-{$ENDREGION}
 
-const
-  DDS_MAGIC                   = $20534444;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SaveBMP(const aStream: TStream);
+var
+  Header: TBMPHeader;
+  Info: TBMPInfo;
+  pData, pTemp: pByte;
 
-  // DDS_header.dwFlags
-  DDSD_CAPS                   = $00000001;
-  DDSD_HEIGHT                 = $00000002;
-  DDSD_WIDTH                  = $00000004;
-  DDSD_PITCH                  = $00000008;
-  DDSD_PIXELFORMAT            = $00001000;
-  DDSD_MIPMAPCOUNT            = $00020000;
-  DDSD_LINEARSIZE             = $00080000;
-  DDSD_DEPTH                  = $00800000;
+  PixelFormat: TglBitmapPixelData;
+  ImageSize, LineSize, Padding, LineIdx, ColorIdx: Integer;
+  Temp, RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
 
-  // DDS_header.sPixelFormat.dwFlags
-  DDPF_ALPHAPIXELS            = $00000001;
-  DDPF_FOURCC                 = $00000004;
-  DDPF_INDEXED                = $00000020;
-  DDPF_RGB                    = $00000040;
+  PaddingBuff: Cardinal;
 
-  // DDS_header.sCaps.dwCaps1
-  DDSCAPS_COMPLEX             = $00000008;
-  DDSCAPS_TEXTURE             = $00001000;
-  DDSCAPS_MIPMAP              = $00400000;
+  function GetLineWidth : Integer;
+  begin
+    result := ((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3;
+  end;
 
-  // DDS_header.sCaps.dwCaps2
-  DDSCAPS2_CUBEMAP            = $00000200;
-  DDSCAPS2_CUBEMAP_POSITIVEX  = $00000400;
-  DDSCAPS2_CUBEMAP_NEGATIVEX  = $00000800;
-  DDSCAPS2_CUBEMAP_POSITIVEY  = $00001000;
-  DDSCAPS2_CUBEMAP_NEGATIVEY  = $00002000;
-  DDSCAPS2_CUBEMAP_POSITIVEZ  = $00004000;
-  DDSCAPS2_CUBEMAP_NEGATIVEZ  = $00008000;
-  DDSCAPS2_VOLUME             = $00200000;
+begin
+  if not (ftBMP in FormatGetSupportedFiles(Format)) then
+    raise EglBitmapUnsupportedFormatFormat.Create('SaveBMP - ' + UNSUPPORTED_FORMAT);
 
-  D3DFMT_DXT1                 = $31545844;
-  D3DFMT_DXT3                 = $33545844;
-  D3DFMT_DXT5                 = $35545844;
+  ImageSize := FORMAT_DESCRIPTORS[Format].GetSize(Dimension);
 
-type
-  TDDSPixelFormat = packed record
-    dwSize: Cardinal;
-    dwFlags: Cardinal;
-    dwFourCC: Cardinal;
-    dwRGBBitCount: Cardinal;
-    dwRBitMask: Cardinal;
-    dwGBitMask: Cardinal;
-    dwBBitMask: Cardinal;
-    dwAlphaBitMask: Cardinal;
-  end;
-
-  TDDSCaps = packed record
-    dwCaps1: Cardinal;
-    dwCaps2: Cardinal;
-    dwDDSX: Cardinal;
-    dwReserved: Cardinal;
-  end;
-
-  TDDSHeader = packed record
-    dwMagic: Cardinal;
-    dwSize: Cardinal;
-    dwFlags: Cardinal;
-    dwHeight: Cardinal;
-    dwWidth: Cardinal;
-    dwPitchOrLinearSize: Cardinal;
-    dwDepth: Cardinal;
-    dwMipMapCount: Cardinal;
-    dwReserved: array[0..10] of Cardinal;
-    PixelFormat: TDDSPixelFormat;
-    Caps: TDDSCaps;
-    dwReserved2: Cardinal;
-  end;
-
-
-
-function TglBitmap.LoadDDS(Stream: TStream): Boolean;
-var
-  Header: TDDSHeader;
-  StreamPos: Int64;
-  Y, LineSize: Cardinal;
+  Header.bfType      := BMP_MAGIC;
+  Header.bfSize      := SizeOf(Header) + SizeOf(Info) + ImageSize;
+  Header.bfReserved1 := 0;
+  Header.bfReserved2 := 0;
+  Header.bfOffBits   := SizeOf(Header) + SizeOf(Info);
 
-//  MipMapCount, X, Y, XSize, YSize: Cardinal;
-  RowSize: Cardinal;
-  NewImage, pData: pByte;
-  Format: TglBitmapFormat;
+  FillChar(Info, SizeOf(Info), 0);
+  Info.biSize        := SizeOf(Info);
+  Info.biWidth       := Width;
+  Info.biHeight      := Height;
+  Info.biPlanes      := 1;
+  Info.biCompression := BMP_COMP_RGB;
+  Info.biSizeImage   := ImageSize;
+  case Format of
+    //TODO tfAlpha8, ifLuminance8, ifDepth8:
+    tfLuminance8:
+      begin
+        Info.biBitCount :=  8;
 
+        Header.bfSize := Header.bfSize + 256 * SizeOf(Cardinal);
+        Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal);
 
-  function RaiseEx : Exception;
-  begin
-    Result := EglBitmapException.Create('LoadDDS - unsupported Pixelformat found.');
+        Info.biClrUsed := 256;
+        Info.biClrImportant := 256;
+      end;
+    //TODO ifLuminance8Alpha8, tfRGBA4, ifR5G6B5, tfRGB5A1:
+    tfLuminance8Alpha8, tfRGB5A1:
+      begin
+        Info.biBitCount := 16;
+        Info.biCompression := BMP_COMP_BITFIELDS;
+      end;
+    tfBGR8, tfRGB8:
+      Info.biBitCount := 24;
+    //TODO tfBGRA8, tfRGBA8, tfRGB10A2:
+    tfBGRA8, tfRGBA8:
+      begin
+        Info.biBitCount := 32;
+        Info.biCompression := BMP_COMP_BITFIELDS;
+      end;
+    else
+      raise EglBitmapUnsupportedFormatFormat.Create('SaveBMP - ' + UNSUPPORTED_FORMAT);
   end;
+  Info.biXPelsPerMeter := 2835;
+  Info.biYPelsPerMeter := 2835;
 
-  
-  function GetInternalFormat: TglBitmapFormat;
-  begin
-    with Header.PixelFormat do begin
-      // Compresses
-      if (dwFlags and DDPF_FOURCC) > 0 then begin
-        case Header.PixelFormat.dwFourCC of
-          D3DFMT_DXT1: Result := ifDXT1;
-          D3DFMT_DXT3: Result := ifDXT3;
-          D3DFMT_DXT5: Result := ifDXT5;
-          else
-            raise RaiseEx;
-        end;
-      end else
-
-      // RGB
-      if (dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS)) > 0 then begin
-        case dwRGBBitCount of
-           8:
-            begin
-              if dwFlags and DDPF_ALPHAPIXELS > 0 then
-                Result := ifAlpha
-              else
-                Result := ifLuminance;
-            end;
-          16:
-            begin
-              if dwFlags and DDPF_ALPHAPIXELS > 0 then begin
-                // Alpha
-                case GetBitSize(dwRBitMask) of
-                  5: Result := tfRGB5A1;
-                  4: Result := tfRGBA4;
-                else
-                  Result := ifLuminanceAlpha;
-                end;
-              end else begin
-                // no Alpha
-                Result := ifR5G6B5;
-              end;
-            end;
-          24:
-            begin
-              if dwRBitMask > dwBBitMask then
-                Result := ifBGR8
-              else
-                Result := tfRGB8;
-            end;
-          32:
-            begin
-              if GetBitSize(dwRBitMask) = 10 then
-                Result := tfRGB10A2
-              else
+  // prepare bitmasks
+  if Info.biCompression = BMP_COMP_BITFIELDS then begin
+    Info.biSize      := Info.biSize      + 4 * SizeOf(Cardinal);
+    Header.bfSize    := Header.bfSize    + 4 * SizeOf(Cardinal);
+    Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal);
 
-              if dwRBitMask > dwBBitMask then
-                Result := ifBGRA8
-              else
-                Result := tfRGBA8;
-            end;
-          else
-            raise RaiseEx;
-        end;
-      end else
-        raise RaiseEx;
+    FORMAT_DESCRIPTORS[Format].PreparePixel(PixelFormat);
+    with PixelFormat.PixelDesc do begin
+      RedMask   := RedRange   shl RedShift;
+      GreenMask := GreenRange shl GreenShift;
+      BlueMask  := BlueRange  shl BlueShift;
+      AlphaMask := AlphaRange shl AlphaShift;
     end;
   end;
 
-begin
-  Result := False;
-
-  // Header
-  StreamPos := Stream.Position;
-  Stream.Read(Header, sizeof(Header));
+  // headers
+  aStream.Write(Header, SizeOf(Header));
+  aStream.Write(Info, SizeOf(Info));
 
-  if ((Header.dwMagic <> DDS_MAGIC) or (Header.dwSize <> 124) or
-     ((Header.dwFlags and DDSD_PIXELFORMAT) = 0) or ((Header.dwFlags and DDSD_CAPS) = 0)) then begin
-    Stream.Position := StreamPos;
-    Exit;
+  // colortable
+  if Info.biBitCount = 8 then begin
+    Temp := 0;
+    for ColorIdx := Low(Byte) to High(Byte) do begin
+      aStream.Write(Temp, 4);
+      Temp := Temp + $00010101;
+    end;
   end;
 
-  // Pixelformat
-//  if Header.dwFlags and DDSD_MIPMAPCOUNT <> 0
-//    then MipMapCount := Header.dwMipMapCount
-//    else MipMapCount := 1;
-
-  Format := GetInternalFormat;
-  LineSize := Trunc(Header.dwWidth * FormatGetSize(Format));
-
-  GetMem(NewImage, Header.dwHeight * LineSize);
-  try
-    pData := NewImage;
-
-    // Compressed
-    if (Header.PixelFormat.dwFlags and DDPF_FOURCC) > 0 then begin
-      RowSize := Header.dwPitchOrLinearSize div Header.dwWidth;
-
-      for Y := 0 to Header.dwHeight -1 do begin
-        Stream.Read(pData^, RowSize);
-        Inc(pData, LineSize);
-      end;
-    end else
+  // bitmasks
+  if Info.biCompression = BMP_COMP_BITFIELDS then begin
+    aStream.Write(RedMask,   SizeOf(Cardinal));
+    aStream.Write(GreenMask, SizeOf(Cardinal));
+    aStream.Write(BlueMask,  SizeOf(Cardinal));
+    aStream.Write(AlphaMask, SizeOf(Cardinal));
+  end;
 
-    // RGB(A)
-    if (Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS)) > 0 then begin
-      RowSize := Header.dwPitchOrLinearSize;
+  // image data
+  LineSize := Trunc(Width * FORMAT_DESCRIPTORS[Format].GetSize);
+  Padding := GetLineWidth - LineSize;
+  PaddingBuff := 0;
 
-      for Y := 0 to Header.dwHeight -1 do begin
-        Stream.Read(pData^, RowSize);
-        Inc(pData, LineSize);
-      end;
-    end
-      else raise RaiseEx;
+  pData := Data;
+  Inc(pData, (Height -1) * LineSize);
 
-    SetDataPointer(NewImage, Format, Header.dwWidth, Header.dwHeight);
+  // prepare row buffer. But only for RGB because RGBA supports color masks
+  // so it's possible to change color within the image.
+  if (Format = tfRGB8) then
+    GetMem(pTemp, fRowSize)
+  else
+    pTemp := nil;
 
-    Result := True;
-  except
-    FreeMem(NewImage);
-    raise;
+  try
+    // write image data
+    for LineIdx := 0 to Height - 1 do begin
+      // preparing row
+      if Format = tfRGB8 then begin
+        Move(pData^, pTemp^, fRowSize);
+        SwapRGB(pTemp, Width, false);
+      end else
+        pTemp := pData;
+      aStream.Write(pTemp^, LineSize);
+      Dec(pData, LineSize);
+      if Padding > 0 then
+        aStream.Write(PaddingBuff, Padding);
+    end;
+  finally
+    // destroy row buffer
+    if Format = tfRGB8 then
+      FreeMem(pTemp);
   end;
 end;
 
-
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TGA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 type
   TTGAHeader = packed record
     ImageID: Byte;
@@ -4487,9 +5337,8 @@ const
   TGA_COMPRESSED_RGB = 10;
   TGA_COMPRESSED_GRAY = 11;
 
-
-
-function TglBitmap.LoadTGA(Stream: TStream): Boolean;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.LoadTGA(const aStream: TStream): Boolean;
 var
   Header: TTGAHeader;
   NewImage, pData: PByte;
@@ -4500,23 +5349,22 @@ var
 const
   CACHE_SIZE = $4000;
 
+  ////////////////////////////////////////////////////////////////////////////////////////
   procedure ReadUncompressed;
   var
     RowSize: Integer;
   begin
     RowSize := Header.Width * PixelSize;
-
     // copy line by line
     while YStart <> YEnd + YInc do begin
       pData := NewImage;
       Inc(pData, YStart * LineSize);
-
-      Stream.Read(pData^, RowSize);
+      aStream.Read(pData^, RowSize);
       Inc(YStart, YInc);
     end;
   end;
 
-
+  ////////////////////////////////////////////////////////////////////////////////////////
   procedure ReadCompressed;
   var
     HeaderWidth, HeaderHeight: Integer;
@@ -4531,7 +5379,7 @@ const
     PixelRepeat: Boolean;
     PixelToRead, TempPixels: Integer;
 
-
+    /////////////////////////////////////////////////////////////////
     procedure CheckLine;
     begin
       if LinePixelsRead >= HeaderWidth then begin
@@ -4542,8 +5390,8 @@ const
       end;
     end;
 
-
-    procedure CachedRead(var Buffer; Count: Integer);
+    /////////////////////////////////////////////////////////////////
+    procedure CachedRead(out Buffer; Count: Integer);
     var
       BytesRead: Integer;
     begin
@@ -4553,14 +5401,13 @@ const
         // Read Data
         if CacheSize - CachePos > 0 then begin
           BytesRead := CacheSize - CachePos;
-
           Move(pByteArray(Cache)^[CachePos], Buffer, BytesRead);
           Inc(CachePos, BytesRead);
         end;
 
         // Reload Data
-        CacheSize := Min(CACHE_SIZE, Stream.Size - Stream.Position);
-        Stream.Read(Cache^, CacheSize);
+        CacheSize := Min(CACHE_SIZE, aStream.Size - aStream.Position);
+        aStream.Read(Cache^, CacheSize);
         CachePos := 0;
 
         // Read else
@@ -4574,7 +5421,6 @@ const
       end;
     end;
 
-
   begin
     CacheSize := 0;
     CachePos := 0;
@@ -4596,7 +5442,7 @@ const
         CachedRead(Temp, 1);
 
         PixelRepeat := Temp and $80 > 0;
-        PixelToRead := (Temp and $7F) + 1; 
+        PixelToRead := (Temp and $7F) + 1;
 
         Inc(ImgPixelsRead, PixelToRead);
 
@@ -4611,36 +5457,31 @@ const
             TempPixels := HeaderWidth - LinePixelsRead;
             if PixelToRead < TempPixels then
               TempPixels := PixelToRead;
-              
+
             Inc(LinePixelsRead, TempPixels);
             Dec(PixelToRead, TempPixels);
 
             while TempPixels > 0 do begin
               case PixelSize of
-                1:
-                  begin
-                    pData^ := TempBuf[0];
-                    Inc(pData);
-                  end;
-                2:
-                  begin
-                    pWord(pData)^ := pWord(@TempBuf[0])^;
-                    Inc(pData, 2);
-                  end;
-                3:
-                  begin
-                    pWord(pData)^ := pWord(@TempBuf[0])^;
-                    Inc(pData, 2);
-                    pData^ := TempBuf[2];
-                    Inc(pData);
-                  end;
-                4:
-                  begin
-                    pDWord(pData)^ := pDWord(@TempBuf[0])^;
-                    Inc(pData, 4);
-                  end;
+                1: begin
+                  pData^ := TempBuf[0];
+                  Inc(pData);
+                end;
+                2: begin
+                  pWord(pData)^ := pWord(@TempBuf[0])^;
+                  Inc(pData, 2);
+                end;
+                3: begin
+                  pWord(pData)^ := pWord(@TempBuf[0])^;
+                  Inc(pData, 2);
+                  pData^ := TempBuf[2];
+                  Inc(pData);
+                end;
+                4: begin
+                  pDWord(pData)^ := pDWord(@TempBuf[0])^;
+                  Inc(pData, 4);
+                end;
               end;
-
               Dec(TempPixels);
             end;
           end;
@@ -4648,16 +5489,12 @@ const
           // copy x pixels
           while PixelToRead > 0 do begin
             CheckLine;
-
             TempPixels := HeaderWidth - LinePixelsRead;
             if PixelToRead < TempPixels then
               TempPixels := PixelToRead;
-
             CachedRead(pData^, PixelSize * TempPixels);
             Inc(pData, PixelSize * TempPixels);
-
             Inc(LinePixelsRead, TempPixels);
-
             Dec(PixelToRead, TempPixels);
           end;
         end;
@@ -4668,30 +5505,30 @@ const
   end;
 
 begin
-  Result := False;
+  result := false;
 
   // reading header to test file and set cursor back to begin
-  StreamPos := Stream.Position;
-  Stream.Read(Header, SizeOf(Header));
+  StreamPos := aStream.Position;
+  aStream.Read(Header, SizeOf(Header));
 
   // no colormapped files
   if (Header.ColorMapType = 0) then begin
     if Header.ImageType in [TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY] then begin
       case Header.Bpp of
-         8: Format := ifAlpha;
-        16: Format := ifLuminanceAlpha;
-        24: Format := ifBGR8;
-        32: Format := ifBGRA8;
-        else
-          raise EglBitmapException.Create('LoadTga - unsupported BitsPerPixel found.');
+        //TODO 8: Format := tfAlpha8;
+        16: Format := tfLuminance8Alpha8;
+        24: Format := tfBGR8;
+        32: Format := tfBGRA8;
+      else
+        raise EglBitmapException.Create('LoadTga - unsupported BitsPerPixel found.');
       end;
 
       // skip image ID
       if Header.ImageID <> 0 then
-        Stream.Position := Stream.Position + Header.ImageID;
+        aStream.Position := aStream.Position + Header.ImageID;
 
-      PixelSize := Trunc(FormatGetSize(Format));
-      LineSize := Trunc(Header.Width * PixelSize);
+      PixelSize := Trunc(FORMAT_DESCRIPTORS[Format].GetSize);
+      LineSize  := Trunc(Header.Width * PixelSize);
 
       GetMem(NewImage, LineSize * Header.Height);
       try
@@ -4715,216 +5552,320 @@ begin
         end;
 
         SetDataPointer(NewImage, Format, Header.Width, Header.Height);
-
-        Result := True;
+        result := true;
       except
         FreeMem(NewImage);
         raise;
       end;
     end
-      else Stream.Position := StreamPos;
+      else aStream.Position := StreamPos;
   end
-    else Stream.Position := StreamPos;
+    else aStream.Position := StreamPos;
 end;
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SaveTGA(const aStream: TStream);
+var
+  Header: TTGAHeader;
+  Size: Integer;
+  pTemp: pByte;
+  FormatDesc: TglBitmapFormatDescClass;
 
-{$IFDEF GLB_SUPPORT_PNG_WRITE}
-{$IFDEF GLB_LIB_PNG}
-procedure glBitmap_libPNG_write_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
-begin
-  TStream(png_get_io_ptr(png)).Write(buffer^, size);
-end;
-{$ENDIF}
+  procedure ConvertData(pTemp: pByte);
+  var
+    Idx, PixelSize: Integer;
+    Temp: byte;
+  begin
+    PixelSize := fPixelSize;
+    for Idx := 1 to Height * Width do begin
+      Temp := pByteArray(pTemp)^[2];
+      pByteArray(pTemp)^[2] := pByteArray(pTemp)^[0];
+      pByteArray(pTemp)^[0] := Temp;
+      Inc(pTemp, PixelSize);
+    end;
+  end;
 
-procedure TglBitmap.SavePNG(Stream: TStream);
-{$IFDEF GLB_LIB_PNG}
-var
-  png: png_structp;
-  png_info: png_infop;
-  png_rows: array of pByte;
-  LineSize: Integer;
-  ColorType: Integer;
-  Row: Integer;
 begin
-  if not (ftPNG in FormatGetSupportedFiles (InternalFormat)) then
-    raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
-
-  if not init_libPNG then
-    raise Exception.Create('SavePNG - unable to initialize libPNG.');
+  if not (ftTGA in FormatGetSupportedFiles(Format)) then
+    raise EglBitmapUnsupportedFormatFormat.Create('SaveTGA - ' + UNSUPPORTED_FORMAT);
 
-  try
-    case FInternalFormat of
-      ifAlpha, ifLuminance, ifDepth8:
-        ColorType := PNG_COLOR_TYPE_GRAY;
-      ifLuminanceAlpha:
-        ColorType := PNG_COLOR_TYPE_GRAY_ALPHA;
-      ifBGR8, ifRGB8:
-        ColorType := PNG_COLOR_TYPE_RGB;
-      ifBGRA8, ifRGBA8:
-        ColorType := PNG_COLOR_TYPE_RGBA;
-      else
-        raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
+  FillChar(Header, SizeOf(Header), 0);
+  case Format of
+    //TODO ifAlpha8, ifLuminance8, ifDepth8: begin
+    tfLuminance8: begin
+      Header.ImageType := TGA_UNCOMPRESSED_GRAY;
+      Header.Bpp := 8;
+    end;
+    tfLuminance8Alpha8: begin
+      Header.ImageType := TGA_UNCOMPRESSED_GRAY;
+      Header.Bpp := 16;
     end;
+    tfRGB8, tfBGR8: begin
+      Header.ImageType := TGA_UNCOMPRESSED_RGB;
+      Header.Bpp := 24;
+    end;
+    tfRGBA8, tfBGRA8: begin
+      Header.ImageType := TGA_UNCOMPRESSED_RGB;
+      Header.Bpp := 32;
+    end;
+  else
+    raise EglBitmapUnsupportedFormatFormat.Create('SaveTGA - ' + UNSUPPORTED_FORMAT);
+  end;
 
-    LineSize := Trunc(FormatGetSize(FInternalFormat) * Width);
+  Header.Width    := Width;
+  Header.Height   := Height;
+  Header.ImageDes := $20;
+  FormatDesc      := FORMAT_DESCRIPTORS[Format];
 
-    // creating array for scanline
-    SetLength(png_rows, Height);
-    try
-      for Row := 0 to Height - 1 do begin
-        png_rows[Row] := Data;
-        Inc(png_rows[Row], Row * LineSize)
-      end;
+  if FormatDesc.HasAlpha then
+    Header.ImageDes := Header.ImageDes or $08;
+  aStream.Write(Header, SizeOf(Header));
 
-      // write struct
-      png := png_create_write_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
-      if png = nil then
-        raise EglBitmapException.Create('SavePng - couldn''t create write struct.');
+  // convert RGB(A) to BGR(A)
+  Size := FormatDesc.GetSize(Dimension);
+  if Format in [tfRGB8, tfRGBA8] then begin
+    GetMem(pTemp, Size);
+  end else
+    pTemp := Data;
 
-      // create png info
-      png_info := png_create_info_struct(png);
-      if png_info = nil then begin
-        png_destroy_write_struct(@png, nil);
-        raise EglBitmapException.Create('SavePng - couldn''t create info struct.');
-      end;
+  try
+    // convert data
+    if Format in [tfRGB8, tfRGBA8] then begin
+      Move(Data^, pTemp^, Size);
+      ConvertData(pTemp);
+    end;
 
-      // set read callback
-      png_set_write_fn(png, stream, glBitmap_libPNG_write_func, nil);
+    // write data
+    aStream.Write(pTemp^, Size);
+  finally
+    // free tempdata
+    if Format in [tfRGB8, tfRGBA8] then
+      FreeMem(pTemp);
+  end;
+end;
 
-      // set compression
-      png_set_compression_level(png, 6);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//DDS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+const
+  DDS_MAGIC                   = $20534444;
 
-      if InternalFormat in [ifBGR8, ifBGRA8] then
-        png_set_bgr(png);
+  // DDS_header.dwFlags
+  DDSD_CAPS                   = $00000001;
+  DDSD_HEIGHT                 = $00000002;
+  DDSD_WIDTH                  = $00000004;
+  DDSD_PITCH                  = $00000008;
+  DDSD_PIXELFORMAT            = $00001000;
+  DDSD_MIPMAPCOUNT            = $00020000;
+  DDSD_LINEARSIZE             = $00080000;
+  DDSD_DEPTH                  = $00800000;
 
-      // setup header
-      png_set_IHDR(png, png_info, Width, Height, 8, ColorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+  // DDS_header.sPixelFormat.dwFlags
+  DDPF_ALPHAPIXELS            = $00000001;
+  DDPF_FOURCC                 = $00000004;
+  DDPF_INDEXED                = $00000020;
+  DDPF_RGB                    = $00000040;
 
-      // write info
-      png_write_info(png, png_info);
+  // DDS_header.sCaps.dwCaps1
+  DDSCAPS_COMPLEX             = $00000008;
+  DDSCAPS_TEXTURE             = $00001000;
+  DDSCAPS_MIPMAP              = $00400000;
 
-      // write image data
-      png_write_image(png, @png_rows[0]);
+  // DDS_header.sCaps.dwCaps2
+  DDSCAPS2_CUBEMAP            = $00000200;
+  DDSCAPS2_CUBEMAP_POSITIVEX  = $00000400;
+  DDSCAPS2_CUBEMAP_NEGATIVEX  = $00000800;
+  DDSCAPS2_CUBEMAP_POSITIVEY  = $00001000;
+  DDSCAPS2_CUBEMAP_NEGATIVEY  = $00002000;
+  DDSCAPS2_CUBEMAP_POSITIVEZ  = $00004000;
+  DDSCAPS2_CUBEMAP_NEGATIVEZ  = $00008000;
+  DDSCAPS2_VOLUME             = $00200000;
 
-      // write end
-      png_write_end(png, png_info);
+  D3DFMT_DXT1                 = $31545844;
+  D3DFMT_DXT3                 = $33545844;
+  D3DFMT_DXT5                 = $35545844;
 
-      // destroy write struct
-      png_destroy_write_struct(@png, @png_info);
-    finally
-      SetLength(png_rows, 0);
-    end;
-  finally
-    quit_libPNG;
+type
+  TDDSPixelFormat = packed record
+    dwSize: Cardinal;
+    dwFlags: Cardinal;
+    dwFourCC: Cardinal;
+    dwRGBBitCount: Cardinal;
+    dwRBitMask: Cardinal;
+    dwGBitMask: Cardinal;
+    dwBBitMask: Cardinal;
+    dwAlphaBitMask: Cardinal;
   end;
-end;
-{$ENDIF}
-{$IFDEF GLB_PNGIMAGE}
+
+  TDDSCaps = packed record
+    dwCaps1: Cardinal;
+    dwCaps2: Cardinal;
+    dwDDSX: Cardinal;
+    dwReserved: Cardinal;
+  end;
+
+  TDDSHeader = packed record
+    dwMagic: Cardinal;
+    dwSize: Cardinal;
+    dwFlags: Cardinal;
+    dwHeight: Cardinal;
+    dwWidth: Cardinal;
+    dwPitchOrLinearSize: Cardinal;
+    dwDepth: Cardinal;
+    dwMipMapCount: Cardinal;
+    dwReserved: array[0..10] of Cardinal;
+    PixelFormat: TDDSPixelFormat;
+    Caps: TDDSCaps;
+    dwReserved2: Cardinal;
+  end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap.LoadDDS(const aStream: TStream): Boolean;
 var
-  Png: TPNGObject;
+  Header: TDDSHeader;
+  StreamPos: Int64;
+  Y, LineSize: Cardinal;
+  RowSize: Cardinal;
+  NewImage, pData: pByte;
+  ddsFormat: TglBitmapFormat;
 
-  pSource, pDest: pByte;
-  X, Y, PixSize: Integer;
-  ColorType: Cardinal;
-  Alpha: Boolean;
+  function RaiseEx : Exception;
+  begin
+    result := EglBitmapException.Create('LoadDDS - unsupported Pixelformat found.');
+  end;
 
-  pTemp: pByte;
-  Temp: Byte;
-begin
-  if not (ftPNG in FormatGetSupportedFiles (InternalFormat)) then 
-    raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
+  function GetDDSFormat: TglBitmapFormat;
+  begin
+    with Header.PixelFormat do begin
+      // Compresses
+      if (dwFlags and DDPF_FOURCC) > 0 then begin
+        (* TODO
+        case Header.PixelFormat.dwFourCC of
+          D3DFMT_DXT1: result := ifDXT1;
+          D3DFMT_DXT3: result := ifDXT3;
+          D3DFMT_DXT5: result := ifDXT5;
+        else
+          raise RaiseEx;
+        end;
+        *)
+        raise RaiseEx;
+      end else
 
-  case FInternalFormat of
-    ifAlpha, ifLuminance, ifDepth8:
-      begin
-        ColorType := COLOR_GRAYSCALE;
-        PixSize := 1;
-        Alpha := False;
-      end;
-    ifLuminanceAlpha:
-      begin
-        ColorType := COLOR_GRAYSCALEALPHA;
-        PixSize := 1;
-        Alpha := True;
-      end;
-    ifBGR8, ifRGB8:
-      begin
-        ColorType := COLOR_RGB;
-        PixSize := 3;
-        Alpha := False;
-      end;
-    ifBGRA8, ifRGBA8:
-      begin
-        ColorType := COLOR_RGBALPHA;
-        PixSize := 3;
-        Alpha := True
-      end;
-    else
-      raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
+      // RGB
+      if (dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS)) > 0 then begin
+        case dwRGBBitCount of
+          8: begin
+            (* TODO if dwFlags and DDPF_ALPHAPIXELS > 0 then
+              result := tfAlpha
+            else
+            *)
+              result := tfLuminance8;
+          end;
+          16: begin
+            if dwFlags and DDPF_ALPHAPIXELS > 0 then begin
+              // Alpha
+              case CountSetBits(dwRBitMask) of
+                5: result := tfRGB5A1;
+                //TODO 4: result := tfRGBA4;
+              else
+                result := tfLuminance8Alpha8;
+              end;
+            end else begin
+              // no Alpha
+              //TODO result := ifR5G6B5;
+              raise RaiseEx;
+            end;
+          end;
+          24: begin
+            if dwRBitMask > dwBBitMask then
+              result := tfBGR8
+            else
+              result := tfRGB8;
+          end;
+        32: begin
+            if CountSetBits(dwRBitMask) = 10 then
+              //TODO result := tfRGB10A2
+              raise RaiseEx
+            else
+
+            if dwRBitMask > dwBBitMask then
+              result := tfBGRA8
+            else
+              result := tfRGBA8;
+          end;
+        else
+          raise RaiseEx;
+        end;
+      end else
+        raise RaiseEx;
+    end;
   end;
 
-  Png := TPNGObject.CreateBlank(ColorType, 8, Width, Height);
-  try
-    // Copy ImageData
-    pSource := Data;
-    for Y := 0 to Height -1 do begin
-      pDest := png.ScanLine[Y];
+begin
+  result := false;
 
-      for X := 0 to Width -1 do begin
-        Move(pSource^, pDest^, PixSize);
+  // Header
+  StreamPos := aStream.Position;
+  aStream.Read(Header, sizeof(Header));
 
-        Inc(pDest, PixSize);
-        Inc(pSource, PixSize);
+  if ((Header.dwMagic <> DDS_MAGIC) or (Header.dwSize <> 124) or
+     ((Header.dwFlags and DDSD_PIXELFORMAT) = 0) or ((Header.dwFlags and DDSD_CAPS) = 0)) then begin
+    aStream.Position := StreamPos;
+    exit;
+  end;
 
-        if Alpha then begin
-          png.AlphaScanline[Y]^[X] := pSource^;
-          Inc(pSource);
-        end;
-      end;
+  ddsFormat := GetDDSFormat;
+  LineSize  := Trunc(Header.dwWidth * FORMAT_DESCRIPTORS[ddsFormat].GetSize);
+  GetMem(NewImage, Header.dwHeight * LineSize);
+  try
+    pData := NewImage;
 
-      // convert RGB line to BGR
-      if InternalFormat in [ifRGB8, ifRGBA8] then begin
-        pTemp := png.ScanLine[Y];
+    // Compressed
+    if (Header.PixelFormat.dwFlags and DDPF_FOURCC) > 0 then begin
+      RowSize := Header.dwPitchOrLinearSize div Header.dwWidth;
+      for Y := 0 to Header.dwHeight -1 do begin
+        aStream.Read(pData^, RowSize);
+        Inc(pData, LineSize);
+      end;
+    end else
 
-        for X := 0 to Width -1 do begin
-          Temp := pByteArray(pTemp)^[0];
-          pByteArray(pTemp)^[0] := pByteArray(pTemp)^[2];
-          pByteArray(pTemp)^[2] := Temp;
+    // RGB(A)
+    if (Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS)) > 0 then begin
+      RowSize := Header.dwPitchOrLinearSize;
 
-          Inc(pTemp, 3);
-        end;
+      for Y := 0 to Header.dwHeight -1 do begin
+        aStream.Read(pData^, RowSize);
+        Inc(pData, LineSize);
       end;
-    end;
+    end else
+      raise RaiseEx;
 
-    // Save to Stream
-    Png.CompressionLevel := 6; 
-    Png.SaveToStream(Stream);
-  finally
-    FreeAndNil(Png);
+    SetDataPointer(NewImage, ddsFormat, Header.dwWidth, Header.dwHeight);
+    result := true;
+  except
+    FreeMem(NewImage);
+    raise;
   end;
 end;
-{$ENDIF}
-{$ENDIF}
-
 
-procedure TglBitmap.SaveDDS(Stream: TStream);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap.SaveDDS(const aStream: TStream);
 var
   Header: TDDSHeader;
   Pix: TglBitmapPixelData;
 begin
-  if not FormatIsUncompressed(InternalFormat) then
-    raise EglBitmapUnsupportedFormatFormat.Create('SaveDDS - ' + UNSUPPORTED_INTERNAL_FORMAT);
+  //if not FormatIsUncompressed(InternalFormat) then
+  //  raise EglBitmapUnsupportedFormatFormat.Create('SaveDDS - ' + UNSUPPORTED_FORMAT);
 
-  if InternalFormat = ifAlpha then
-    FormatPreparePixel(Pix, ifLuminance)
-  else
-    FormatPreparePixel(Pix, InternalFormat);
+  (* TODO if Format = tfAlpha8 then
+    FORMAT_DESCRIPTORS[tfLuminance8].PreparePixel(Pix);
+  else    *)
+    FORMAT_DESCRIPTORS[Format].PreparePixel(Pix);
 
   // Generell
   FillChar(Header, SizeOf(Header), 0);
-
   Header.dwMagic := DDS_MAGIC;
-  Header.dwSize := 124;
+  Header.dwSize  := 124;
   Header.dwFlags := DDSD_PITCH or DDSD_CAPS or DDSD_PIXELFORMAT;
 
   if Width > 0 then begin
@@ -4937,1255 +5878,289 @@ begin
     Header.dwFlags := Header.dwFlags or DDSD_HEIGHT;
   end;
 
-  Header.dwPitchOrLinearSize := fRowSize;
-  Header.dwMipMapCount := 1;
-
-  // Caps
-  Header.Caps.dwCaps1 := DDSCAPS_TEXTURE;
-
-  // Pixelformat
-  Header.PixelFormat.dwSize := Sizeof(Header.PixelFormat);
-  Header.PixelFormat.dwFlags := DDPF_RGB;
-
-  if FormatHasAlpha(InternalFormat) and (InternalFormat <> ifAlpha)
-    then Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHAPIXELS;
-
-  Header.PixelFormat.dwRGBBitCount  := Trunc(FormatGetSize(InternalFormat) * 8);
-  Header.PixelFormat.dwRBitMask     := Pix.PixelDesc.RedRange   shl Pix.PixelDesc.RedShift;
-  Header.PixelFormat.dwGBitMask     := Pix.PixelDesc.GreenRange shl Pix.PixelDesc.GreenShift;
-  Header.PixelFormat.dwBBitMask     := Pix.PixelDesc.BlueRange  shl Pix.PixelDesc.BlueShift;
-  Header.PixelFormat.dwAlphaBitMask := Pix.PixelDesc.AlphaRange shl Pix.PixelDesc.AlphaShift;
-
-  // Write
-  Stream.Write(Header, SizeOf(Header));
-
-  Stream.Write(Data^, FormatGetImageSize(glBitmapPosition(Width, Height), InternalFormat));
-end;
-
-
-procedure TglBitmap.SaveTGA(Stream: TStream);
-var
-  Header: TTGAHeader;
-  Size: Integer;
-  pTemp: pByte;
-
-
-  procedure ConvertData(pTemp: pByte);
-  var
-    Idx, PixelSize: Integer;
-    Temp: byte;
-  begin
-    PixelSize := fPixelSize;
-
-    for Idx := 1 to Height * Width do begin
-      Temp := pByteArray(pTemp)^[2];
-      pByteArray(pTemp)^[2] := pByteArray(pTemp)^[0];
-      pByteArray(pTemp)^[0] := Temp;
-
-      Inc(pTemp, PixelSize);
-    end;
-  end;
-
-
-begin
-  if not (ftTGA in FormatGetSupportedFiles (InternalFormat)) then 
-    raise EglBitmapUnsupportedFormatFormat.Create('SaveTGA - ' + UNSUPPORTED_INTERNAL_FORMAT);
-
-  FillChar(Header, SizeOf(Header), 0);
-
-  case InternalFormat of
-    ifAlpha, ifLuminance, ifDepth8:
-      begin
-        Header.ImageType := TGA_UNCOMPRESSED_GRAY;
-        Header.Bpp := 8;
-      end;
-    ifLuminanceAlpha:
-      begin
-        Header.ImageType := TGA_UNCOMPRESSED_GRAY;
-        Header.Bpp := 16;
-      end;
-    tfRGB8, ifBGR8:
-      begin
-        Header.ImageType := TGA_UNCOMPRESSED_RGB;
-        Header.Bpp := 24;
-      end;
-    tfRGBA8, ifBGRA8:
-      begin
-        Header.ImageType := TGA_UNCOMPRESSED_RGB;
-        Header.Bpp := 32;
-      end;
-    else
-      raise EglBitmapUnsupportedFormatFormat.Create('SaveTGA - ' + UNSUPPORTED_INTERNAL_FORMAT);
-  end;
-
-  Header.Width := Width;
-  Header.Height := Height;
-  Header.ImageDes := $20;
-
-  if FormatHasAlpha(InternalFormat) then
-    Header.ImageDes := Header.ImageDes or $08;
-
-  Stream.Write(Header, SizeOf(Header));
-
-  // convert RGB(A) to BGR(A)
-  Size := FormatGetImageSize(glBitmapPosition(Width, Height), InternalFormat);
-  if InternalFormat in [tfRGB8, tfRGBA8] then begin
-    GetMem(pTemp, Size);
-  end else
-    pTemp := Data;
-
-  try
-    // convert data
-    if InternalFormat in [tfRGB8, tfRGBA8] then begin
-      Move(Data^, pTemp^, Size);
-      ConvertData(pTemp);
-    end;
-
-    // write data
-    Stream.Write(pTemp^, Size);
-  finally
-    // free tempdata
-    if InternalFormat in [tfRGB8, tfRGBA8] then
-      FreeMem(pTemp);
-  end;
-end;
-
-
-{$IFDEF GLB_SUPPORT_JPEG_WRITE}
-procedure TglBitmap.SaveJPEG(Stream: TStream);
-{$IFDEF GLB_LIB_JPEG}
-var
-  jpeg: jpeg_compress_struct;
-  jpeg_err: jpeg_error_mgr;
-  Row: Integer;
-  pTemp, pTemp2: pByte;
-
-
-  procedure CopyRow(pDest, pSource: pByte);
-  var
-    X: Integer;
-  begin
-    for X := 0 to Width - 1 do begin
-      pByteArray(pDest)^[0] := pByteArray(pSource)^[2];
-      pByteArray(pDest)^[1] := pByteArray(pSource)^[1];
-      pByteArray(pDest)^[2] := pByteArray(pSource)^[0];
-
-      Inc(pDest, 3);
-      Inc(pSource, 3); 
-    end;
-  end;
-
-begin
-  if not (ftJPEG in FormatGetSupportedFiles(InternalFormat)) then
-    raise EglBitmapUnsupportedInternalFormat.Create('SaveJpg - ' + UNSUPPORTED_INTERNAL_FORMAT);
-
-  if not init_libJPEG then
-    raise Exception.Create('SaveJPG - unable to initialize libJPEG.');
-
-  try
-    FillChar(jpeg, SizeOf(jpeg_compress_struct), $00);
-    FillChar(jpeg_err, SizeOf(jpeg_error_mgr), $00);
-
-    // error managment
-    jpeg.err := jpeg_std_error(@jpeg_err);
-    jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
-    jpeg_err.output_message := glBitmap_libJPEG_output_message;
-
-    // compression struct
-    jpeg_create_compress(@jpeg);
-
-    // allocation space for streaming methods
-    jpeg.dest := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_dest_mgr));
-
-    // seeting up custom functions
-    with glBitmap_libJPEG_dest_mgr_ptr(jpeg.dest)^ do begin
-      pub.init_destination    := glBitmap_libJPEG_init_destination;
-      pub.empty_output_buffer := glBitmap_libJPEG_empty_output_buffer;
-      pub.term_destination    := glBitmap_libJPEG_term_destination;
-
-      pub.next_output_byte  := @DestBuffer[1];
-      pub.free_in_buffer    := Length(DestBuffer);
-
-      DestStream := Stream;
-    end;
-
-    // very important state
-    jpeg.global_state := CSTATE_START;
-
-    jpeg.image_width := Width;
-    jpeg.image_height := Height;
-    case InternalFormat of
-      ifAlpha, ifLuminance, ifDepth8:
-        begin
-          jpeg.input_components := 1;
-          jpeg.in_color_space := JCS_GRAYSCALE;
-        end;
-      ifRGB8, ifBGR8:
-        begin
-          jpeg.input_components := 3;
-          jpeg.in_color_space := JCS_RGB;
-        end;
-    end;
-
-    // setting defaults
-    jpeg_set_defaults(@jpeg);
-
-    // compression quality
-    jpeg_set_quality(@jpeg, 95, True);
-
-    // start compression
-    jpeg_start_compress(@jpeg, true);
-
-    // write rows
-    pTemp := Data;
-
-    // initialing row  
-    if InternalFormat = ifBGR8 then
-      GetMem(pTemp2, fRowSize)
-    else
-      pTemp2 := pTemp;
-
-    try
-      for Row := 0 to jpeg.image_height -1 do begin
-        // prepare row
-        if InternalFormat = ifBGR8 then
-          CopyRow(pTemp2, pTemp)
-        else
-          pTemp2 := pTemp;
-
-        // write row
-        jpeg_write_scanlines(@jpeg, @pTemp2, 1);
-        inc(pTemp, fRowSize);
-      end;
-    finally
-      // free memory
-      if InternalFormat = ifBGR8 then
-        FreeMem(pTemp2);
-    end;
-
-    // finish compression
-    jpeg_finish_compress(@jpeg);
-
-    // destroy compression
-    jpeg_destroy_compress(@jpeg);
-  finally
-    quit_libJPEG;
-  end;
-end;
-{$ENDIF}
-{$IFDEF GLB_DELPHI_JPEG}
-var
-  Bmp: TBitmap;
-  Jpg: TJPEGImage;
-begin
-  if not (ftJPEG in FormatGetSupportedFiles (InternalFormat)) then 
-    raise EglBitmapUnsupportedInternalFormat.Create('SaveJpg - ' + UNSUPPORTED_INTERNAL_FORMAT);
-
-  Bmp := TBitmap.Create;
-  try
-    Jpg := TJPEGImage.Create;
-    try
-      AssignToBitmap(Bmp);
-
-      if FInternalFormat in [ifAlpha, ifLuminance, ifDepth8] then begin
-        Jpg.Grayscale := True;
-        Jpg.PixelFormat := jf8Bit;
-      end;
-
-      Jpg.Assign(Bmp);
-
-      Jpg.SaveToStream(Stream);
-    finally
-      FreeAndNil(Jpg);
-    end;
-  finally
-    FreeAndNil(Bmp);
-  end;
-end;
-{$ENDIF}
-{$ENDIF}
-
-
-procedure TglBitmap.SaveBMP(Stream: TStream);
-var
-  Header: TBMPHeader;
-  Info: TBMPInfo;
-  pData, pTemp: pByte;
-
-  PixelFormat: TglBitmapPixelData;
-  ImageSize, LineSize, Padding, LineIdx, ColorIdx: Integer;
-  Temp, RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
-
-  PaddingBuff: Cardinal;
-
-
-  function GetLineWidth : Integer;
-  begin
-    Result := ((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3;
-  end;
-
-
-begin
-  if not (ftBMP in FormatGetSupportedFiles(InternalFormat)) then
-    raise EglBitmapUnsupportedFormatFormat.Create('SaveBMP - ' + UNSUPPORTED_INTERNAL_FORMAT);
-
-  ImageSize := Trunc(Width * Height * FormatGetSize(InternalFormat));
-
-  Header.bfType := BMP_MAGIC;
-  Header.bfSize := SizeOf(Header) + SizeOf(Info) + ImageSize;
-  Header.bfReserved1 := 0;
-  Header.bfReserved2 := 0;
-  Header.bfOffBits := SizeOf(Header) + SizeOf(Info);
-
-  FillChar(Info, SizeOf(Info), 0);
-  Info.biSize := SizeOf(Info);
-  Info.biWidth := Width;
-  Info.biHeight := Height;
-  Info.biPlanes := 1;
-  Info.biCompression := BMP_COMP_RGB;
-  Info.biSizeImage := ImageSize;
-  case InternalFormat of
-    ifAlpha, ifLuminance, ifDepth8:
-      begin
-        Info.biBitCount :=  8;
-
-        Header.bfSize := Header.bfSize + 256 * SizeOf(Cardinal);
-        Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal);
-
-        Info.biClrUsed := 256;
-        Info.biClrImportant := 256;
-      end;
-    ifLuminanceAlpha, tfRGBA4, ifR5G6B5, tfRGB5A1:
-      begin
-        Info.biBitCount := 16;
-        Info.biCompression := BMP_COMP_BITFIELDS;
-      end;
-    ifBGR8, tfRGB8:
-      Info.biBitCount := 24;
-    ifBGRA8, tfRGBA8, tfRGB10A2:
-      begin
-        Info.biBitCount := 32;
-        Info.biCompression := BMP_COMP_BITFIELDS;
-      end;
-    else
-      raise EglBitmapUnsupportedFormatFormat.Create('SaveBMP - ' + UNSUPPORTED_INTERNAL_FORMAT);
-  end;
-  Info.biXPelsPerMeter := 2835;
-  Info.biYPelsPerMeter := 2835;
-
-  // prepare bitmasks
-  if Info.biCompression = BMP_COMP_BITFIELDS then begin
-    Info.biSize := Info.biSize + 4 * SizeOf(Cardinal);
-    Header.bfSize := Header.bfSize + 4 * SizeOf(Cardinal);
-    Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal);
-
-    FormatPreparePixel(PixelFormat, InternalFormat);
-
-    with PixelFormat.PixelDesc do begin
-      RedMask   := RedRange   shl RedShift;
-      GreenMask := GreenRange shl GreenShift;
-      BlueMask  := BlueRange  shl BlueShift;
-      AlphaMask := AlphaRange shl AlphaShift;
-    end;
-  end;
-
-  // headers
-  Stream.Write(Header, SizeOf(Header));
-  Stream.Write(Info, SizeOf(Info));
-
-  // colortable
-  if Info.biBitCount = 8 then begin
-    Temp := 0;
-    for ColorIdx := Low(Byte) to High(Byte) do begin
-      Stream.Write(Temp, 4);
-      Temp := Temp + $00010101;
-    end;
-  end;
-
-  // bitmasks
-  if Info.biCompression = BMP_COMP_BITFIELDS then begin
-    Stream.Write(RedMask, SizeOf(Cardinal));
-    Stream.Write(GreenMask, SizeOf(Cardinal));
-    Stream.Write(BlueMask, SizeOf(Cardinal));
-    Stream.Write(AlphaMask, SizeOf(Cardinal));
-  end;
-
-  // image data
-  LineSize := Trunc(Width * FormatGetSize(InternalFormat));
-  Padding := GetLineWidth - LineSize;
-  PaddingBuff := 0;
-
-  pData := Data;
-  Inc(pData, (Height -1) * LineSize);
-
-  // prepare row buffer. But only for RGB because RGBA supports color masks
-  // so it's possible to change color within the image.
-  if InternalFormat = tfRGB8 then
-    GetMem(pTemp, fRowSize)
-  else
-    pTemp := nil;
-
-  try
-    // write image data
-    for LineIdx := 0 to Height - 1 do begin
-      // preparing row
-      if InternalFormat = tfRGB8 then begin
-        Move(pData^, pTemp^, fRowSize);
-        SwapRGB(pTemp, Width, False);
-      end else
-        pTemp := pData;
-
-      Stream.Write(pTemp^, LineSize);
-
-      Dec(pData, LineSize);
-
-      if Padding > 0 then
-        Stream.Write(PaddingBuff, Padding);
-    end;
-  finally
-    // destroy row buffer
-    if InternalFormat = tfRGB8 then
-      FreeMem(pTemp);
-  end;
-end;
-
-
-procedure TglBitmap.Bind(EnableTextureUnit: Boolean);
-begin
-  if EnableTextureUnit then
-    glEnable(Target);
-
-  if ID > 0 then
-    glBindTexture(Target, ID);
-end;
-
-
-procedure TglBitmap.Unbind(DisableTextureUnit: Boolean);
-begin
-  if DisableTextureUnit then
-    glDisable(Target);
-
-  glBindTexture(Target, 0);
-end;
-
-
-procedure TglBitmap.GetPixel(const Pos: TglBitmapPixelPosition;
-  var Pixel: TglBitmapPixelData);
-begin
-  if Assigned (fGetPixelFunc) then
-    fGetPixelFunc(Pos, Pixel);
-end;
-
-
-procedure TglBitmap.SetPixel (const Pos: TglBitmapPixelPosition;
-  const Pixel: TglBitmapPixelData);
-begin
-  if Assigned (fSetPixelFunc) then
-    fSetPixelFunc(Pos, Pixel);
-end;
-
-
-
-
-
-
-function TglBitmap.FlipHorz: Boolean;
-begin
-  Result := False;
-end;
-
-
-function TglBitmap.FlipVert: Boolean;
-begin
-  Result := False;
-end;
-
-
-procedure TglBitmap.FreeData;
-begin
-  SetDataPointer(nil, ifEmpty);
-end;
-
-
-procedure glBitmapFillWithColorFunc(var FuncRec: TglBitmapFunctionRec);
-type
-  PglBitmapPixelData = ^TglBitmapPixelData;
-begin
-  with FuncRec do begin
-    Dest.Red   := PglBitmapPixelData(CustomData)^.Red;
-    Dest.Green := PglBitmapPixelData(CustomData)^.Green;
-    Dest.Blue  := PglBitmapPixelData(CustomData)^.Blue;
-    Dest.Alpha := PglBitmapPixelData(CustomData)^.Alpha;
-  end;
-end;
-
-
-procedure TglBitmap.FillWithColor(Red, Green, Blue: Byte; Alpha: Byte);
-begin
-  FillWithColorFloat(Red / $FF, Green / $FF, Blue / $FF, Alpha / $FF);
-end;
-
-
-procedure TglBitmap.FillWithColorFloat(Red, Green, Blue: Single; Alpha: Single);
-var
-  PixelData: TglBitmapPixelData;
-begin
-  FormatPreparePixel(PixelData, InternalFormat);
-
-  PixelData.Red   := Max(0, Min(PixelData.PixelDesc.RedRange,   Trunc(PixelData.PixelDesc.RedRange   * Red)));
-  PixelData.Green := Max(0, Min(PixelData.PixelDesc.GreenRange, Trunc(PixelData.PixelDesc.GreenRange * Green)));
-  PixelData.Blue  := Max(0, Min(PixelData.PixelDesc.BlueRange,  Trunc(PixelData.PixelDesc.BlueRange  * Blue)));
-  PixelData.Alpha := Max(0, Min(PixelData.PixelDesc.AlphaRange, Trunc(PixelData.PixelDesc.AlphaRange * Alpha)));
-
-  AddFunc(glBitmapFillWithColorFunc, False, @PixelData);
-end;
-
-
-procedure TglBitmap.FillWithColorRange(Red, Green, Blue: Cardinal;
-  Alpha: Cardinal);
-var
-  PixelData: TglBitmapPixelData;
-begin
-  FormatPreparePixel(PixelData, FormatGetWithAlpha(InternalFormat));
-
-  FillWithColorFloat(
-    Red   / PixelData.PixelDesc.RedRange,
-    Green / PixelData.PixelDesc.GreenRange,
-    Blue  / PixelData.PixelDesc.BlueRange,
-    Alpha / PixelData.PixelDesc.AlphaRange);
-end;
-
-
-
-procedure TglBitmap.SetInternalFormat(const aValue: TglBitmapFormat);
-begin
-  if InternalFormat <> Value then begin
-    if FormatGetSize(Value) <> FormatGetSize(InternalFormat) then
-      raise EglBitmapUnsupportedFormatFormat.Create('SetInternalFormat - ' + UNSUPPORTED_INTERNAL_FORMAT);
-
-    // Update whatever
-    SetDataPointer(Data, Value);
-  end;
-end;
-
-
-function TglBitmap.AddFunc(Func: TglBitmapFunction; CreateTemp: Boolean;
-  CustomData: Pointer): boolean;
-begin
-  Result := AddFunc(Self, Func, CreateTemp, InternalFormat, CustomData);
-end;
-
-
-function TglBitmap.AddFunc(Source: TglBitmap; Func: TglBitmapFunction;
-  CreateTemp: Boolean; Format: TglBitmapFormat; CustomData: Pointer): boolean;
-var
-  pDest, NewImage, pSource: pByte;
-  TempHeight, TempWidth: Integer;
-  MapFunc: TglBitmapMapFunc;
-  UnMapFunc: TglBitmapUnMapFunc;
-
-  FuncRec: TglBitmapFunctionRec;
-begin
-  Assert(Assigned(Data));
-  Assert(Assigned(Source));
-  Assert(Assigned(Source.Data));
-
-  Result := False;
-
-  if Assigned (Source.Data) and FormatIsUncompressed(Format) and
-     ((Source.Height > 0) or (Source.Width > 0)) then begin
-
-    // inkompatible Formats so CreateTemp
-    if FormatGetSize(Format) <> FormatGetSize(InternalFormat) then
-      CreateTemp := True;
-
-    // Values
-    TempHeight := Max(1, Source.Height);
-    TempWidth := Max(1, Source.Width);
-
-    FuncRec.Sender := Self;
-    FuncRec.CustomData := CustomData;
-
-    NewImage := nil;
-
-    if CreateTemp then begin
-      GetMem(NewImage, Trunc(FormatGetSize(Format) * TempHeight * TempWidth));
-      pDest := NewImage;
-    end
-      else pDest := Data;
-
-    try
-      // Mapping
-      MapFunc := FormatGetMapFunc(Format);
-      FormatPreparePixel(FuncRec.Dest, Format);
-      FormatPreparePixel(FuncRec.Source, Source.InternalFormat);
-
-      FuncRec.Size := Source.Dimension;
-      FuncRec.Position.Fields := FuncRec.Size.Fields;
-
-      if FormatIsUncompressed(Source.InternalFormat) then begin
-        // Uncompressed Images
-        pSource := Source.Data;
-        UnMapFunc := FormatGetUnMapFunc(Source.InternalFormat);
-
-        FuncRec.Position.Y := 0;
-        while FuncRec.Position.Y < TempHeight do begin
-          FuncRec.Position.X := 0;
-          while FuncRec.Position.X < TempWidth do begin
-            // Get Data
-            UnMapFunc(pSource, FuncRec.Source);
-            // Func
-            Func(FuncRec);
-            // Set Data
-            MapFunc(FuncRec.Dest, pDest);
-            Inc(FuncRec.Position.X);
-          end;
-          Inc(FuncRec.Position.Y);
-        end;
-      end else begin
-        // Compressed Images
-        FuncRec.Position.Y := 0;
-        while FuncRec.Position.Y < TempHeight do begin
-          FuncRec.Position.X := 0;
-          while FuncRec.Position.X < TempWidth do begin
-            // Get Data
-            fGetPixelFunc(FuncRec.Position, FuncRec.Source);
-            // Func
-            Func(FuncRec);
-            // Set Data
-            MapFunc(FuncRec.Dest, pDest);
-            Inc(FuncRec.Position.X);
-          end;
-          Inc(FuncRec.Position.Y);
-        end;
-      end;
-
-      // Updating Image or InternalFormat
-      if CreateTemp then
-        SetDataPointer(NewImage, Format)
-      else
-
-      if Format <> InternalFormat then
-        SetInternalFormat(Format);
-
-      Result := True;
-    except
-      if CreateTemp
-        then FreeMem(NewImage);
-      raise;
-    end;
-  end;
-end;
-
-
-procedure glBitmapConvertCopyFunc(var FuncRec: TglBitmapFunctionRec);
-begin
-  with FuncRec do begin
-    if Source.PixelDesc.RedRange > 0 then
-      Dest.Red   := Source.Red;
-
-    if Source.PixelDesc.GreenRange > 0 then
-      Dest.Green := Source.Green;
-
-    if Source.PixelDesc.BlueRange > 0 then
-      Dest.Blue  := Source.Blue;
-
-    if Source.PixelDesc.AlphaRange > 0 then
-      Dest.Alpha := Source.Alpha;
-  end;
-end;
-
-
-procedure glBitmapConvertCalculateRGBAFunc(var FuncRec: TglBitmapFunctionRec);
-begin
-  with FuncRec do begin
-    if Source.PixelDesc.RedRange > 0 then
-      Dest.Red   := Round(Dest.PixelDesc.RedRange   * Source.Red   / Source.PixelDesc.RedRange);
-
-    if Source.PixelDesc.GreenRange > 0 then
-      Dest.Green := Round(Dest.PixelDesc.GreenRange * Source.Green / Source.PixelDesc.GreenRange);
-
-    if Source.PixelDesc.BlueRange > 0 then
-      Dest.Blue  := Round(Dest.PixelDesc.BlueRange  * Source.Blue  / Source.PixelDesc.BlueRange);
-
-    if Source.PixelDesc.AlphaRange > 0 then
-      Dest.Alpha := Round(Dest.PixelDesc.AlphaRange * Source.Alpha / Source.PixelDesc.AlphaRange);
-  end;
-end;
-
-
-procedure glBitmapConvertShiftRGBAFunc(var FuncRec: TglBitmapFunctionRec);
-begin
-  with FuncRec do
-    with TglBitmapPixelDesc(CustomData^) do begin
-      if Source.PixelDesc.RedRange > 0 then
-        Dest.Red   := Source.Red   shr RedShift;
-
-      if Source.PixelDesc.GreenRange > 0 then
-        Dest.Green := Source.Green shr GreenShift;
-
-      if Source.PixelDesc.BlueRange > 0 then
-        Dest.Blue  := Source.Blue  shr BlueShift;
-
-      if Source.PixelDesc.AlphaRange > 0 then
-        Dest.Alpha := Source.Alpha shr AlphaShift;
-    end;
-end;
-
-
-function TglBitmap.ConvertTo(NewFormat: TglBitmapFormat): boolean;
-var
-  Source, Dest: TglBitmapPixelData;
-  PixelDesc: TglBitmapPixelDesc;
-
-  function CopyDirect: Boolean;
-  begin
-    Result :=
-      ((Source.PixelDesc.RedRange   = Dest.PixelDesc.RedRange)   or (Source.PixelDesc.RedRange   = 0) or (Dest.PixelDesc.RedRange   = 0)) and
-      ((Source.PixelDesc.GreenRange = Dest.PixelDesc.GreenRange) or (Source.PixelDesc.GreenRange = 0) or (Dest.PixelDesc.GreenRange = 0)) and
-      ((Source.PixelDesc.BlueRange  = Dest.PixelDesc.BlueRange)  or (Source.PixelDesc.BlueRange  = 0) or (Dest.PixelDesc.BlueRange  = 0)) and
-      ((Source.PixelDesc.AlphaRange = Dest.PixelDesc.AlphaRange) or (Source.PixelDesc.AlphaRange = 0) or (Dest.PixelDesc.AlphaRange = 0));
-  end;
-
-  function CanShift: Boolean;
-  begin
-    Result :=
-      ((Source.PixelDesc.RedRange   >= Dest.PixelDesc.RedRange  ) or (Source.PixelDesc.RedRange   = 0) or (Dest.PixelDesc.RedRange   = 0)) and
-      ((Source.PixelDesc.GreenRange >= Dest.PixelDesc.GreenRange) or (Source.PixelDesc.GreenRange = 0) or (Dest.PixelDesc.GreenRange = 0)) and
-      ((Source.PixelDesc.BlueRange  >= Dest.PixelDesc.BlueRange ) or (Source.PixelDesc.BlueRange  = 0) or (Dest.PixelDesc.BlueRange  = 0)) and
-      ((Source.PixelDesc.AlphaRange >= Dest.PixelDesc.AlphaRange) or (Source.PixelDesc.AlphaRange = 0) or (Dest.PixelDesc.AlphaRange = 0));
-  end;
-
-  function GetShift(Source, Dest: Cardinal) : ShortInt;
-  begin
-    Result := 0;
-
-    while (Source > Dest) and (Source > 0) do begin
-      Inc(Result);
-      Source := Source shr 1;
-    end;
-  end;
-
-begin
-  if NewFormat <> InternalFormat then begin
-    FormatPreparePixel(Source, InternalFormat);
-    FormatPreparePixel(Dest, NewFormat);
-
-    if CopyDirect then
-      Result := AddFunc(Self, glBitmapConvertCopyFunc, False, NewFormat)
-    else
-    if CanShift then begin
-      PixelDesc.RedShift   := GetShift(Source.PixelDesc.RedRange,   Dest.PixelDesc.RedRange);
-      PixelDesc.GreenShift := GetShift(Source.PixelDesc.GreenRange, Dest.PixelDesc.GreenRange);
-      PixelDesc.BlueShift  := GetShift(Source.PixelDesc.BlueRange,  Dest.PixelDesc.BlueRange);
-      PixelDesc.AlphaShift := GetShift(Source.PixelDesc.AlphaRange, Dest.PixelDesc.AlphaRange);
-
-      Result := AddFunc(Self, glBitmapConvertShiftRGBAFunc, False, NewFormat, @PixelDesc);
-    end
-      else Result := AddFunc(Self, glBitmapConvertCalculateRGBAFunc, False, NewFormat);
-  end
-    else Result := True;
-end;
-
-
-function TglBitmap.RemoveAlpha: Boolean;
-begin
-  Result := False;
-
-  if (Assigned(Data)) then begin
-    if not (FormatIsUncompressed(InternalFormat) or FormatHasAlpha(InternalFormat)) then
-      raise EglBitmapUnsupportedFormatFormat.Create('RemoveAlpha - ' + UNSUPPORTED_INTERNAL_FORMAT);
-
-    Result := ConvertTo(FormatGetWithoutAlpha(InternalFormat));
-  end;
-end;
-
-
-function TglBitmap.AddAlphaFromFunc(Func: TglBitmapFunction; CustomData: Pointer): boolean;
-begin
-  if not FormatIsUncompressed(InternalFormat) then
-    raise EglBitmapUnsupportedFormatFormat.Create('AddAlphaFromFunc - ' + UNSUPPORTED_INTERNAL_FORMAT);
-
-  Result := AddFunc(Self, Func, False, FormatGetWithAlpha(InternalFormat), CustomData);
-end;
-
-
-function TglBitmap.GetFileHeight: Integer;
-begin
-  Result := Max(1, Height);
-end;
-
-
-function TglBitmap.GetFileWidth: Integer;
-begin
-  Result := Max(1, Width);
-end;
-
-
-procedure glBitmapAlphaFunc(var FuncRec: TglBitmapFunctionRec);
-var
-  Temp: Single;
-begin
-  with FuncRec do begin
-    Temp :=
-      Source.Red   / Source.PixelDesc.RedRange   * 0.3 +
-      Source.Green / Source.PixelDesc.GreenRange * 0.59 +
-      Source.Blue  / Source.PixelDesc.BlueRange  * 0.11;
-
-    Dest.Alpha := Round (Dest.PixelDesc.AlphaRange * Temp);
-  end;
-end;
-
-
-function TglBitmap.AddAlphaFromglBitmap(glBitmap: TglBitmap; Func: TglBitmapFunction; CustomData: Pointer): boolean;
-var
-  pDest, pDest2, pSource: pByte;
-  TempHeight, TempWidth: Integer;
-  MapFunc: TglBitmapMapFunc;
-  DestUnMapFunc, UnMapFunc: TglBitmapUnMapFunc;
-
-  FuncRec: TglBitmapFunctionRec;
-begin
-  Result := False;
-
-  assert(Assigned(Data));
-  assert(Assigned(glBitmap));
-  assert(Assigned(glBitmap.Data));
-
-  if ((glBitmap.Width = Width) and (glBitmap.Height = Height)) then begin
-    // Convert to Data with Alpha
-    Result := ConvertTo(FormatGetWithAlpha(FormatGetUncompressed(InternalFormat)));
-
-    if not Assigned(Func) then
-      Func := glBitmapAlphaFunc;
-
-    // Values
-    TempHeight := glBitmap.FileHeight;
-    TempWidth := glBitmap.FileWidth;
-
-    FuncRec.Sender := Self;
-    FuncRec.CustomData := CustomData;
-
-    pDest := Data;
-    pDest2 := Data;
-    pSource := glBitmap.Data;
-
-    // Mapping
-    FormatPreparePixel(FuncRec.Dest, InternalFormat);
-    FormatPreparePixel(FuncRec.Source, glBitmap.InternalFormat);
-    MapFunc := FormatGetMapFunc(InternalFormat);
-    DestUnMapFunc := FormatGetUnMapFunc(InternalFormat);
-    UnMapFunc := FormatGetUnMapFunc(glBitmap.InternalFormat);
-
-    FuncRec.Size := Dimension;
-    FuncRec.Position.Fields := FuncRec.Size.Fields;
-
-    FuncRec.Position.Y := 0;
-    while FuncRec.Position.Y < TempHeight do begin
-      FuncRec.Position.X := 0;
-      while FuncRec.Position.X < TempWidth do begin
-        // Get Data
-        UnMapFunc(pSource, FuncRec.Source);
-        DestUnMapFunc(pDest2, FuncRec.Dest);
-        // Func
-        Func(FuncRec);
-        // Set Data
-        MapFunc(FuncRec.Dest, pDest);
-        Inc(FuncRec.Position.X);
-      end;
-      Inc(FuncRec.Position.Y);
-    end;
-  end;
-end;
-
-
-procedure TglBitmap.SetBorderColor(Red, Green, Blue, Alpha: Single);
-begin
-  fBorderColor[0] := Red;
-  fBorderColor[1] := Green;
-  fBorderColor[2] := Blue;
-  fBorderColor[3] := Alpha;
-
-  if ID > 0 then begin
-    Bind (False);
-
-    glTexParameterfv(Target, GL_TEXTURE_BORDER_COLOR, @fBorderColor[0]);
-  end;
-end;
-
-
-{ TglBitmap2D }
-
-procedure TglBitmap2D.SetDataPointer(Data: pByte; Format: TglBitmapFormat; Width, Height: Integer);
-var
-  Idx, LineWidth: Integer;
-begin
-  inherited;
-
-  // Format
-  if FormatIsUncompressed(Format) then begin
-    fUnmapFunc := FormatGetUnMapFunc(Format);
-    fGetPixelFunc := GetPixel2DUnmap;
-
-    fMapFunc := FormatGetMapFunc(Format);
-    fSetPixelFunc := SetPixel2DUnmap;
-
-    // Assigning Data
-    if Assigned(Data) then begin
-      SetLength(fLines, GetHeight);
-
-      LineWidth := Trunc(GetWidth * FormatGetSize(InternalFormat));
-
-      for Idx := 0 to GetHeight -1 do begin
-        fLines[Idx] := Data;
-        Inc(fLines[Idx], Idx * LineWidth);
-      end;
-    end
-      else SetLength(fLines, 0);
-  end else begin
-    SetLength(fLines, 0);
-
-    fSetPixelFunc := nil;
-
-    case Format of
-      ifDXT1:
-        fGetPixelFunc := GetPixel2DDXT1;
-      ifDXT3:
-        fGetPixelFunc := GetPixel2DDXT3;
-      ifDXT5:
-        fGetPixelFunc := GetPixel2DDXT5;
-      else
-        fGetPixelFunc := nil;
-    end;
-  end;
-end;
-
-
-procedure TglBitmap2D.GetDXTColorBlock(pData: pByte; relX, relY: Integer; var Pixel: TglBitmapPixelData);
-type
-  PDXT1Chunk = ^TDXT1Chunk;
-  TDXT1Chunk = packed record
-    Color1: WORD;
-    Color2: WORD;
-    Pixels: array [0..3] of byte;
-  end;
-
-var
-  BasePtr: pDXT1Chunk;
-  PixPos: Integer;
-  Colors: array [0..3] of TRGBQuad;
-begin
-  BasePtr := pDXT1Chunk(pData);
-
-  PixPos := BasePtr^.Pixels[relY] shr (relX * 2) and $3;
-
-  if PixPos in [0, 2, 3] then begin
-    Colors[0].rgbRed      := BasePtr^.Color1 and $F800 shr 8;
-    Colors[0].rgbGreen    := BasePtr^.Color1 and $07E0 shr 3;
-    Colors[0].rgbBlue     := BasePtr^.Color1 and $001F shl 3;
-    Colors[0].rgbReserved := 255;
-  end;
-
-  if PixPos in [1, 2, 3] then begin
-    Colors[1].rgbRed      := BasePtr^.Color2 and $F800 shr 8;
-    Colors[1].rgbGreen    := BasePtr^.Color2 and $07E0 shr 3;
-    Colors[1].rgbBlue     := BasePtr^.Color2 and $001F shl 3;
-    Colors[1].rgbReserved := 255;
-  end;
-
-  if PixPos = 2 then begin
-    Colors[2].rgbRed      := (Colors[0].rgbRed   * 67 + Colors[1].rgbRed   * 33) div 100;
-    Colors[2].rgbGreen    := (Colors[0].rgbGreen * 67 + Colors[1].rgbGreen * 33) div 100;
-    Colors[2].rgbBlue     := (Colors[0].rgbBlue  * 67 + Colors[1].rgbBlue  * 33) div 100;
-    Colors[2].rgbReserved := 255;
-  end;
-
-  if PixPos = 3 then begin
-    Colors[3].rgbRed      := (Colors[0].rgbRed   * 33 + Colors[1].rgbRed   * 67) div 100;
-    Colors[3].rgbGreen    := (Colors[0].rgbGreen * 33 + Colors[1].rgbGreen * 67) div 100;
-    Colors[3].rgbBlue     := (Colors[0].rgbBlue  * 33 + Colors[1].rgbBlue  * 67) div 100;
-    if BasePtr^.Color1 > BasePtr^.Color2 then
-      Colors[3].rgbReserved := 255
-    else
-      Colors[3].rgbReserved := 0;
-  end;
-
-  Pixel.Red   := Colors[PixPos].rgbRed;
-  Pixel.Green := Colors[PixPos].rgbGreen;
-  Pixel.Blue  := Colors[PixPos].rgbBlue;
-  Pixel.Alpha := Colors[PixPos].rgbReserved;
-end;
-
-
-procedure TglBitmap2D.GetPixel2DDXT1(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
-var
-  BasePtr: pByte;
-  PosX, PosY: Integer;
-begin
-  inherited;
-
-  if (Pos.Y <= Height) and (Pos.X <= Width) then begin
-    PosX := Pos.X div 4;
-    PosY := Pos.Y div 4;
-
-    BasePtr := Data;
-    Inc(BasePtr, (PosY * Width div 4 + PosX) * 8);
-
-    GetDXTColorBlock(BasePtr, Pos.X - PosX * 4, Pos.Y - PosY * 4, Pixel);
-  end;
-end;
-
-
-procedure TglBitmap2D.GetPixel2DDXT3(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
-type
-  PDXT3AlphaChunk = ^TDXT3AlphaChunk;
-  TDXT3AlphaChunk = array [0..3] of WORD;
-
-var
-  ColorPtr: pByte;
-  AlphaPtr: PDXT3AlphaChunk;
-  PosX, PosY, relX, relY: Integer;
-begin
-  inherited;
-
-  if (Pos.Y <= Height) and (Pos.X <= Width) then begin
-    PosX := Pos.X div 4;
-    PosY := Pos.Y div 4;
-    relX := Pos.X - PosX * 4;
-    relY := Pos.Y - PosY * 4;
-
-    // get color value
-    AlphaPtr := PDXT3AlphaChunk(Data);
-    Inc(AlphaPtr, (PosY * Width div 4 + PosX) * 2);
-
-    ColorPtr := pByte(AlphaPtr);
-    Inc(ColorPtr, 8);
-
-    GetDXTColorBlock(ColorPtr, relX, relY, Pixel);
-
-    // extracting alpha
-    Pixel.Alpha := AlphaPtr^[relY] shr (4 * relX) and $0F shl 4;
-  end;
-end;
-
-
-procedure TglBitmap2D.GetPixel2DDXT5(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
-var
-  ColorPtr: pByte;
-  AlphaPtr: PInt64;
-  PixPos, PosX, PosY, relX, relY: Integer;
-  Alpha0, Alpha1: Byte;
-begin
-  inherited;
-
-  if (Pos.Y <= Height) and (Pos.X <= Width) then begin
-    PosX := Pos.X div 4;
-    PosY := Pos.Y div 4;
-    relX := Pos.X - PosX * 4;
-    relY := Pos.Y - PosY * 4;
-
-    // get color value
-    AlphaPtr := PInt64(Data);
-    Inc(AlphaPtr, (PosY * Width div 4 + PosX) * 2);
-
-    ColorPtr := pByte(AlphaPtr);
-    Inc(ColorPtr, 8);
-
-    GetDXTColorBlock(ColorPtr, relX, relY, Pixel);
-
-    // extracting alpha
-    Alpha0 := AlphaPtr^ and $FF;
-    Alpha1 := AlphaPtr^ shr 8 and $FF;
-
-    PixPos := AlphaPtr^ shr (16 + (relY * 4 + relX) * 3) and $07;
-
-    // use alpha 0
-    if PixPos = 0 then begin
-      Pixel.Alpha := Alpha0;
-    end else
-
-    // use alpha 1
-    if PixPos = 1 then begin
-      Pixel.Alpha := Alpha1;
-    end else
-
-    // alpha interpolate 7 Steps
-    if Alpha0 > Alpha1 then begin
-      Pixel.Alpha := ((8 - PixPos) * Alpha0 + (PixPos - 1) * Alpha1) div 7;
-    end else
-
-    // alpha is 100% transparent or not transparent
-    if PixPos >= 6 then begin
-      if PixPos = 6 then
-        Pixel.Alpha := 0
-      else
-        Pixel.Alpha := 255;
-    end else
-
-    // alpha interpolate 5 Steps
-    begin
-      Pixel.Alpha := ((6 - PixPos) * Alpha0 + (PixPos - 1) * Alpha1) div 5;
-    end;
-  end;
-end;
-
-
-procedure TglBitmap2D.GetPixel2DUnmap(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
-var
-  pTemp: pByte;
-begin
-  pTemp := fLines[Pos.Y];
-  Inc(pTemp, Pos.X * fPixelSize);
-
-  fUnmapFunc(pTemp, Pixel);
-end;
-
-
-procedure TglBitmap2D.SetPixel2DUnmap(const Pos: TglBitmapPixelPosition; const Pixel: TglBitmapPixelData);
-var
-  pTemp: pByte;
-begin
-  pTemp := fLines[Pos.Y];
-  Inc(pTemp, Pos.X * fPixelSize);
-
-  fMapFunc(Pixel, pTemp);
-end;
-
-
-function TglBitmap2D.FlipHorz: Boolean;
-var
-  Col, Row: Integer;
-  pTempDest, pDest, pSource: pByte;
-  ImgSize: Integer;
-begin
-  Result := Inherited FlipHorz;
-
-  if Assigned(Data) then begin
-    pSource := Data;
-    ImgSize := Height * fRowSize;
+  Header.dwPitchOrLinearSize := fRowSize;
+  Header.dwMipMapCount := 1;
 
-    GetMem(pDest, ImgSize);
-    try
-      pTempDest := pDest;
+  // Caps
+  Header.Caps.dwCaps1 := DDSCAPS_TEXTURE;
 
-      Dec(pTempDest, fRowSize + fPixelSize);
-      for Row := 0 to Height -1 do begin
-        Inc(pTempDest, fRowSize * 2);
-        for Col := 0 to Width -1 do begin
-          Move(pSource^, pTempDest^, fPixelSize);
+  // Pixelformat
+  Header.PixelFormat.dwSize  := Sizeof(Header.PixelFormat);
+  Header.PixelFormat.dwFlags := DDPF_RGB;
 
-          Inc(pSource, fPixelSize);
-          Dec(pTempDest, fPixelSize);
-        end;
-      end;
+  (* TODO tfAlpha8
+  if FORMAT_DESCRIPTORS[Format].HasAlpha and (Format <> tfAlpha8) then
+    Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHAPIXELS;
+  *)
 
-      SetDataPointer(pDest, InternalFormat);
+  Header.PixelFormat.dwRGBBitCount  := Trunc(FORMAT_DESCRIPTORS[Format].GetSize * 8);
+  Header.PixelFormat.dwRBitMask     := Pix.PixelDesc.RedRange   shl Pix.PixelDesc.RedShift;
+  Header.PixelFormat.dwGBitMask     := Pix.PixelDesc.GreenRange shl Pix.PixelDesc.GreenShift;
+  Header.PixelFormat.dwBBitMask     := Pix.PixelDesc.BlueRange  shl Pix.PixelDesc.BlueShift;
+  Header.PixelFormat.dwAlphaBitMask := Pix.PixelDesc.AlphaRange shl Pix.PixelDesc.AlphaShift;
 
-      Result := True;
-    except
-      FreeMem(pDest);
-      raise;
-    end;
-  end;
+  aStream.Write(Header, SizeOf(Header));
+  aStream.Write(Data^, FORMAT_DESCRIPTORS[Format].GetSize(Dimension));
 end;
+{$ENDREGION}
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TglBitmap2D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap2D.GetScanline(const aIndex: Integer): Pointer;
+begin
+  if (aIndex >= Low(fLines)) and (aIndex <= High(fLines)) then
+    result := fLines[aIndex]
+  else
+    result := nil;
+end;
 
-function TglBitmap2D.FlipVert: Boolean;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap2D.SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
+  const aWidth: Integer; const aHeight: Integer);
 var
-  Row: Integer;
-  pTempDest, pDest, pSource: pByte;
+  Idx, LineWidth: Integer;
 begin
-  Result := Inherited FlipVert;
-
-  if Assigned(Data) then begin
-    pSource := Data;
-    GetMem(pDest, Height * fRowSize);
-    try
-      pTempDest := pDest;
-
-      Inc(pTempDest, Width * (Height -1) * fPixelSize);
+  inherited SetDataPointer(aData, aFormat, aWidth, aHeight);
 
-      for Row := 0 to Height -1 do begin
-        Move(pSource^, pTempDest^, fRowSize);
+  //TODO compression
+  if {FormatIsUncompressed(Format)} true then begin
+    (* TODO PixelFuncs
+    fGetPixelFunc := GetPixel2DUnmap;
+    fSetPixelFunc := SetPixel2DUnmap;
+    *)
+    // Assigning Data
+    if Assigned(Data) then begin
+      SetLength(fLines, GetHeight);
+      LineWidth := Trunc(GetWidth * FORMAT_DESCRIPTORS[Format].GetSize);
 
-        Dec(pTempDest, fRowSize);
-        Inc(pSource, fRowSize);
+      for Idx := 0 to GetHeight -1 do begin
+        fLines[Idx] := Data;
+        Inc(fLines[Idx], Idx * LineWidth);
       end;
+    end
+      else SetLength(fLines, 0);
+  end else begin
+    (*
+    SetLength(fLines, 0);
 
-      SetDataPointer(pDest, InternalFormat);
+    fSetPixelFunc := nil;
 
-      Result := True;
-    except
-      FreeMem(pDest);
-      raise;
+    case Format of
+      ifDXT1:
+        fGetPixelFunc := GetPixel2DDXT1;
+      ifDXT3:
+        fGetPixelFunc := GetPixel2DDXT3;
+      ifDXT5:
+        fGetPixelFunc := GetPixel2DDXT5;
+      else
+        fGetPixelFunc := nil;
     end;
+    *)
   end;
 end;
 
-
-procedure TglBitmap2D.UploadData (Target, Format, InternalFormat, Typ: Cardinal; BuildWithGlu: Boolean);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap2D.UploadData(const aTarget: Cardinal; const aBuildWithGlu: Boolean);
+var
+  FormatDescriptor: TglBitmapFormatDescClass;
+  FormatDesc: TglBitmapFormatDesc;
 begin
   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 
-  // Upload data
+  (* TODO compression
   if Self.InternalFormat in [ifDXT1, ifDXT3, ifDXT5] then
     glCompressedTexImage2D(Target, 0, InternalFormat, Width, Height, 0, Trunc(Width * Height * FormatGetSize(Self.InternalFormat)), Data)
   else
+  *)
 
-  if BuildWithGlu then
-    gluBuild2DMipmaps(Target, InternalFormat, Width, Height, Format, Typ, Data)
+  FormatDescriptor := FORMAT_DESCRIPTORS[Format];
+  FormatDesc       := FormatDescriptor.GetFormatDesc;
+  if aBuildWithGlu then
+    gluBuild2DMipmaps(aTarget, FormatDescriptor.GetColorCompCount, Width, Height,
+      FormatDesc.Format, FormatDesc.DataType, Data)
   else
-    glTexImage2D(Target, 0, InternalFormat, Width, Height, 0, Format, Typ, Data);
+    glTexImage2D(aTarget, 0, FormatDesc.InternalFormat, Width, Height, 0,
+      FormatDesc.Format, FormatDesc.DataType, Data);
 
   // Freigeben
   if (FreeDataAfterGenTexture) then
     FreeData;
 end;
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap2D.AfterConstruction;
+begin
+  inherited;
+  Target := GL_TEXTURE_2D;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap2D.GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
+var
+  Temp: pByte;
+  Size, w, h: Integer;
+  FormatDesc: TglBitmapFormatDescClass;
+  glFormatDesc: TglBitmapFormatDesc;
+begin
+  (* TODO compression
+  if not FormatIsUncompressed(Format) then
+    raise EglBitmapUnsupportedFormatFormat.Create('TglBitmap2D.GrabScreen - ' + UNSUPPORTED_FORMAT);
+  *)
+
+  w := aRight  - aLeft;
+  h := aBottom - aTop;
+  FormatDesc   := FORMAT_DESCRIPTORS[Format];
+  glFormatDesc := FormatDesc.GetFormatDesc;
+  Size         := FormatDesc.GetSize(glBitmapPosition(w, h));
+  GetMem(Temp, Size);
+  try
+    glPixelStorei(GL_PACK_ALIGNMENT, 1);
+    glReadPixels(aLeft, aTop, w, h, glFormatDesc.Format, glFormatDesc.DataType, Temp);
+    SetDataPointer(Temp, Format, w, h);
+    FlipVert;
+  except
+    FreeMem(Temp);
+    raise;
+  end;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap2D.GetDataFromTexture;
+var
+  Temp: PByte;
+  TempWidth, TempHeight, RedSize, GreenSize, BlueSize, AlphaSize, LumSize: Integer;
+  TempType, TempIntFormat: Cardinal;
+  IntFormat: TglBitmapFormat;
+  FormatDesc: TglBitmapFormatDescClass;
+begin
+  Bind;
+
+  // Request Data
+  glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_WIDTH,           @TempWidth);
+  glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT,          @TempHeight);
+  glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat);
+
+  glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_RED_SIZE,       @RedSize);
+  glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_GREEN_SIZE,     @GreenSize);
+  glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_BLUE_SIZE,      @BlueSize);
+  glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_ALPHA_SIZE,     @AlphaSize);
+  glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_LUMINANCE_SIZE, @LumSize);
+
+  IntFormat := tfEmpty;
+  for FormatDesc in FORMAT_DESCRIPTORS do
+    if (FormatDesc.GetFormatDesc.InternalFormat = TempIntFormat) then begin
+      IntFormat := FormatDesc.GetFormat;
+      break;
+    end;
+
+  // Getting data from OpenGL
+  GetMem(Temp, FormatDesc.GetSize(glBitmapPosition(TempWidth, TempHeight)));
+  try
+    (* TODO Compression
+    if FormatIsCompressed(IntFormat) and (GL_VERSION_1_3 or GL_ARB_texture_compression) then
+      glGetCompressedTexImage(Target, 0, Temp)
+    else
+    *)
+    with FormatDesc.GetFormatDesc do
+      glGetTexImage(Target, 0, InternalFormat, DataType, Temp);
+    SetDataPointer(Temp, IntFormat, TempWidth, TempHeight);
+  except
+    FreeMem(Temp);
+    raise;
+  end;
+end;
 
-procedure TglBitmap2D.GenTexture(TestTextureSize: Boolean);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap2D.GenTexture(const aTestTextureSize: Boolean);
 var
   BuildWithGlu, PotTex, TexRec: Boolean;
-  glFormat, glInternalFormat, glType: Cardinal;
   TexSize: Integer;
 begin
   if Assigned(Data) then begin
     // Check Texture Size
-    if (TestTextureSize) then begin
+    if (aTestTextureSize) then begin
       glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
 
       if ((Height > TexSize) or (Width > TexSize)) then
         raise EglBitmapSizeToLargeException.Create('TglBitmap2D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
 
-      PotTex := IsPowerOfTwo (Height) and IsPowerOfTwo (Width);
-      TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and
-                (Target = GL_TEXTURE_RECTANGLE_ARB);
+      PotTex := IsPowerOfTwo(Height) and IsPowerOfTwo(Width);
+      TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and (Target = GL_TEXTURE_RECTANGLE_ARB);
 
       if not (PotTex or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
         raise EglBitmapNonPowerOfTwoException.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
     end;
 
     CreateId;
-
     SetupParameters(BuildWithGlu);
-    SelectFormat(InternalFormat, glFormat, glInternalFormat, glType);
-
-    UploadData(Target, glFormat, glInternalFormat, glType, BuildWithGlu);
-
-    // Infos sammeln
-    glAreTexturesResident(1, @ID, @fIsResident);
+    UploadData(Target, BuildWithGlu);
+    glAreTexturesResident(1, @fID, @fIsResident);
   end;
 end;
 
-
-procedure TglBitmap2D.AfterConstruction;
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap2D.FlipHorz: Boolean;
+var
+  Col, Row: Integer;
+  TempDestData, DestData, SourceData: PByte;
+  ImgSize: Integer;
 begin
-  inherited;
-
-  Target := GL_TEXTURE_2D;
+  result := inherited FlipHorz;
+  if Assigned(Data) then begin
+    SourceData := Data;
+    ImgSize := Height * fRowSize;
+    GetMem(DestData, ImgSize);
+    try
+      TempDestData := DestData;
+      Dec(TempDestData, fRowSize + fPixelSize);
+      for Row := 0 to Height -1 do begin
+        Inc(TempDestData, fRowSize * 2);
+        for Col := 0 to Width -1 do begin
+          Move(SourceData^, TempDestData^, fPixelSize);
+          Inc(SourceData, fPixelSize);
+          Dec(TempDestData, fPixelSize);
+        end;
+      end;
+      SetDataPointer(DestData, Format);
+      result := true;
+    except
+      FreeMem(DestData);
+      raise;
+    end;
+  end;
 end;
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TglBitmap2D.FlipVert: Boolean;
+var
+  Row: Integer;
+  TempDestData, DestData, SourceData: PByte;
+begin
+  result := inherited FlipVert;
+  if Assigned(Data) then begin
+    SourceData := Data;
+    GetMem(DestData, Height * fRowSize);
+    try
+      TempDestData := DestData;
+      Inc(TempDestData, Width * (Height -1) * fPixelSize);
+      for Row := 0 to Height -1 do begin
+        Move(SourceData^, TempDestData^, fRowSize);
+        Dec(TempDestData, fRowSize);
+        Inc(SourceData, fRowSize);
+      end;
+      SetDataPointer(DestData, Format);
+      result := true;
+    except
+      FreeMem(DestData);
+      raise;
+    end;
+  end;
+end;
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TglBitmap2D - ToNormalMap///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 type
   TMatrixItem = record
     X, Y: Integer;
@@ -6203,24 +6178,25 @@ type
 const
   oneover255 = 1 / 255;
 
-procedure glBitmapToNormalMapPrepareFunc (var FuncRec: TglBitmapFunctionRec);
+  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure glBitmapToNormalMapPrepareFunc(var FuncRec: TglBitmapFunctionRec);
 var
   Val: Single;
 begin
   with FuncRec do begin
     Val := Source.Red * 0.3 + Source.Green * 0.59 + Source.Blue *  0.11;
-    PglBitmapToNormalMapRec (CustomData)^.Heights[Position.Y * Size.X + Position.X] := Val * oneover255;
+    PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Val * oneover255;
   end;
 end;
 
-
-procedure glBitmapToNormalMapPrepareAlphaFunc (var FuncRec: TglBitmapFunctionRec);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure glBitmapToNormalMapPrepareAlphaFunc(var FuncRec: TglBitmapFunctionRec);
 begin
   with FuncRec do
-    PglBitmapToNormalMapRec (CustomData)^.Heights[Position.Y * Size.X + Position.X] := Source.Alpha * oneover255;
+    PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Source.Alpha * oneover255;
 end;
 
-
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 procedure glBitmapToNormalMapFunc (var FuncRec: TglBitmapFunctionRec);
 type
   TVec = Array[0..2] of Single;
@@ -6235,14 +6211,13 @@ var
     with FuncRec do begin
       X := Max(0, Min(Size.X -1, X));
       Y := Max(0, Min(Size.Y -1, Y));
-
-      Result := PglBitmapToNormalMapRec (CustomData)^.Heights[Y * Size.X + X];
+      result := PglBitmapToNormalMapRec(Args)^.Heights[Y * Size.X + X];
     end;
   end;
 
 begin
   with FuncRec do begin
-    with PglBitmapToNormalMapRec (CustomData)^ do begin
+    with PglBitmapToNormalMapRec(Args)^ do begin
       du := 0;
       for Idx := Low(MatrixU) to High(MatrixU) do
         du := du + GetHeight(Position.X + MatrixU[Idx].X, Position.Y + MatrixU[Idx].Y) * MatrixU[Idx].W;
@@ -6271,8 +6246,8 @@ begin
   end;
 end;
 
-
-procedure TglBitmap2D.ToNormalMap(Func: TglBitmapNormalMapFunc; Scale: Single; UseAlpha: Boolean);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TglBitmap2D.ToNormalMap(const aFunc: TglBitmapNormalMapFunc; const aScale: Single; const aUseAlpha: Boolean);
 var
   Rec: TglBitmapToNormalMapRec;
 
@@ -6286,253 +6261,134 @@ var
   end;
 
 begin
+  (* TODO Compression
   if not FormatIsUncompressed(InternalFormat) then
-    raise EglBitmapUnsupportedFormatFormat.Create('TglBitmap2D.ToNormalMap - ' + UNSUPPORTED_INTERNAL_FORMAT);
+    raise EglBitmapUnsupportedFormatFormat.Create('TglBitmap2D.ToNormalMap - ' + UNSUPPORTED_FORMAT);
+    *)
 
-  if Scale > 100 then
+  if aScale > 100 then
     Rec.Scale := 100
-  else
-  if Scale < -100 then
+  else if aScale < -100 then
     Rec.Scale := -100
   else
-    Rec.Scale := Scale;
+    Rec.Scale := aScale;
 
   SetLength(Rec.Heights, Width * Height);
   try
-    case Func of
-      nm4Samples:
-        begin
-          SetLength(Rec.MatrixU, 2);
-          SetEntry(Rec.MatrixU, 0, -1,  0, -0.5);
-          SetEntry(Rec.MatrixU, 1,  1,  0,  0.5);
-
-          SetLength(Rec.MatrixV, 2);
-          SetEntry(Rec.MatrixV, 0,  0,  1,  0.5);
-          SetEntry(Rec.MatrixV, 1,  0, -1, -0.5);
-        end;
-      nmSobel:
-        begin
-          SetLength(Rec.MatrixU, 6);
-          SetEntry(Rec.MatrixU, 0, -1,  1, -1.0);
-          SetEntry(Rec.MatrixU, 1, -1,  0, -2.0);
-          SetEntry(Rec.MatrixU, 2, -1, -1, -1.0);
-          SetEntry(Rec.MatrixU, 3,  1,  1,  1.0);
-          SetEntry(Rec.MatrixU, 4,  1,  0,  2.0);
-          SetEntry(Rec.MatrixU, 5,  1, -1,  1.0);
-
-          SetLength(Rec.MatrixV, 6);
-          SetEntry(Rec.MatrixV, 0, -1,  1,  1.0);
-          SetEntry(Rec.MatrixV, 1,  0,  1,  2.0);
-          SetEntry(Rec.MatrixV, 2,  1,  1,  1.0);
-          SetEntry(Rec.MatrixV, 3, -1, -1, -1.0);
-          SetEntry(Rec.MatrixV, 4,  0, -1, -2.0);
-          SetEntry(Rec.MatrixV, 5,  1, -1, -1.0);
-        end;
-      nm3x3:
-        begin
-          SetLength(Rec.MatrixU, 6);
-          SetEntry(Rec.MatrixU, 0, -1,  1, -1/6);
-          SetEntry(Rec.MatrixU, 1, -1,  0, -1/6);
-          SetEntry(Rec.MatrixU, 2, -1, -1, -1/6);
-          SetEntry(Rec.MatrixU, 3,  1,  1,  1/6);
-          SetEntry(Rec.MatrixU, 4,  1,  0,  1/6);
-          SetEntry(Rec.MatrixU, 5,  1, -1,  1/6);
-
-          SetLength(Rec.MatrixV, 6);
-          SetEntry(Rec.MatrixV, 0, -1,  1,  1/6);
-          SetEntry(Rec.MatrixV, 1,  0,  1,  1/6);
-          SetEntry(Rec.MatrixV, 2,  1,  1,  1/6);
-          SetEntry(Rec.MatrixV, 3, -1, -1, -1/6);
-          SetEntry(Rec.MatrixV, 4,  0, -1, -1/6);
-          SetEntry(Rec.MatrixV, 5,  1, -1, -1/6);
-        end;
-      nm5x5:
-        begin
-          SetLength(Rec.MatrixU, 20);
-          SetEntry(Rec.MatrixU,  0, -2,  2, -1 / 16);
-          SetEntry(Rec.MatrixU,  1, -1,  2, -1 / 10);
-          SetEntry(Rec.MatrixU,  2,  1,  2,  1 / 10);
-          SetEntry(Rec.MatrixU,  3,  2,  2,  1 / 16);
-          SetEntry(Rec.MatrixU,  4, -2,  1, -1 / 10);
-          SetEntry(Rec.MatrixU,  5, -1,  1, -1 /  8);
-          SetEntry(Rec.MatrixU,  6,  1,  1,  1 /  8);
-          SetEntry(Rec.MatrixU,  7,  2,  1,  1 / 10);
-          SetEntry(Rec.MatrixU,  8, -2,  0, -1 / 2.8);
-          SetEntry(Rec.MatrixU,  9, -1,  0, -0.5);
-          SetEntry(Rec.MatrixU, 10,  1,  0,  0.5);
-          SetEntry(Rec.MatrixU, 11,  2,  0,  1 / 2.8);
-          SetEntry(Rec.MatrixU, 12, -2, -1, -1 / 10);
-          SetEntry(Rec.MatrixU, 13, -1, -1, -1 /  8);
-          SetEntry(Rec.MatrixU, 14,  1, -1,  1 /  8);
-          SetEntry(Rec.MatrixU, 15,  2, -1,  1 / 10);
-          SetEntry(Rec.MatrixU, 16, -2, -2, -1 / 16);
-          SetEntry(Rec.MatrixU, 17, -1, -2, -1 / 10);
-          SetEntry(Rec.MatrixU, 18,  1, -2,  1 / 10);
-          SetEntry(Rec.MatrixU, 19,  2, -2,  1 / 16);
-
-          SetLength(Rec.MatrixV, 20);
-          SetEntry(Rec.MatrixV,  0, -2,  2,  1 / 16);
-          SetEntry(Rec.MatrixV,  1, -1,  2,  1 / 10);
-          SetEntry(Rec.MatrixV,  2,  0,  2,  0.25);
-          SetEntry(Rec.MatrixV,  3,  1,  2,  1 / 10);
-          SetEntry(Rec.MatrixV,  4,  2,  2,  1 / 16);
-          SetEntry(Rec.MatrixV,  5, -2,  1,  1 / 10);
-          SetEntry(Rec.MatrixV,  6, -1,  1,  1 /  8);
-          SetEntry(Rec.MatrixV,  7,  0,  1,  0.5);
-          SetEntry(Rec.MatrixV,  8,  1,  1,  1 /  8);
-          SetEntry(Rec.MatrixV,  9,  2,  1,  1 / 16);
-          SetEntry(Rec.MatrixV, 10, -2, -1, -1 / 16);
-          SetEntry(Rec.MatrixV, 11, -1, -1, -1 /  8);
-          SetEntry(Rec.MatrixV, 12,  0, -1, -0.5);
-          SetEntry(Rec.MatrixV, 13,  1, -1, -1 /  8);
-          SetEntry(Rec.MatrixV, 14,  2, -1, -1 / 10);
-          SetEntry(Rec.MatrixV, 15, -2, -2, -1 / 16);
-          SetEntry(Rec.MatrixV, 16, -1, -2, -1 / 10);
-          SetEntry(Rec.MatrixV, 17,  0, -2, -0.25);
-          SetEntry(Rec.MatrixV, 18,  1, -2, -1 / 10);
-          SetEntry(Rec.MatrixV, 19,  2, -2, -1 / 16);
-        end;
+    case aFunc of
+      nm4Samples: begin
+        SetLength(Rec.MatrixU, 2);
+        SetEntry(Rec.MatrixU, 0, -1,  0, -0.5);
+        SetEntry(Rec.MatrixU, 1,  1,  0,  0.5);
+
+        SetLength(Rec.MatrixV, 2);
+        SetEntry(Rec.MatrixV, 0,  0,  1,  0.5);
+        SetEntry(Rec.MatrixV, 1,  0, -1, -0.5);
+      end;
+
+      nmSobel: begin
+        SetLength(Rec.MatrixU, 6);
+        SetEntry(Rec.MatrixU, 0, -1,  1, -1.0);
+        SetEntry(Rec.MatrixU, 1, -1,  0, -2.0);
+        SetEntry(Rec.MatrixU, 2, -1, -1, -1.0);
+        SetEntry(Rec.MatrixU, 3,  1,  1,  1.0);
+        SetEntry(Rec.MatrixU, 4,  1,  0,  2.0);
+        SetEntry(Rec.MatrixU, 5,  1, -1,  1.0);
+
+        SetLength(Rec.MatrixV, 6);
+        SetEntry(Rec.MatrixV, 0, -1,  1,  1.0);
+        SetEntry(Rec.MatrixV, 1,  0,  1,  2.0);
+        SetEntry(Rec.MatrixV, 2,  1,  1,  1.0);
+        SetEntry(Rec.MatrixV, 3, -1, -1, -1.0);
+        SetEntry(Rec.MatrixV, 4,  0, -1, -2.0);
+        SetEntry(Rec.MatrixV, 5,  1, -1, -1.0);
+      end;
+
+      nm3x3: begin
+        SetLength(Rec.MatrixU, 6);
+        SetEntry(Rec.MatrixU, 0, -1,  1, -1/6);
+        SetEntry(Rec.MatrixU, 1, -1,  0, -1/6);
+        SetEntry(Rec.MatrixU, 2, -1, -1, -1/6);
+        SetEntry(Rec.MatrixU, 3,  1,  1,  1/6);
+        SetEntry(Rec.MatrixU, 4,  1,  0,  1/6);
+        SetEntry(Rec.MatrixU, 5,  1, -1,  1/6);
+
+        SetLength(Rec.MatrixV, 6);
+        SetEntry(Rec.MatrixV, 0, -1,  1,  1/6);
+        SetEntry(Rec.MatrixV, 1,  0,  1,  1/6);
+        SetEntry(Rec.MatrixV, 2,  1,  1,  1/6);
+        SetEntry(Rec.MatrixV, 3, -1, -1, -1/6);
+        SetEntry(Rec.MatrixV, 4,  0, -1, -1/6);
+        SetEntry(Rec.MatrixV, 5,  1, -1, -1/6);
+      end;
+
+      nm5x5: begin
+        SetLength(Rec.MatrixU, 20);
+        SetEntry(Rec.MatrixU,  0, -2,  2, -1 / 16);
+        SetEntry(Rec.MatrixU,  1, -1,  2, -1 / 10);
+        SetEntry(Rec.MatrixU,  2,  1,  2,  1 / 10);
+        SetEntry(Rec.MatrixU,  3,  2,  2,  1 / 16);
+        SetEntry(Rec.MatrixU,  4, -2,  1, -1 / 10);
+        SetEntry(Rec.MatrixU,  5, -1,  1, -1 /  8);
+        SetEntry(Rec.MatrixU,  6,  1,  1,  1 /  8);
+        SetEntry(Rec.MatrixU,  7,  2,  1,  1 / 10);
+        SetEntry(Rec.MatrixU,  8, -2,  0, -1 / 2.8);
+        SetEntry(Rec.MatrixU,  9, -1,  0, -0.5);
+        SetEntry(Rec.MatrixU, 10,  1,  0,  0.5);
+        SetEntry(Rec.MatrixU, 11,  2,  0,  1 / 2.8);
+        SetEntry(Rec.MatrixU, 12, -2, -1, -1 / 10);
+        SetEntry(Rec.MatrixU, 13, -1, -1, -1 /  8);
+        SetEntry(Rec.MatrixU, 14,  1, -1,  1 /  8);
+        SetEntry(Rec.MatrixU, 15,  2, -1,  1 / 10);
+        SetEntry(Rec.MatrixU, 16, -2, -2, -1 / 16);
+        SetEntry(Rec.MatrixU, 17, -1, -2, -1 / 10);
+        SetEntry(Rec.MatrixU, 18,  1, -2,  1 / 10);
+        SetEntry(Rec.MatrixU, 19,  2, -2,  1 / 16);
+
+        SetLength(Rec.MatrixV, 20);
+        SetEntry(Rec.MatrixV,  0, -2,  2,  1 / 16);
+        SetEntry(Rec.MatrixV,  1, -1,  2,  1 / 10);
+        SetEntry(Rec.MatrixV,  2,  0,  2,  0.25);
+        SetEntry(Rec.MatrixV,  3,  1,  2,  1 / 10);
+        SetEntry(Rec.MatrixV,  4,  2,  2,  1 / 16);
+        SetEntry(Rec.MatrixV,  5, -2,  1,  1 / 10);
+        SetEntry(Rec.MatrixV,  6, -1,  1,  1 /  8);
+        SetEntry(Rec.MatrixV,  7,  0,  1,  0.5);
+        SetEntry(Rec.MatrixV,  8,  1,  1,  1 /  8);
+        SetEntry(Rec.MatrixV,  9,  2,  1,  1 / 16);
+        SetEntry(Rec.MatrixV, 10, -2, -1, -1 / 16);
+        SetEntry(Rec.MatrixV, 11, -1, -1, -1 /  8);
+        SetEntry(Rec.MatrixV, 12,  0, -1, -0.5);
+        SetEntry(Rec.MatrixV, 13,  1, -1, -1 /  8);
+        SetEntry(Rec.MatrixV, 14,  2, -1, -1 / 10);
+        SetEntry(Rec.MatrixV, 15, -2, -2, -1 / 16);
+        SetEntry(Rec.MatrixV, 16, -1, -2, -1 / 10);
+        SetEntry(Rec.MatrixV, 17,  0, -2, -0.25);
+        SetEntry(Rec.MatrixV, 18,  1, -2, -1 / 10);
+        SetEntry(Rec.MatrixV, 19,  2, -2, -1 / 16);
+      end;
     end;
 
     // Daten Sammeln
-    if UseAlpha and FormatHasAlpha(InternalFormat) then
-      AddFunc(glBitmapToNormalMapPrepareAlphaFunc, False, @Rec)
+    if aUseAlpha and FORMAT_DESCRIPTORS[Format].HasAlpha then
+      AddFunc(glBitmapToNormalMapPrepareAlphaFunc, false, PtrInt(@Rec))
     else
-      AddFunc(glBitmapToNormalMapPrepareFunc, False, @Rec);
-
-    // Neues Bild berechnen
-    AddFunc(glBitmapToNormalMapFunc, False, @Rec);
+      AddFunc(glBitmapToNormalMapPrepareFunc, false, PtrInt(@Rec));
+    AddFunc(glBitmapToNormalMapFunc, false, PtrInt(@Rec));
   finally
     SetLength(Rec.Heights, 0);
   end;
 end;
 
 
-procedure TglBitmap2D.GrabScreen(Top, Left, Right, Bottom: Integer; Format: TglBitmapFormat);
-var
-  Temp: pByte;
-  Size: Integer;
-  glFormat, glInternalFormat, glType: Cardinal;
-begin
-  if not FormatIsUncompressed(Format) then
-    raise EglBitmapUnsupportedFormatFormat.Create('TglBitmap2D.GrabScreen - ' + UNSUPPORTED_INTERNAL_FORMAT);
-
-  // Only to select Formats
-  SelectFormat(Format, glFormat, glInternalFormat, glType, False);
-
-  Size := FormatGetImageSize(glBitmapPosition(Right - Left, Bottom - Top), Format);
-  GetMem(Temp, Size);
-  try
-    glPixelStorei(GL_PACK_ALIGNMENT, 1);
-    glReadPixels(Left, Top, Right - Left, Bottom - Top, glFormat, glType, Temp);
-
-    // Set Data
-    SetDataPointer(Temp, Format, Right - Left, Bottom - Top);
-
-    // Flip
-    FlipVert;
-  except
-    FreeMem(Temp);
-    raise;
-  end;
-end;
-
-
-procedure TglBitmap2D.GetDataFromTexture;
-var
-  Temp: pByte;
-  TempWidth, TempHeight, RedSize, GreenSize, BlueSize, AlphaSize, LumSize: Integer;
-  TempType, TempIntFormat: Cardinal;
-  IntFormat: TglBitmapFormat;
-begin
-  Bind;
-
-  // Request Data
-  glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_WIDTH, @TempWidth);
-  glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT, @TempHeight);
-  glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat);
-
-  glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_RED_SIZE, @RedSize);
-  glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_GREEN_SIZE, @GreenSize);
-  glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_BLUE_SIZE, @BlueSize);
-  glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_ALPHA_SIZE, @AlphaSize);
-  glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_LUMINANCE_SIZE, @LumSize);
-
-  // Get glBitmapInternalFormat from TempIntFormat
-  TempType := GL_UNSIGNED_BYTE;
-  case TempIntFormat of
-    GL_ALPHA:
-      IntFormat := ifAlpha;
-    GL_LUMINANCE:
-      IntFormat := ifLuminance;
-    GL_LUMINANCE_ALPHA:
-      IntFormat := ifLuminanceAlpha;
-    GL_RGB4:
-      begin
-        IntFormat := ifR5G6B5;
-        TempIntFormat := GL_RGB;
-        TempType := GL_UNSIGNED_SHORT_5_6_5;
-      end;
-    GL_RGB, GL_RGB8:
-      IntFormat := tfRGB8;
-    GL_RGBA, GL_RGBA4, GL_RGBA8:
-      begin
-        if (RedSize = 4) and (BlueSize = 4) and (GreenSize = 4) and (AlphaSize = 4) then begin
-          IntFormat := tfRGBA4;
-          TempIntFormat := GL_BGRA;
-          TempType := GL_UNSIGNED_SHORT_4_4_4_4_REV;
-        end else
-        if (RedSize = 5) and (BlueSize = 5) and (GreenSize = 5) and (AlphaSize = 1) then begin
-          IntFormat := tfRGB5A1;
-          TempIntFormat := GL_BGRA;
-          TempType := GL_UNSIGNED_SHORT_1_5_5_5_REV;
-        end else begin
-          IntFormat := tfRGBA8;
-        end;
-      end;
-    GL_BGR:
-      IntFormat := ifBGR8;
-    GL_BGRA:
-      IntFormat := ifBGRA8;
-    GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
-      IntFormat := ifDXT1;
-    GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
-      IntFormat := ifDXT1;
-    GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
-      IntFormat := ifDXT3;
-    GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
-      IntFormat := ifDXT5;
-    else
-      IntFormat := ifEmpty;
-  end;
 
-  // Getting data from OpenGL
-  GetMem(Temp, FormatGetImageSize(glBitmapPosition(TempWidth, TempHeight), IntFormat));
-  try
-    if FormatIsCompressed(IntFormat) and (GL_VERSION_1_3 or GL_ARB_texture_compression) then
-      glGetCompressedTexImage(Target, 0, Temp)
-    else
-      glGetTexImage(Target, 0, TempIntFormat, TempType, Temp);
 
-    SetDataPointer(Temp, IntFormat, TempWidth, TempHeight);
-  except
-    FreeMem(Temp);
-    raise;
-  end;
-end;
 
 
-function TglBitmap2D.GetScanline(Index: Integer): Pointer;
-begin
-  if (Index >= Low(fLines)) and (Index <= High(fLines)) then
-    Result := fLines[Index]
-  else
-    Result := nil;
-end;
 
 
-{ TglBitmap1D }
 
+(*
 procedure TglBitmap1D.SetDataPointer(Data: pByte; Format: TglBitmapInternalFormat; Width, Height: Integer);
 var
   pTemp: pByte;
@@ -6575,7 +6431,7 @@ var
   Col: Integer;
   pTempDest, pDest, pSource: pByte;
 begin
-  Result := Inherited FlipHorz;
+  result := inherited FlipHorz;
 
   if Assigned(Data) and FormatIsUncompressed(InternalFormat) then begin
     pSource := Data;
@@ -6594,7 +6450,7 @@ begin
 
       SetDataPointer(pDest, InternalFormat);
 
-      Result := True;
+      result := true;
     finally
       FreeMem(pDest);
     end;
@@ -6650,7 +6506,7 @@ begin
     UploadData(Target, glFormat, glInternalFormat, glType, BuildWithGlu);
 
     // Infos sammeln
-    glAreTexturesResident(1, @ID, @fIsResident);
+    glAreTexturesResident(1, @fID, @fIsResident);
   end;
 end;
 
@@ -6724,7 +6580,7 @@ end;
 
 procedure TglBitmapCubeMap.GenTexture(TestTextureSize: Boolean);
 begin
-  Assert(False, 'TglBitmapCubeMap.GenTexture - Don''t call GenTextures directly.');
+  Assert(false, 'TglBitmapCubeMap.GenTexture - Don''t call GenTextures directly.');
 end;
 
 
@@ -6849,7 +6705,7 @@ var
 begin
   Rec.HalfSize := Size div 2;
 
-  FreeDataAfterGenTexture := False;
+  FreeDataAfterGenTexture := false;
 
   SizeRec.Fields := [ffX, ffY];
   SizeRec.X := Size;
@@ -6885,6 +6741,7 @@ begin
   LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
   GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, TestTextureSize);
 end;
+*)
 
 initialization
   glBitmapSetDefaultFormat(tfEmpty);