* added HasOpenGLSupport to FormatDescriptor to check if the given format is supporte...
[glBitmap.git] / glBitmap.pas
1 { glBitmap by Steffen Xonna aka Lossy eX (2003-2008)
2   http://www.opengl24.de/index.php?cat=header&file=glbitmap
3
4   modified by Delphi OpenGL Community (http://delphigl.com/) (2013)
5
6   The contents of this file are used with permission, subject to
7   the Mozilla Public License Version 1.1 (the "License"); you may
8   not use this file except in compliance with the License. You may
9   obtain a copy of the License at
10   http://www.mozilla.org/MPL/MPL-1.1.html
11
12   The glBitmap is a Delphi/FPC unit that contains several wrapper classes
13   to manage OpenGL texture objects. Below you can find a list of the main
14   functionality of this classes:
15   - load texture data from file (e.g. BMP, TGA, DDS, PNG, JPEG, ...)
16   - load texture data from several other image objects (e.g. TBitmap, TLazIntfImage, SDL Surface)
17   - save texture data to file (e.g. BMP, TGA, DDS, PNG, JPEG, ...)
18   - save texture data to several other image objects (e.g. TBitmap, TLazIntfImage, SDL Surface)
19   - support for many texture formats (e.g. RGB8, BGR8, RGBA8, BGRA8, ...)
20   - manage texture properties (e.g. Filter, Clamp, Mipmap, ...)
21   - upload texture data to video card
22   - download texture data from video card
23   - manipulate texture data (e.g. add alpha, remove alpha, convert to other format, switch RGB, ...) }
24
25 unit glBitmap;
26
27 {$I glBitmapConf.inc}
28
29 // Delphi Versions
30 {$IFDEF fpc}
31   {$MODE Delphi}
32
33   {$IFDEF CPUI386}
34     {$DEFINE CPU386}
35     {$ASMMODE INTEL}
36   {$ENDIF}
37
38   {$IFNDEF WINDOWS}
39     {$linklib c}
40   {$ENDIF}
41 {$ENDIF}
42
43 // Operation System
44 {$IF DEFINED(WIN32) or DEFINED(WIN64) or DEFINED(WINDOWS)}
45   {$DEFINE GLB_WIN}
46 {$ELSEIF DEFINED(LINUX)}
47   {$DEFINE GLB_LINUX}
48 {$IFEND}
49
50 // OpenGL ES
51 {$IF DEFINED(OPENGL_ES_EXT)} {$DEFINE OPENGL_ES_1_1} {$IFEND}
52 {$IF DEFINED(OPENGL_ES_3_0)} {$DEFINE OPENGL_ES_2_0} {$IFEND}
53 {$IF DEFINED(OPENGL_ES_2_0)} {$DEFINE OPENGL_ES_1_1} {$IFEND}
54 {$IF DEFINED(OPENGL_ES_1_1)} {$DEFINE OPENGL_ES}     {$IFEND}
55
56 // checking define combinations
57 //SDL Image
58 {$IFDEF GLB_SDL_IMAGE}
59   {$IFNDEF GLB_SDL}
60     {$MESSAGE warn 'SDL_image won''t work without SDL. SDL will be activated.'}
61     {$DEFINE GLB_SDL}
62   {$ENDIF}
63
64   {$IFDEF GLB_LAZ_PNG}
65     {$MESSAGE warn 'The Lazarus TPortableNetworkGraphics will be ignored because you are using SDL_image.'}
66     {$undef GLB_LAZ_PNG}
67   {$ENDIF}
68
69   {$IFDEF GLB_PNGIMAGE}
70     {$MESSAGE warn 'The unit pngimage will be ignored because you are using SDL_image.'}
71     {$undef GLB_PNGIMAGE}
72   {$ENDIF}
73
74   {$IFDEF GLB_LAZ_JPEG}
75     {$MESSAGE warn 'The Lazarus TJPEGImage will be ignored because you are using SDL_image.'}
76     {$undef GLB_LAZ_JPEG}
77   {$ENDIF}
78
79   {$IFDEF GLB_DELPHI_JPEG}
80     {$MESSAGE warn 'The unit JPEG will be ignored because you are using SDL_image.'}
81     {$undef GLB_DELPHI_JPEG}
82   {$ENDIF}
83
84   {$IFDEF GLB_LIB_PNG}
85     {$MESSAGE warn 'The library libPNG will be ignored because you are using SDL_image.'}
86     {$undef GLB_LIB_PNG}
87   {$ENDIF}
88
89   {$IFDEF GLB_LIB_JPEG}
90     {$MESSAGE warn 'The library libJPEG will be ignored because you are using SDL_image.'}
91     {$undef GLB_LIB_JPEG}
92   {$ENDIF}
93
94   {$DEFINE GLB_SUPPORT_PNG_READ}
95   {$DEFINE GLB_SUPPORT_JPEG_READ}
96 {$ENDIF}
97
98 // Lazarus TPortableNetworkGraphic
99 {$IFDEF GLB_LAZ_PNG}
100   {$IFNDEF GLB_LAZARUS}
101     {$MESSAGE warn 'Lazarus TPortableNetworkGraphic won''t work without Lazarus. Lazarus will be activated.'}
102     {$DEFINE GLB_LAZARUS}
103   {$ENDIF}
104
105   {$IFDEF GLB_PNGIMAGE}
106     {$MESSAGE warn 'The pngimage will be ignored if you are using Lazarus TPortableNetworkGraphic.'}
107     {$undef GLB_PNGIMAGE}
108   {$ENDIF}
109
110   {$IFDEF GLB_LIB_PNG}
111     {$MESSAGE warn 'The library libPNG will be ignored if you are using Lazarus TPortableNetworkGraphic.'}
112     {$undef GLB_LIB_PNG}
113   {$ENDIF}
114
115   {$DEFINE GLB_SUPPORT_PNG_READ}
116   {$DEFINE GLB_SUPPORT_PNG_WRITE}
117 {$ENDIF}
118
119 // PNG Image
120 {$IFDEF GLB_PNGIMAGE}
121   {$IFDEF GLB_LIB_PNG}
122     {$MESSAGE warn 'The library libPNG will be ignored if you are using pngimage.'}
123     {$undef GLB_LIB_PNG}
124   {$ENDIF}
125
126   {$DEFINE GLB_SUPPORT_PNG_READ}
127   {$DEFINE GLB_SUPPORT_PNG_WRITE}
128 {$ENDIF}
129
130 // libPNG
131 {$IFDEF GLB_LIB_PNG}
132   {$DEFINE GLB_SUPPORT_PNG_READ}
133   {$DEFINE GLB_SUPPORT_PNG_WRITE}
134 {$ENDIF}
135
136 // Lazarus TJPEGImage
137 {$IFDEF GLB_LAZ_JPEG}
138   {$IFNDEF GLB_LAZARUS}
139     {$MESSAGE warn 'Lazarus TJPEGImage won''t work without Lazarus. Lazarus will be activated.'}
140     {$DEFINE GLB_LAZARUS}
141   {$ENDIF}
142
143   {$IFDEF GLB_DELPHI_JPEG}
144     {$MESSAGE warn 'The Delphi JPEGImage will be ignored if you are using the Lazarus TJPEGImage.'}
145     {$undef GLB_DELPHI_JPEG}
146   {$ENDIF}
147
148   {$IFDEF GLB_LIB_JPEG}
149     {$MESSAGE warn 'The library libJPEG will be ignored if you are using the Lazarus TJPEGImage.'}
150     {$undef GLB_LIB_JPEG}
151   {$ENDIF}
152
153   {$DEFINE GLB_SUPPORT_JPEG_READ}
154   {$DEFINE GLB_SUPPORT_JPEG_WRITE}
155 {$ENDIF}
156
157 // JPEG Image
158 {$IFDEF GLB_DELPHI_JPEG}
159   {$IFDEF GLB_LIB_JPEG}
160     {$MESSAGE warn 'The library libJPEG will be ignored if you are using the unit JPEG.'}
161     {$undef GLB_LIB_JPEG}
162   {$ENDIF}
163
164   {$DEFINE GLB_SUPPORT_JPEG_READ}
165   {$DEFINE GLB_SUPPORT_JPEG_WRITE}
166 {$ENDIF}
167
168 // libJPEG
169 {$IFDEF GLB_LIB_JPEG}
170   {$DEFINE GLB_SUPPORT_JPEG_READ}
171   {$DEFINE GLB_SUPPORT_JPEG_WRITE}
172 {$ENDIF}
173
174 // general options
175 {$EXTENDEDSYNTAX ON}
176 {$LONGSTRINGS ON}
177 {$ALIGN ON}
178 {$IFNDEF FPC}
179   {$OPTIMIZATION ON}
180 {$ENDIF}
181
182 {$UNDEF GLB_LAZARUS}
183
184 interface
185
186 uses
187   {$IFDEF OPENGL_ES}            dglOpenGLES,
188   {$ELSE}                       dglOpenGL,                          {$ENDIF}
189
190   {$IF DEFINED(GLB_WIN) AND
191        DEFINED(GLB_DELPHI)}     windows,                            {$IFEND}
192
193   {$IFDEF GLB_SDL}              SDL,                                {$ENDIF}
194   {$IFDEF GLB_LAZARUS}          IntfGraphics, GraphType, Graphics,  {$ENDIF}
195   {$IFDEF GLB_DELPHI}           Dialogs, Graphics, Types,           {$ENDIF}
196
197   {$IFDEF GLB_SDL_IMAGE}        SDL_image,                          {$ENDIF}
198   {$IFDEF GLB_PNGIMAGE}         pngimage,                           {$ENDIF}
199   {$IFDEF GLB_LIB_PNG}          libPNG,                             {$ENDIF}
200   {$IFDEF GLB_DELPHI_JPEG}      JPEG,                               {$ENDIF}
201   {$IFDEF GLB_LIB_JPEG}         libJPEG,                            {$ENDIF}
202
203   Classes, SysUtils;
204
205 type
206 {$IFNDEF fpc}
207   QWord   = System.UInt64;
208   PQWord  = ^QWord;
209
210   PtrInt  = Longint;
211   PtrUInt = DWord;
212 {$ENDIF}
213
214
215   { type that describes the format of the data stored in a texture.
216     the name of formats is composed of the following constituents:
217     - multiple channels:
218        - channel                          (e.g. R, G, B, A or Alpha, Luminance or X (reserved))
219        - width of the chanel in bit       (4, 8, 16, ...)
220     - data type                           (e.g. ub, us, ui)
221     - number of elements of data types }
222   TglBitmapFormat = (
223     tfEmpty = 0,
224
225     tfAlpha4ub1,                //< 1 x unsigned byte
226     tfAlpha8ub1,                //< 1 x unsigned byte
227     tfAlpha16us1,               //< 1 x unsigned short
228
229     tfLuminance4ub1,            //< 1 x unsigned byte
230     tfLuminance8ub1,            //< 1 x unsigned byte
231     tfLuminance16us1,           //< 1 x unsigned short
232
233     tfLuminance4Alpha4ub2,      //< 1 x unsigned byte (lum), 1 x unsigned byte (alpha)
234     tfLuminance6Alpha2ub2,      //< 1 x unsigned byte (lum), 1 x unsigned byte (alpha)
235     tfLuminance8Alpha8ub2,      //< 1 x unsigned byte (lum), 1 x unsigned byte (alpha)
236     tfLuminance12Alpha4us2,     //< 1 x unsigned short (lum), 1 x unsigned short (alpha)
237     tfLuminance16Alpha16us2,    //< 1 x unsigned short (lum), 1 x unsigned short (alpha)
238
239     tfR3G3B2ub1,                //< 1 x unsigned byte (3bit red, 3bit green, 2bit blue)
240     tfRGBX4us1,                 //< 1 x unsigned short (4bit red, 4bit green, 4bit blue, 4bit reserverd)
241     tfXRGB4us1,                 //< 1 x unsigned short (4bit reserved, 4bit red, 4bit green, 4bit blue)
242     tfR5G6B5us1,                //< 1 x unsigned short (5bit red, 6bit green, 5bit blue)
243     tfRGB5X1us1,                //< 1 x unsigned short (5bit red, 5bit green, 5bit blue, 1bit reserved)
244     tfX1RGB5us1,                //< 1 x unsigned short (1bit reserved, 5bit red, 5bit green, 5bit blue)
245     tfRGB8ub3,                  //< 1 x unsigned byte (red), 1 x unsigned byte (green), 1 x unsigned byte (blue)
246     tfRGBX8ui1,                 //< 1 x unsigned int (8bit red, 8bit green, 8bit blue, 8bit reserved)
247     tfXRGB8ui1,                 //< 1 x unsigned int (8bit reserved, 8bit red, 8bit green, 8bit blue)
248     tfRGB10X2ui1,               //< 1 x unsigned int (10bit red, 10bit green, 10bit blue, 2bit reserved)
249     tfX2RGB10ui1,               //< 1 x unsigned int (2bit reserved, 10bit red, 10bit green, 10bit blue)
250     tfRGB16us3,                 //< 1 x unsigned short (red), 1 x unsigned short (green), 1 x unsigned short (blue)
251
252     tfRGBA4us1,                 //< 1 x unsigned short (4bit red, 4bit green, 4bit blue, 4bit alpha)
253     tfARGB4us1,                 //< 1 x unsigned short (4bit alpha, 4bit red, 4bit green, 4bit blue)
254     tfRGB5A1us1,                //< 1 x unsigned short (5bit red, 5bit green, 5bit blue, 1bit alpha)
255     tfA1RGB5us1,                //< 1 x unsigned short (1bit alpha, 5bit red, 5bit green, 5bit blue)
256     tfRGBA8ui1,                 //< 1 x unsigned int (8bit red, 8bit green, 8bit blue, 8 bit alpha)
257     tfARGB8ui1,                 //< 1 x unsigned int (8 bit alpha, 8bit red, 8bit green, 8bit blue)
258     tfRGBA8ub4,                 //< 1 x unsigned byte (red), 1 x unsigned byte (green), 1 x unsigned byte (blue), 1 x unsigned byte (alpha)
259     tfRGB10A2ui1,               //< 1 x unsigned int (10bit red, 10bit green, 10bit blue, 2bit alpha)
260     tfA2RGB10ui1,               //< 1 x unsigned int (2bit alpha, 10bit red, 10bit green, 10bit blue)
261     tfRGBA16us4,                //< 1 x unsigned short (red), 1 x unsigned short (green), 1 x unsigned short (blue), 1 x unsigned short (alpha)
262
263     tfBGRX4us1,                 //< 1 x unsigned short (4bit blue, 4bit green, 4bit red, 4bit reserved)
264     tfXBGR4us1,                 //< 1 x unsigned short (4bit reserved, 4bit blue, 4bit green, 4bit red)
265     tfB5G6R5us1,                //< 1 x unsigned short (5bit blue, 6bit green, 5bit red)
266     tfBGR5X1us1,                //< 1 x unsigned short (5bit blue, 5bit green, 5bit red, 1bit reserved)
267     tfX1BGR5us1,                //< 1 x unsigned short (1bit reserved, 5bit blue, 5bit green, 5bit red)
268     tfBGR8ub3,                  //< 1 x unsigned byte (blue), 1 x unsigned byte (green), 1 x unsigned byte (red)
269     tfBGRX8ui1,                 //< 1 x unsigned int (8bit blue, 8bit green, 8bit red, 8bit reserved)
270     tfXBGR8ui1,                 //< 1 x unsigned int (8bit reserved, 8bit blue, 8bit green, 8bit red)
271     tfBGR10X2ui1,               //< 1 x unsigned int (10bit blue, 10bit green, 10bit red, 2bit reserved)
272     tfX2BGR10ui1,               //< 1 x unsigned int (2bit reserved, 10bit blue, 10bit green, 10bit red)
273     tfBGR16us3,                 //< 1 x unsigned short (blue), 1 x unsigned short (green), 1 x unsigned short (red)
274
275     tfBGRA4us1,                 //< 1 x unsigned short (4bit blue, 4bit green, 4bit red, 4bit alpha)
276     tfABGR4us1,                 //< 1 x unsigned short (4bit alpha, 4bit blue, 4bit green, 4bit red)
277     tfBGR5A1us1,                //< 1 x unsigned short (5bit blue, 5bit green, 5bit red, 1bit alpha)
278     tfA1BGR5us1,                //< 1 x unsigned short (1bit alpha, 5bit blue, 5bit green, 5bit red)
279     tfBGRA8ui1,                 //< 1 x unsigned int (8bit blue, 8bit green, 8bit red, 8bit alpha)
280     tfABGR8ui1,                 //< 1 x unsigned int (8bit alpha, 8bit blue, 8bit green, 8bit red)
281     tfBGRA8ub4,                 //< 1 x unsigned byte (blue), 1 x unsigned byte (green), 1 x unsigned byte (red), 1 x unsigned byte (alpha)
282     tfBGR10A2ui1,               //< 1 x unsigned int (10bit blue, 10bit green, 10bit red, 2bit alpha)
283     tfA2BGR10ui1,               //< 1 x unsigned int (2bit alpha, 10bit blue, 10bit green, 10bit red)
284     tfBGRA16us4,                //< 1 x unsigned short (blue), 1 x unsigned short (green), 1 x unsigned short (red), 1 x unsigned short (alpha)
285
286     tfDepth16us1,               //< 1 x unsigned short (depth)
287     tfDepth24ui1,               //< 1 x unsigned int (depth)
288     tfDepth32ui1,               //< 1 x unsigned int (depth)
289
290     tfS3tcDtx1RGBA,
291     tfS3tcDtx3RGBA,
292     tfS3tcDtx5RGBA
293   );
294
295   { type to define suitable file formats }
296   TglBitmapFileType = (
297      {$IFDEF GLB_SUPPORT_PNG_WRITE} ftPNG,  {$ENDIF}    //< Portable Network Graphic file (PNG)
298      {$IFDEF GLB_SUPPORT_JPEG_WRITE}ftJPEG, {$ENDIF}    //< JPEG file
299      ftDDS,                                             //< Direct Draw Surface file (DDS)
300      ftTGA,                                             //< Targa Image File (TGA)
301      ftBMP,                                             //< Windows Bitmap File (BMP)
302      ftRAW);                                            //< glBitmap RAW file format
303    TglBitmapFileTypes = set of TglBitmapFileType;
304
305   { possible mipmap types }
306   TglBitmapMipMap = (
307      mmNone,                //< no mipmaps
308      mmMipmap,              //< normal mipmaps
309      mmMipmapGlu);          //< mipmaps generated with glu functions
310
311   { possible normal map functions }
312    TglBitmapNormalMapFunc = (
313      nm4Samples,
314      nmSobel,
315      nm3x3,
316      nm5x5);
317
318  ////////////////////////////////////////////////////////////////////////////////////////////////////
319    EglBitmap                  = class(Exception);   //< glBitmap exception
320    EglBitmapNotSupported      = class(Exception);   //< exception for not supported functions
321    EglBitmapSizeToLarge       = class(EglBitmap);   //< exception for to large textures
322    EglBitmapNonPowerOfTwo     = class(EglBitmap);   //< exception for non power of two textures
323    EglBitmapUnsupportedFormat = class(EglBitmap)    //< exception for unsupporetd formats
324    public
325      constructor Create(const aFormat: TglBitmapFormat); overload;
326      constructor Create(const aMsg: String; const aFormat: TglBitmapFormat); overload;
327    end;
328
329 ////////////////////////////////////////////////////////////////////////////////////////////////////
330   { record that stores 4 unsigned integer values }
331   TglBitmapRec4ui = packed record
332   case Integer of
333     0: (r, g, b, a: Cardinal);
334     1: (arr: array[0..3] of Cardinal);
335   end;
336
337   { record that stores 4 unsigned byte values }
338   TglBitmapRec4ub = packed record
339   case Integer of
340     0: (r, g, b, a: Byte);
341     1: (arr: array[0..3] of Byte);
342   end;
343
344   { record that stores 4 unsigned long integer values }
345   TglBitmapRec4ul = packed record
346   case Integer of
347     0: (r, g, b, a: QWord);
348     1: (arr: array[0..3] of QWord);
349   end;
350
351   { structure to store pixel data in }
352   TglBitmapPixelData = packed record
353     Data:   TglBitmapRec4ui;  //< color data for each color channel
354     Range:  TglBitmapRec4ui;  //< maximal color value for each channel
355     Format: TglBitmapFormat;  //< format of the pixel
356   end;
357   PglBitmapPixelData = ^TglBitmapPixelData;
358
359   TglBitmapSizeFields = set of (ffX, ffY);
360   TglBitmapSize = packed record
361     Fields: TglBitmapSizeFields;
362     X: Word;
363     Y: Word;
364   end;
365   TglBitmapPixelPosition = TglBitmapSize;
366
367   { describes the properties of a given texture data format }
368   TglBitmapFormatDescriptor = class(TObject)
369   private
370     // cached properties
371     fBytesPerPixel: Single;   //< number of bytes for each pixel
372     fChannelCount: Integer;   //< number of color channels
373     fMask: TglBitmapRec4ul;   //< bitmask for each color channel
374     fRange: TglBitmapRec4ui;  //< maximal value of each color channel
375
376     { @return @true if the format has a red color channel, @false otherwise }
377     function GetHasRed: Boolean;
378
379     { @return @true if the format has a green color channel, @false otherwise }
380     function GetHasGreen: Boolean;
381
382     { @return @true if the format has a blue color channel, @false otherwise }
383     function GetHasBlue: Boolean;
384
385     { @return @true if the format has a alpha color channel, @false otherwise }
386     function GetHasAlpha: Boolean;
387
388     { @return @true if the format has any color color channel, @false otherwise }
389     function GetHasColor: Boolean;
390
391     { @return @true if the format is a grayscale format, @false otherwise }
392     function GetIsGrayscale: Boolean;
393
394     { @return @true if the format is supported by OpenGL, @false otherwise }
395     function GetHasOpenGLSupport: Boolean;
396
397   protected
398     fFormat:        TglBitmapFormat;  //< format this descriptor belongs to
399     fWithAlpha:     TglBitmapFormat;  //< suitable format with alpha channel
400     fWithoutAlpha:  TglBitmapFormat;  //< suitable format without alpha channel
401     fOpenGLFormat:  TglBitmapFormat;  //< suitable format that is supported by OpenGL
402     fRGBInverted:   TglBitmapFormat;  //< suitable format with inverted RGB channels
403     fUncompressed:  TglBitmapFormat;  //< suitable format with uncompressed data
404
405     fBitsPerPixel: Integer;           //< number of bits per pixel
406     fIsCompressed: Boolean;           //< @true if the format is compressed, @false otherwise
407
408     fPrecision: TglBitmapRec4ub;      //< number of bits for each color channel
409     fShift:     TglBitmapRec4ub;      //< bit offset for each color channel
410
411     fglFormat:         GLenum;        //< OpenGL format enum (e.g. GL_RGB)
412     fglInternalFormat: GLenum;        //< OpenGL internal format enum (e.g. GL_RGB8)
413     fglDataFormat:     GLenum;        //< OpenGL data format enum (e.g. GL_UNSIGNED_BYTE)
414
415     { set values for this format descriptor }
416     procedure SetValues; virtual;
417
418     { calculate cached values }
419     procedure CalcValues;
420   public
421     property Format:        TglBitmapFormat read fFormat;         //< format this descriptor belongs to
422     property ChannelCount:  Integer         read fChannelCount;   //< number of color channels
423     property IsCompressed:  Boolean         read fIsCompressed;   //< @true if the format is compressed, @false otherwise
424     property BitsPerPixel:  Integer         read fBitsPerPixel;   //< number of bytes per pixel
425     property BytesPerPixel: Single          read fBytesPerPixel;  //< number of bits per pixel
426
427     property Precision: TglBitmapRec4ub read fPrecision;  //< number of bits for each color channel
428     property Shift:     TglBitmapRec4ub read fShift;      //< bit offset for each color channel
429     property Range:     TglBitmapRec4ui read fRange;      //< maximal value of each color channel
430     property Mask:      TglBitmapRec4ul read fMask;       //< bitmask for each color channel
431
432     property RGBInverted:  TglBitmapFormat read fRGBInverted;  //< suitable format with inverted RGB channels
433     property WithAlpha:    TglBitmapFormat read fWithAlpha;    //< suitable format with alpha channel
434     property WithoutAlpha: TglBitmapFormat read fWithAlpha;    //< suitable format without alpha channel
435     property OpenGLFormat: TglBitmapFormat read fOpenGLFormat; //< suitable format that is supported by OpenGL
436     property Uncompressed: TglBitmapFormat read fUncompressed; //< suitable format with uncompressed data
437
438     property glFormat:         GLenum  read fglFormat;         //< OpenGL format enum (e.g. GL_RGB)
439     property glInternalFormat: GLenum  read fglInternalFormat; //< OpenGL internal format enum (e.g. GL_RGB8)
440     property glDataFormat:     GLenum  read fglDataFormat;     //< OpenGL data format enum (e.g. GL_UNSIGNED_BYTE)
441
442     property HasRed:       Boolean read GetHasRed;        //< @true if the format has a red color channel, @false otherwise
443     property HasGreen:     Boolean read GetHasGreen;      //< @true if the format has a green color channel, @false otherwise
444     property HasBlue:      Boolean read GetHasBlue;       //< @true if the format has a blue color channel, @false otherwise
445     property HasAlpha:     Boolean read GetHasAlpha;      //< @true if the format has a alpha color channel, @false otherwise
446     property HasColor:     Boolean read GetHasColor;      //< @true if the format has any color color channel, @false otherwise
447     property IsGrayscale:  Boolean read GetIsGrayscale;   //< @true if the format is a grayscale format, @false otherwise
448
449     property HasOpenGLSupport: Boolean read GetHasOpenGLSupport; //< @true if the format is supported by OpenGL, @false otherwise
450
451     function GetSize(const aSize: TglBitmapSize): Integer;     overload; virtual;
452     function GetSize(const aWidth, aHeight: Integer): Integer; overload; virtual;
453
454     { constructor }
455     constructor Create;
456   public
457     { get the format descriptor by a given OpenGL internal format
458         @param aInternalFormat  OpenGL internal format to get format descriptor for
459         @returns                suitable format descriptor or tfEmpty-Descriptor }
460     class function GetByFormat(const aInternalFormat: GLenum): TglBitmapFormatDescriptor;
461   end;
462
463 ////////////////////////////////////////////////////////////////////////////////////////////////////
464   TglBitmapData = class;
465
466   { structure to store data for converting in }
467   TglBitmapFunctionRec = record
468     Sender:   TglBitmapData;          //< texture object that stores the data to convert
469     Size:     TglBitmapSize;          //< size of the texture
470     Position: TglBitmapPixelPosition; //< position of the currently pixel
471     Source:   TglBitmapPixelData;     //< pixel data of the current pixel
472     Dest:     TglBitmapPixelData;     //< new data of the pixel (must be filled in)
473     Args:     Pointer;                //< user defined args that was passed to the convert function
474   end;
475
476   { callback to use for converting texture data }
477   TglBitmapFunction = procedure(var FuncRec: TglBitmapFunctionRec);
478
479 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
480   { class to store texture data in. used to load, save and
481     manipulate data before assigned to texture object
482     all operations on a data object can be done from a background thread }
483   TglBitmapData = class
484   private { fields }
485
486     fData: PByte;               //< texture data
487     fDimension: TglBitmapSize;  //< pixel size of the data
488     fFormat: TglBitmapFormat;   //< format the texture data is stored in
489     fFilename: String;          //< file the data was load from
490
491     fScanlines:    array of PByte;  //< pointer to begin of each line
492     fHasScanlines: Boolean;         //< @true if scanlines are initialized, @false otherwise
493
494   private { getter / setter }
495
496     { @returns the format descriptor suitable to the texture data format }
497     function GetFormatDescriptor: TglBitmapFormatDescriptor;
498
499     { @returns the width of the texture data (in pixel) or -1 if no data is set }
500     function GetWidth: Integer;
501
502     { @returns the height of the texture data (in pixel) or -1 if no data is set }
503     function GetHeight: Integer;
504
505     { get scanline at index aIndex
506         @returns Pointer to start of line or @nil }
507     function GetScanlines(const aIndex: Integer): PByte;
508
509     { set new value for the data format. only possible if new format has the same pixel size.
510       if you want to convert the texture data, see ConvertTo function }
511     procedure SetFormat(const aValue: TglBitmapFormat);
512
513   private { internal misc }
514
515     { splits a resource identifier into the resource and it's type
516         @param aResource  resource identifier to split and store name in
517         @param aResType   type of the resource }
518     procedure PrepareResType(var aResource: String; var aResType: PChar);
519
520     { updates scanlines array }
521     procedure UpdateScanlines;
522
523   private { internal load and save }
524 {$IFDEF GLB_SUPPORT_PNG_READ}
525     { try to load a PNG from a stream
526         @param aStream  stream to load PNG from
527         @returns        @true on success, @false otherwise }
528     function  LoadPNG(const aStream: TStream): Boolean; virtual;
529 {$ENDIF}
530
531 {$ifdef GLB_SUPPORT_PNG_WRITE}
532     { save texture data as PNG to stream
533         @param aStream stream to save data to}
534     procedure SavePNG(const aStream: TStream); virtual;
535 {$ENDIF}
536
537 {$IFDEF GLB_SUPPORT_JPEG_READ}
538     { try to load a JPEG from a stream
539         @param aStream  stream to load JPEG from
540         @returns        @true on success, @false otherwise }
541     function  LoadJPEG(const aStream: TStream): Boolean; virtual;
542 {$ENDIF}
543
544 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
545     { save texture data as JPEG to stream
546         @param aStream stream to save data to}
547     procedure SaveJPEG(const aStream: TStream); virtual;
548 {$ENDIF}
549
550     { try to load a RAW image from a stream
551         @param aStream  stream to load RAW image from
552         @returns        @true on success, @false otherwise }
553     function LoadRAW(const aStream: TStream): Boolean;
554
555     { save texture data as RAW image to stream
556         @param aStream stream to save data to}
557     procedure SaveRAW(const aStream: TStream);
558
559     { try to load a BMP from a stream
560         @param aStream  stream to load BMP from
561         @returns        @true on success, @false otherwise }
562     function LoadBMP(const aStream: TStream): Boolean;
563
564     { save texture data as BMP to stream
565         @param aStream stream to save data to}
566     procedure SaveBMP(const aStream: TStream);
567
568     { try to load a TGA from a stream
569         @param aStream  stream to load TGA from
570         @returns        @true on success, @false otherwise }
571     function LoadTGA(const aStream: TStream): Boolean;
572
573     { save texture data as TGA to stream
574         @param aStream stream to save data to}
575     procedure SaveTGA(const aStream: TStream);
576
577     { try to load a DDS from a stream
578         @param aStream  stream to load DDS from
579         @returns        @true on success, @false otherwise }
580     function LoadDDS(const aStream: TStream): Boolean;
581
582     { save texture data as DDS to stream
583         @param aStream stream to save data to}
584     procedure SaveDDS(const aStream: TStream);
585
586   public { properties }
587     property Data:      PByte           read fData;                     //< texture data (be carefull with this!)
588     property Dimension: TglBitmapSize   read fDimension;                //< size of the texture data (in pixel)
589     property Filename:  String          read fFilename;                 //< file the data was loaded from
590     property Width:     Integer         read GetWidth;                  //< width of the texture data (in pixel)
591     property Height:    Integer         read GetHeight;                 //< height of the texture data (in pixel)
592     property Format:    TglBitmapFormat read fFormat write SetFormat;   //< format the texture data is stored in
593     property Scanlines[const aIndex: Integer]: PByte read GetScanlines; //< pointer to begin of line at given index or @nil
594
595     property FormatDescriptor: TglBitmapFormatDescriptor read GetFormatDescriptor; //< descriptor object that describes the format of the stored data
596
597   public { flip }
598
599     { flip texture horizontal
600         @returns @true in success, @false otherwise }
601     function FlipHorz: Boolean; virtual;
602
603     { flip texture vertical
604         @returns @true in success, @false otherwise }
605     function FlipVert: Boolean; virtual;
606
607   public { load }
608
609     { load a texture from a file
610         @param aFilename file to load texuture from }
611     procedure LoadFromFile(const aFilename: String);
612
613     { load a texture from a stream
614         @param aStream  stream to load texture from }
615     procedure LoadFromStream(const aStream: TStream); virtual;
616
617     { use a function to generate texture data
618         @param aSize    size of the texture
619         @param aFormat  format of the texture data
620         @param aFunc    callback to use for generation
621         @param aArgs    user defined paramaters (use at will) }
622     procedure LoadFromFunc(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer = nil);
623
624     { load a texture from a resource
625         @param aInstance  resource handle
626         @param aResource  resource indentifier
627         @param aResType   resource type (if known) }
628     procedure LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil);
629
630     { load a texture from a resource id
631         @param aInstance  resource handle
632         @param aResource  resource ID
633         @param aResType   resource type }
634     procedure LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
635
636   public { save }
637
638     { save texture data to a file
639         @param aFilename  filename to store texture in
640         @param aFileType  file type to store data into }
641     procedure SaveToFile(const aFilename: String; const aFileType: TglBitmapFileType);
642
643     { save texture data to a stream
644         @param aFilename  filename to store texture in
645         @param aFileType  file type to store data into }
646     procedure SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType); virtual;
647
648   public { convert }
649
650     { convert texture data using a user defined callback
651         @param aFunc        callback to use for converting
652         @param aCreateTemp  create a temporary buffer to use for converting
653         @param aArgs        user defined paramters (use at will)
654         @returns            @true if converting was successful, @false otherwise }
655     function Convert(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer = nil): Boolean; overload;
656
657     { convert texture data using a user defined callback
658         @param aSource      glBitmap to read data from
659         @param aFunc        callback to use for converting
660         @param aCreateTemp  create a temporary buffer to use for converting
661         @param aFormat      format of the new data
662         @param aArgs        user defined paramters (use at will)
663         @returns            @true if converting was successful, @false otherwise }
664     function Convert(const aSource: TglBitmapData; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
665       const aFormat: TglBitmapFormat; const aArgs: Pointer = nil): Boolean; overload;
666
667     { convert texture data using a specific format
668         @param aFormat  new format of texture data
669         @returns        @true if converting was successful, @false otherwise }
670     function ConvertTo(const aFormat: TglBitmapFormat): Boolean; virtual;
671
672 {$IFDEF GLB_SDL}
673   public { SDL }
674
675     { assign texture data to SDL surface
676         @param aSurface SDL surface to write data to
677         @returns        @true on success, @false otherwise }
678     function AssignToSurface(out aSurface: PSDL_Surface): Boolean;
679
680     { assign texture data from SDL surface
681         @param aSurface SDL surface to read data from
682         @returns        @true on success, @false otherwise }
683     function AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
684
685     { assign alpha channel data to SDL surface
686         @param aSurface SDL surface to write alpha channel data to
687         @returns        @true on success, @false otherwise }
688     function AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
689
690     { assign alpha channel data from SDL surface
691         @param aSurface SDL surface to read data from
692         @param aFunc    callback to use for converting
693         @param aArgs    user defined parameters (use at will)
694         @returns        @true on success, @false otherwise }
695     function AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
696 {$ENDIF}
697
698 {$IFDEF GLB_DELPHI}
699   public { Delphi }
700
701     { assign texture data to TBitmap object
702         @param aBitmap  TBitmap to write data to
703         @returns        @true on success, @false otherwise }
704     function AssignToBitmap(const aBitmap: TBitmap): Boolean;
705
706     { assign texture data from TBitmap object
707         @param aBitmap  TBitmap to read data from
708         @returns        @true on success, @false otherwise }
709     function AssignFromBitmap(const aBitmap: TBitmap): Boolean;
710
711     { assign alpha channel data to TBitmap object
712         @param aBitmap  TBitmap to write data to
713         @returns        @true on success, @false otherwise }
714     function AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
715
716     { assign alpha channel data from TBitmap object
717         @param aBitmap  TBitmap to read data from
718         @param aFunc    callback to use for converting
719         @param aArgs    user defined parameters (use at will)
720         @returns        @true on success, @false otherwise }
721     function AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
722 {$ENDIF}
723
724 {$IFDEF GLB_LAZARUS}
725   public { Lazarus }
726
727     { assign texture data to TLazIntfImage object
728         @param aImage   TLazIntfImage to write data to
729         @returns        @true on success, @false otherwise }
730     function AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
731
732     { assign texture data from TLazIntfImage object
733         @param aImage   TLazIntfImage to read data from
734         @returns        @true on success, @false otherwise }
735     function AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
736
737     { assign alpha channel data to TLazIntfImage object
738         @param aImage   TLazIntfImage to write data to
739         @returns        @true on success, @false otherwise }
740     function AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
741
742     { assign alpha channel data from TLazIntfImage object
743         @param aImage   TLazIntfImage to read data from
744         @param aFunc    callback to use for converting
745         @param aArgs    user defined parameters (use at will)
746         @returns        @true on success, @false otherwise }
747     function AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
748 {$ENDIF}
749
750   public { Alpha }
751     { load alpha channel data from resource
752         @param aInstance  resource handle
753         @param aResource  resource ID
754         @param aResType   resource type
755         @param aFunc      callback to use for converting
756         @param aArgs      user defined parameters (use at will)
757         @returns          @true on success, @false otherwise }
758     function AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
759
760     { load alpha channel data from resource ID
761         @param aInstance    resource handle
762         @param aResourceID  resource ID
763         @param aResType     resource type
764         @param aFunc        callback to use for converting
765         @param aArgs        user defined parameters (use at will)
766         @returns            @true on success, @false otherwise }
767     function AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
768
769     { add alpha channel data from function
770         @param aFunc  callback to get data from
771         @param aArgs  user defined parameters (use at will)
772         @returns      @true on success, @false otherwise }
773     function AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer = nil): Boolean; virtual;
774
775     { add alpha channel data from file (macro for: new glBitmap, LoadFromFile, AddAlphaFromGlBitmap)
776         @param aFilename  file to load alpha channel data from
777         @param aFunc      callback to use for converting
778         @param aArgs     SetFormat user defined parameters (use at will)
779         @returns          @true on success, @false otherwise }
780     function AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
781
782     { add alpha channel data from stream (macro for: new glBitmap, LoadFromStream, AddAlphaFromGlBitmap)
783         @param aStream  stream to load alpha channel data from
784         @param aFunc    callback to use for converting
785         @param aArgs    user defined parameters (use at will)
786         @returns        @true on success, @false otherwise }
787     function AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
788
789     { add alpha channel data from existing glBitmap object
790         @param aBitmap  TglBitmap to copy alpha channel data from
791         @param aFunc    callback to use for converting
792         @param aArgs    user defined parameters (use at will)
793         @returns        @true on success, @false otherwise }
794     function AddAlphaFromDataObj(const aDataObj: TglBitmapData; aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
795
796     { add alpha to pixel if the pixels color is greter than the given color value
797         @param aRed         red threshold (0-255)
798         @param aGreen       green threshold (0-255)
799         @param aBlue        blue threshold (0-255)
800         @param aDeviatation accepted deviatation (0-255)
801         @returns            @true on success, @false otherwise }
802     function AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte = 0): Boolean;
803
804     { add alpha to pixel if the pixels color is greter than the given color value
805         @param aRed         red threshold (0-Range.r)
806         @param aGreen       green threshold (0-Range.g)
807         @param aBlue        blue threshold (0-Range.b)
808         @param aDeviatation accepted deviatation (0-max(Range.rgb))
809         @returns            @true on success, @false otherwise }
810     function AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal = 0): Boolean;
811
812     { add alpha to pixel if the pixels color is greter than the given color value
813         @param aRed         red threshold (0.0-1.0)
814         @param aGreen       green threshold (0.0-1.0)
815         @param aBlue        blue threshold (0.0-1.0)
816         @param aDeviatation accepted deviatation (0.0-1.0)
817         @returns            @true on success, @false otherwise }
818     function AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single = 0): Boolean;
819
820     { add a constand alpha value to all pixels
821         @param aAlpha alpha value to add (0-255)
822         @returns      @true on success, @false otherwise }
823     function AddAlphaFromValue(const aAlpha: Byte): Boolean;
824
825     { add a constand alpha value to all pixels
826         @param aAlpha alpha value to add (0-max(Range.rgb))
827         @returns      @true on success, @false otherwise }
828     function AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
829
830     { add a constand alpha value to all pixels
831         @param aAlpha alpha value to add (0.0-1.0)
832         @returns      @true on success, @false otherwise }
833     function AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
834
835     { remove alpha channel
836         @returns  @true on success, @false otherwise }
837     function RemoveAlpha: Boolean; virtual;
838
839   public { fill }
840     { fill complete texture with one color
841         @param aRed   red color for border (0-255)
842         @param aGreen green color for border (0-255)
843         @param aBlue  blue color for border (0-255)
844         @param aAlpha alpha color for border (0-255) }
845     procedure FillWithColor(const aRed, aGreen, aBlue: Byte; const aAlpha: Byte = 255);
846
847     { fill complete texture with one color
848         @param aRed   red color for border (0-Range.r)
849         @param aGreen green color for border (0-Range.g)
850         @param aBlue  blue color for border (0-Range.b)
851         @param aAlpha alpha color for border (0-Range.a) }
852     procedure FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal = $FFFFFFFF);
853
854     { fill complete texture with one color
855         @param aRed   red color for border (0.0-1.0)
856         @param aGreen green color for border (0.0-1.0)
857         @param aBlue  blue color for border (0.0-1.0)
858         @param aAlpha alpha color for border (0.0-1.0) }
859     procedure FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single = 1.0);
860
861   public { Misc }
862
863     { set data pointer of texture data
864         @param aData    pointer to new texture data
865         @param aFormat  format of the data stored at aData
866         @param aWidth   width of the texture data
867         @param aHeight  height of the texture data }
868     procedure SetData(const aData: PByte; const aFormat: TglBitmapFormat;
869       const aWidth: Integer = -1; const aHeight: Integer = -1); virtual;
870
871       { create a clone of the current object
872         @returns clone of this object}
873     function Clone: TglBitmapData;
874
875     { invert color data (bitwise not)
876         @param aRed     invert red channel
877         @param aGreen   invert green channel
878         @param aBlue    invert blue channel
879         @param aAlpha   invert alpha channel }
880     procedure Invert(const aRed, aGreen, aBlue, aAlpha: Boolean);
881
882     { create normal map from texture data
883         @param aFunc      normal map function to generate normalmap with
884         @param aScale     scale of the normale stored in the normal map
885         @param aUseAlpha  generate normalmap from alpha channel data (if present) }
886     procedure GenerateNormalMap(const aFunc: TglBitmapNormalMapFunc = nm3x3;
887       const aScale: Single = 2; const aUseAlpha: Boolean = false);
888
889   public { constructor }
890
891     { constructor - creates a texutre data object }
892     constructor Create; overload;
893
894     { constructor - creates a texture data object and loads it from a file
895         @param aFilename file to load texture from }
896     constructor Create(const aFileName: String); overload;
897
898     { constructor - creates a texture data object and loads it from a stream
899         @param aStream stream to load texture from }
900     constructor Create(const aStream: TStream); overload;
901
902     { constructor - creates a texture data object with the given size, format and data
903         @param aSize    size of the texture
904         @param aFormat  format of the given data
905         @param aData    texture data - be carefull: the data will now be managed by the texture data object }
906     constructor Create(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat; aData: PByte = nil); overload;
907
908     { constructor - creates a texture data object with the given size and format and uses the given callback to create the data
909         @param aSize    size of the texture
910         @param aFormat  format of the given data
911         @param aFunc    callback to use for generating the data
912         @param aArgs    user defined parameters (use at will) }
913     constructor Create(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer = nil); overload;
914
915     { constructor - creates a texture data object and loads it from a resource
916         @param aInstance  resource handle
917         @param aResource  resource indentifier
918         @param aResType   resource type (if known) }
919     constructor Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil); overload;
920
921     { constructor - creates a texture data object and loads it from a resource
922         @param aInstance    resource handle
923         @param aResourceID  resource ID
924         @param aResType     resource type (if known) }
925     constructor Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar); overload;
926
927     { destructor }
928     destructor Destroy; override;
929
930   end;
931
932 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
933   { base class for all glBitmap classes. used to manage OpenGL texture objects
934     all operations on a bitmap object must be done from the render thread }
935   TglBitmap = class
936   protected
937     fID: GLuint;                          //< name of the OpenGL texture object
938     fTarget: GLuint;                      //< texture target (e.g. GL_TEXTURE_2D)
939     fDeleteTextureOnFree: Boolean;        //< delete OpenGL texture object when this object is destroyed
940
941     // texture properties
942     fFilterMin: GLenum;                   //< min filter to apply to the texture
943     fFilterMag: GLenum;                   //< mag filter to apply to the texture
944     fWrapS: GLenum;                       //< texture wrapping for x axis
945     fWrapT: GLenum;                       //< texture wrapping for y axis
946     fWrapR: GLenum;                       //< texture wrapping for z axis
947     fAnisotropic: Integer;                //< anisotropic level
948     fBorderColor: array[0..3] of Single;  //< color of the texture border
949
950 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
951     //Swizzle
952     fSwizzle: array[0..3] of GLenum;      //< color channel swizzle
953 {$IFEND}
954 {$IFNDEF OPENGL_ES}
955     fIsResident: GLboolean;               //< @true if OpenGL texture object has data, @false otherwise
956 {$ENDIF}
957
958     fDimension: TglBitmapSize;            //< size of this texture
959     fMipMap: TglBitmapMipMap;             //< mipmap type
960
961     // CustomData
962     fCustomData: Pointer;                 //< user defined data
963     fCustomName: String;                  //< user defined name
964     fCustomNameW: WideString;             //< user defined name
965   protected
966     { @returns the actual width of the texture }
967     function GetWidth:  Integer; virtual;
968
969     { @returns the actual height of the texture }
970     function GetHeight: Integer; virtual;
971
972   protected
973     { set a new value for fCustomData }
974     procedure SetCustomData(const aValue: Pointer);
975
976     { set a new value for fCustomName }
977     procedure SetCustomName(const aValue: String);
978
979     { set a new value for fCustomNameW }
980     procedure SetCustomNameW(const aValue: WideString);
981
982     { set new value for fDeleteTextureOnFree }
983     procedure SetDeleteTextureOnFree(const aValue: Boolean);
984
985     { set name of OpenGL texture object }
986     procedure SetID(const aValue: Cardinal);
987
988     { set new value for fMipMap }
989     procedure SetMipMap(const aValue: TglBitmapMipMap);
990
991     { set new value for target }
992     procedure SetTarget(const aValue: Cardinal);
993
994     { set new value for fAnisotrophic }
995     procedure SetAnisotropic(const aValue: Integer);
996
997   protected
998     { create OpenGL texture object (delete exisiting object if exists) }
999     procedure CreateID;
1000
1001     { setup texture parameters }
1002     procedure SetupParameters({$IFNDEF OPENGL_ES}out aBuildWithGlu: Boolean{$ENDIF});
1003
1004   protected
1005     property Width:  Integer read GetWidth;   //< the actual width of the texture
1006     property Height: Integer read GetHeight;  //< the actual height of the texture
1007
1008   public
1009     property ID:                  Cardinal  read fID                  write SetID;                  //< name of the OpenGL texture object
1010     property Target:              Cardinal  read fTarget              write SetTarget;              //< texture target (e.g. GL_TEXTURE_2D)
1011     property DeleteTextureOnFree: Boolean   read fDeleteTextureOnFree write SetDeleteTextureOnFree; //< delete texture object when this object is destroyed
1012
1013     property MipMap:       TglBitmapMipMap read fMipMap      write SetMipMap;       //< mipmap type
1014     property Anisotropic:  Integer         read fAnisotropic write SetAnisotropic;  //< anisotropic level
1015
1016     property CustomData:  Pointer    read fCustomData  write SetCustomData;   //< user defined data (use at will)
1017     property CustomName:  String     read fCustomName  write SetCustomName;   //< user defined name (use at will)
1018     property CustomNameW: WideString read fCustomNameW write SetCustomNameW;  //< user defined name (as WideString; use at will)
1019
1020     property Dimension:  TglBitmapSize read fDimension;     //< size of the texture
1021 {$IFNDEF OPENGL_ES}
1022     property IsResident: GLboolean read fIsResident;        //< @true if OpenGL texture object has data, @false otherwise
1023 {$ENDIF}
1024
1025     { this method is called after the constructor and sets the default values of this object }
1026     procedure AfterConstruction; override;
1027
1028     { this method is called before the destructor and does some cleanup }
1029     procedure BeforeDestruction; override;
1030
1031   public
1032 {$IFNDEF OPENGL_ES}
1033     { set the new value for texture border color
1034         @param aRed   red color for border (0.0-1.0)
1035         @param aGreen green color for border (0.0-1.0)
1036         @param aBlue  blue color for border (0.0-1.0)
1037         @param aAlpha alpha color for border (0.0-1.0) }
1038     procedure SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
1039 {$ENDIF}
1040
1041   public
1042     { set new texture filer
1043         @param aMin   min filter
1044         @param aMag   mag filter }
1045     procedure SetFilter(const aMin, aMag: GLenum);
1046
1047     { set new texture wrapping
1048         @param S  texture wrapping for x axis
1049         @param T  texture wrapping for y axis
1050         @param R  texture wrapping for z axis }
1051     procedure SetWrap(
1052       const S: GLenum = GL_CLAMP_TO_EDGE;
1053       const T: GLenum = GL_CLAMP_TO_EDGE;
1054       const R: GLenum = GL_CLAMP_TO_EDGE);
1055
1056 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
1057     { set new swizzle
1058         @param r  swizzle for red channel
1059         @param g  swizzle for green channel
1060         @param b  swizzle for blue channel
1061         @param a  swizzle for alpha channel }
1062     procedure SetSwizzle(const r, g, b, a: GLenum);
1063 {$IFEND}
1064
1065   public
1066     { bind texture
1067         @param aEnableTextureUnit   enable texture unit for this texture (e.g. glEnable(GL_TEXTURE_2D)) }
1068     procedure Bind(const aEnableTextureUnit: Boolean = true); virtual;
1069
1070     { bind texture
1071         @param aDisableTextureUnit  disable texture unit for this texture (e.g. glEnable(GL_TEXTURE_2D)) }
1072     procedure Unbind(const aDisableTextureUnit: Boolean = true); virtual;
1073
1074     { upload texture data from given data object to video card
1075         @param aData        texture data object that contains the actual data
1076         @param aCheckSize   check size before upload and throw exception if something is wrong }
1077     procedure UploadData(const aDataObj: TglBitmapData; const aCheckSize: Boolean = true); virtual;
1078
1079 {$IFNDEF OPENGL_ES}
1080     { download texture data from video card and store it into given data object
1081         @returns @true when download was successfull, @false otherwise }
1082     function DownloadData(const aDataObj: TglBitmapData): Boolean; virtual;
1083 {$ENDIF}
1084   public
1085     { constructor - creates an empty texture }
1086     constructor Create; overload;
1087
1088     { constructor - creates an texture object and uploads the given data }
1089     constructor Create(const aData: TglBitmapData); overload;
1090
1091   end;
1092
1093 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1094 {$IF NOT DEFINED(OPENGL_ES)}
1095   { wrapper class for 1-dimensional textures (OpenGL target = GL_TEXTURE_1D
1096     all operations on a bitmap object must be done from the render thread }
1097   TglBitmap1D = class(TglBitmap)
1098   protected
1099
1100     { upload the texture data to video card
1101         @param aDataObj       texture data object that contains the actual data
1102         @param aBuildWithGlu  use glu functions to build mipmaps }
1103     procedure UploadDataIntern(const aDataObj: TglBitmapData; const aBuildWithGlu: Boolean);
1104
1105   public
1106     property Width; //< actual with of the texture
1107
1108     { this method is called after constructor and initializes the object }
1109     procedure AfterConstruction; override;
1110
1111     { upload texture data from given data object to video card
1112         @param aData        texture data object that contains the actual data
1113         @param aCheckSize   check size before upload and throw exception if something is wrong }
1114     procedure UploadData(const aDataObj: TglBitmapData; const aCheckSize: Boolean = true); override;
1115
1116   end;
1117 {$IFEND}
1118
1119 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1120   { wrapper class for 2-dimensional textures (OpenGL target = GL_TEXTURE_2D)
1121     all operations on a bitmap object must be done from the render thread }
1122   TglBitmap2D = class(TglBitmap)
1123   protected
1124
1125     { upload the texture data to video card
1126         @param aDataObj       texture data object that contains the actual data
1127         @param aTarget        target o upload data to (e.g. GL_TEXTURE_2D)
1128         @param aBuildWithGlu  use glu functions to build mipmaps }
1129     procedure UploadDataIntern(const aDataObj: TglBitmapData; const aTarget: GLenum
1130       {$IFNDEF OPENGL_ES}; const aBuildWithGlu: Boolean{$ENDIF});
1131
1132   public
1133     property Width;   //< actual width of the texture
1134     property Height;  //< actual height of the texture
1135
1136     { this method is called after constructor and initializes the object }
1137     procedure AfterConstruction; override;
1138
1139     { upload texture data from given data object to video card
1140         @param aData        texture data object that contains the actual data
1141         @param aCheckSize   check size before upload and throw exception if something is wrong }
1142     procedure UploadData(const aDataObj: TglBitmapData; const aCheckSize: Boolean = true); override;
1143
1144   public
1145
1146     { copy a part of the frame buffer to the texture
1147         @param aTop     topmost pixel to copy
1148         @param aLeft    leftmost pixel to copy
1149         @param aRight   rightmost pixel to copy
1150         @param aBottom  bottommost pixel to copy
1151         @param aFormat  format to store data in
1152         @param aDataObj texture data object to store the data in }
1153     class procedure GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat; const aDataObj: TglBitmapData);
1154
1155   end;
1156
1157 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1158 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
1159   { wrapper class for cube maps (OpenGL target = GL_TEXTURE_CUBE_MAP)
1160     all operations on a bitmap object must be done from the render thread }
1161   TglBitmapCubeMap = class(TglBitmap2D)
1162   protected
1163   {$IFNDEF OPENGL_ES}
1164     fGenMode: Integer;  //< generation mode for the cube map (e.g. GL_REFLECTION_MAP)
1165   {$ENDIF}
1166
1167   public
1168     { this method is called after constructor and initializes the object }
1169     procedure AfterConstruction; override;
1170
1171     { upload texture data from given data object to video card
1172         @param aData        texture data object that contains the actual data
1173         @param aCheckSize   check size before upload and throw exception if something is wrong }
1174     procedure UploadData(const aDataObj: TglBitmapData; const aCheckSize: Boolean = true); override;
1175
1176     { upload texture data from given data object to video card
1177         @param aData        texture data object that contains the actual data
1178         @param aCubeTarget  cube map target to upload data to (e.g. GL_TEXTURE_CUBE_MAP_POSITIVE_X)
1179         @param aCheckSize   check size before upload and throw exception if something is wrong }
1180     procedure UploadCubeMap(const aDataObj: TglBitmapData; const aCubeTarget: Cardinal; const aCheckSize: Boolean);
1181
1182     { bind texture
1183         @param aEnableTexCoordsGen  enable cube map generator
1184         @param aEnableTextureUnit   enable texture unit }
1185     procedure Bind({$IFNDEF OPENGL_ES}const aEnableTexCoordsGen: Boolean = true;{$ENDIF} const aEnableTextureUnit: Boolean = true); reintroduce; virtual;
1186
1187     { unbind texture
1188         @param aDisableTexCoordsGen   disable cube map generator
1189         @param aDisableTextureUnit    disable texture unit }
1190     procedure Unbind({$IFNDEF OPENGL_ES}const aDisableTexCoordsGen: Boolean = true;{$ENDIF} const aDisableTextureUnit: Boolean = true); reintroduce; virtual;
1191   end;
1192 {$IFEND}
1193
1194 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
1195 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1196   { wrapper class for cube normal maps
1197     all operations on a bitmap object must be done from the render thread }
1198   TglBitmapNormalMap = class(TglBitmapCubeMap)
1199   public
1200     { this method is called after constructor and initializes the object }
1201     procedure AfterConstruction; override;
1202
1203     { create cube normal map from texture data and upload it to video card
1204         @param aSize        size of each cube map texture
1205         @param aCheckSize   check size before upload and throw exception if something is wrong }
1206     procedure GenerateNormalMap(const aSize: Integer = 32; const aCheckSize: Boolean = true);
1207   end;
1208 {$IFEND}
1209
1210 const
1211   NULL_SIZE: TglBitmapSize = (Fields: []; X: 0; Y: 0);
1212
1213 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
1214 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
1215 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
1216 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
1217 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
1218 procedure glBitmapSetDefaultWrap(
1219   const S: Cardinal = GL_CLAMP_TO_EDGE;
1220   const T: Cardinal = GL_CLAMP_TO_EDGE;
1221   const R: Cardinal = GL_CLAMP_TO_EDGE);
1222
1223 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
1224 procedure glBitmapSetDefaultSwizzle(const r: GLenum = GL_RED; g: GLenum = GL_GREEN; b: GLenum = GL_BLUE; a: GLenum = GL_ALPHA);
1225 {$IFEND}
1226
1227 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
1228 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
1229 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
1230 function glBitmapGetDefaultFormat: TglBitmapFormat;
1231 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
1232 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
1233 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
1234 procedure glBitmapGetDefaultSwizzle(var r, g, b, a: GLenum);
1235 {$IFEND}
1236
1237 function glBitmapSize(X: Integer = -1; Y: Integer = -1): TglBitmapSize;
1238 function glBitmapPosition(X: Integer = -1; Y: Integer = -1): TglBitmapPixelPosition;
1239 function glBitmapRec4ub(const r, g, b, a: Byte): TglBitmapRec4ub;
1240 function glBitmapRec4ui(const r, g, b, a: Cardinal): TglBitmapRec4ui;
1241 function glBitmapRec4ul(const r, g, b, a: QWord): TglBitmapRec4ul;
1242 function glBitmapRec4ubCompare(const r1, r2: TglBitmapRec4ub): Boolean;
1243 function glBitmapRec4uiCompare(const r1, r2: TglBitmapRec4ui): Boolean;
1244
1245 function glBitmapCreateTestData(const aFormat: TglBitmapFormat): TglBitmapData;
1246
1247 {$IFDEF GLB_DELPHI}
1248 function CreateGrayPalette: HPALETTE;
1249 {$ENDIF}
1250
1251 implementation
1252
1253 uses
1254   Math, syncobjs, typinfo
1255   {$IF DEFINED(GLB_SUPPORT_JPEG_READ) AND DEFINED(GLB_LAZ_JPEG)}, FPReadJPEG{$IFEND};
1256
1257
1258 var
1259   glBitmapDefaultDeleteTextureOnFree: Boolean;
1260   glBitmapDefaultFreeDataAfterGenTextures: Boolean;
1261   glBitmapDefaultFormat: TglBitmapFormat;
1262   glBitmapDefaultMipmap: TglBitmapMipMap;
1263   glBitmapDefaultFilterMin: Cardinal;
1264   glBitmapDefaultFilterMag: Cardinal;
1265   glBitmapDefaultWrapS: Cardinal;
1266   glBitmapDefaultWrapT: Cardinal;
1267   glBitmapDefaultWrapR: Cardinal;
1268   glDefaultSwizzle: array[0..3] of GLenum;
1269
1270 ////////////////////////////////////////////////////////////////////////////////////////////////////
1271 type
1272   TFormatDescriptor = class(TglBitmapFormatDescriptor)
1273   public
1274     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); virtual; abstract;
1275     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); virtual; abstract;
1276
1277     function CreateMappingData: Pointer; virtual;
1278     procedure FreeMappingData(var aMappingData: Pointer); virtual;
1279
1280     function IsEmpty: Boolean; virtual;
1281     function MaskMatch(const aMask: TglBitmapRec4ul): Boolean; virtual;
1282
1283     procedure PreparePixel(out aPixel: TglBitmapPixelData); virtual;
1284
1285     constructor Create; virtual;
1286   public
1287     class procedure Init;
1288     class function Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
1289     class function GetAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
1290     class function GetFromMask(const aMask: TglBitmapRec4ul; const aBitCount: Integer = 0): TFormatDescriptor;
1291     class function GetFromPrecShift(const aPrec, aShift: TglBitmapRec4ub; const aBitCount: Integer): TFormatDescriptor;
1292     class procedure Clear;
1293     class procedure Finalize;
1294   end;
1295   TFormatDescriptorClass = class of TFormatDescriptor;
1296
1297   TfdEmpty = class(TFormatDescriptor);
1298
1299 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1300   TfdAlphaUB1 = class(TFormatDescriptor) //1* unsigned byte
1301     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1302     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1303   end;
1304
1305   TfdLuminanceUB1 = class(TFormatDescriptor) //1* unsigned byte
1306     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1307     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1308   end;
1309
1310   TfdUniversalUB1 = class(TFormatDescriptor) //1* unsigned byte
1311     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1312     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1313   end;
1314
1315   TfdLuminanceAlphaUB2 = class(TfdLuminanceUB1) //2* unsigned byte
1316     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1317     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1318   end;
1319
1320   TfdRGBub3 = class(TFormatDescriptor) //3* unsigned byte
1321     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1322     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1323   end;
1324
1325   TfdBGRub3 = class(TFormatDescriptor) //3* unsigned byte (inverse)
1326     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1327     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1328   end;
1329
1330   TfdRGBAub4 = class(TfdRGBub3) //3* unsigned byte
1331     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1332     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1333   end;
1334
1335   TfdBGRAub4 = class(TfdBGRub3) //3* unsigned byte (inverse)
1336     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1337     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1338   end;
1339
1340 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1341   TfdAlphaUS1 = class(TFormatDescriptor) //1* unsigned short
1342     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1343     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1344   end;
1345
1346   TfdLuminanceUS1 = class(TFormatDescriptor) //1* unsigned short
1347     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1348     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1349   end;
1350
1351   TfdUniversalUS1 = class(TFormatDescriptor) //1* unsigned short
1352     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1353     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1354   end;
1355
1356   TfdDepthUS1 = class(TFormatDescriptor) //1* unsigned short
1357     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1358     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1359   end;
1360
1361   TfdLuminanceAlphaUS2 = class(TfdLuminanceUS1) //2* unsigned short
1362     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1363     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1364   end;
1365
1366   TfdRGBus3 = class(TFormatDescriptor) //3* unsigned short
1367     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1368     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1369   end;
1370
1371   TfdBGRus3 = class(TFormatDescriptor) //3* unsigned short (inverse)
1372     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1373     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1374   end;
1375
1376   TfdRGBAus4 = class(TfdRGBus3) //4* unsigned short
1377     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1378     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1379   end;
1380
1381   TfdARGBus4 = class(TfdRGBus3) //4* unsigned short
1382     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1383     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1384   end;
1385
1386   TfdBGRAus4 = class(TfdBGRus3) //4* unsigned short (inverse)
1387     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1388     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1389   end;
1390
1391   TfdABGRus4 = class(TfdBGRus3) //4* unsigned short (inverse)
1392     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1393     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1394   end;
1395
1396 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1397   TfdUniversalUI1 = class(TFormatDescriptor) //1* unsigned int
1398     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1399     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1400   end;
1401
1402   TfdDepthUI1 = class(TFormatDescriptor) //1* unsigned int
1403     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1404     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1405   end;
1406
1407 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1408   TfdAlpha4ub1 = class(TfdAlphaUB1)
1409     procedure SetValues; override;
1410   end;
1411
1412   TfdAlpha8ub1 = class(TfdAlphaUB1)
1413     procedure SetValues; override;
1414   end;
1415
1416   TfdAlpha16us1 = class(TfdAlphaUS1)
1417     procedure SetValues; override;
1418   end;
1419
1420   TfdLuminance4ub1 = class(TfdLuminanceUB1)
1421     procedure SetValues; override;
1422   end;
1423
1424   TfdLuminance8ub1 = class(TfdLuminanceUB1)
1425     procedure SetValues; override;
1426   end;
1427
1428   TfdLuminance16us1 = class(TfdLuminanceUS1)
1429     procedure SetValues; override;
1430   end;
1431
1432   TfdLuminance4Alpha4ub2 = class(TfdLuminanceAlphaUB2)
1433     procedure SetValues; override;
1434   end;
1435
1436   TfdLuminance6Alpha2ub2 = class(TfdLuminanceAlphaUB2)
1437     procedure SetValues; override;
1438   end;
1439
1440   TfdLuminance8Alpha8ub2 = class(TfdLuminanceAlphaUB2)
1441     procedure SetValues; override;
1442   end;
1443
1444   TfdLuminance12Alpha4us2 = class(TfdLuminanceAlphaUS2)
1445     procedure SetValues; override;
1446   end;
1447
1448   TfdLuminance16Alpha16us2 = class(TfdLuminanceAlphaUS2)
1449     procedure SetValues; override;
1450   end;
1451
1452 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1453   TfdR3G3B2ub1 = class(TfdUniversalUB1)
1454     procedure SetValues; override;
1455   end;
1456
1457   TfdRGBX4us1 = class(TfdUniversalUS1)
1458     procedure SetValues; override;
1459   end;
1460
1461   TfdXRGB4us1 = class(TfdUniversalUS1)
1462     procedure SetValues; override;
1463   end;
1464
1465   TfdR5G6B5us1 = class(TfdUniversalUS1)
1466     procedure SetValues; override;
1467   end;
1468
1469   TfdRGB5X1us1 = class(TfdUniversalUS1)
1470     procedure SetValues; override;
1471   end;
1472
1473   TfdX1RGB5us1 = class(TfdUniversalUS1)
1474     procedure SetValues; override;
1475   end;
1476
1477   TfdRGB8ub3 = class(TfdRGBub3)
1478     procedure SetValues; override;
1479   end;
1480
1481   TfdRGBX8ui1 = class(TfdUniversalUI1)
1482     procedure SetValues; override;
1483   end;
1484
1485   TfdXRGB8ui1 = class(TfdUniversalUI1)
1486     procedure SetValues; override;
1487   end;
1488
1489   TfdRGB10X2ui1 = class(TfdUniversalUI1)
1490     procedure SetValues; override;
1491   end;
1492
1493   TfdX2RGB10ui1 = class(TfdUniversalUI1)
1494     procedure SetValues; override;
1495   end;
1496
1497   TfdRGB16us3 = class(TfdRGBus3)
1498     procedure SetValues; override;
1499   end;
1500
1501   TfdRGBA4us1 = class(TfdUniversalUS1)
1502     procedure SetValues; override;
1503   end;
1504
1505   TfdARGB4us1 = class(TfdUniversalUS1)
1506     procedure SetValues; override;
1507   end;
1508
1509   TfdRGB5A1us1 = class(TfdUniversalUS1)
1510     procedure SetValues; override;
1511   end;
1512
1513   TfdA1RGB5us1 = class(TfdUniversalUS1)
1514     procedure SetValues; override;
1515   end;
1516
1517   TfdRGBA8ui1 = class(TfdUniversalUI1)
1518     procedure SetValues; override;
1519   end;
1520
1521   TfdARGB8ui1 = class(TfdUniversalUI1)
1522     procedure SetValues; override;
1523   end;
1524
1525   TfdRGBA8ub4 = class(TfdRGBAub4)
1526     procedure SetValues; override;
1527   end;
1528
1529   TfdRGB10A2ui1 = class(TfdUniversalUI1)
1530     procedure SetValues; override;
1531   end;
1532
1533   TfdA2RGB10ui1 = class(TfdUniversalUI1)
1534     procedure SetValues; override;
1535   end;
1536
1537   TfdRGBA16us4 = class(TfdRGBAus4)
1538     procedure SetValues; override;
1539   end;
1540
1541 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1542   TfdBGRX4us1 = class(TfdUniversalUS1)
1543     procedure SetValues; override;
1544   end;
1545
1546   TfdXBGR4us1 = class(TfdUniversalUS1)
1547     procedure SetValues; override;
1548   end;
1549
1550   TfdB5G6R5us1 = class(TfdUniversalUS1)
1551     procedure SetValues; override;
1552   end;
1553
1554   TfdBGR5X1us1 = class(TfdUniversalUS1)
1555     procedure SetValues; override;
1556   end;
1557
1558   TfdX1BGR5us1 = class(TfdUniversalUS1)
1559     procedure SetValues; override;
1560   end;
1561
1562   TfdBGR8ub3 = class(TfdBGRub3)
1563     procedure SetValues; override;
1564   end;
1565
1566   TfdBGRX8ui1 = class(TfdUniversalUI1)
1567     procedure SetValues; override;
1568   end;
1569
1570   TfdXBGR8ui1 = class(TfdUniversalUI1)
1571     procedure SetValues; override;
1572   end;
1573
1574   TfdBGR10X2ui1 = class(TfdUniversalUI1)
1575     procedure SetValues; override;
1576   end;
1577
1578   TfdX2BGR10ui1 = class(TfdUniversalUI1)
1579     procedure SetValues; override;
1580   end;
1581
1582   TfdBGR16us3 = class(TfdBGRus3)
1583     procedure SetValues; override;
1584   end;
1585
1586   TfdBGRA4us1 = class(TfdUniversalUS1)
1587     procedure SetValues; override;
1588   end;
1589
1590   TfdABGR4us1 = class(TfdUniversalUS1)
1591     procedure SetValues; override;
1592   end;
1593
1594   TfdBGR5A1us1 = class(TfdUniversalUS1)
1595     procedure SetValues; override;
1596   end;
1597
1598   TfdA1BGR5us1 = class(TfdUniversalUS1)
1599     procedure SetValues; override;
1600   end;
1601
1602   TfdBGRA8ui1 = class(TfdUniversalUI1)
1603     procedure SetValues; override;
1604   end;
1605
1606   TfdABGR8ui1 = class(TfdUniversalUI1)
1607     procedure SetValues; override;
1608   end;
1609
1610   TfdBGRA8ub4 = class(TfdBGRAub4)
1611     procedure SetValues; override;
1612   end;
1613
1614   TfdBGR10A2ui1 = class(TfdUniversalUI1)
1615     procedure SetValues; override;
1616   end;
1617
1618   TfdA2BGR10ui1 = class(TfdUniversalUI1)
1619     procedure SetValues; override;
1620   end;
1621
1622   TfdBGRA16us4 = class(TfdBGRAus4)
1623     procedure SetValues; override;
1624   end;
1625
1626   TfdDepth16us1 = class(TfdDepthUS1)
1627     procedure SetValues; override;
1628   end;
1629
1630   TfdDepth24ui1 = class(TfdDepthUI1)
1631     procedure SetValues; override;
1632   end;
1633
1634   TfdDepth32ui1 = class(TfdDepthUI1)
1635     procedure SetValues; override;
1636   end;
1637
1638   TfdS3tcDtx1RGBA = class(TFormatDescriptor)
1639     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1640     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1641     procedure SetValues; override;
1642   end;
1643
1644   TfdS3tcDtx3RGBA = class(TFormatDescriptor)
1645     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1646     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1647     procedure SetValues; override;
1648   end;
1649
1650   TfdS3tcDtx5RGBA = class(TFormatDescriptor)
1651     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1652     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1653     procedure SetValues; override;
1654   end;
1655
1656 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1657   TbmpBitfieldFormat = class(TFormatDescriptor)
1658   public
1659     procedure SetCustomValues(const aBPP: Integer; aMask: TglBitmapRec4ul); overload;
1660     procedure SetCustomValues(const aBBP: Integer; const aPrec, aShift: TglBitmapRec4ub); overload;
1661     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1662     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1663   end;
1664
1665 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1666   TbmpColorTableEnty = packed record
1667     b, g, r, a: Byte;
1668   end;
1669   TbmpColorTable = array of TbmpColorTableEnty;
1670   TbmpColorTableFormat = class(TFormatDescriptor)
1671   private
1672     fColorTable: TbmpColorTable;
1673   protected
1674     procedure SetValues; override;
1675   public
1676     property ColorTable:   TbmpColorTable  read fColorTable   write fColorTable;
1677
1678     procedure SetCustomValues(const aFormat: TglBitmapFormat; const aBPP: Integer; const aPrec, aShift: TglBitmapRec4ub); overload;
1679     procedure CalcValues;
1680     procedure CreateColorTable;
1681
1682     function CreateMappingData: Pointer; override;
1683     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1684     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1685     destructor Destroy; override;
1686   end;
1687
1688 const
1689   LUMINANCE_WEIGHT_R = 0.30;
1690   LUMINANCE_WEIGHT_G = 0.59;
1691   LUMINANCE_WEIGHT_B = 0.11;
1692
1693   ALPHA_WEIGHT_R = 0.30;
1694   ALPHA_WEIGHT_G = 0.59;
1695   ALPHA_WEIGHT_B = 0.11;
1696
1697   DEPTH_WEIGHT_R = 0.333333333;
1698   DEPTH_WEIGHT_G = 0.333333333;
1699   DEPTH_WEIGHT_B = 0.333333333;
1700
1701   FORMAT_DESCRIPTOR_CLASSES: array[TglBitmapFormat] of TFormatDescriptorClass = (
1702     TfdEmpty,
1703
1704     TfdAlpha4ub1,
1705     TfdAlpha8ub1,
1706     TfdAlpha16us1,
1707
1708     TfdLuminance4ub1,
1709     TfdLuminance8ub1,
1710     TfdLuminance16us1,
1711
1712     TfdLuminance4Alpha4ub2,
1713     TfdLuminance6Alpha2ub2,
1714     TfdLuminance8Alpha8ub2,
1715     TfdLuminance12Alpha4us2,
1716     TfdLuminance16Alpha16us2,
1717
1718     TfdR3G3B2ub1,
1719     TfdRGBX4us1,
1720     TfdXRGB4us1,
1721     TfdR5G6B5us1,
1722     TfdRGB5X1us1,
1723     TfdX1RGB5us1,
1724     TfdRGB8ub3,
1725     TfdRGBX8ui1,
1726     TfdXRGB8ui1,
1727     TfdRGB10X2ui1,
1728     TfdX2RGB10ui1,
1729     TfdRGB16us3,
1730
1731     TfdRGBA4us1,
1732     TfdARGB4us1,
1733     TfdRGB5A1us1,
1734     TfdA1RGB5us1,
1735     TfdRGBA8ui1,
1736     TfdARGB8ui1,
1737     TfdRGBA8ub4,
1738     TfdRGB10A2ui1,
1739     TfdA2RGB10ui1,
1740     TfdRGBA16us4,
1741
1742     TfdBGRX4us1,
1743     TfdXBGR4us1,
1744     TfdB5G6R5us1,
1745     TfdBGR5X1us1,
1746     TfdX1BGR5us1,
1747     TfdBGR8ub3,
1748     TfdBGRX8ui1,
1749     TfdXBGR8ui1,
1750     TfdBGR10X2ui1,
1751     TfdX2BGR10ui1,
1752     TfdBGR16us3,
1753
1754     TfdBGRA4us1,
1755     TfdABGR4us1,
1756     TfdBGR5A1us1,
1757     TfdA1BGR5us1,
1758     TfdBGRA8ui1,
1759     TfdABGR8ui1,
1760     TfdBGRA8ub4,
1761     TfdBGR10A2ui1,
1762     TfdA2BGR10ui1,
1763     TfdBGRA16us4,
1764
1765     TfdDepth16us1,
1766     TfdDepth24ui1,
1767     TfdDepth32ui1,
1768
1769     TfdS3tcDtx1RGBA,
1770     TfdS3tcDtx3RGBA,
1771     TfdS3tcDtx5RGBA
1772   );
1773
1774 var
1775   FormatDescriptorCS: TCriticalSection;
1776   FormatDescriptors: array[TglBitmapFormat] of TFormatDescriptor;
1777
1778 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1779 constructor EglBitmapUnsupportedFormat.Create(const aFormat: TglBitmapFormat);
1780 begin
1781   inherited Create('unsupported format: ' + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
1782 end;
1783
1784 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1785 constructor EglBitmapUnsupportedFormat.Create(const aMsg: String; const aFormat: TglBitmapFormat);
1786 begin
1787   inherited Create(aMsg + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
1788 end;
1789
1790 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1791 function glBitmapSize(X: Integer; Y: Integer): TglBitmapSize;
1792 begin
1793   result.Fields := [];
1794   if (X >= 0) then
1795     result.Fields := result.Fields + [ffX];
1796   if (Y >= 0) then
1797     result.Fields := result.Fields + [ffY];
1798   result.X := Max(0, X);
1799   result.Y := Max(0, Y);
1800 end;
1801
1802 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1803 function glBitmapPosition(X: Integer; Y: Integer): TglBitmapPixelPosition;
1804 begin
1805   result := glBitmapSize(X, Y);
1806 end;
1807
1808 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1809 function glBitmapRec4ub(const r, g, b, a: Byte): TglBitmapRec4ub;
1810 begin
1811   result.r := r;
1812   result.g := g;
1813   result.b := b;
1814   result.a := a;
1815 end;
1816
1817 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1818 function glBitmapRec4ui(const r, g, b, a: Cardinal): TglBitmapRec4ui;
1819 begin
1820   result.r := r;
1821   result.g := g;
1822   result.b := b;
1823   result.a := a;
1824 end;
1825
1826 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1827 function glBitmapRec4ul(const r, g, b, a: QWord): TglBitmapRec4ul;
1828 begin
1829   result.r := r;
1830   result.g := g;
1831   result.b := b;
1832   result.a := a;
1833 end;
1834
1835 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1836 function glBitmapRec4ubCompare(const r1, r2: TglBitmapRec4ub): Boolean;
1837 var
1838   i: Integer;
1839 begin
1840   result := false;
1841   for i := 0 to high(r1.arr) do
1842     if (r1.arr[i] <> r2.arr[i]) then
1843       exit;
1844   result := true;
1845 end;
1846
1847 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1848 function glBitmapRec4uiCompare(const r1, r2: TglBitmapRec4ui): Boolean;
1849 var
1850   i: Integer;
1851 begin
1852   result := false;
1853   for i := 0 to high(r1.arr) do
1854     if (r1.arr[i] <> r2.arr[i]) then
1855       exit;
1856   result := true;
1857 end;
1858
1859 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1860 function glBitmapCreateTestData(const aFormat: TglBitmapFormat): TglBitmapData;
1861 var
1862   desc: TFormatDescriptor;
1863   p, tmp: PByte;
1864   x, y, i: Integer;
1865   md: Pointer;
1866   px: TglBitmapPixelData;
1867 begin
1868   result := nil;
1869   desc := TFormatDescriptor.Get(aFormat);
1870   if (desc.IsCompressed) or (desc.glFormat = 0) then
1871     exit;
1872
1873   p := GetMemory(ceil(25 * desc.BytesPerPixel)); // 5 x 5 pixel
1874   md := desc.CreateMappingData;
1875   try
1876     tmp := p;
1877     desc.PreparePixel(px);
1878     for y := 0 to 4 do
1879       for x := 0 to 4 do begin
1880         px.Data := glBitmapRec4ui(0, 0, 0, 0);
1881         for i := 0 to 3 do begin
1882           if ((y < 3) and (y = i)) or
1883              ((y = 3) and (i < 3)) or
1884              ((y = 4) and (i = 3))
1885           then
1886             px.Data.arr[i] := Trunc(px.Range.arr[i] / 4 * x)
1887           else if ((y < 4) and (i = 3)) or
1888                   ((y = 4) and (i < 3))
1889           then
1890             px.Data.arr[i] := px.Range.arr[i]
1891           else
1892             px.Data.arr[i] := 0; //px.Range.arr[i];
1893         end;
1894         desc.Map(px, tmp, md);
1895       end;
1896   finally
1897     desc.FreeMappingData(md);
1898   end;
1899
1900   result := TglBitmapData.Create(glBitmapPosition(5, 5), aFormat, p);
1901 end;
1902
1903 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1904 function glBitmapShiftRec(const r, g, b, a: Byte): TglBitmapRec4ub;
1905 begin
1906   result.r := r;
1907   result.g := g;
1908   result.b := b;
1909   result.a := a;
1910 end;
1911
1912 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1913 function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes;
1914 begin
1915   result := [];
1916
1917   if (aFormat in [
1918         //8bpp
1919         tfAlpha4ub1, tfAlpha8ub1,
1920         tfLuminance4ub1, tfLuminance8ub1, tfR3G3B2ub1,
1921
1922         //16bpp
1923         tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
1924         tfRGBX4us1, tfXRGB4us1, tfRGB5X1us1, tfX1RGB5us1, tfR5G6B5us1, tfRGB5A1us1, tfA1RGB5us1, tfRGBA4us1, tfARGB4us1,
1925         tfBGRX4us1, tfXBGR4us1, tfBGR5X1us1, tfX1BGR5us1, tfB5G6R5us1, tfBGR5A1us1, tfA1BGR5us1, tfBGRA4us1, tfABGR4us1,
1926
1927         //24bpp
1928         tfBGR8ub3, tfRGB8ub3,
1929
1930         //32bpp
1931         tfRGBX8ui1, tfXRGB8ui1, tfRGB10X2ui1, tfX2RGB10ui1, tfRGBA8ui1, tfARGB8ui1, tfRGBA8ub4, tfRGB10A2ui1, tfA2RGB10ui1,
1932         tfBGRX8ui1, tfXBGR8ui1, tfBGR10X2ui1, tfX2BGR10ui1, tfBGRA8ui1, tfABGR8ui1, tfBGRA8ub4, tfBGR10A2ui1, tfA2BGR10ui1])
1933   then
1934     result := result + [ ftBMP ];
1935
1936   if (aFormat in [
1937         //8bbp
1938         tfAlpha4ub1, tfAlpha8ub1, tfLuminance4ub1, tfLuminance8ub1,
1939
1940         //16bbp
1941         tfAlpha16us1, tfLuminance16us1,
1942         tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
1943         tfX1RGB5us1, tfARGB4us1, tfA1RGB5us1, tfDepth16us1,
1944
1945         //24bbp
1946         tfBGR8ub3,
1947
1948         //32bbp
1949         tfX2RGB10ui1, tfARGB8ui1, tfBGRA8ub4, tfA2RGB10ui1,
1950         tfDepth24ui1, tfDepth32ui1])
1951   then
1952     result := result + [ftTGA];
1953
1954   if not (aFormat in [tfEmpty, tfRGB16us3, tfBGR16us3]) then
1955     result := result + [ftDDS];
1956
1957 {$IFDEF GLB_SUPPORT_PNG_WRITE}
1958   if aFormat in [
1959       tfAlpha8ub1, tfLuminance8ub1, tfLuminance8Alpha8ub2,
1960       tfRGB8ub3, tfRGBA8ui1,
1961       tfBGR8ub3, tfBGRA8ui1] then
1962     result := result + [ftPNG];
1963 {$ENDIF}
1964
1965 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
1966   if aFormat in [tfAlpha8ub1, tfLuminance8ub1, tfRGB8ub3, tfBGR8ub3] then
1967     result := result + [ftJPEG];
1968 {$ENDIF}
1969 end;
1970
1971 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1972 function IsPowerOfTwo(aNumber: Integer): Boolean;
1973 begin
1974   while (aNumber and 1) = 0 do
1975     aNumber := aNumber shr 1;
1976   result := aNumber = 1;
1977 end;
1978
1979 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1980 function GetTopMostBit(aBitSet: QWord): Integer;
1981 begin
1982   result := 0;
1983   while aBitSet > 0 do begin
1984     inc(result);
1985     aBitSet := aBitSet shr 1;
1986   end;
1987 end;
1988
1989 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1990 function CountSetBits(aBitSet: QWord): Integer;
1991 begin
1992   result := 0;
1993   while aBitSet > 0 do begin
1994     if (aBitSet and 1) = 1 then
1995       inc(result);
1996     aBitSet := aBitSet shr 1;
1997   end;
1998 end;
1999
2000 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2001 function LuminanceWeight(const aPixel: TglBitmapPixelData): Cardinal;
2002 begin
2003   result := Trunc(
2004     LUMINANCE_WEIGHT_R * aPixel.Data.r +
2005     LUMINANCE_WEIGHT_G * aPixel.Data.g +
2006     LUMINANCE_WEIGHT_B * aPixel.Data.b);
2007 end;
2008
2009 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2010 function DepthWeight(const aPixel: TglBitmapPixelData): Cardinal;
2011 begin
2012   result := Trunc(
2013     DEPTH_WEIGHT_R * aPixel.Data.r +
2014     DEPTH_WEIGHT_G * aPixel.Data.g +
2015     DEPTH_WEIGHT_B * aPixel.Data.b);
2016 end;
2017
2018 {$IFDEF GLB_SDL_IMAGE}
2019 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2020 // SDL Image Helper /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2021 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2022 function glBitmapRWseek(context: PSDL_RWops; offset: Integer; whence: Integer): Integer; cdecl;
2023 begin
2024   result := TStream(context^.unknown.data1).Seek(offset, whence);
2025 end;
2026
2027 function glBitmapRWread(context: PSDL_RWops; Ptr: Pointer; size: Integer; maxnum : Integer): Integer; cdecl;
2028 begin
2029   result := TStream(context^.unknown.data1).Read(Ptr^, size * maxnum);
2030 end;
2031
2032 function glBitmapRWwrite(context: PSDL_RWops; Ptr: Pointer; size: Integer; num: Integer): Integer; cdecl;
2033 begin
2034   result := TStream(context^.unknown.data1).Write(Ptr^, size * num);
2035 end;
2036
2037 function glBitmapRWclose(context: PSDL_RWops): Integer; cdecl;
2038 begin
2039   result := 0;
2040 end;
2041
2042 function glBitmapCreateRWops(Stream: TStream): PSDL_RWops;
2043 begin
2044   result := SDL_AllocRW;
2045
2046   if result = nil then
2047     raise EglBitmap.Create('glBitmapCreateRWops - SDL_AllocRW failed.');
2048
2049   result^.seek := glBitmapRWseek;
2050   result^.read := glBitmapRWread;
2051   result^.write := glBitmapRWwrite;
2052   result^.close := glBitmapRWclose;
2053   result^.unknown.data1 := Stream;
2054 end;
2055 {$ENDIF}
2056
2057 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2058 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
2059 begin
2060   glBitmapDefaultDeleteTextureOnFree := aDeleteTextureOnFree;
2061 end;
2062
2063 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2064 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
2065 begin
2066   glBitmapDefaultFreeDataAfterGenTextures := aFreeData;
2067 end;
2068
2069 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2070 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
2071 begin
2072   glBitmapDefaultMipmap := aValue;
2073 end;
2074
2075 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2076 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
2077 begin
2078   glBitmapDefaultFormat := aFormat;
2079 end;
2080
2081 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2082 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
2083 begin
2084   glBitmapDefaultFilterMin := aMin;
2085   glBitmapDefaultFilterMag := aMag;
2086 end;
2087
2088 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2089 procedure glBitmapSetDefaultWrap(const S: Cardinal = GL_CLAMP_TO_EDGE; const T: Cardinal = GL_CLAMP_TO_EDGE; const R: Cardinal = GL_CLAMP_TO_EDGE);
2090 begin
2091   glBitmapDefaultWrapS := S;
2092   glBitmapDefaultWrapT := T;
2093   glBitmapDefaultWrapR := R;
2094 end;
2095
2096 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2097 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
2098 procedure glBitmapSetDefaultSwizzle(const r: GLenum = GL_RED; g: GLenum = GL_GREEN; b: GLenum = GL_BLUE; a: GLenum = GL_ALPHA);
2099 begin
2100   glDefaultSwizzle[0] := r;
2101   glDefaultSwizzle[1] := g;
2102   glDefaultSwizzle[2] := b;
2103   glDefaultSwizzle[3] := a;
2104 end;
2105 {$IFEND}
2106
2107 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2108 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
2109 begin
2110   result := glBitmapDefaultDeleteTextureOnFree;
2111 end;
2112
2113 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2114 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
2115 begin
2116   result := glBitmapDefaultFreeDataAfterGenTextures;
2117 end;
2118
2119 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2120 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
2121 begin
2122   result := glBitmapDefaultMipmap;
2123 end;
2124
2125 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2126 function glBitmapGetDefaultFormat: TglBitmapFormat;
2127 begin
2128   result := glBitmapDefaultFormat;
2129 end;
2130
2131 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2132 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
2133 begin
2134   aMin := glBitmapDefaultFilterMin;
2135   aMag := glBitmapDefaultFilterMag;
2136 end;
2137
2138 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2139 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
2140 begin
2141   S := glBitmapDefaultWrapS;
2142   T := glBitmapDefaultWrapT;
2143   R := glBitmapDefaultWrapR;
2144 end;
2145
2146 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
2147 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2148 procedure glBitmapGetDefaultSwizzle(var r, g, b, a: GLenum);
2149 begin
2150   r := glDefaultSwizzle[0];
2151   g := glDefaultSwizzle[1];
2152   b := glDefaultSwizzle[2];
2153   a := glDefaultSwizzle[3];
2154 end;
2155 {$IFEND}
2156
2157 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2158 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2159 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2160 function TFormatDescriptor.CreateMappingData: Pointer;
2161 begin
2162   result := nil;
2163 end;
2164
2165 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2166 procedure TFormatDescriptor.FreeMappingData(var aMappingData: Pointer);
2167 begin
2168   //DUMMY
2169 end;
2170
2171 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2172 function TFormatDescriptor.IsEmpty: Boolean;
2173 begin
2174   result := (fFormat = tfEmpty);
2175 end;
2176
2177 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2178 function TFormatDescriptor.MaskMatch(const aMask: TglBitmapRec4ul): Boolean;
2179 var
2180   i: Integer;
2181   m: TglBitmapRec4ul;
2182 begin
2183   result := false;
2184   if (aMask.r = 0) and (aMask.g = 0) and (aMask.b = 0) and (aMask.a = 0) then
2185     raise EglBitmap.Create('FormatCheckFormat - All Masks are 0');
2186   m := Mask;
2187   for i := 0 to 3 do
2188     if (aMask.arr[i] <> m.arr[i]) then
2189       exit;
2190   result := true;
2191 end;
2192
2193 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2194 procedure TFormatDescriptor.PreparePixel(out aPixel: TglBitmapPixelData);
2195 begin
2196   FillChar(aPixel{%H-}, SizeOf(aPixel), 0);
2197   aPixel.Data   := Range;
2198   aPixel.Format := fFormat;
2199   aPixel.Range  := Range;
2200 end;
2201
2202 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2203 constructor TFormatDescriptor.Create;
2204 begin
2205   inherited Create;
2206 end;
2207
2208 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2209 //TfdAlpha_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2210 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2211 procedure TfdAlphaUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2212 begin
2213   aData^ := aPixel.Data.a;
2214   inc(aData);
2215 end;
2216
2217 procedure TfdAlphaUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2218 begin
2219   aPixel.Data.r := 0;
2220   aPixel.Data.g := 0;
2221   aPixel.Data.b := 0;
2222   aPixel.Data.a := aData^;
2223   inc(aData);
2224 end;
2225
2226 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2227 //TfdLuminance_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2228 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2229 procedure TfdLuminanceUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2230 begin
2231   aData^ := LuminanceWeight(aPixel);
2232   inc(aData);
2233 end;
2234
2235 procedure TfdLuminanceUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2236 begin
2237   aPixel.Data.r := aData^;
2238   aPixel.Data.g := aData^;
2239   aPixel.Data.b := aData^;
2240   aPixel.Data.a := 0;
2241   inc(aData);
2242 end;
2243
2244 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2245 //TfdUniversal_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2246 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2247 procedure TfdUniversalUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2248 var
2249   i: Integer;
2250 begin
2251   aData^ := 0;
2252   for i := 0 to 3 do
2253     if (Range.arr[i] > 0) then
2254       aData^ := aData^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
2255   inc(aData);
2256 end;
2257
2258 procedure TfdUniversalUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2259 var
2260   i: Integer;
2261 begin
2262   for i := 0 to 3 do
2263     aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and Range.arr[i];
2264   inc(aData);
2265 end;
2266
2267 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2268 //TfdLuminanceAlpha_UB2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2269 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2270 procedure TfdLuminanceAlphaUB2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2271 begin
2272   inherited Map(aPixel, aData, aMapData);
2273   aData^ := aPixel.Data.a;
2274   inc(aData);
2275 end;
2276
2277 procedure TfdLuminanceAlphaUB2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2278 begin
2279   inherited Unmap(aData, aPixel, aMapData);
2280   aPixel.Data.a := aData^;
2281   inc(aData);
2282 end;
2283
2284 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2285 //TfdRGB_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2286 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2287 procedure TfdRGBub3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2288 begin
2289   aData^ := aPixel.Data.r;
2290   inc(aData);
2291   aData^ := aPixel.Data.g;
2292   inc(aData);
2293   aData^ := aPixel.Data.b;
2294   inc(aData);
2295 end;
2296
2297 procedure TfdRGBub3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2298 begin
2299   aPixel.Data.r := aData^;
2300   inc(aData);
2301   aPixel.Data.g := aData^;
2302   inc(aData);
2303   aPixel.Data.b := aData^;
2304   inc(aData);
2305   aPixel.Data.a := 0;
2306 end;
2307
2308 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2309 //TfdBGR_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2310 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2311 procedure TfdBGRub3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2312 begin
2313   aData^ := aPixel.Data.b;
2314   inc(aData);
2315   aData^ := aPixel.Data.g;
2316   inc(aData);
2317   aData^ := aPixel.Data.r;
2318   inc(aData);
2319 end;
2320
2321 procedure TfdBGRub3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2322 begin
2323   aPixel.Data.b := aData^;
2324   inc(aData);
2325   aPixel.Data.g := aData^;
2326   inc(aData);
2327   aPixel.Data.r := aData^;
2328   inc(aData);
2329   aPixel.Data.a := 0;
2330 end;
2331
2332 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2333 //TfdRGBA_UB4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2334 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2335 procedure TfdRGBAub4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2336 begin
2337   inherited Map(aPixel, aData, aMapData);
2338   aData^ := aPixel.Data.a;
2339   inc(aData);
2340 end;
2341
2342 procedure TfdRGBAub4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2343 begin
2344   inherited Unmap(aData, aPixel, aMapData);
2345   aPixel.Data.a := aData^;
2346   inc(aData);
2347 end;
2348
2349 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2350 //TfdBGRA_UB4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2351 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2352 procedure TfdBGRAub4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2353 begin
2354   inherited Map(aPixel, aData, aMapData);
2355   aData^ := aPixel.Data.a;
2356   inc(aData);
2357 end;
2358
2359 procedure TfdBGRAub4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2360 begin
2361   inherited Unmap(aData, aPixel, aMapData);
2362   aPixel.Data.a := aData^;
2363   inc(aData);
2364 end;
2365
2366 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2367 //TfdAlpha_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2368 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2369 procedure TfdAlphaUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2370 begin
2371   PWord(aData)^ := aPixel.Data.a;
2372   inc(aData, 2);
2373 end;
2374
2375 procedure TfdAlphaUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2376 begin
2377   aPixel.Data.r := 0;
2378   aPixel.Data.g := 0;
2379   aPixel.Data.b := 0;
2380   aPixel.Data.a := PWord(aData)^;
2381   inc(aData, 2);
2382 end;
2383
2384 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2385 //TfdLuminance_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2386 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2387 procedure TfdLuminanceUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2388 begin
2389   PWord(aData)^ := LuminanceWeight(aPixel);
2390   inc(aData, 2);
2391 end;
2392
2393 procedure TfdLuminanceUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2394 begin
2395   aPixel.Data.r := PWord(aData)^;
2396   aPixel.Data.g := PWord(aData)^;
2397   aPixel.Data.b := PWord(aData)^;
2398   aPixel.Data.a := 0;
2399   inc(aData, 2);
2400 end;
2401
2402 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2403 //TfdUniversal_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2404 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2405 procedure TfdUniversalUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2406 var
2407   i: Integer;
2408 begin
2409   PWord(aData)^ := 0;
2410   for i := 0 to 3 do
2411     if (Range.arr[i] > 0) then
2412       PWord(aData)^ := PWord(aData)^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
2413   inc(aData, 2);
2414 end;
2415
2416 procedure TfdUniversalUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2417 var
2418   i: Integer;
2419 begin
2420   for i := 0 to 3 do
2421     aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and Range.arr[i];
2422   inc(aData, 2);
2423 end;
2424
2425 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2426 //TfdDepth_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2427 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2428 procedure TfdDepthUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2429 begin
2430   PWord(aData)^ := DepthWeight(aPixel);
2431   inc(aData, 2);
2432 end;
2433
2434 procedure TfdDepthUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2435 begin
2436   aPixel.Data.r := PWord(aData)^;
2437   aPixel.Data.g := PWord(aData)^;
2438   aPixel.Data.b := PWord(aData)^;
2439   aPixel.Data.a := PWord(aData)^;;
2440   inc(aData, 2);
2441 end;
2442
2443 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2444 //TfdLuminanceAlpha_US2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2445 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2446 procedure TfdLuminanceAlphaUS2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2447 begin
2448   inherited Map(aPixel, aData, aMapData);
2449   PWord(aData)^ := aPixel.Data.a;
2450   inc(aData, 2);
2451 end;
2452
2453 procedure TfdLuminanceAlphaUS2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2454 begin
2455   inherited Unmap(aData, aPixel, aMapData);
2456   aPixel.Data.a := PWord(aData)^;
2457   inc(aData, 2);
2458 end;
2459
2460 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2461 //TfdRGB_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2462 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2463 procedure TfdRGBus3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2464 begin
2465   PWord(aData)^ := aPixel.Data.r;
2466   inc(aData, 2);
2467   PWord(aData)^ := aPixel.Data.g;
2468   inc(aData, 2);
2469   PWord(aData)^ := aPixel.Data.b;
2470   inc(aData, 2);
2471 end;
2472
2473 procedure TfdRGBus3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2474 begin
2475   aPixel.Data.r := PWord(aData)^;
2476   inc(aData, 2);
2477   aPixel.Data.g := PWord(aData)^;
2478   inc(aData, 2);
2479   aPixel.Data.b := PWord(aData)^;
2480   inc(aData, 2);
2481   aPixel.Data.a := 0;
2482 end;
2483
2484 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2485 //TfdBGR_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2486 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2487 procedure TfdBGRus3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2488 begin
2489   PWord(aData)^ := aPixel.Data.b;
2490   inc(aData, 2);
2491   PWord(aData)^ := aPixel.Data.g;
2492   inc(aData, 2);
2493   PWord(aData)^ := aPixel.Data.r;
2494   inc(aData, 2);
2495 end;
2496
2497 procedure TfdBGRus3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2498 begin
2499   aPixel.Data.b := PWord(aData)^;
2500   inc(aData, 2);
2501   aPixel.Data.g := PWord(aData)^;
2502   inc(aData, 2);
2503   aPixel.Data.r := PWord(aData)^;
2504   inc(aData, 2);
2505   aPixel.Data.a := 0;
2506 end;
2507
2508 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2509 //TfdRGBA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2510 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2511 procedure TfdRGBAus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2512 begin
2513   inherited Map(aPixel, aData, aMapData);
2514   PWord(aData)^ := aPixel.Data.a;
2515   inc(aData, 2);
2516 end;
2517
2518 procedure TfdRGBAus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2519 begin
2520   inherited Unmap(aData, aPixel, aMapData);
2521   aPixel.Data.a := PWord(aData)^;
2522   inc(aData, 2);
2523 end;
2524
2525 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2526 //TfdARGB_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2527 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2528 procedure TfdARGBus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2529 begin
2530   PWord(aData)^ := aPixel.Data.a;
2531   inc(aData, 2);
2532   inherited Map(aPixel, aData, aMapData);
2533 end;
2534
2535 procedure TfdARGBus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2536 begin
2537   aPixel.Data.a := PWord(aData)^;
2538   inc(aData, 2);
2539   inherited Unmap(aData, aPixel, aMapData);
2540 end;
2541
2542 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2543 //TfdBGRA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2544 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2545 procedure TfdBGRAus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2546 begin
2547   inherited Map(aPixel, aData, aMapData);
2548   PWord(aData)^ := aPixel.Data.a;
2549   inc(aData, 2);
2550 end;
2551
2552 procedure TfdBGRAus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2553 begin
2554   inherited Unmap(aData, aPixel, aMapData);
2555   aPixel.Data.a := PWord(aData)^;
2556   inc(aData, 2);
2557 end;
2558
2559 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2560 //TfdABGR_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2561 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2562 procedure TfdABGRus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2563 begin
2564   PWord(aData)^ := aPixel.Data.a;
2565   inc(aData, 2);
2566   inherited Map(aPixel, aData, aMapData);
2567 end;
2568
2569 procedure TfdABGRus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2570 begin
2571   aPixel.Data.a := PWord(aData)^;
2572   inc(aData, 2);
2573   inherited Unmap(aData, aPixel, aMapData);
2574 end;
2575
2576 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2577 //TfdUniversal_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2578 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2579 procedure TfdUniversalUI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2580 var
2581   i: Integer;
2582 begin
2583   PCardinal(aData)^ := 0;
2584   for i := 0 to 3 do
2585     if (Range.arr[i] > 0) then
2586       PCardinal(aData)^ := PCardinal(aData)^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
2587   inc(aData, 4);
2588 end;
2589
2590 procedure TfdUniversalUI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2591 var
2592   i: Integer;
2593 begin
2594   for i := 0 to 3 do
2595     aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and Range.arr[i];
2596   inc(aData, 2);
2597 end;
2598
2599 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2600 //TfdDepth_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2601 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2602 procedure TfdDepthUI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2603 begin
2604   PCardinal(aData)^ := DepthWeight(aPixel);
2605   inc(aData, 4);
2606 end;
2607
2608 procedure TfdDepthUI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2609 begin
2610   aPixel.Data.r := PCardinal(aData)^;
2611   aPixel.Data.g := PCardinal(aData)^;
2612   aPixel.Data.b := PCardinal(aData)^;
2613   aPixel.Data.a := PCardinal(aData)^;
2614   inc(aData, 4);
2615 end;
2616
2617 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2618 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2619 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2620 procedure TfdAlpha4ub1.SetValues;
2621 begin
2622   inherited SetValues;
2623   fBitsPerPixel     := 8;
2624   fFormat           := tfAlpha4ub1;
2625   fWithAlpha        := tfAlpha4ub1;
2626   fPrecision        := glBitmapRec4ub(0, 0, 0, 8);
2627   fShift            := glBitmapRec4ub(0, 0, 0, 0);
2628 {$IFNDEF OPENGL_ES}
2629   fOpenGLFormat     := tfAlpha4ub1;
2630   fglFormat         := GL_ALPHA;
2631   fglInternalFormat := GL_ALPHA4;
2632   fglDataFormat     := GL_UNSIGNED_BYTE;
2633 {$ELSE}
2634   fOpenGLFormat     := tfAlpha8ub1;
2635 {$ENDIF}
2636 end;
2637
2638 procedure TfdAlpha8ub1.SetValues;
2639 begin
2640   inherited SetValues;
2641   fBitsPerPixel     := 8;
2642   fFormat           := tfAlpha8ub1;
2643   fWithAlpha        := tfAlpha8ub1;
2644   fPrecision        := glBitmapRec4ub(0, 0, 0, 8);
2645   fShift            := glBitmapRec4ub(0, 0, 0, 0);
2646   fOpenGLFormat     := tfAlpha8ub1;
2647   fglFormat         := GL_ALPHA;
2648   fglInternalFormat := {$IFNDEF OPENGL_ES}GL_ALPHA8{$ELSE}GL_ALPHA{$ENDIF};
2649   fglDataFormat     := GL_UNSIGNED_BYTE;
2650 end;
2651
2652 procedure TfdAlpha16us1.SetValues;
2653 begin
2654   inherited SetValues;
2655   fBitsPerPixel     := 16;
2656   fFormat           := tfAlpha16us1;
2657   fWithAlpha        := tfAlpha16us1;
2658   fPrecision        := glBitmapRec4ub(0, 0, 0, 16);
2659   fShift            := glBitmapRec4ub(0, 0, 0,  0);
2660 {$IFNDEF OPENGL_ES}
2661   fOpenGLFormat     := tfAlpha16us1;
2662   fglFormat         := GL_ALPHA;
2663   fglInternalFormat := GL_ALPHA16;
2664   fglDataFormat     := GL_UNSIGNED_SHORT;
2665 {$ELSE}
2666   fOpenGLFormat     := tfAlpha8ub1;
2667 {$ENDIF}
2668 end;
2669
2670 procedure TfdLuminance4ub1.SetValues;
2671 begin
2672   inherited SetValues;
2673   fBitsPerPixel     := 8;
2674   fFormat           := tfLuminance4ub1;
2675   fWithAlpha        := tfLuminance4Alpha4ub2;
2676   fWithoutAlpha     := tfLuminance4ub1;
2677   fPrecision        := glBitmapRec4ub(8, 8, 8, 0);
2678   fShift            := glBitmapRec4ub(0, 0, 0, 0);
2679 {$IFNDEF OPENGL_ES}
2680   fOpenGLFormat     := tfLuminance4ub1;
2681   fglFormat         := GL_LUMINANCE;
2682   fglInternalFormat := GL_LUMINANCE4;
2683   fglDataFormat     := GL_UNSIGNED_BYTE;
2684 {$ELSE}
2685   fOpenGLFormat     := tfLuminance8ub1;
2686 {$ENDIF}
2687 end;
2688
2689 procedure TfdLuminance8ub1.SetValues;
2690 begin
2691   inherited SetValues;
2692   fBitsPerPixel     := 8;
2693   fFormat           := tfLuminance8ub1;
2694   fWithAlpha        := tfLuminance8Alpha8ub2;
2695   fWithoutAlpha     := tfLuminance8ub1;
2696   fOpenGLFormat     := tfLuminance8ub1;
2697   fPrecision        := glBitmapRec4ub(8, 8, 8, 0);
2698   fShift            := glBitmapRec4ub(0, 0, 0, 0);
2699   fglFormat         := GL_LUMINANCE;
2700   fglInternalFormat := {$IFNDEF OPENGL_ES}GL_LUMINANCE8{$ELSE}GL_LUMINANCE{$ENDIF};
2701   fglDataFormat     := GL_UNSIGNED_BYTE;
2702 end;
2703
2704 procedure TfdLuminance16us1.SetValues;
2705 begin
2706   inherited SetValues;
2707   fBitsPerPixel     := 16;
2708   fFormat           := tfLuminance16us1;
2709   fWithAlpha        := tfLuminance16Alpha16us2;
2710   fWithoutAlpha     := tfLuminance16us1;
2711   fPrecision        := glBitmapRec4ub(16, 16, 16,  0);
2712   fShift            := glBitmapRec4ub( 0,  0,  0,  0);
2713 {$IFNDEF OPENGL_ES}
2714   fOpenGLFormat     := tfLuminance16us1;
2715   fglFormat         := GL_LUMINANCE;
2716   fglInternalFormat := GL_LUMINANCE16;
2717   fglDataFormat     := GL_UNSIGNED_SHORT;
2718 {$ELSE}
2719   fOpenGLFormat     := tfLuminance8ub1;
2720 {$ENDIF}
2721 end;
2722
2723 procedure TfdLuminance4Alpha4ub2.SetValues;
2724 begin
2725   inherited SetValues;
2726   fBitsPerPixel     := 16;
2727   fFormat           := tfLuminance4Alpha4ub2;
2728   fWithAlpha        := tfLuminance4Alpha4ub2;
2729   fWithoutAlpha     := tfLuminance4ub1;
2730   fPrecision        := glBitmapRec4ub(8, 8, 8, 8);
2731   fShift            := glBitmapRec4ub(0, 0, 0, 8);
2732 {$IFNDEF OPENGL_ES}
2733   fOpenGLFormat     := tfLuminance4Alpha4ub2;
2734   fglFormat         := GL_LUMINANCE_ALPHA;
2735   fglInternalFormat := GL_LUMINANCE4_ALPHA4;
2736   fglDataFormat     := GL_UNSIGNED_BYTE;
2737 {$ELSE}
2738   fOpenGLFormat     := tfLuminance8Alpha8ub2;
2739 {$ENDIF}
2740 end;
2741
2742 procedure TfdLuminance6Alpha2ub2.SetValues;
2743 begin
2744   inherited SetValues;
2745   fBitsPerPixel     := 16;
2746   fFormat           := tfLuminance6Alpha2ub2;
2747   fWithAlpha        := tfLuminance6Alpha2ub2;
2748   fWithoutAlpha     := tfLuminance8ub1;
2749   fPrecision        := glBitmapRec4ub(8, 8, 8, 8);
2750   fShift            := glBitmapRec4ub(0, 0, 0, 8);
2751 {$IFNDEF OPENGL_ES}
2752   fOpenGLFormat     := tfLuminance6Alpha2ub2;
2753   fglFormat         := GL_LUMINANCE_ALPHA;
2754   fglInternalFormat := GL_LUMINANCE6_ALPHA2;
2755   fglDataFormat     := GL_UNSIGNED_BYTE;
2756 {$ELSE}
2757   fOpenGLFormat     := tfLuminance8Alpha8ub2;
2758 {$ENDIF}
2759 end;
2760
2761 procedure TfdLuminance8Alpha8ub2.SetValues;
2762 begin
2763   inherited SetValues;
2764   fBitsPerPixel     := 16;
2765   fFormat           := tfLuminance8Alpha8ub2;
2766   fWithAlpha        := tfLuminance8Alpha8ub2;
2767   fWithoutAlpha     := tfLuminance8ub1;
2768   fOpenGLFormat     := tfLuminance8Alpha8ub2;
2769   fPrecision        := glBitmapRec4ub(8, 8, 8, 8);
2770   fShift            := glBitmapRec4ub(0, 0, 0, 8);
2771   fglFormat         := GL_LUMINANCE_ALPHA;
2772   fglInternalFormat := {$IFNDEF OPENGL_ES}GL_LUMINANCE8_ALPHA8{$ELSE}GL_LUMINANCE_ALPHA{$ENDIF};
2773   fglDataFormat     := GL_UNSIGNED_BYTE;
2774 end;
2775
2776 procedure TfdLuminance12Alpha4us2.SetValues;
2777 begin
2778   inherited SetValues;
2779   fBitsPerPixel     := 32;
2780   fFormat           := tfLuminance12Alpha4us2;
2781   fWithAlpha        := tfLuminance12Alpha4us2;
2782   fWithoutAlpha     := tfLuminance16us1;
2783   fPrecision        := glBitmapRec4ub(16, 16, 16, 16);
2784   fShift            := glBitmapRec4ub( 0,  0,  0, 16);
2785 {$IFNDEF OPENGL_ES}
2786   fOpenGLFormat     := tfLuminance12Alpha4us2;
2787   fglFormat         := GL_LUMINANCE_ALPHA;
2788   fglInternalFormat := GL_LUMINANCE12_ALPHA4;
2789   fglDataFormat     := GL_UNSIGNED_SHORT;
2790 {$ELSE}
2791   fOpenGLFormat     := tfLuminance8Alpha8ub2;
2792 {$ENDIF}
2793 end;
2794
2795 procedure TfdLuminance16Alpha16us2.SetValues;
2796 begin
2797   inherited SetValues;
2798   fBitsPerPixel     := 32;
2799   fFormat           := tfLuminance16Alpha16us2;
2800   fWithAlpha        := tfLuminance16Alpha16us2;
2801   fWithoutAlpha     := tfLuminance16us1;
2802   fPrecision        := glBitmapRec4ub(16, 16, 16, 16);
2803   fShift            := glBitmapRec4ub( 0,  0,  0, 16);
2804 {$IFNDEF OPENGL_ES}
2805   fOpenGLFormat     := tfLuminance16Alpha16us2;
2806   fglFormat         := GL_LUMINANCE_ALPHA;
2807   fglInternalFormat := GL_LUMINANCE16_ALPHA16;
2808   fglDataFormat     := GL_UNSIGNED_SHORT;
2809 {$ELSE}
2810   fOpenGLFormat     := tfLuminance8Alpha8ub2;
2811 {$ENDIF}
2812 end;
2813
2814 procedure TfdR3G3B2ub1.SetValues;
2815 begin
2816   inherited SetValues;
2817   fBitsPerPixel     := 8;
2818   fFormat           := tfR3G3B2ub1;
2819   fWithAlpha        := tfRGBA4us1;
2820   fWithoutAlpha     := tfR3G3B2ub1;
2821   fRGBInverted      := tfEmpty;
2822   fPrecision        := glBitmapRec4ub(3, 3, 2, 0);
2823   fShift            := glBitmapRec4ub(5, 2, 0, 0);
2824 {$IFNDEF OPENGL_ES}
2825   fOpenGLFormat     := tfR3G3B2ub1;
2826   fglFormat         := GL_RGB;
2827   fglInternalFormat := GL_R3_G3_B2;
2828   fglDataFormat     := GL_UNSIGNED_BYTE_3_3_2;
2829 {$ELSE}
2830   fOpenGLFormat     := tfR5G6B5us1;
2831 {$ENDIF}
2832 end;
2833
2834 procedure TfdRGBX4us1.SetValues;
2835 begin
2836   inherited SetValues;
2837   fBitsPerPixel     := 16;
2838   fFormat           := tfRGBX4us1;
2839   fWithAlpha        := tfRGBA4us1;
2840   fWithoutAlpha     := tfRGBX4us1;
2841   fRGBInverted      := tfBGRX4us1;
2842   fPrecision        := glBitmapRec4ub( 4, 4, 4, 0);
2843   fShift            := glBitmapRec4ub(12, 8, 4, 0);
2844 {$IFNDEF OPENGL_ES}
2845   fOpenGLFormat     := tfRGBX4us1;
2846   fglFormat         := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
2847   fglInternalFormat := GL_RGB4;
2848   fglDataFormat     := GL_UNSIGNED_SHORT_4_4_4_4;
2849 {$ELSE}
2850   fOpenGLFormat     := tfR5G6B5us1;
2851 {$ENDIF}
2852 end;
2853
2854 procedure TfdXRGB4us1.SetValues;
2855 begin
2856   inherited SetValues;
2857   fBitsPerPixel     := 16;
2858   fFormat           := tfXRGB4us1;
2859   fWithAlpha        := tfARGB4us1;
2860   fWithoutAlpha     := tfXRGB4us1;
2861   fRGBInverted      := tfXBGR4us1;
2862   fPrecision        := glBitmapRec4ub(4, 4, 4, 0);
2863   fShift            := glBitmapRec4ub(8, 4, 0, 0);
2864 {$IFNDEF OPENGL_ES}
2865   fOpenGLFormat     := tfXRGB4us1;
2866   fglFormat         := GL_BGRA;
2867   fglInternalFormat := GL_RGB4;
2868   fglDataFormat     := GL_UNSIGNED_SHORT_4_4_4_4_REV;
2869 {$ELSE}
2870   fOpenGLFormat     := tfR5G6B5us1;
2871 {$ENDIF}
2872 end;
2873
2874 procedure TfdR5G6B5us1.SetValues;
2875 begin
2876   inherited SetValues;
2877   fBitsPerPixel     := 16;
2878   fFormat           := tfR5G6B5us1;
2879   fWithAlpha        := tfRGB5A1us1;
2880   fWithoutAlpha     := tfR5G6B5us1;
2881   fRGBInverted      := tfB5G6R5us1;
2882   fPrecision        := glBitmapRec4ub( 5, 6, 5, 0);
2883   fShift            := glBitmapRec4ub(11, 5, 0, 0);
2884 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
2885   fOpenGLFormat     := tfR5G6B5us1;
2886   fglFormat         := GL_RGB;
2887   fglInternalFormat := GL_RGB565;
2888   fglDataFormat     := GL_UNSIGNED_SHORT_5_6_5;
2889 {$ELSE}
2890   fOpenGLFormat     := tfRGB8ub3;
2891 {$IFEND}
2892 end;
2893
2894 procedure TfdRGB5X1us1.SetValues;
2895 begin
2896   inherited SetValues;
2897   fBitsPerPixel     := 16;
2898   fFormat           := tfRGB5X1us1;
2899   fWithAlpha        := tfRGB5A1us1;
2900   fWithoutAlpha     := tfRGB5X1us1;
2901   fRGBInverted      := tfBGR5X1us1;
2902   fPrecision        := glBitmapRec4ub( 5, 5, 5, 0);
2903   fShift            := glBitmapRec4ub(11, 6, 1, 0);
2904 {$IFNDEF OPENGL_ES}
2905   fOpenGLFormat     := tfRGB5X1us1;
2906   fglFormat         := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
2907   fglInternalFormat := GL_RGB5;
2908   fglDataFormat     := GL_UNSIGNED_SHORT_5_5_5_1;
2909 {$ELSE}
2910   fOpenGLFormat     := tfR5G6B5us1;
2911 {$ENDIF}
2912 end;
2913
2914 procedure TfdX1RGB5us1.SetValues;
2915 begin
2916   inherited SetValues;
2917   fBitsPerPixel     := 16;
2918   fFormat           := tfX1RGB5us1;
2919   fWithAlpha        := tfA1RGB5us1;
2920   fWithoutAlpha     := tfX1RGB5us1;
2921   fRGBInverted      := tfX1BGR5us1;
2922   fPrecision        := glBitmapRec4ub( 5, 5, 5, 0);
2923   fShift            := glBitmapRec4ub(10, 5, 0, 0);
2924 {$IFNDEF OPENGL_ES}
2925   fOpenGLFormat     := tfX1RGB5us1;
2926   fglFormat         := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
2927   fglInternalFormat := GL_RGB5;
2928   fglDataFormat     := GL_UNSIGNED_SHORT_1_5_5_5_REV;
2929 {$ELSE}
2930   fOpenGLFormat     := tfR5G6B5us1;
2931 {$ENDIF}
2932 end;
2933
2934 procedure TfdRGB8ub3.SetValues;
2935 begin
2936   inherited SetValues;
2937   fBitsPerPixel     := 24;
2938   fFormat           := tfRGB8ub3;
2939   fWithAlpha        := tfRGBA8ub4;
2940   fWithoutAlpha     := tfRGB8ub3;
2941   fRGBInverted      := tfBGR8ub3;
2942   fPrecision        := glBitmapRec4ub(8, 8,  8, 0);
2943   fShift            := glBitmapRec4ub(0, 8, 16, 0);
2944   fOpenGLFormat     := tfRGB8ub3;
2945   fglFormat         := GL_RGB;
2946   fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}GL_RGB8{$ELSE}GL_RGB{$IFEND};
2947   fglDataFormat     := GL_UNSIGNED_BYTE;
2948 end;
2949
2950 procedure TfdRGBX8ui1.SetValues;
2951 begin
2952   inherited SetValues;
2953   fBitsPerPixel     := 32;
2954   fFormat           := tfRGBX8ui1;
2955   fWithAlpha        := tfRGBA8ui1;
2956   fWithoutAlpha     := tfRGBX8ui1;
2957   fRGBInverted      := tfBGRX8ui1;
2958   fPrecision        := glBitmapRec4ub( 8,  8,  8, 0);
2959   fShift            := glBitmapRec4ub(24, 16,  8, 0);
2960 {$IFNDEF OPENGL_ES}
2961   fOpenGLFormat     := tfRGBX8ui1;
2962   fglFormat         := GL_RGBA;  //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
2963   fglInternalFormat := GL_RGB8;
2964   fglDataFormat     := GL_UNSIGNED_INT_8_8_8_8;
2965 {$ELSE}
2966   fOpenGLFormat     := tfRGB8ub3;
2967 {$ENDIF}
2968 end;
2969
2970 procedure TfdXRGB8ui1.SetValues;
2971 begin
2972   inherited SetValues;
2973   fBitsPerPixel     := 32;
2974   fFormat           := tfXRGB8ui1;
2975   fWithAlpha        := tfXRGB8ui1;
2976   fWithoutAlpha     := tfXRGB8ui1;
2977   fOpenGLFormat     := tfXRGB8ui1;
2978   fRGBInverted      := tfXBGR8ui1;
2979   fPrecision        := glBitmapRec4ub( 8,  8,  8, 0);
2980   fShift            := glBitmapRec4ub(16,  8,  0, 0);
2981 {$IFNDEF OPENGL_ES}
2982   fOpenGLFormat     := tfXRGB8ui1;
2983   fglFormat         := GL_BGRA;  //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
2984   fglInternalFormat := GL_RGB8;
2985   fglDataFormat     := GL_UNSIGNED_INT_8_8_8_8_REV;
2986 {$ELSE}
2987   fOpenGLFormat     := tfRGB8ub3;
2988 {$ENDIF}
2989 end;
2990
2991 procedure TfdRGB10X2ui1.SetValues;
2992 begin
2993   inherited SetValues;
2994   fBitsPerPixel     := 32;
2995   fFormat           := tfRGB10X2ui1;
2996   fWithAlpha        := tfRGB10A2ui1;
2997   fWithoutAlpha     := tfRGB10X2ui1;
2998   fRGBInverted      := tfBGR10X2ui1;
2999   fPrecision        := glBitmapRec4ub(10, 10, 10, 0);
3000   fShift            := glBitmapRec4ub(22, 12,  2, 0);
3001 {$IFNDEF OPENGL_ES}
3002   fOpenGLFormat     := tfRGB10X2ui1;
3003   fglFormat         := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3004   fglInternalFormat := GL_RGB10;
3005   fglDataFormat     := GL_UNSIGNED_INT_10_10_10_2;
3006 {$ELSE}
3007   fOpenGLFormat     := tfRGB16us3;
3008 {$ENDIF}
3009 end;
3010
3011 procedure TfdX2RGB10ui1.SetValues;
3012 begin
3013   inherited SetValues;
3014   fBitsPerPixel     := 32;
3015   fFormat           := tfX2RGB10ui1;
3016   fWithAlpha        := tfA2RGB10ui1;
3017   fWithoutAlpha     := tfX2RGB10ui1;
3018   fRGBInverted      := tfX2BGR10ui1;
3019   fPrecision        := glBitmapRec4ub(10, 10, 10, 0);
3020   fShift            := glBitmapRec4ub(20, 10,  0, 0);
3021 {$IFNDEF OPENGL_ES}
3022   fOpenGLFormat     := tfX2RGB10ui1;
3023   fglFormat         := GL_BGRA;  //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3024   fglInternalFormat := GL_RGB10;
3025   fglDataFormat     := GL_UNSIGNED_INT_2_10_10_10_REV;
3026 {$ELSE}
3027   fOpenGLFormat     := tfRGB16us3;
3028 {$ENDIF}
3029 end;
3030
3031 procedure TfdRGB16us3.SetValues;
3032 begin
3033   inherited SetValues;
3034   fBitsPerPixel     := 48;
3035   fFormat           := tfRGB16us3;
3036   fWithAlpha        := tfRGBA16us4;
3037   fWithoutAlpha     := tfRGB16us3;
3038   fRGBInverted      := tfBGR16us3;
3039   fPrecision        := glBitmapRec4ub(16, 16, 16, 0);
3040   fShift            := glBitmapRec4ub( 0, 16, 32, 0);
3041 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
3042   fOpenGLFormat     := tfRGB16us3;
3043   fglFormat         := GL_RGB;
3044   fglInternalFormat := {$IFNDEF OPENGL_ES}GL_RGB16{$ELSE}GL_RGB16UI{$ENDIF};
3045   fglDataFormat     := GL_UNSIGNED_SHORT;
3046 {$ELSE}
3047   fOpenGLFormat     := tfRGB8ub3;
3048 {$IFEND}
3049 end;
3050
3051 procedure TfdRGBA4us1.SetValues;
3052 begin
3053   inherited SetValues;
3054   fBitsPerPixel     := 16;
3055   fFormat           := tfRGBA4us1;
3056   fWithAlpha        := tfRGBA4us1;
3057   fWithoutAlpha     := tfRGBX4us1;
3058   fOpenGLFormat     := tfRGBA4us1;
3059   fRGBInverted      := tfBGRA4us1;
3060   fPrecision        := glBitmapRec4ub( 4,  4,  4,  4);
3061   fShift            := glBitmapRec4ub(12,  8,  4,  0);
3062   fglFormat         := GL_RGBA;
3063   fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}GL_RGBA8{$ELSE}GL_RGBA{$IFEND};
3064   fglDataFormat     := GL_UNSIGNED_SHORT_4_4_4_4;
3065 end;
3066
3067 procedure TfdARGB4us1.SetValues;
3068 begin
3069   inherited SetValues;
3070   fBitsPerPixel     := 16;
3071   fFormat           := tfARGB4us1;
3072   fWithAlpha        := tfARGB4us1;
3073   fWithoutAlpha     := tfXRGB4us1;
3074   fRGBInverted      := tfABGR4us1;
3075   fPrecision        := glBitmapRec4ub( 4,  4,  4,  4);
3076   fShift            := glBitmapRec4ub( 8,  4,  0, 12);
3077 {$IFNDEF OPENGL_ES}
3078   fOpenGLFormat     := tfARGB4us1;
3079   fglFormat         := GL_BGRA;
3080   fglInternalFormat := GL_RGBA4;
3081   fglDataFormat     := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3082 {$ELSE}
3083   fOpenGLFormat     := tfRGBA4us1;
3084 {$ENDIF}
3085 end;
3086
3087 procedure TfdRGB5A1us1.SetValues;
3088 begin
3089   inherited SetValues;
3090   fBitsPerPixel     := 16;
3091   fFormat           := tfRGB5A1us1;
3092   fWithAlpha        := tfRGB5A1us1;
3093   fWithoutAlpha     := tfRGB5X1us1;
3094   fOpenGLFormat     := tfRGB5A1us1;
3095   fRGBInverted      := tfBGR5A1us1;
3096   fPrecision        := glBitmapRec4ub( 5,  5,  5,  1);
3097   fShift            := glBitmapRec4ub(11,  6,  1,  0);
3098   fglFormat         := GL_RGBA;
3099   fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}GL_RGB5_A1{$ELSE}GL_RGBA{$IFEND};
3100   fglDataFormat     := GL_UNSIGNED_SHORT_5_5_5_1;
3101 end;
3102
3103 procedure TfdA1RGB5us1.SetValues;
3104 begin
3105   inherited SetValues;
3106   fBitsPerPixel     := 16;
3107   fFormat           := tfA1RGB5us1;
3108   fWithAlpha        := tfA1RGB5us1;
3109   fWithoutAlpha     := tfX1RGB5us1;
3110   fRGBInverted      := tfA1BGR5us1;
3111   fPrecision        := glBitmapRec4ub( 5,  5,  5,  1);
3112   fShift            := glBitmapRec4ub(10,  5,  0, 15);
3113 {$IFNDEF OPENGL_ES}
3114   fOpenGLFormat     := tfA1RGB5us1;
3115   fglFormat         := GL_BGRA;
3116   fglInternalFormat := GL_RGB5_A1;
3117   fglDataFormat     := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3118 {$ELSE}
3119   fOpenGLFormat     := tfRGB5A1us1;
3120 {$ENDIF}
3121 end;
3122
3123 procedure TfdRGBA8ui1.SetValues;
3124 begin
3125   inherited SetValues;
3126   fBitsPerPixel     := 32;
3127   fFormat           := tfRGBA8ui1;
3128   fWithAlpha        := tfRGBA8ui1;
3129   fWithoutAlpha     := tfRGBX8ui1;
3130   fRGBInverted      := tfBGRA8ui1;
3131   fPrecision        := glBitmapRec4ub( 8,  8,  8,  8);
3132   fShift            := glBitmapRec4ub(24, 16,  8,  0);
3133 {$IFNDEF OPENGL_ES}
3134   fOpenGLFormat     := tfRGBA8ui1;
3135   fglFormat         := GL_RGBA;
3136   fglInternalFormat := GL_RGBA8;
3137   fglDataFormat     := GL_UNSIGNED_INT_8_8_8_8;
3138 {$ELSE}
3139   fOpenGLFormat     := tfRGBA8ub4;
3140 {$ENDIF}
3141 end;
3142
3143 procedure TfdARGB8ui1.SetValues;
3144 begin
3145   inherited SetValues;
3146   fBitsPerPixel     := 32;
3147   fFormat           := tfARGB8ui1;
3148   fWithAlpha        := tfARGB8ui1;
3149   fWithoutAlpha     := tfXRGB8ui1;
3150   fRGBInverted      := tfABGR8ui1;
3151   fPrecision        := glBitmapRec4ub( 8,  8,  8,  8);
3152   fShift            := glBitmapRec4ub(16,  8,  0, 24);
3153 {$IFNDEF OPENGL_ES}
3154   fOpenGLFormat     := tfARGB8ui1;
3155   fglFormat         := GL_BGRA;
3156   fglInternalFormat := GL_RGBA8;
3157   fglDataFormat     := GL_UNSIGNED_INT_8_8_8_8_REV;
3158 {$ELSE}
3159   fOpenGLFormat     := tfRGBA8ub4;
3160 {$ENDIF}
3161 end;
3162
3163 procedure TfdRGBA8ub4.SetValues;
3164 begin
3165   inherited SetValues;
3166   fBitsPerPixel     := 32;
3167   fFormat           := tfRGBA8ub4;
3168   fWithAlpha        := tfRGBA8ub4;
3169   fWithoutAlpha     := tfRGB8ub3;
3170   fOpenGLFormat     := tfRGBA8ub4;
3171   fRGBInverted      := tfBGRA8ub4;
3172   fPrecision        := glBitmapRec4ub( 8,  8,  8,  8);
3173   fShift            := glBitmapRec4ub( 0,  8, 16, 24);
3174   fglFormat         := GL_RGBA;
3175   fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}GL_RGBA8{$ELSE}GL_RGBA{$IFEND};
3176   fglDataFormat     := GL_UNSIGNED_BYTE;
3177 end;
3178
3179 procedure TfdRGB10A2ui1.SetValues;
3180 begin
3181   inherited SetValues;
3182   fBitsPerPixel     := 32;
3183   fFormat           := tfRGB10A2ui1;
3184   fWithAlpha        := tfRGB10A2ui1;
3185   fWithoutAlpha     := tfRGB10X2ui1;
3186   fRGBInverted      := tfBGR10A2ui1;
3187   fPrecision        := glBitmapRec4ub(10, 10, 10,  2);
3188   fShift            := glBitmapRec4ub(22, 12,  2,  0);
3189 {$IFNDEF OPENGL_ES}
3190   fOpenGLFormat     := tfRGB10A2ui1;
3191   fglFormat         := GL_RGBA;
3192   fglInternalFormat := GL_RGB10_A2;
3193   fglDataFormat     := GL_UNSIGNED_INT_10_10_10_2;
3194 {$ELSE}
3195   fOpenGLFormat     := tfA2RGB10ui1;
3196 {$ENDIF}
3197 end;
3198
3199 procedure TfdA2RGB10ui1.SetValues;
3200 begin
3201   inherited SetValues;
3202   fBitsPerPixel     := 32;
3203   fFormat           := tfA2RGB10ui1;
3204   fWithAlpha        := tfA2RGB10ui1;
3205   fWithoutAlpha     := tfX2RGB10ui1;
3206   fRGBInverted      := tfA2BGR10ui1;
3207   fPrecision        := glBitmapRec4ub(10, 10, 10,  2);
3208   fShift            := glBitmapRec4ub(20, 10,  0, 30);
3209 {$IF NOT DEFINED(OPENGL_ES)}
3210   fOpenGLFormat     := tfA2RGB10ui1;
3211   fglFormat         := GL_BGRA;
3212   fglInternalFormat := GL_RGB10_A2;
3213   fglDataFormat     := GL_UNSIGNED_INT_2_10_10_10_REV;
3214 {$ELSEIF DEFINED(OPENGL_ES_3_0)}
3215   fOpenGLFormat     := tfA2RGB10ui1;
3216   fglFormat         := GL_RGBA;
3217   fglInternalFormat := GL_RGB10_A2;
3218   fglDataFormat     := GL_UNSIGNED_INT_2_10_10_10_REV;
3219 {$ELSE}
3220   fOpenGLFormat     := tfRGBA8ui1;
3221 {$IFEND}
3222 end;
3223
3224 procedure TfdRGBA16us4.SetValues;
3225 begin
3226   inherited SetValues;
3227   fBitsPerPixel     := 64;
3228   fFormat           := tfRGBA16us4;
3229   fWithAlpha        := tfRGBA16us4;
3230   fWithoutAlpha     := tfRGB16us3;
3231   fRGBInverted      := tfBGRA16us4;
3232   fPrecision        := glBitmapRec4ub(16, 16, 16, 16);
3233   fShift            := glBitmapRec4ub( 0, 16, 32, 48);
3234 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
3235   fOpenGLFormat     := tfRGBA16us4;
3236   fglFormat         := GL_RGBA;
3237   fglInternalFormat := {$IFNDEF OPENGL_ES}GL_RGBA16{$ELSE}GL_RGBA16UI{$ENDIF};
3238   fglDataFormat     := GL_UNSIGNED_SHORT;
3239 {$ELSE}
3240   fOpenGLFormat     := tfRGBA8ub4;
3241 {$IFEND}
3242 end;
3243
3244 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3245 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3246 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3247 procedure TfdBGRX4us1.SetValues;
3248 begin
3249   inherited SetValues;
3250   fBitsPerPixel     := 16;
3251   fFormat           := tfBGRX4us1;
3252   fWithAlpha        := tfBGRA4us1;
3253   fWithoutAlpha     := tfBGRX4us1;
3254   fRGBInverted      := tfRGBX4us1;
3255   fPrecision        := glBitmapRec4ub( 4,  4,  4,  0);
3256   fShift            := glBitmapRec4ub( 4,  8, 12,  0);
3257 {$IFNDEF OPENGL_ES}
3258   fOpenGLFormat     := tfBGRX4us1;
3259   fglFormat         := GL_BGRA;  //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3260   fglInternalFormat := GL_RGB4;
3261   fglDataFormat     := GL_UNSIGNED_SHORT_4_4_4_4;
3262 {$ELSE}
3263   fOpenGLFormat     := tfR5G6B5us1;
3264 {$ENDIF}
3265 end;
3266
3267 procedure TfdXBGR4us1.SetValues;
3268 begin
3269   inherited SetValues;
3270   fBitsPerPixel     := 16;
3271   fFormat           := tfXBGR4us1;
3272   fWithAlpha        := tfABGR4us1;
3273   fWithoutAlpha     := tfXBGR4us1;
3274   fRGBInverted      := tfXRGB4us1;
3275   fPrecision        := glBitmapRec4ub( 4,  4,  4,  0);
3276   fShift            := glBitmapRec4ub( 0,  4,  8,  0);
3277 {$IFNDEF OPENGL_ES}
3278   fOpenGLFormat     := tfXBGR4us1;
3279   fglFormat         := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3280   fglInternalFormat := GL_RGB4;
3281   fglDataFormat     := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3282 {$ELSE}
3283   fOpenGLFormat     := tfR5G6B5us1;
3284 {$ENDIF}
3285 end;
3286
3287 procedure TfdB5G6R5us1.SetValues;
3288 begin
3289   inherited SetValues;
3290   fBitsPerPixel     := 16;
3291   fFormat           := tfB5G6R5us1;
3292   fWithAlpha        := tfBGR5A1us1;
3293   fWithoutAlpha     := tfB5G6R5us1;
3294   fRGBInverted      := tfR5G6B5us1;
3295   fPrecision        := glBitmapRec4ub( 5,  6,  5,  0);
3296   fShift            := glBitmapRec4ub( 0,  5, 11,  0);
3297 {$IFNDEF OPENGL_ES}
3298   fOpenGLFormat     := tfB5G6R5us1;
3299   fglFormat         := GL_RGB;
3300   fglInternalFormat := GL_RGB565;
3301   fglDataFormat     := GL_UNSIGNED_SHORT_5_6_5_REV;
3302 {$ELSE}
3303   fOpenGLFormat     := tfR5G6B5us1;
3304 {$ENDIF}
3305 end;
3306
3307 procedure TfdBGR5X1us1.SetValues;
3308 begin
3309   inherited SetValues;
3310   fBitsPerPixel     := 16;
3311   fFormat           := tfBGR5X1us1;
3312   fWithAlpha        := tfBGR5A1us1;
3313   fWithoutAlpha     := tfBGR5X1us1;
3314   fRGBInverted      := tfRGB5X1us1;
3315   fPrecision        := glBitmapRec4ub( 5,  5,  5,  0);
3316   fShift            := glBitmapRec4ub( 1,  6, 11,  0);
3317 {$IFNDEF OPENGL_ES}
3318   fOpenGLFormat     := tfBGR5X1us1;
3319   fglFormat         := GL_BGRA;
3320   fglInternalFormat := GL_RGB5;
3321   fglDataFormat     := GL_UNSIGNED_SHORT_5_5_5_1;
3322 {$ELSE}
3323   fOpenGLFormat     := tfR5G6B5us1;
3324 {$ENDIF}
3325 end;
3326
3327 procedure TfdX1BGR5us1.SetValues;
3328 begin
3329   inherited SetValues;
3330   fBitsPerPixel     := 16;
3331   fFormat           := tfX1BGR5us1;
3332   fWithAlpha        := tfA1BGR5us1;
3333   fWithoutAlpha     := tfX1BGR5us1;
3334   fRGBInverted      := tfX1RGB5us1;
3335   fPrecision        := glBitmapRec4ub( 5,  5,  5,  0);
3336   fShift            := glBitmapRec4ub( 0,  5, 10,  0);
3337 {$IFNDEF OPENGL_ES}
3338   fOpenGLFormat     := tfX1BGR5us1;
3339   fglFormat         := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3340   fglInternalFormat := GL_RGB5;
3341   fglDataFormat     := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3342 {$ELSE}
3343   fOpenGLFormat     := tfR5G6B5us1;
3344 {$ENDIF}
3345 end;
3346
3347 procedure TfdBGR8ub3.SetValues;
3348 begin
3349   inherited SetValues;
3350   fBitsPerPixel     := 24;
3351   fFormat           := tfBGR8ub3;
3352   fWithAlpha        := tfBGRA8ub4;
3353   fWithoutAlpha     := tfBGR8ub3;
3354   fRGBInverted      := tfRGB8ub3;
3355   fPrecision        := glBitmapRec4ub( 8,  8,  8,  0);
3356   fShift            := glBitmapRec4ub(16,  8,  0,  0);
3357 {$IFNDEF OPENGL_ES}
3358   fOpenGLFormat     := tfBGR8ub3;
3359   fglFormat         := GL_BGR;
3360   fglInternalFormat := GL_RGB8;
3361   fglDataFormat     := GL_UNSIGNED_BYTE;
3362 {$ELSE}
3363   fOpenGLFormat     := tfRGB8ub3;
3364 {$ENDIF}
3365 end;
3366
3367 procedure TfdBGRX8ui1.SetValues;
3368 begin
3369   inherited SetValues;
3370   fBitsPerPixel     := 32;
3371   fFormat           := tfBGRX8ui1;
3372   fWithAlpha        := tfBGRA8ui1;
3373   fWithoutAlpha     := tfBGRX8ui1;
3374   fRGBInverted      := tfRGBX8ui1;
3375   fPrecision        := glBitmapRec4ub( 8,  8,  8,  0);
3376   fShift            := glBitmapRec4ub( 8, 16, 24,  0);
3377 {$IFNDEF OPENGL_ES}
3378   fOpenGLFormat     := tfBGRX8ui1;
3379   fglFormat         := GL_BGRA;  //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3380   fglInternalFormat := GL_RGB8;
3381   fglDataFormat     := GL_UNSIGNED_INT_8_8_8_8;
3382 {$ELSE}
3383   fOpenGLFormat     := tfRGB8ub3;
3384 {$ENDIF}
3385 end;
3386
3387 procedure TfdXBGR8ui1.SetValues;
3388 begin
3389   inherited SetValues;
3390   fBitsPerPixel     := 32;
3391   fFormat           := tfXBGR8ui1;
3392   fWithAlpha        := tfABGR8ui1;
3393   fWithoutAlpha     := tfXBGR8ui1;
3394   fRGBInverted      := tfXRGB8ui1;
3395   fPrecision        := glBitmapRec4ub( 8,  8,  8,  0);
3396   fShift            := glBitmapRec4ub( 0,  8, 16,  0);
3397 {$IFNDEF OPENGL_ES}
3398   fOpenGLFormat     := tfXBGR8ui1;
3399   fglFormat         := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3400   fglInternalFormat := GL_RGB8;
3401   fglDataFormat     := GL_UNSIGNED_INT_8_8_8_8_REV;
3402 {$ELSE}
3403   fOpenGLFormat     := tfRGB8ub3;
3404 {$ENDIF}
3405 end;
3406
3407 procedure TfdBGR10X2ui1.SetValues;
3408 begin
3409   inherited SetValues;
3410   fBitsPerPixel     := 32;
3411   fFormat           := tfBGR10X2ui1;
3412   fWithAlpha        := tfBGR10A2ui1;
3413   fWithoutAlpha     := tfBGR10X2ui1;
3414   fRGBInverted      := tfRGB10X2ui1;
3415   fPrecision        := glBitmapRec4ub(10, 10, 10,  0);
3416   fShift            := glBitmapRec4ub( 2, 12, 22,  0);
3417 {$IFNDEF OPENGL_ES}
3418   fOpenGLFormat     := tfBGR10X2ui1;
3419   fglFormat         := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3420   fglInternalFormat := GL_RGB10;
3421   fglDataFormat     := GL_UNSIGNED_INT_10_10_10_2;
3422 {$ELSE}
3423   fOpenGLFormat     := tfRGB16us3;
3424 {$ENDIF}
3425 end;
3426
3427 procedure TfdX2BGR10ui1.SetValues;
3428 begin
3429   inherited SetValues;
3430   fBitsPerPixel     := 32;
3431   fFormat           := tfX2BGR10ui1;
3432   fWithAlpha        := tfA2BGR10ui1;
3433   fWithoutAlpha     := tfX2BGR10ui1;
3434   fRGBInverted      := tfX2RGB10ui1;
3435   fPrecision        := glBitmapRec4ub(10, 10, 10,  0);
3436   fShift            := glBitmapRec4ub( 0, 10, 20,  0);
3437 {$IFNDEF OPENGL_ES}
3438   fOpenGLFormat     := tfX2BGR10ui1;
3439   fglFormat         := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3440   fglInternalFormat := GL_RGB10;
3441   fglDataFormat     := GL_UNSIGNED_INT_2_10_10_10_REV;
3442 {$ELSE}
3443   fOpenGLFormat     := tfRGB16us3;
3444 {$ENDIF}
3445 end;
3446
3447 procedure TfdBGR16us3.SetValues;
3448 begin
3449   inherited SetValues;
3450   fBitsPerPixel     := 48;
3451   fFormat           := tfBGR16us3;
3452   fWithAlpha        := tfBGRA16us4;
3453   fWithoutAlpha     := tfBGR16us3;
3454   fRGBInverted      := tfRGB16us3;
3455   fPrecision        := glBitmapRec4ub(16, 16, 16,  0);
3456   fShift            := glBitmapRec4ub(32, 16,  0,  0);
3457 {$IFNDEF OPENGL_ES}
3458   fOpenGLFormat     := tfBGR16us3;
3459   fglFormat         := GL_BGR;
3460   fglInternalFormat := GL_RGB16;
3461   fglDataFormat     := GL_UNSIGNED_SHORT;
3462 {$ELSE}
3463   fOpenGLFormat     := tfRGB16us3;
3464 {$ENDIF}
3465 end;
3466
3467 procedure TfdBGRA4us1.SetValues;
3468 begin
3469   inherited SetValues;
3470   fBitsPerPixel     := 16;
3471   fFormat           := tfBGRA4us1;
3472   fWithAlpha        := tfBGRA4us1;
3473   fWithoutAlpha     := tfBGRX4us1;
3474   fRGBInverted      := tfRGBA4us1;
3475   fPrecision        := glBitmapRec4ub( 4,  4,  4,  4);
3476   fShift            := glBitmapRec4ub( 4,  8, 12,  0);
3477 {$IFNDEF OPENGL_ES}
3478   fOpenGLFormat     := tfBGRA4us1;
3479   fglFormat         := GL_BGRA;
3480   fglInternalFormat := GL_RGBA4;
3481   fglDataFormat     := GL_UNSIGNED_SHORT_4_4_4_4;
3482 {$ELSE}
3483   fOpenGLFormat     := tfRGBA4us1;
3484 {$ENDIF}
3485 end;
3486
3487 procedure TfdABGR4us1.SetValues;
3488 begin
3489   inherited SetValues;
3490   fBitsPerPixel     := 16;
3491   fFormat           := tfABGR4us1;
3492   fWithAlpha        := tfABGR4us1;
3493   fWithoutAlpha     := tfXBGR4us1;
3494   fRGBInverted      := tfARGB4us1;
3495   fPrecision        := glBitmapRec4ub( 4,  4,  4,  4);
3496   fShift            := glBitmapRec4ub( 0,  4,  8, 12);
3497 {$IFNDEF OPENGL_ES}
3498   fOpenGLFormat     := tfABGR4us1;
3499   fglFormat         := GL_RGBA;
3500   fglInternalFormat := GL_RGBA4;
3501   fglDataFormat     := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3502 {$ELSE}
3503   fOpenGLFormat     := tfRGBA4us1;
3504 {$ENDIF}
3505 end;
3506
3507 procedure TfdBGR5A1us1.SetValues;
3508 begin
3509   inherited SetValues;
3510   fBitsPerPixel     := 16;
3511   fFormat           := tfBGR5A1us1;
3512   fWithAlpha        := tfBGR5A1us1;
3513   fWithoutAlpha     := tfBGR5X1us1;
3514   fRGBInverted      := tfRGB5A1us1;
3515   fPrecision        := glBitmapRec4ub( 5,  5,  5,  1);
3516   fShift            := glBitmapRec4ub( 1,  6, 11,  0);
3517 {$IFNDEF OPENGL_ES}
3518   fOpenGLFormat     := tfBGR5A1us1;
3519   fglFormat         := GL_BGRA;
3520   fglInternalFormat := GL_RGB5_A1;
3521   fglDataFormat     := GL_UNSIGNED_SHORT_5_5_5_1;
3522 {$ELSE}
3523   fOpenGLFormat     := tfRGB5A1us1;
3524 {$ENDIF}
3525 end;
3526
3527 procedure TfdA1BGR5us1.SetValues;
3528 begin
3529   inherited SetValues;
3530   fBitsPerPixel     := 16;
3531   fFormat           := tfA1BGR5us1;
3532   fWithAlpha        := tfA1BGR5us1;
3533   fWithoutAlpha     := tfX1BGR5us1;
3534   fRGBInverted      := tfA1RGB5us1;
3535   fPrecision        := glBitmapRec4ub( 5,  5,  5,  1);
3536   fShift            := glBitmapRec4ub( 0,  5, 10, 15);
3537 {$IFNDEF OPENGL_ES}
3538   fOpenGLFormat     := tfA1BGR5us1;
3539   fglFormat         := GL_RGBA;
3540   fglInternalFormat := GL_RGB5_A1;
3541   fglDataFormat     := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3542 {$ELSE}
3543   fOpenGLFormat     := tfRGB5A1us1;
3544 {$ENDIF}
3545 end;
3546
3547 procedure TfdBGRA8ui1.SetValues;
3548 begin
3549   inherited SetValues;
3550   fBitsPerPixel     := 32;
3551   fFormat           := tfBGRA8ui1;
3552   fWithAlpha        := tfBGRA8ui1;
3553   fWithoutAlpha     := tfBGRX8ui1;
3554   fRGBInverted      := tfRGBA8ui1;
3555   fPrecision        := glBitmapRec4ub( 8,  8,  8,  8);
3556   fShift            := glBitmapRec4ub( 8, 16, 24,  0);
3557 {$IFNDEF OPENGL_ES}
3558   fOpenGLFormat     := tfBGRA8ui1;
3559   fglFormat         := GL_BGRA;
3560   fglInternalFormat := GL_RGBA8;
3561   fglDataFormat     := GL_UNSIGNED_INT_8_8_8_8;
3562 {$ELSE}
3563   fOpenGLFormat     := tfRGBA8ub4;
3564 {$ENDIF}
3565 end;
3566
3567 procedure TfdABGR8ui1.SetValues;
3568 begin
3569   inherited SetValues;
3570   fBitsPerPixel     := 32;
3571   fFormat           := tfABGR8ui1;
3572   fWithAlpha        := tfABGR8ui1;
3573   fWithoutAlpha     := tfXBGR8ui1;
3574   fRGBInverted      := tfARGB8ui1;
3575   fPrecision        := glBitmapRec4ub( 8,  8,  8,  8);
3576   fShift            := glBitmapRec4ub( 0,  8, 16, 24);
3577 {$IFNDEF OPENGL_ES}
3578   fOpenGLFormat     := tfABGR8ui1;
3579   fglFormat         := GL_RGBA;
3580   fglInternalFormat := GL_RGBA8;
3581   fglDataFormat     := GL_UNSIGNED_INT_8_8_8_8_REV;
3582 {$ELSE}
3583   fOpenGLFormat     := tfRGBA8ub4
3584 {$ENDIF}
3585 end;
3586
3587 procedure TfdBGRA8ub4.SetValues;
3588 begin
3589   inherited SetValues;
3590   fBitsPerPixel     := 32;
3591   fFormat           := tfBGRA8ub4;
3592   fWithAlpha        := tfBGRA8ub4;
3593   fWithoutAlpha     := tfBGR8ub3;
3594   fRGBInverted      := tfRGBA8ub4;
3595   fPrecision        := glBitmapRec4ub( 8,  8,  8,  8);
3596   fShift            := glBitmapRec4ub(16,  8,  0, 24);
3597 {$IFNDEF OPENGL_ES}
3598   fOpenGLFormat     := tfBGRA8ub4;
3599   fglFormat         := GL_BGRA;
3600   fglInternalFormat := GL_RGBA8;
3601   fglDataFormat     := GL_UNSIGNED_BYTE;
3602 {$ELSE}
3603   fOpenGLFormat     := tfRGBA8ub4;
3604 {$ENDIF}
3605 end;
3606
3607 procedure TfdBGR10A2ui1.SetValues;
3608 begin
3609   inherited SetValues;
3610   fBitsPerPixel     := 32;
3611   fFormat           := tfBGR10A2ui1;
3612   fWithAlpha        := tfBGR10A2ui1;
3613   fWithoutAlpha     := tfBGR10X2ui1;
3614   fRGBInverted      := tfRGB10A2ui1;
3615   fPrecision        := glBitmapRec4ub(10, 10, 10,  2);
3616   fShift            := glBitmapRec4ub( 2, 12, 22,  0);
3617 {$IFNDEF OPENGL_ES}
3618   fOpenGLFormat     := tfBGR10A2ui1;
3619   fglFormat         := GL_BGRA;
3620   fglInternalFormat := GL_RGB10_A2;
3621   fglDataFormat     := GL_UNSIGNED_INT_10_10_10_2;
3622 {$ELSE}
3623   fOpenGLFormat     := tfA2RGB10ui1;
3624 {$ENDIF}
3625 end;
3626
3627 procedure TfdA2BGR10ui1.SetValues;
3628 begin
3629   inherited SetValues;
3630   fBitsPerPixel     := 32;
3631   fFormat           := tfA2BGR10ui1;
3632   fWithAlpha        := tfA2BGR10ui1;
3633   fWithoutAlpha     := tfX2BGR10ui1;
3634   fRGBInverted      := tfA2RGB10ui1;
3635   fPrecision        := glBitmapRec4ub(10, 10, 10,  2);
3636   fShift            := glBitmapRec4ub( 0, 10, 20, 30);
3637 {$IFNDEF OPENGL_ES}
3638   fOpenGLFormat     := tfA2BGR10ui1;
3639   fglFormat         := GL_RGBA;
3640   fglInternalFormat := GL_RGB10_A2;
3641   fglDataFormat     := GL_UNSIGNED_INT_2_10_10_10_REV;
3642 {$ELSE}
3643   fOpenGLFormat     := tfA2RGB10ui1;
3644 {$ENDIF}
3645 end;
3646
3647 procedure TfdBGRA16us4.SetValues;
3648 begin
3649   inherited SetValues;
3650   fBitsPerPixel     := 64;
3651   fFormat           := tfBGRA16us4;
3652   fWithAlpha        := tfBGRA16us4;
3653   fWithoutAlpha     := tfBGR16us3;
3654   fRGBInverted      := tfRGBA16us4;
3655   fPrecision        := glBitmapRec4ub(16, 16, 16, 16);
3656   fShift            := glBitmapRec4ub(32, 16,  0, 48);
3657 {$IFNDEF OPENGL_ES}
3658   fOpenGLFormat     := tfBGRA16us4;
3659   fglFormat         := GL_BGRA;
3660   fglInternalFormat := GL_RGBA16;
3661   fglDataFormat     := GL_UNSIGNED_SHORT;
3662 {$ELSE}
3663   fOpenGLFormat     := tfRGBA16us4;
3664 {$ENDIF}
3665 end;
3666
3667 procedure TfdDepth16us1.SetValues;
3668 begin
3669   inherited SetValues;
3670   fBitsPerPixel     := 16;
3671   fFormat           := tfDepth16us1;
3672   fWithoutAlpha     := tfDepth16us1;
3673   fPrecision        := glBitmapRec4ub(16, 16, 16, 16);
3674   fShift            := glBitmapRec4ub( 0,  0,  0,  0);
3675 {$IF NOT DEFINED (OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
3676   fOpenGLFormat     := tfDepth16us1;
3677   fglFormat         := GL_DEPTH_COMPONENT;
3678   fglInternalFormat := GL_DEPTH_COMPONENT16;
3679   fglDataFormat     := GL_UNSIGNED_SHORT;
3680 {$IFEND}
3681 end;
3682
3683 procedure TfdDepth24ui1.SetValues;
3684 begin
3685   inherited SetValues;
3686   fBitsPerPixel     := 32;
3687   fFormat           := tfDepth24ui1;
3688   fWithoutAlpha     := tfDepth24ui1;
3689   fOpenGLFormat     := tfDepth24ui1;
3690   fPrecision        := glBitmapRec4ub(32, 32, 32, 32);
3691   fShift            := glBitmapRec4ub( 0,  0,  0,  0);
3692 {$IF NOT DEFINED (OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
3693   fOpenGLFormat     := tfDepth24ui1;
3694   fglFormat         := GL_DEPTH_COMPONENT;
3695   fglInternalFormat := GL_DEPTH_COMPONENT24;
3696   fglDataFormat     := GL_UNSIGNED_INT;
3697 {$IFEND}
3698 end;
3699
3700 procedure TfdDepth32ui1.SetValues;
3701 begin
3702   inherited SetValues;
3703   fBitsPerPixel     := 32;
3704   fFormat           := tfDepth32ui1;
3705   fWithoutAlpha     := tfDepth32ui1;
3706   fPrecision        := glBitmapRec4ub(32, 32, 32, 32);
3707   fShift            := glBitmapRec4ub( 0,  0,  0,  0);
3708 {$IF NOT DEFINED(OPENGL_ES)}
3709   fOpenGLFormat     := tfDepth32ui1;
3710   fglFormat         := GL_DEPTH_COMPONENT;
3711   fglInternalFormat := GL_DEPTH_COMPONENT32;
3712   fglDataFormat     := GL_UNSIGNED_INT;
3713 {$ELSEIF DEFINED(OPENGL_ES_3_0)}
3714   fOpenGLFormat     := tfDepth24ui1;
3715 {$ELSEIF DEFINED(OPENGL_ES_2_0)}
3716   fOpenGLFormat     := tfDepth16us1;
3717 {$IFEND}
3718 end;
3719
3720 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3721 //TfdS3tcDtx1RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3722 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3723 procedure TfdS3tcDtx1RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3724 begin
3725   raise EglBitmap.Create('mapping for compressed formats is not supported');
3726 end;
3727
3728 procedure TfdS3tcDtx1RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3729 begin
3730   raise EglBitmap.Create('mapping for compressed formats is not supported');
3731 end;
3732
3733 procedure TfdS3tcDtx1RGBA.SetValues;
3734 begin
3735   inherited SetValues;
3736   fFormat           := tfS3tcDtx1RGBA;
3737   fWithAlpha        := tfS3tcDtx1RGBA;
3738   fUncompressed     := tfRGB5A1us1;
3739   fBitsPerPixel     := 4;
3740   fIsCompressed     := true;
3741 {$IFNDEF OPENGL_ES}
3742   fOpenGLFormat     := tfS3tcDtx1RGBA;
3743   fglFormat         := GL_COMPRESSED_RGBA;
3744   fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
3745   fglDataFormat     := GL_UNSIGNED_BYTE;
3746 {$ELSE}
3747   fOpenGLFormat     := fUncompressed;
3748 {$ENDIF}
3749 end;
3750
3751 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3752 //TfdS3tcDtx3RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3753 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3754 procedure TfdS3tcDtx3RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3755 begin
3756   raise EglBitmap.Create('mapping for compressed formats is not supported');
3757 end;
3758
3759 procedure TfdS3tcDtx3RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3760 begin
3761   raise EglBitmap.Create('mapping for compressed formats is not supported');
3762 end;
3763
3764 procedure TfdS3tcDtx3RGBA.SetValues;
3765 begin
3766   inherited SetValues;
3767   fFormat           := tfS3tcDtx3RGBA;
3768   fWithAlpha        := tfS3tcDtx3RGBA;
3769   fUncompressed     := tfRGBA8ub4;
3770   fBitsPerPixel     := 8;
3771   fIsCompressed     := true;
3772 {$IFNDEF OPENGL_ES}
3773   fOpenGLFormat     := tfS3tcDtx3RGBA;
3774   fglFormat         := GL_COMPRESSED_RGBA;
3775   fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
3776   fglDataFormat     := GL_UNSIGNED_BYTE;
3777 {$ELSE}
3778   fOpenGLFormat     := fUncompressed;
3779 {$ENDIF}
3780 end;
3781
3782 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3783 //TfdS3tcDtx5RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3784 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3785 procedure TfdS3tcDtx5RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3786 begin
3787   raise EglBitmap.Create('mapping for compressed formats is not supported');
3788 end;
3789
3790 procedure TfdS3tcDtx5RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3791 begin
3792   raise EglBitmap.Create('mapping for compressed formats is not supported');
3793 end;
3794
3795 procedure TfdS3tcDtx5RGBA.SetValues;
3796 begin
3797   inherited SetValues;
3798   fFormat           := tfS3tcDtx3RGBA;
3799   fWithAlpha        := tfS3tcDtx3RGBA;
3800   fUncompressed     := tfRGBA8ub4;
3801   fBitsPerPixel     := 8;
3802   fIsCompressed     := true;
3803 {$IFNDEF OPENGL_ES}
3804   fOpenGLFormat     := tfS3tcDtx3RGBA;
3805   fglFormat         := GL_COMPRESSED_RGBA;
3806   fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
3807   fglDataFormat     := GL_UNSIGNED_BYTE;
3808 {$ELSE}
3809   fOpenGLFormat     := fUncompressed;
3810 {$ENDIF}
3811 end;
3812
3813 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3814 //TglBitmapFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3815 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3816 function TglBitmapFormatDescriptor.GetHasRed: Boolean;
3817 begin
3818   result := (fPrecision.r > 0);
3819 end;
3820
3821 function TglBitmapFormatDescriptor.GetHasGreen: Boolean;
3822 begin
3823   result := (fPrecision.g > 0);
3824 end;
3825
3826 function TglBitmapFormatDescriptor.GetHasBlue: Boolean;
3827 begin
3828   result := (fPrecision.b > 0);
3829 end;
3830
3831 function TglBitmapFormatDescriptor.GetHasAlpha: Boolean;
3832 begin