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