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