* fixed some format issues
[glBitmap.git] / glBitmap.pas
1 {***********************************************************
2 glBitmap by Steffen Xonna aka Lossy eX (2003-2008)
3 http://www.opengl24.de/index.php?cat=header&file=glbitmap
4
5 modified by Delphi OpenGL Community (http://delphigl.com/) (2013)
6
7 ------------------------------------------------------------
8 The contents of this file are used with permission, subject to
9 the Mozilla Public License Version 1.1 (the "License"); you may
10 not use this file except in compliance with the License. You may
11 obtain a copy of the License at
12 http://www.mozilla.org/MPL/MPL-1.1.html
13 ------------------------------------------------------------
14 Version 3.0.1
15 ------------------------------------------------------------
16 History
17 20-11-2013
18 - refactoring of the complete library
19 21-03-2010
20 - The define GLB_DELPHI dosn't check versions anymore. If you say you are using delphi
21   then it's your problem if that isn't true. This prevents the unit for incompatibility
22   with newer versions of Delphi.
23 - Problems with D2009+ resolved (Thanks noeska and all i forgot)
24 - GetPixel isn't set if you are loading textures inside the constructor (Thanks Wilson)
25 10-08-2008
26 - AddAlphaFromglBitmap used the custom pointer instead the imagedatapointer (Thanks Wilson)
27 - Additional Datapointer for functioninterface now has the name CustomData
28 24-07-2008
29 - AssigneAlphaToBitmap overwrites his own palette (Thanks Wilson)
30 - If you load an texture from an file the property Filename will be set to the name of the file
31 - Three new properties to attach custom data to the Texture objects
32   - CustomName  (free for use string)
33   - CustomNameW (free for use widestring)
34   - CustomDataPointer (free for use pointer to attach other objects or complex structures)
35 27-05-2008
36 - RLE TGAs loaded much faster
37 26-05-2008
38 - fixed some problem with reading RLE TGAs.
39 21-05-2008
40 - function clone now only copys data if it's assigned and now it also copies the ID
41 - it seems that lazarus dont like comments in comments.
42 01-05-2008
43 - It's possible to set the id of the texture
44 - define GLB_NO_NATIVE_GL deactivated by default
45 27-04-2008
46 - Now supports the following libraries
47   - SDL and SDL_image
48   - libPNG
49   - libJPEG
50 - Linux compatibillity via free pascal compatibility (delphi sources optional)
51 - BMPs now loaded manuel
52 - Large restructuring
53 - Property DataPtr now has the name Data
54 - Functions are more flexible between RGB(A) and BGR(A). RGB can be saved as Bitmap and will be saved as BGR
55 - Unused Depth removed
56 - Function FreeData to freeing image data added
57 24-10-2007
58 - ImageID flag of TGAs was ignored. (Thanks Zwoetzen)
59 15-11-2006
60 - Function SetBorderColor implemented (only used by opengl if wrap is set to GL_CLAMP_TO_BORDER)
61 - Function AddAlphaFromValue implemented to use an fixed Value as Alphachannel
62 - Function ReadOpenGLExtension is now only intern
63 29-06-2006
64 - pngimage now disabled by default like all other versions.
65 26-06-2006
66 - Setting up an anisotropic filter of 0 isnt allowed by nvidia (Thanks Ogridi)
67 22-06-2006
68 - Fixed some Problem with Delphi 5
69 - Now uses the newest version of pngimage. Makes saving pngs much easier.
70 22-03-2006
71 - Property IsCompressed and Size removed. Not really supported by Spec (Thanks Ogridi)
72 09-03-2006
73 - Internal Format ifDepth8 added
74 - function GrabScreen now supports all uncompressed formats
75 31-01-2006
76 - AddAlphaFromglBitmap implemented
77 29-12-2005
78 - LoadFromResource and LoadFromResourceId now needs an Instance and an ResourceType (for ID)
79 28-12-2005
80 - Width, Height and Depth internal changed to TglBitmapPixelPosition.
81   property Width, Height, Depth are still existing and new property Dimension are avail
82 11-12-2005
83 - Added native OpenGL Support. Breaking the dglOpenGL "barrier".
84 19-10-2005
85 - Added function GrabScreen to class TglBitmap2D
86 18-10-2005
87 - Added support to Save images
88 - Added function Clone to Clone Instance
89 11-10-2005
90 - Functions now works with Cardinals for each channel. Up to 32 Bits per channel.
91   Usefull for Future
92 - Several speed optimizations
93 09-10-2005
94 - Internal structure change. Loading of TGA, PNG and DDS improved.
95   Data, format and size will now set directly with SetDataPtr.
96 - AddFunc now works with all Types of Images and Formats
97 - Some Funtions moved to Baseclass TglBitmap
98 06-10-2005
99 - Added Support to decompress DXT3 and DXT5 compressed Images.
100 - Added Mapping to convert data from one format into an other.
101 05-10-2005
102 - Added method ConvertTo in Class TglBitmap2D. Method allows to convert every
103   supported Input format (supported by GetPixel) into any uncompresed Format
104 - Added Support to decompress DXT1 compressed Images.
105 - SwapColors replaced by ConvertTo
106 04-10-2005
107 - Added Support for compressed DDSs
108 - Added new internal formats (DXT1, DXT3, DXT5)
109 29-09-2005
110 - Parameter Components renamed to InternalFormat
111 23-09-2005
112 - Some AllocMem replaced with GetMem (little speed change)
113 - better exception handling. Better protection from memory leaks.
114 22-09-2005
115 - Added support for Direct Draw Surfaces (.DDS) (uncompressed images only)
116 - Added new internal formats (RGB8, RGBA8, RGBA4, RGB5A1, RGB10A2, R5G6B5)
117 07-09-2005
118 - Added support for Grayscale textures
119 - Added internal formats (Alpha, Luminance, LuminanceAlpha, BGR8, BGRA8)
120 10-07-2005
121 - Added support for GL_VERSION_2_0
122 - Added support for GL_EXT_texture_filter_anisotropic
123 04-07-2005
124 - Function FillWithColor fills the Image with one Color
125 - Function LoadNormalMap added
126 30-06-2005
127 - ToNormalMap allows to Create an NormalMap from the Alphachannel
128 - ToNormalMap now supports Sobel (nmSobel) function.
129 29-06-2005
130 - support for RLE Compressed RGB TGAs added
131 28-06-2005
132 - Class TglBitmapNormalMap added to support Normalmap generation
133 - Added function ToNormalMap in class TglBitmap2D to genereate normal maps from textures.
134   3 Filters are supported. (4 Samples, 3x3 and 5x5)
135 16-06-2005
136 - Method LoadCubeMapClass removed
137 - LoadCubeMap returnvalue is now the Texture paramter. Such as LoadTextures
138 - virtual abstract method GenTexture in class TglBitmap now is protected
139 12-06-2005
140 - now support DescriptionFlag in LoadTga. Allows vertical flipped images to be loaded as normal
141 10-06-2005
142 - little enhancement for IsPowerOfTwo
143 - TglBitmap1D.GenTexture now tests NPOT Textures
144 06-06-2005
145 - some little name changes. All properties or function with Texture in name are
146   now without texture in name. We have allways texture so we dosn't name it.
147 03-06-2005
148 - GenTexture now tests if texture is NPOT and NPOT-Texture are supported or
149   TextureTarget is GL_TEXTURE_RECTANGLE. Else it raised an exception.
150 02-06-2005
151 - added support for GL_ARB_texture_rectangle, GL_EXT_texture_rectangle and GL_NV_texture_rectangle
152 25-04-2005
153 - Function Unbind added
154 - call of SetFilter or SetTextureWrap if TextureID exists results in setting properties to opengl texture.
155 21-04-2005
156 - class TglBitmapCubeMap added (allows to Create Cubemaps)
157 29-03-2005
158 - Added Support for PNG Images. (http://pngdelphi.sourceforge.net/)
159   To Enable png's use the define pngimage
160 22-03-2005
161 - New Functioninterface added
162 - Function GetPixel added
163 27-11-2004
164 - Property BuildMipMaps renamed to MipMap
165 21-11-2004
166 - property Name removed.
167 - BuildMipMaps is now a set of 3 values. None, GluBuildMipmaps and SGIS_generate_mipmap
168 22-05-2004
169 - property name added. Only used in glForms!
170 26-11-2003
171 - property FreeDataAfterGenTexture is now available as default (default = true)
172 - BuildMipmaps now implemented in TglBitmap1D (i've forgotten it)
173 - function MoveMemory replaced with function Move (little speed change)
174 - several calculations stored in variables (little speed change)
175 29-09-2003
176 - property BuildMipsMaps added (default = true)
177   if BuildMipMaps isn't set GenTextures uses glTexImage[12]D else it use gluBuild[12]dMipmaps
178 - property FreeDataAfterGenTexture added (default = true)
179   if FreeDataAfterGenTexture is set the texturedata were deleted after the texture was generated.
180 - parameter DisableOtherTextureUnits of Bind removed
181 - parameter FreeDataAfterGeneration of GenTextures removed
182 12-09-2003
183 - TglBitmap dosn't delete data if class was destroyed (fixed)
184 09-09-2003
185 - Bind now enables TextureUnits (by params)
186 - GenTextures can leave data (by param)
187 - LoadTextures now optimal
188 03-09-2003
189 - Performance optimization in AddFunc
190 - procedure Bind moved to subclasses
191 - Added new Class TglBitmap1D to support real OpenGL 1D Textures
192 19-08-2003
193 - Texturefilter and texturewrap now also as defaults
194   Minfilter = GL_LINEAR_MIPMAP_LINEAR
195   Magfilter = GL_LINEAR
196   Wrap(str) = GL_CLAMP_TO_EDGE
197 - Added new format tfCompressed to create a compressed texture.
198 - propertys IsCompressed, TextureSize and IsResident added
199   IsCompressed and TextureSize only contains data from level 0
200 18-08-2003
201 - Added function AddFunc to add PerPixelEffects to Image
202 - LoadFromFunc now based on AddFunc
203 - Invert now based on AddFunc
204 - SwapColors now based on AddFunc
205 16-08-2003
206 - Added function FlipHorz
207 15-08-2003
208 - Added function LaodFromFunc to create images with function
209 - Added function FlipVert
210 - Added internal format RGB(A) if GL_EXT_bgra or OpenGL 1.2 isn't supported
211 29-07-2003
212 - Added Alphafunctions to calculate alpha per function
213 - Added Alpha from ColorKey using alphafunctions
214 28-07-2003
215 - First full functionally Version of glBitmap
216 - Support for 24Bit and 32Bit TGA Pictures added
217 25-07-2003
218 - begin of programming
219 ***********************************************************}
220 unit glBitmap;
221
222 // Please uncomment the defines below to configure the glBitmap to your preferences.
223 // If you have configured the unit you can uncomment the warning above.
224 {$MESSAGE error 'Hey. I''m the glBitmap.pas and i need to be configured. My master tell me your preferences! ;)'}
225
226 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
227 // Preferences ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
228 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
229 // activate to enable build-in OpenGL support with statically linked methods
230 // use dglOpenGL.pas if not enabled
231 {.$DEFINE GLB_NATIVE_OGL_STATIC}
232
233 // activate to enable build-in OpenGL support with dynamically linked methods
234 // use dglOpenGL.pas if not enabled
235 {.$DEFINE GLB_NATIVE_OGL_DYNAMIC}
236
237
238 // activate to enable the support for SDL_surfaces
239 {.$DEFINE GLB_SDL}
240
241 // activate  to enable the support for Delphi (including support for Delphi's (not Lazarus') TBitmap)
242 {.$DEFINE GLB_DELPHI}
243
244 // activate to enable the support for TLazIntfImage from Lazarus
245 {.$DEFINE GLB_LAZARUS}
246
247
248
249 // activate to enable the support of SDL_image to load files. (READ ONLY)
250 // If you enable SDL_image all other libraries will be ignored!
251 {.$DEFINE GLB_SDL_IMAGE}
252
253
254
255 // activate to enable Lazarus TPortableNetworkGraphic support
256 // if you enable this pngImage and libPNG will be ignored
257 {.$DEFINE GLB_LAZ_PNG}
258
259 // activate to enable png support with the unit pngimage -> http://pngdelphi.sourceforge.net/
260 // if you enable pngimage the libPNG will be ignored
261 {.$DEFINE GLB_PNGIMAGE}
262
263 // activate to use the libPNG -> http://www.libpng.org/
264 // You will need an aditional header -> http://www.opengl24.de/index.php?cat=header&file=libpng
265 {.$DEFINE GLB_LIB_PNG}
266
267
268
269 // activate to enable Lazarus TJPEGImage support
270 // if you enable this delphi jpegs and libJPEG will be ignored
271 {.$DEFINE GLB_LAZ_JPEG}
272
273 // if you enable delphi jpegs the libJPEG will be ignored
274 {.$DEFINE GLB_DELPHI_JPEG}
275
276 // activate to use the libJPEG -> http://www.ijg.org/
277 // You will need an aditional header -> http://www.opengl24.de/index.php?cat=header&file=libjpeg
278 {.$DEFINE GLB_LIB_JPEG}
279
280
281 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
282 // PRIVATE: do not change anything! //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
283 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
284 // Delphi Versions
285 {$IFDEF fpc}
286   {$MODE Delphi}
287
288   {$IFDEF CPUI386}
289     {$DEFINE CPU386}
290     {$ASMMODE INTEL}
291   {$ENDIF}
292
293   {$IFNDEF WINDOWS}
294     {$linklib c}
295   {$ENDIF}
296 {$ENDIF}
297
298 // Operation System
299 {$IF DEFINED(WIN32) or DEFINED(WIN64) or DEFINED(WINDOWS)}
300   {$DEFINE GLB_WIN}
301 {$ELSEIF DEFINED(LINUX)}
302   {$DEFINE GLB_LINUX}
303 {$IFEND}
304
305 // native OpenGL Support
306 {$IF DEFINED(GLB_NATIVE_OGL_STATIC) OR DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
307   {$DEFINE GLB_NATIVE_OGL}
308 {$IFEND}
309
310 // checking define combinations
311 //SDL Image
312 {$IFDEF GLB_SDL_IMAGE}
313   {$IFNDEF GLB_SDL}
314     {$MESSAGE warn 'SDL_image won''t work without SDL. SDL will be activated.'}
315     {$DEFINE GLB_SDL}
316   {$ENDIF}
317
318   {$IFDEF GLB_LAZ_PNG}
319     {$MESSAGE warn 'The Lazarus TPortableNetworkGraphics will be ignored because you are using SDL_image.'}
320     {$undef GLB_LAZ_PNG}
321   {$ENDIF}
322
323   {$IFDEF GLB_PNGIMAGE}
324     {$MESSAGE warn 'The unit pngimage will be ignored because you are using SDL_image.'}
325     {$undef GLB_PNGIMAGE}
326   {$ENDIF}
327
328   {$IFDEF GLB_LAZ_JPEG}
329     {$MESSAGE warn 'The Lazarus TJPEGImage will be ignored because you are using SDL_image.'}
330     {$undef GLB_LAZ_JPEG}
331   {$ENDIF}
332
333   {$IFDEF GLB_DELPHI_JPEG}
334     {$MESSAGE warn 'The unit JPEG will be ignored because you are using SDL_image.'}
335     {$undef GLB_DELPHI_JPEG}
336   {$ENDIF}
337
338   {$IFDEF GLB_LIB_PNG}
339     {$MESSAGE warn 'The library libPNG will be ignored because you are using SDL_image.'}
340     {$undef GLB_LIB_PNG}
341   {$ENDIF}
342
343   {$IFDEF GLB_LIB_JPEG}
344     {$MESSAGE warn 'The library libJPEG will be ignored because you are using SDL_image.'}
345     {$undef GLB_LIB_JPEG}
346   {$ENDIF}
347
348   {$DEFINE GLB_SUPPORT_PNG_READ}
349   {$DEFINE GLB_SUPPORT_JPEG_READ}
350 {$ENDIF}
351
352 // Lazarus TPortableNetworkGraphic
353 {$IFDEF GLB_LAZ_PNG}
354   {$IFNDEF GLB_LAZARUS}
355     {$MESSAGE warn 'Lazarus TPortableNetworkGraphic won''t work without Lazarus. Lazarus will be activated.'}
356     {$DEFINE GLB_LAZARUS}
357   {$ENDIF}
358
359   {$IFDEF GLB_PNGIMAGE}
360     {$MESSAGE warn 'The pngimage will be ignored if you are using Lazarus TPortableNetworkGraphic.'}
361     {$undef GLB_PNGIMAGE}
362   {$ENDIF}
363
364   {$IFDEF GLB_LIB_PNG}
365     {$MESSAGE warn 'The library libPNG will be ignored if you are using Lazarus TPortableNetworkGraphic.'}
366     {$undef GLB_LIB_PNG}
367   {$ENDIF}
368
369   {$DEFINE GLB_SUPPORT_PNG_READ}
370   {$DEFINE GLB_SUPPORT_PNG_WRITE}
371 {$ENDIF}
372
373 // PNG Image
374 {$IFDEF GLB_PNGIMAGE}
375   {$IFDEF GLB_LIB_PNG}
376     {$MESSAGE warn 'The library libPNG will be ignored if you are using pngimage.'}
377     {$undef GLB_LIB_PNG}
378   {$ENDIF}
379
380   {$DEFINE GLB_SUPPORT_PNG_READ}
381   {$DEFINE GLB_SUPPORT_PNG_WRITE}
382 {$ENDIF}
383
384 // libPNG
385 {$IFDEF GLB_LIB_PNG}
386   {$DEFINE GLB_SUPPORT_PNG_READ}
387   {$DEFINE GLB_SUPPORT_PNG_WRITE}
388 {$ENDIF}
389
390 // Lazarus TJPEGImage
391 {$IFDEF GLB_LAZ_JPEG}
392   {$IFNDEF GLB_LAZARUS}
393     {$MESSAGE warn 'Lazarus TJPEGImage won''t work without Lazarus. Lazarus will be activated.'}
394     {$DEFINE GLB_LAZARUS}
395   {$ENDIF}
396
397   {$IFDEF GLB_DELPHI_JPEG}
398     {$MESSAGE warn 'The Delphi JPEGImage will be ignored if you are using the Lazarus TJPEGImage.'}
399     {$undef GLB_DELPHI_JPEG}
400   {$ENDIF}
401
402   {$IFDEF GLB_LIB_JPEG}
403     {$MESSAGE warn 'The library libJPEG will be ignored if you are using the Lazarus TJPEGImage.'}
404     {$undef GLB_LIB_JPEG}
405   {$ENDIF}
406
407   {$DEFINE GLB_SUPPORT_JPEG_READ}
408   {$DEFINE GLB_SUPPORT_JPEG_WRITE}
409 {$ENDIF}
410
411 // JPEG Image
412 {$IFDEF GLB_DELPHI_JPEG}
413   {$IFDEF GLB_LIB_JPEG}
414     {$MESSAGE warn 'The library libJPEG will be ignored if you are using the unit JPEG.'}
415     {$undef GLB_LIB_JPEG}
416   {$ENDIF}
417
418   {$DEFINE GLB_SUPPORT_JPEG_READ}
419   {$DEFINE GLB_SUPPORT_JPEG_WRITE}
420 {$ENDIF}
421
422 // libJPEG
423 {$IFDEF GLB_LIB_JPEG}
424   {$DEFINE GLB_SUPPORT_JPEG_READ}
425   {$DEFINE GLB_SUPPORT_JPEG_WRITE}
426 {$ENDIF}
427
428 // native OpenGL
429 {$IF DEFINED(GLB_NATIVE_OGL_STATIC) AND DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
430   {$MESSAGE warn 'GLB_NATIVE_OGL_STATIC will be ignored because you enabled GLB_NATIVE_OGL_DYNAMIC'}
431 {$IFEND}
432
433 // general options
434 {$EXTENDEDSYNTAX ON}
435 {$LONGSTRINGS ON}
436 {$ALIGN ON}
437 {$IFNDEF FPC}
438   {$OPTIMIZATION ON}
439 {$ENDIF}
440
441 interface
442
443 uses
444   {$IFNDEF GLB_NATIVE_OGL}      dglOpenGL,                          {$ENDIF}
445   {$IF DEFINED(GLB_WIN) AND
446        (DEFINED(GLB_NATIVE_OGL) OR
447         DEFINED(GLB_DELPHI))}   windows,                            {$IFEND}
448
449   {$IFDEF GLB_SDL}              SDL,                                {$ENDIF}
450   {$IFDEF GLB_LAZARUS}          IntfGraphics, GraphType, Graphics,  {$ENDIF}
451   {$IFDEF GLB_DELPHI}           Dialogs, Graphics, Types,           {$ENDIF}
452
453   {$IFDEF GLB_SDL_IMAGE}        SDL_image,                          {$ENDIF}
454   {$IFDEF GLB_PNGIMAGE}         pngimage,                           {$ENDIF}
455   {$IFDEF GLB_LIB_PNG}          libPNG,                             {$ENDIF}
456   {$IFDEF GLB_DELPHI_JPEG}      JPEG,                               {$ENDIF}
457   {$IFDEF GLB_LIB_JPEG}         libJPEG,                            {$ENDIF}
458
459   Classes, SysUtils;
460
461 {$IFDEF GLB_NATIVE_OGL}
462 const
463   GL_TRUE   = 1;
464   GL_FALSE  = 0;
465
466   GL_ZERO = 0;
467   GL_ONE  = 1;
468
469   GL_VERSION    = $1F02;
470   GL_EXTENSIONS = $1F03;
471
472   GL_TEXTURE_1D         = $0DE0;
473   GL_TEXTURE_2D         = $0DE1;
474   GL_TEXTURE_RECTANGLE  = $84F5;
475
476   GL_NORMAL_MAP                   = $8511;
477   GL_TEXTURE_CUBE_MAP             = $8513;
478   GL_REFLECTION_MAP               = $8512;
479   GL_TEXTURE_CUBE_MAP_POSITIVE_X  = $8515;
480   GL_TEXTURE_CUBE_MAP_NEGATIVE_X  = $8516;
481   GL_TEXTURE_CUBE_MAP_POSITIVE_Y  = $8517;
482   GL_TEXTURE_CUBE_MAP_NEGATIVE_Y  = $8518;
483   GL_TEXTURE_CUBE_MAP_POSITIVE_Z  = $8519;
484   GL_TEXTURE_CUBE_MAP_NEGATIVE_Z  = $851A;
485
486   GL_TEXTURE_WIDTH            = $1000;
487   GL_TEXTURE_HEIGHT           = $1001;
488   GL_TEXTURE_INTERNAL_FORMAT  = $1003;
489   GL_TEXTURE_SWIZZLE_RGBA     = $8E46;
490
491   GL_S = $2000;
492   GL_T = $2001;
493   GL_R = $2002;
494   GL_Q = $2003;
495
496   GL_TEXTURE_GEN_S = $0C60;
497   GL_TEXTURE_GEN_T = $0C61;
498   GL_TEXTURE_GEN_R = $0C62;
499   GL_TEXTURE_GEN_Q = $0C63;
500
501   GL_RED    = $1903;
502   GL_GREEN  = $1904;
503   GL_BLUE   = $1905;
504
505   GL_ALPHA    = $1906;
506   GL_ALPHA4   = $803B;
507   GL_ALPHA8   = $803C;
508   GL_ALPHA12  = $803D;
509   GL_ALPHA16  = $803E;
510
511   GL_LUMINANCE    = $1909;
512   GL_LUMINANCE4   = $803F;
513   GL_LUMINANCE8   = $8040;
514   GL_LUMINANCE12  = $8041;
515   GL_LUMINANCE16  = $8042;
516
517   GL_LUMINANCE_ALPHA      = $190A;
518   GL_LUMINANCE4_ALPHA4    = $8043;
519   GL_LUMINANCE6_ALPHA2    = $8044;
520   GL_LUMINANCE8_ALPHA8    = $8045;
521   GL_LUMINANCE12_ALPHA4   = $8046;
522   GL_LUMINANCE12_ALPHA12  = $8047;
523   GL_LUMINANCE16_ALPHA16  = $8048;
524
525   GL_RGB      = $1907;
526   GL_BGR      = $80E0;
527   GL_R3_G3_B2 = $2A10;
528   GL_RGB4     = $804F;
529   GL_RGB5     = $8050;
530   GL_RGB565   = $8D62;
531   GL_RGB8     = $8051;
532   GL_RGB10    = $8052;
533   GL_RGB12    = $8053;
534   GL_RGB16    = $8054;
535
536   GL_RGBA     = $1908;
537   GL_BGRA     = $80E1;
538   GL_RGBA2    = $8055;
539   GL_RGBA4    = $8056;
540   GL_RGB5_A1  = $8057;
541   GL_RGBA8    = $8058;
542   GL_RGB10_A2 = $8059;
543   GL_RGBA12   = $805A;
544   GL_RGBA16   = $805B;
545
546   GL_DEPTH_COMPONENT    = $1902;
547   GL_DEPTH_COMPONENT16  = $81A5;
548   GL_DEPTH_COMPONENT24  = $81A6;
549   GL_DEPTH_COMPONENT32  = $81A7;
550
551   GL_COMPRESSED_RGB                 = $84ED;
552   GL_COMPRESSED_RGBA                = $84EE;
553   GL_COMPRESSED_RGB_S3TC_DXT1_EXT   = $83F0;
554   GL_COMPRESSED_RGBA_S3TC_DXT1_EXT  = $83F1;
555   GL_COMPRESSED_RGBA_S3TC_DXT3_EXT  = $83F2;
556   GL_COMPRESSED_RGBA_S3TC_DXT5_EXT  = $83F3;
557
558   GL_UNSIGNED_BYTE            = $1401;
559   GL_UNSIGNED_BYTE_3_3_2      = $8032;
560   GL_UNSIGNED_BYTE_2_3_3_REV  = $8362;
561
562   GL_UNSIGNED_SHORT             = $1403;
563   GL_UNSIGNED_SHORT_5_6_5       = $8363;
564   GL_UNSIGNED_SHORT_4_4_4_4     = $8033;
565   GL_UNSIGNED_SHORT_5_5_5_1     = $8034;
566   GL_UNSIGNED_SHORT_5_6_5_REV   = $8364;
567   GL_UNSIGNED_SHORT_4_4_4_4_REV = $8365;
568   GL_UNSIGNED_SHORT_1_5_5_5_REV = $8366;
569
570   GL_UNSIGNED_INT                 = $1405;
571   GL_UNSIGNED_INT_8_8_8_8         = $8035;
572   GL_UNSIGNED_INT_10_10_10_2      = $8036;
573   GL_UNSIGNED_INT_8_8_8_8_REV     = $8367;
574   GL_UNSIGNED_INT_2_10_10_10_REV  = $8368;
575
576   { Texture Filter }
577   GL_TEXTURE_MAG_FILTER     = $2800;
578   GL_TEXTURE_MIN_FILTER     = $2801;
579   GL_NEAREST                = $2600;
580   GL_NEAREST_MIPMAP_NEAREST = $2700;
581   GL_NEAREST_MIPMAP_LINEAR  = $2702;
582   GL_LINEAR                 = $2601;
583   GL_LINEAR_MIPMAP_NEAREST  = $2701;
584   GL_LINEAR_MIPMAP_LINEAR   = $2703;
585
586   { Texture Wrap }
587   GL_TEXTURE_WRAP_S   = $2802;
588   GL_TEXTURE_WRAP_T   = $2803;
589   GL_TEXTURE_WRAP_R   = $8072;
590   GL_CLAMP            = $2900;
591   GL_REPEAT           = $2901;
592   GL_CLAMP_TO_EDGE    = $812F;
593   GL_CLAMP_TO_BORDER  = $812D;
594   GL_MIRRORED_REPEAT  = $8370;
595
596   { Other }
597   GL_GENERATE_MIPMAP      = $8191;
598   GL_TEXTURE_BORDER_COLOR = $1004;
599   GL_MAX_TEXTURE_SIZE     = $0D33;
600   GL_PACK_ALIGNMENT       = $0D05;
601   GL_UNPACK_ALIGNMENT     = $0CF5;
602
603   GL_TEXTURE_MAX_ANISOTROPY_EXT     = $84FE;
604   GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = $84FF;
605   GL_MAX_CUBE_MAP_TEXTURE_SIZE      = $851C;
606   GL_TEXTURE_GEN_MODE               = $2500;
607
608 {$IF DEFINED(GLB_WIN)}
609   libglu    = 'glu32.dll';
610   libopengl = 'opengl32.dll';
611 {$ELSEIF DEFINED(GLB_LINUX)}
612   libglu    = 'libGLU.so.1';
613   libopengl = 'libGL.so.1';
614 {$IFEND}
615
616 type
617   GLboolean = BYTEBOOL;
618   GLint     = Integer;
619   GLsizei   = Integer;
620   GLuint    = Cardinal;
621   GLfloat   = Single;
622   GLenum    = Cardinal;
623
624   PGLvoid    = Pointer;
625   PGLboolean = ^GLboolean;
626   PGLint     = ^GLint;
627   PGLuint    = ^GLuint;
628   PGLfloat   = ^GLfloat;
629
630   TglCompressedTexImage1D  = procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
631   TglCompressedTexImage2D  = procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
632   TglGetCompressedTexImage = procedure(target: GLenum; level: GLint; img: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
633
634 {$IF DEFINED(GLB_WIN)}
635   TwglGetProcAddress = function (ProcName: PAnsiChar): Pointer; stdcall;
636 {$ELSEIF DEFINED(GLB_LINUX)}
637   TglXGetProcAddress = function(ProcName: PAnsiChar): Pointer; cdecl;
638   TglXGetProcAddressARB = function(const name: PAnsiChar): pointer; cdecl;
639 {$IFEND}
640
641 {$IF DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
642   TglEnable  = procedure(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
643   TglDisable = procedure(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
644
645   TglGetString   = function(name: GLenum): PAnsiChar; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
646   TglGetIntegerv = procedure(pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
647
648   TglTexParameteri          = procedure(target: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
649   TglTexParameteriv         = procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
650   TglTexParameterfv         = procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
651   TglGetTexParameteriv      = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
652   TglGetTexParameterfv      = procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
653   TglGetTexLevelParameteriv = procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
654   TglGetTexLevelParameterfv = procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
655
656   TglTexGeni        = procedure(coord: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
657   TglGenTextures    = procedure(n: GLsizei; textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
658   TglBindTexture    = procedure(target: GLenum; texture: GLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
659   TglDeleteTextures = procedure(n: GLsizei; const textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
660
661   TglAreTexturesResident = function(n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
662   TglReadPixels          = procedure(x: GLint; y: GLint; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
663   TglPixelStorei         = procedure(pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
664
665   TglTexImage1D  = procedure(target: GLenum; level: GLint; internalformat: GLint; width: GLsizei; border: GLint; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
666   TglTexImage2D  = procedure(target: GLenum; level: GLint; internalformat: GLint; width: GLsizei; height: GLsizei; border: GLint; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
667   TglGetTexImage = procedure(target: GLenum; level: GLint; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
668
669   TgluBuild1DMipmaps = function(target: GLEnum; components, width: GLint; format, atype: GLEnum; const data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
670   TgluBuild2DMipmaps = function(target: GLEnum; components, width, height: GLint; format, atype: GLEnum; const Data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
671
672 {$ELSEIF DEFINED(GLB_NATIVE_OGL_STATIC)}
673   procedure glEnable(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
674   procedure glDisable(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
675
676   function glGetString(name: GLenum): PAnsiChar; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
677   procedure glGetIntegerv(pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
678
679   procedure glTexParameteri(target: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
680   procedure glTexParameteriv(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
681   procedure glTexParameterfv(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
682   procedure glGetTexParameteriv(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
683   procedure glGetTexParameterfv(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
684   procedure glGetTexLevelParameteriv(target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
685   procedure glGetTexLevelParameterfv(target: GLenum; level: GLint; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
686
687   procedure glTexGeni(coord: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
688   procedure glGenTextures(n: GLsizei; textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
689   procedure glBindTexture(target: GLenum; texture: GLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
690   procedure glDeleteTextures(n: GLsizei; const textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
691
692   function  glAreTexturesResident(n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
693   procedure glReadPixels(x: GLint; y: GLint; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
694   procedure glPixelStorei(pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
695
696   procedure glTexImage1D(target: GLenum; level: GLint; internalformat: GLint; width: GLsizei; border: GLint; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
697   procedure glTexImage2D(target: GLenum; level: GLint; internalformat: GLint; width: GLsizei; height: GLsizei; border: GLint; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
698   procedure glGetTexImage(target: GLenum; level: GLint; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
699
700   function gluBuild1DMipmaps(target: GLEnum; components, width: GLint; format, atype: GLEnum; const data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libglu;
701   function gluBuild2DMipmaps(target: GLEnum; components, width, height: GLint; format, atype: GLEnum; const Data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libglu;
702 {$IFEND}
703
704 var
705   GL_VERSION_1_2,
706   GL_VERSION_1_3,
707   GL_VERSION_1_4,
708   GL_VERSION_2_0,
709   GL_VERSION_3_3,
710
711   GL_SGIS_generate_mipmap,
712
713   GL_ARB_texture_border_clamp,
714   GL_ARB_texture_mirrored_repeat,
715   GL_ARB_texture_rectangle,
716   GL_ARB_texture_non_power_of_two,
717   GL_ARB_texture_swizzle,
718   GL_ARB_texture_cube_map,
719
720   GL_IBM_texture_mirrored_repeat,
721
722   GL_NV_texture_rectangle,
723
724   GL_EXT_texture_edge_clamp,
725   GL_EXT_texture_rectangle,
726   GL_EXT_texture_swizzle,
727   GL_EXT_texture_cube_map,
728   GL_EXT_texture_filter_anisotropic: Boolean;
729
730   glCompressedTexImage1D: TglCompressedTexImage1D;
731   glCompressedTexImage2D: TglCompressedTexImage2D;
732   glGetCompressedTexImage: TglGetCompressedTexImage;
733
734 {$IF DEFINED(GLB_WIN)}
735   wglGetProcAddress: TwglGetProcAddress;
736 {$ELSEIF DEFINED(GLB_LINUX)}
737   glXGetProcAddress: TglXGetProcAddress;
738   glXGetProcAddressARB: TglXGetProcAddress;
739 {$IFEND}
740
741 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
742   glEnable: TglEnable;
743   glDisable: TglDisable;
744
745   glGetString: TglGetString;
746   glGetIntegerv: TglGetIntegerv;
747
748   glTexParameteri: TglTexParameteri;
749   glTexParameteriv: TglTexParameteriv;
750   glTexParameterfv: TglTexParameterfv;
751   glGetTexParameteriv: TglGetTexParameteriv;
752   glGetTexParameterfv: TglGetTexParameterfv;
753   glGetTexLevelParameteriv: TglGetTexLevelParameteriv;
754   glGetTexLevelParameterfv: TglGetTexLevelParameterfv;
755
756   glTexGeni: TglTexGeni;
757   glGenTextures: TglGenTextures;
758   glBindTexture: TglBindTexture;
759   glDeleteTextures: TglDeleteTextures;
760
761   glAreTexturesResident: TglAreTexturesResident;
762   glReadPixels: TglReadPixels;
763   glPixelStorei: TglPixelStorei;
764
765   glTexImage1D: TglTexImage1D;
766   glTexImage2D: TglTexImage2D;
767   glGetTexImage: TglGetTexImage;
768
769   gluBuild1DMipmaps: TgluBuild1DMipmaps;
770   gluBuild2DMipmaps: TgluBuild2DMipmaps;
771 {$ENDIF}
772 {$ENDIF}
773
774 type
775 ////////////////////////////////////////////////////////////////////////////////////////////////////
776   TglBitmapFormat = (
777     tfEmpty = 0, //must be smallest value!
778
779     tfAlpha4,
780     tfAlpha8,
781     tfAlpha16,
782
783     tfLuminance4,
784     tfLuminance8,
785     tfLuminance16,
786
787     tfLuminance4Alpha4,
788     tfLuminance6Alpha2,
789     tfLuminance8Alpha8,
790     tfLuminance12Alpha4,
791     tfLuminance16Alpha16,
792
793     tfR3G3B2,
794     tfRGBX4,
795     tfXRGB4,
796     tfR5G6B5,
797     tfRGB5X1,
798     tfX1RGB5,
799     tfRGB8,
800     tfRGBX8,
801     tfXRGB8,
802     tfRGB10X2,
803     tfX2RGB10,
804     tfRGB16,
805
806     tfRGBA4,
807     tfARGB4,
808     tfRGB5A1,
809     tfA1RGB5,
810     tfRGBA8,
811     tfARGB8,
812     tfRGB10A2,
813     tfA2RGB10,
814     tfRGBA16,
815
816     tfBGRX4,
817     tfXBGR4,
818     tfB5G6R5,
819     tfBGR5X1,
820     tfX1BGR5,
821     tfBGR8,
822     tfBGRX8,
823     tfXBGR8,
824     tfBGR10X2,
825     tfX2BGR10,
826     tfBGR16,
827
828     tfBGRA4,
829     tfABGR4,
830     tfBGR5A1,
831     tfA1BGR5,
832     tfBGRA8,
833     tfABGR8,
834     tfBGR10A2,
835     tfA2BGR10,
836     tfBGRA16,
837
838     tfDepth16,
839     tfDepth24,
840     tfDepth32,
841
842     tfS3tcDtx1RGBA,
843     tfS3tcDtx3RGBA,
844     tfS3tcDtx5RGBA
845   );
846
847   TglBitmapFileType = (
848      {$IFDEF GLB_SUPPORT_PNG_WRITE} ftPNG,  {$ENDIF}
849      {$IFDEF GLB_SUPPORT_JPEG_WRITE}ftJPEG, {$ENDIF}
850      ftDDS,
851      ftTGA,
852      ftBMP);
853    TglBitmapFileTypes = set of TglBitmapFileType;
854
855    TglBitmapMipMap = (
856      mmNone,
857      mmMipmap,
858      mmMipmapGlu);
859
860    TglBitmapNormalMapFunc = (
861      nm4Samples,
862      nmSobel,
863      nm3x3,
864      nm5x5);
865
866  ////////////////////////////////////////////////////////////////////////////////////////////////////
867    EglBitmap                  = class(Exception);
868    EglBitmapNotSupported      = class(Exception);
869    EglBitmapSizeToLarge       = class(EglBitmap);
870    EglBitmapNonPowerOfTwo     = class(EglBitmap);
871    EglBitmapUnsupportedFormat = class(EglBitmap)
872    public
873      constructor Create(const aFormat: TglBitmapFormat); overload;
874      constructor Create(const aMsg: String; const aFormat: TglBitmapFormat); overload;
875    end;
876
877 ////////////////////////////////////////////////////////////////////////////////////////////////////
878   TglBitmapColorRec = packed record
879   case Integer of
880     0: (r, g, b, a: Cardinal);
881     1: (arr: array[0..3] of Cardinal);
882   end;
883
884   TglBitmapPixelData = packed record
885     Data, Range: TglBitmapColorRec;
886     Format: TglBitmapFormat;
887   end;
888   PglBitmapPixelData = ^TglBitmapPixelData;
889
890 ////////////////////////////////////////////////////////////////////////////////////////////////////
891   TglBitmapPixelPositionFields = set of (ffX, ffY);
892   TglBitmapPixelPosition = record
893     Fields : TglBitmapPixelPositionFields;
894     X : Word;
895     Y : Word;
896   end;
897
898   TglBitmapFormatDescriptor = class(TObject)
899   protected
900     function GetIsCompressed: Boolean; virtual; abstract;
901     function GetHasRed:       Boolean; virtual; abstract;
902     function GetHasGreen:     Boolean; virtual; abstract;
903     function GetHasBlue:      Boolean; virtual; abstract;
904     function GetHasAlpha:     Boolean; virtual; abstract;
905
906     function GetRGBInverted:  TglBitmapFormat; virtual; abstract;
907     function GetWithAlpha:    TglBitmapFormat; virtual; abstract;
908     function GetWithoutAlpha: TglBitmapFormat; virtual; abstract;
909     function GetOpenGLFormat: TglBitmapFormat; virtual; abstract;
910     function GetUncompressed: TglBitmapFormat; virtual; abstract;
911
912     function GetglDataFormat:     GLenum;  virtual; abstract;
913     function GetglFormat:         GLenum;  virtual; abstract;
914     function GetglInternalFormat: GLenum;  virtual; abstract;
915   public
916     property IsCompressed: Boolean read GetIsCompressed;
917     property HasRed:       Boolean read GetHasRed;
918     property HasGreen:     Boolean read GetHasGreen;
919     property HasBlue:      Boolean read GetHasBlue;
920     property HasAlpha:     Boolean read GetHasAlpha;
921
922     property RGBInverted:  TglBitmapFormat read GetRGBInverted;
923     property WithAlpha:    TglBitmapFormat read GetWithAlpha;
924     property WithoutAlpha: TglBitmapFormat read GetWithoutAlpha;
925     property OpenGLFormat: TglBitmapFormat read GetOpenGLFormat;
926     property Uncompressed: TglBitmapFormat read GetUncompressed;
927
928     property glFormat:         GLenum  read GetglFormat;
929     property glInternalFormat: GLenum  read GetglInternalFormat;
930     property glDataFormat:     GLenum  read GetglDataFormat;
931   public
932     class function GetByFormat(const aInternalFormat: GLenum): TglBitmapFormatDescriptor;
933   end;
934
935 ////////////////////////////////////////////////////////////////////////////////////////////////////
936   TglBitmap = class;
937   TglBitmapFunctionRec = record
938     Sender:   TglBitmap;
939     Size:     TglBitmapPixelPosition;
940     Position: TglBitmapPixelPosition;
941     Source:   TglBitmapPixelData;
942     Dest:     TglBitmapPixelData;
943     Args:     Pointer;
944   end;
945   TglBitmapFunction = procedure(var FuncRec: TglBitmapFunctionRec);
946
947 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
948   TglBitmap = class
949   private
950     function GetFormatDesc: TglBitmapFormatDescriptor;
951   protected
952     fID: GLuint;
953     fTarget: GLuint;
954     fAnisotropic: Integer;
955     fDeleteTextureOnFree: Boolean;
956     fFreeDataOnDestroy: Boolean;
957     fFreeDataAfterGenTexture: Boolean;
958     fData: PByte;
959     fIsResident: GLboolean;
960     fBorderColor: array[0..3] of Single;
961
962     fDimension: TglBitmapPixelPosition;
963     fMipMap: TglBitmapMipMap;
964     fFormat: TglBitmapFormat;
965
966     // Mapping
967     fPixelSize: Integer;
968     fRowSize: Integer;
969
970     // Filtering
971     fFilterMin: GLenum;
972     fFilterMag: GLenum;
973
974     // TexturWarp
975     fWrapS: GLenum;
976     fWrapT: GLenum;
977     fWrapR: GLenum;
978
979     //Swizzle
980     fSwizzle: array[0..3] of GLenum;
981
982     // CustomData
983     fFilename: String;
984     fCustomName: String;
985     fCustomNameW: WideString;
986     fCustomData: Pointer;
987
988     //Getter
989     function GetWidth:  Integer; virtual;
990     function GetHeight: Integer; virtual;
991
992     function GetFileWidth:  Integer; virtual;
993     function GetFileHeight: Integer; virtual;
994
995     //Setter
996     procedure SetCustomData(const aValue: Pointer);
997     procedure SetCustomName(const aValue: String);
998     procedure SetCustomNameW(const aValue: WideString);
999     procedure SetFreeDataOnDestroy(const aValue: Boolean);
1000     procedure SetDeleteTextureOnFree(const aValue: Boolean);
1001     procedure SetFormat(const aValue: TglBitmapFormat);
1002     procedure SetFreeDataAfterGenTexture(const aValue: Boolean);
1003     procedure SetID(const aValue: Cardinal);
1004     procedure SetMipMap(const aValue: TglBitmapMipMap);
1005     procedure SetTarget(const aValue: Cardinal);
1006     procedure SetAnisotropic(const aValue: Integer);
1007
1008     procedure CreateID;
1009     procedure SetupParameters(out aBuildWithGlu: Boolean);
1010     procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
1011       const aWidth: Integer = -1; const aHeight: Integer = -1); virtual;  //be careful, aData could be freed by this method
1012     procedure GenTexture(const aTestTextureSize: Boolean = true); virtual; abstract;
1013
1014     function FlipHorz: Boolean; virtual;
1015     function FlipVert: Boolean; virtual;
1016
1017     property Width:  Integer read GetWidth;
1018     property Height: Integer read GetHeight;
1019
1020     property FileWidth:  Integer read GetFileWidth;
1021     property FileHeight: Integer read GetFileHeight;
1022   public
1023     //Properties
1024     property ID:           Cardinal        read fID          write SetID;
1025     property Target:       Cardinal        read fTarget      write SetTarget;
1026     property Format:       TglBitmapFormat read fFormat      write SetFormat;
1027     property MipMap:       TglBitmapMipMap read fMipMap      write SetMipMap;
1028     property Anisotropic:  Integer         read fAnisotropic write SetAnisotropic;
1029
1030     property FormatDesc:   TglBitmapFormatDescriptor read GetFormatDesc;
1031
1032     property Filename:    String     read fFilename;
1033     property CustomName:  String     read fCustomName  write SetCustomName;
1034     property CustomNameW: WideString read fCustomNameW write SetCustomNameW;
1035     property CustomData:  Pointer    read fCustomData  write SetCustomData;
1036
1037     property DeleteTextureOnFree:     Boolean read fDeleteTextureOnFree     write SetDeleteTextureOnFree;
1038     property FreeDataOnDestroy:       Boolean read fFreeDataOnDestroy       write SetFreeDataOnDestroy;
1039     property FreeDataAfterGenTexture: Boolean read fFreeDataAfterGenTexture write SetFreeDataAfterGenTexture;
1040
1041     property Dimension:  TglBitmapPixelPosition  read fDimension;
1042     property Data:       PByte                   read fData;
1043     property IsResident: GLboolean               read fIsResident;
1044
1045     procedure AfterConstruction; override;
1046     procedure BeforeDestruction; override;
1047
1048     procedure PrepareResType(var aResource: String; var aResType: PChar);
1049
1050     //Load
1051     procedure LoadFromFile(const aFilename: String);
1052     procedure LoadFromStream(const aStream: TStream); virtual;
1053     procedure LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
1054       const aFormat: TglBitmapFormat; const aArgs: Pointer = nil);
1055     procedure LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil);
1056     procedure LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
1057
1058     //Save
1059     procedure SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
1060     procedure SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType); virtual;
1061
1062     //Convert
1063     function AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer = nil): Boolean; overload;
1064     function AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
1065       const aFormat: TglBitmapFormat; const aArgs: Pointer = nil): Boolean; overload;
1066   public
1067     //Alpha & Co
1068     {$IFDEF GLB_SDL}
1069     function AssignToSurface(out aSurface: PSDL_Surface): Boolean;
1070     function AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
1071     function AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
1072     function AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil;
1073       const aArgs: Pointer = nil): Boolean;
1074     {$ENDIF}
1075
1076     {$IFDEF GLB_DELPHI}
1077     function AssignToBitmap(const aBitmap: TBitmap): Boolean;
1078     function AssignFromBitmap(const aBitmap: TBitmap): Boolean;
1079     function AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
1080     function AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction = nil;
1081       const aArgs: Pointer = nil): Boolean;
1082     {$ENDIF}
1083
1084     {$IFDEF GLB_LAZARUS}
1085     function AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
1086     function AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
1087     function AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
1088     function AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction = nil;
1089       const aArgs: Pointer = nil): Boolean;
1090     {$ENDIF}
1091
1092     function AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil;
1093       const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1094     function AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
1095       const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1096
1097     function AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer = nil): Boolean; virtual;
1098     function AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1099     function AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1100     function AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1101
1102     function AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte = 0): Boolean;
1103     function AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal = 0): Boolean;
1104     function AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single = 0): Boolean;
1105
1106     function AddAlphaFromValue(const aAlpha: Byte): Boolean;
1107     function AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
1108     function AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
1109
1110     function RemoveAlpha: Boolean; virtual;
1111   public
1112     //Common
1113     function Clone: TglBitmap;
1114     function ConvertTo(const aFormat: TglBitmapFormat): Boolean; virtual;
1115     procedure Invert(const aUseRGB: Boolean = true; const aUseAlpha: Boolean = false);
1116     procedure SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
1117     procedure FreeData;
1118
1119     //ColorFill
1120     procedure FillWithColor(const aRed, aGreen, aBlue: Byte; const aAlpha: Byte = 255);
1121     procedure FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal = $FFFFFFFF);
1122     procedure FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha : Single = 1);
1123
1124     //TexParameters
1125     procedure SetFilter(const aMin, aMag: GLenum);
1126     procedure SetWrap(
1127       const S: GLenum = GL_CLAMP_TO_EDGE;
1128       const T: GLenum = GL_CLAMP_TO_EDGE;
1129       const R: GLenum = GL_CLAMP_TO_EDGE);
1130     procedure SetSwizzle(const r, g, b, a: GLenum);
1131
1132     procedure Bind(const aEnableTextureUnit: Boolean = true); virtual;
1133     procedure Unbind(const aDisableTextureUnit: Boolean = true); virtual;
1134
1135     //Constructors
1136     constructor Create; overload;
1137     constructor Create(const aFileName: String); overload;
1138     constructor Create(const aStream: TStream); overload;
1139     constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; aData: PByte = nil); overload;
1140     constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer = nil); overload;
1141     constructor Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil); overload;
1142     constructor Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar); overload;
1143   private
1144     {$IFDEF GLB_SUPPORT_PNG_READ}  function  LoadPNG(const aStream: TStream): Boolean; virtual; {$ENDIF}
1145     {$ifdef GLB_SUPPORT_PNG_WRITE} procedure SavePNG(const aStream: TStream); virtual; {$ENDIF}
1146
1147     {$IFDEF GLB_SUPPORT_JPEG_READ}  function  LoadJPEG(const aStream: TStream): Boolean; virtual; {$ENDIF}
1148     {$IFDEF GLB_SUPPORT_JPEG_WRITE} procedure SaveJPEG(const aStream: TStream); virtual; {$ENDIF}
1149
1150     function LoadBMP(const aStream: TStream): Boolean; virtual;
1151     procedure SaveBMP(const aStream: TStream); virtual;
1152
1153     function LoadTGA(const aStream: TStream): Boolean; virtual;
1154     procedure SaveTGA(const aStream: TStream); virtual;
1155
1156     function LoadDDS(const aStream: TStream): Boolean; virtual;
1157     procedure SaveDDS(const aStream: TStream); virtual;
1158   end;
1159
1160 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1161   TglBitmap1D = class(TglBitmap)
1162   protected
1163     procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
1164       const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
1165     procedure UploadData(const aBuildWithGlu: Boolean);
1166   public
1167     property Width;
1168     procedure AfterConstruction; override;
1169     function FlipHorz: Boolean; override;
1170     procedure GenTexture(const aTestTextureSize: Boolean = true); override;
1171   end;
1172
1173 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1174   TglBitmap2D = class(TglBitmap)
1175   protected
1176     fLines: array of PByte;
1177     function GetScanline(const aIndex: Integer): Pointer;
1178     procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
1179       const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
1180     procedure UploadData(const aTarget: GLenum; const aBuildWithGlu: Boolean);
1181   public
1182     property Width;
1183     property Height;
1184     property Scanline[const aIndex: Integer]: Pointer read GetScanline;
1185
1186     procedure AfterConstruction; override;
1187
1188     procedure GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
1189     procedure GetDataFromTexture;
1190     procedure GenTexture(const aTestTextureSize: Boolean = true); override;
1191
1192     function FlipHorz: Boolean; override;
1193     function FlipVert: Boolean; override;
1194
1195     procedure ToNormalMap(const aFunc: TglBitmapNormalMapFunc = nm3x3;
1196       const aScale: Single = 2; const aUseAlpha: Boolean = false);
1197   end;
1198
1199 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1200   TglBitmapCubeMap = class(TglBitmap2D)
1201   protected
1202     fGenMode: Integer;
1203     procedure GenTexture(const aTestTextureSize: Boolean = true); reintroduce;
1204   public
1205     procedure AfterConstruction; override;
1206     procedure GenerateCubeMap(const aCubeTarget: Cardinal; const aTestTextureSize: Boolean = true);
1207     procedure Bind(const aEnableTexCoordsGen: Boolean = true; const aEnableTextureUnit: Boolean = true); reintroduce; virtual;
1208     procedure Unbind(const aDisableTexCoordsGen: Boolean = true; const aDisableTextureUnit: Boolean = true); reintroduce; virtual;
1209   end;
1210
1211 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1212   TglBitmapNormalMap = class(TglBitmapCubeMap)
1213   public
1214     procedure AfterConstruction; override;
1215     procedure GenerateNormalMap(const aSize: Integer = 32; const aTestTextureSize: Boolean = true);
1216   end;
1217
1218 const
1219   NULL_SIZE: TglBitmapPixelPosition = (Fields: []; X: 0; Y: 0);
1220
1221 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
1222 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
1223 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
1224 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
1225 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
1226 procedure glBitmapSetDefaultWrap(
1227   const S: Cardinal = GL_CLAMP_TO_EDGE;
1228   const T: Cardinal = GL_CLAMP_TO_EDGE;
1229   const R: Cardinal = GL_CLAMP_TO_EDGE);
1230
1231 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
1232 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
1233 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
1234 function glBitmapGetDefaultFormat: TglBitmapFormat;
1235 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
1236 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
1237
1238 function glBitmapPosition(X: Integer = -1; Y: Integer = -1): TglBitmapPixelPosition;
1239 function glBitmapColorRec(const r, g, b, a: Cardinal): TglBitmapColorRec;
1240 function glBitmapColorRecCmp(const r1, r2: TglBitmapColorRec): Boolean;
1241
1242 var
1243   glBitmapDefaultDeleteTextureOnFree: Boolean;
1244   glBitmapDefaultFreeDataAfterGenTextures: Boolean;
1245   glBitmapDefaultFormat: TglBitmapFormat;
1246   glBitmapDefaultMipmap: TglBitmapMipMap;
1247   glBitmapDefaultFilterMin: Cardinal;
1248   glBitmapDefaultFilterMag: Cardinal;
1249   glBitmapDefaultWrapS: Cardinal;
1250   glBitmapDefaultWrapT: Cardinal;
1251   glBitmapDefaultWrapR: Cardinal;
1252   glDefaultSwizzle: array[0..3] of GLenum;
1253
1254 {$IFDEF GLB_DELPHI}
1255 function CreateGrayPalette: HPALETTE;
1256 {$ENDIF}
1257
1258 implementation
1259
1260 uses
1261   Math, syncobjs, typinfo
1262   {$IF DEFINED(GLB_SUPPORT_JPEG_READ) AND DEFINED(GLB_LAZ_JPEG)}, FPReadJPEG{$IFEND};
1263
1264 type
1265 {$IFNDEF fpc}
1266   QWord   = System.UInt64;
1267   PQWord  = ^QWord;
1268
1269   PtrInt  = Longint;
1270   PtrUInt = DWord;
1271 {$ENDIF}
1272
1273 ////////////////////////////////////////////////////////////////////////////////////////////////////
1274   TShiftRec = packed record
1275   case Integer of
1276     0: (r, g, b, a: Byte);
1277     1: (arr: array[0..3] of Byte);
1278   end;
1279
1280   TFormatDescriptor = class(TglBitmapFormatDescriptor)
1281   private
1282     function GetRedMask: QWord;
1283     function GetGreenMask: QWord;
1284     function GetBlueMask: QWord;
1285     function GetAlphaMask: QWord;
1286   protected
1287     fFormat: TglBitmapFormat;
1288     fWithAlpha: TglBitmapFormat;
1289     fWithoutAlpha: TglBitmapFormat;
1290     fOpenGLFormat: TglBitmapFormat;
1291     fRGBInverted: TglBitmapFormat;
1292     fUncompressed: TglBitmapFormat;
1293
1294     fPixelSize: Single;
1295     fIsCompressed: Boolean;
1296
1297     fRange: TglBitmapColorRec;
1298     fShift: TShiftRec;
1299
1300     fglFormat:         GLenum;
1301     fglInternalFormat: GLenum;
1302     fglDataFormat:     GLenum;
1303
1304     function GetIsCompressed: Boolean; override;
1305     function GetHasRed: Boolean; override;
1306     function GetHasGreen: Boolean; override;
1307     function GetHasBlue: Boolean; override;
1308     function GetHasAlpha: Boolean; override;
1309
1310     function GetRGBInverted:  TglBitmapFormat; override;
1311     function GetWithAlpha:    TglBitmapFormat; override;
1312     function GetWithoutAlpha: TglBitmapFormat; override;
1313     function GetOpenGLFormat: TglBitmapFormat; override;
1314     function GetUncompressed: TglBitmapFormat; override;
1315
1316     function GetglFormat: GLenum; override;
1317     function GetglInternalFormat: GLenum; override;
1318     function GetglDataFormat: GLenum; override;
1319
1320     function GetComponents: Integer; virtual;
1321   public
1322     property Format:       TglBitmapFormat read fFormat;
1323     property Components:   Integer         read GetComponents;
1324     property PixelSize:    Single          read fPixelSize;
1325
1326     property Range: TglBitmapColorRec read fRange;
1327     property Shift: TShiftRec         read fShift;
1328
1329     property RedMask:   QWord read GetRedMask;
1330     property GreenMask: QWord read GetGreenMask;
1331     property BlueMask:  QWord read GetBlueMask;
1332     property AlphaMask: QWord read GetAlphaMask;
1333
1334     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); virtual; abstract;
1335     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); virtual; abstract;
1336
1337     function GetSize(const aSize: TglBitmapPixelPosition): Integer; overload; virtual;
1338     function GetSize(const aWidth, aHeight: Integer): Integer; overload; virtual;
1339
1340     function CreateMappingData: Pointer; virtual;
1341     procedure FreeMappingData(var aMappingData: Pointer); virtual;
1342
1343     function IsEmpty:  Boolean; virtual;
1344     function MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: QWord): Boolean; virtual;
1345
1346     procedure PreparePixel(out aPixel: TglBitmapPixelData); virtual;
1347
1348     constructor Create; virtual;
1349   public
1350     class procedure Init;
1351     class function Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
1352     class function GetAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
1353     class procedure Clear;
1354     class procedure Finalize;
1355   end;
1356   TFormatDescriptorClass = class of TFormatDescriptor;
1357
1358   TfdEmpty = class(TFormatDescriptor);
1359
1360 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1361   TfdAlpha_UB1 = class(TFormatDescriptor) //1* unsigned byte
1362     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1363     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1364   end;
1365
1366   TfdLuminance_UB1 = class(TFormatDescriptor) //1* unsigned byte
1367     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1368     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1369   end;
1370
1371   TfdUniversal_UB1 = class(TFormatDescriptor) //1* unsigned byte
1372     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1373     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1374   end;
1375
1376   TfdLuminanceAlpha_UB2 = class(TfdLuminance_UB1) //2* unsigned byte
1377     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1378     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1379   end;
1380
1381   TfdRGB_UB3 = class(TFormatDescriptor) //3* unsigned byte
1382     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1383     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1384   end;
1385
1386   TfdBGR_UB3 = class(TFormatDescriptor) //3* unsigned byte (inverse)
1387     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1388     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1389   end;
1390
1391 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1392   TfdAlpha_US1 = class(TFormatDescriptor) //1* unsigned short
1393     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1394     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1395   end;
1396
1397   TfdLuminance_US1 = class(TFormatDescriptor) //1* unsigned short
1398     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1399     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1400   end;
1401
1402   TfdUniversal_US1 = class(TFormatDescriptor) //1* unsigned short
1403     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1404     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1405   end;
1406
1407   TfdDepth_US1 = class(TFormatDescriptor) //1* unsigned short
1408     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1409     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1410   end;
1411
1412   TfdLuminanceAlpha_US2 = class(TfdLuminance_US1) //2* unsigned short
1413     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1414     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1415   end;
1416
1417   TfdRGB_US3 = class(TFormatDescriptor) //3* unsigned short
1418     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1419     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1420   end;
1421
1422   TfdBGR_US3 = class(TFormatDescriptor) //3* unsigned short (inverse)
1423     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1424     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1425   end;
1426
1427   TfdRGBA_US4 = class(TfdRGB_US3) //4* unsigned short
1428     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1429     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1430   end;
1431
1432   TfdARGB_US4 = class(TfdRGB_US3) //4* unsigned short
1433     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1434     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1435   end;
1436
1437   TfdBGRA_US4 = class(TfdBGR_US3) //4* unsigned short (inverse)
1438     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1439     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1440   end;
1441
1442   TfdABGR_US4 = class(TfdBGR_US3) //4* unsigned short (inverse)
1443     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1444     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1445   end;
1446
1447 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1448   TfdUniversal_UI1 = class(TFormatDescriptor) //1* unsigned int
1449     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1450     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1451   end;
1452
1453   TfdDepth_UI1 = class(TFormatDescriptor) //1* unsigned int
1454     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1455     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1456   end;
1457
1458 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1459   TfdAlpha4 = class(TfdAlpha_UB1)
1460     constructor Create; override;
1461   end;
1462
1463   TfdAlpha8 = class(TfdAlpha_UB1)
1464     constructor Create; override;
1465   end;
1466
1467   TfdAlpha16 = class(TfdAlpha_US1)
1468     constructor Create; override;
1469   end;
1470
1471   TfdLuminance4 = class(TfdLuminance_UB1)
1472     constructor Create; override;
1473   end;
1474
1475   TfdLuminance8 = class(TfdLuminance_UB1)
1476     constructor Create; override;
1477   end;
1478
1479   TfdLuminance16 = class(TfdLuminance_US1)
1480     constructor Create; override;
1481   end;
1482
1483   TfdLuminance4Alpha4 = class(TfdLuminanceAlpha_UB2)
1484     constructor Create; override;
1485   end;
1486
1487   TfdLuminance6Alpha2 = class(TfdLuminanceAlpha_UB2)
1488     constructor Create; override;
1489   end;
1490
1491   TfdLuminance8Alpha8 = class(TfdLuminanceAlpha_UB2)
1492     constructor Create; override;
1493   end;
1494
1495   TfdLuminance12Alpha4 = class(TfdLuminanceAlpha_US2)
1496     constructor Create; override;
1497   end;
1498
1499   TfdLuminance16Alpha16 = class(TfdLuminanceAlpha_US2)
1500     constructor Create; override;
1501   end;
1502
1503 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1504   TfdR3G3B2 = class(TfdUniversal_UB1)
1505     constructor Create; override;
1506   end;
1507
1508   TfdRGBX4 = class(TfdUniversal_US1)
1509     constructor Create; override;
1510   end;
1511
1512   TfdXRGB4 = class(TfdUniversal_US1)
1513     constructor Create; override;
1514   end;
1515
1516   TfdR5G6B5 = class(TfdUniversal_US1)
1517     constructor Create; override;
1518   end;
1519
1520   TfdRGB5X1 = class(TfdUniversal_US1)
1521     constructor Create; override;
1522   end;
1523
1524   TfdX1RGB5 = class(TfdUniversal_US1)
1525     constructor Create; override;
1526   end;
1527
1528   TfdRGB8 = class(TfdRGB_UB3)
1529     constructor Create; override;
1530   end;
1531
1532   TfdRGBX8 = class(TfdUniversal_UI1)
1533     constructor Create; override;
1534   end;
1535
1536   TfdXRGB8 = class(TfdUniversal_UI1)
1537     constructor Create; override;
1538   end;
1539
1540   TfdRGB10X2 = class(TfdUniversal_UI1)
1541     constructor Create; override;
1542   end;
1543
1544   TfdX2RGB10 = class(TfdUniversal_UI1)
1545     constructor Create; override;
1546   end;
1547
1548   TfdRGB16 = class(TfdRGB_US3)
1549     constructor Create; override;
1550   end;
1551
1552   TfdRGBA4 = class(TfdUniversal_US1)
1553     constructor Create; override;
1554   end;
1555
1556   TfdARGB4 = class(TfdUniversal_US1)
1557     constructor Create; override;
1558   end;
1559
1560   TfdRGB5A1 = class(TfdUniversal_US1)
1561     constructor Create; override;
1562   end;
1563
1564   TfdA1RGB5 = class(TfdUniversal_US1)
1565     constructor Create; override;
1566   end;
1567
1568   TfdRGBA8 = class(TfdUniversal_UI1)
1569     constructor Create; override;
1570   end;
1571
1572   TfdARGB8 = class(TfdUniversal_UI1)
1573     constructor Create; override;
1574   end;
1575
1576   TfdRGB10A2 = class(TfdUniversal_UI1)
1577     constructor Create; override;
1578   end;
1579
1580   TfdA2RGB10 = class(TfdUniversal_UI1)
1581     constructor Create; override;
1582   end;
1583
1584   TfdRGBA16 = class(TfdUniversal_UI1)
1585     constructor Create; override;
1586   end;
1587
1588 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1589   TfdBGRX4 = class(TfdUniversal_US1)
1590     constructor Create; override;
1591   end;
1592
1593   TfdXBGR4 = class(TfdUniversal_US1)
1594     constructor Create; override;
1595   end;
1596
1597   TfdB5G6R5 = class(TfdUniversal_US1)
1598     constructor Create; override;
1599   end;
1600
1601   TfdBGR5X1 = class(TfdUniversal_US1)
1602     constructor Create; override;
1603   end;
1604
1605   TfdX1BGR5 = class(TfdUniversal_US1)
1606     constructor Create; override;
1607   end;
1608
1609   TfdBGR8 = class(TfdBGR_UB3)
1610     constructor Create; override;
1611   end;
1612
1613   TfdBGRX8 = class(TfdUniversal_UI1)
1614     constructor Create; override;
1615   end;
1616
1617   TfdXBGR8 = class(TfdUniversal_UI1)
1618     constructor Create; override;
1619   end;
1620
1621   TfdBGR10X2 = class(TfdUniversal_UI1)
1622     constructor Create; override;
1623   end;
1624
1625   TfdX2BGR10 = class(TfdUniversal_UI1)
1626     constructor Create; override;
1627   end;
1628
1629   TfdBGR16 = class(TfdBGR_US3)
1630     constructor Create; override;
1631   end;
1632
1633   TfdBGRA4 = class(TfdUniversal_US1)
1634     constructor Create; override;
1635   end;
1636
1637   TfdABGR4 = class(TfdUniversal_US1)
1638     constructor Create; override;
1639   end;
1640
1641   TfdBGR5A1 = class(TfdUniversal_US1)
1642     constructor Create; override;
1643   end;
1644
1645   TfdA1BGR5 = class(TfdUniversal_US1)
1646     constructor Create; override;
1647   end;
1648
1649   TfdBGRA8 = class(TfdUniversal_UI1)
1650     constructor Create; override;
1651   end;
1652
1653   TfdABGR8 = class(TfdUniversal_UI1)
1654     constructor Create; override;
1655   end;
1656
1657   TfdBGR10A2 = class(TfdUniversal_UI1)
1658     constructor Create; override;
1659   end;
1660
1661   TfdA2BGR10 = class(TfdUniversal_UI1)
1662     constructor Create; override;
1663   end;
1664
1665   TfdBGRA16 = class(TfdBGRA_US4)
1666     constructor Create; override;
1667   end;
1668
1669   TfdDepth16 = class(TfdDepth_US1)
1670     constructor Create; override;
1671   end;
1672
1673   TfdDepth24 = class(TfdDepth_UI1)
1674     constructor Create; override;
1675   end;
1676
1677   TfdDepth32 = class(TfdDepth_UI1)
1678     constructor Create; override;
1679   end;
1680
1681   TfdS3tcDtx1RGBA = class(TFormatDescriptor)
1682     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1683     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1684     constructor Create; override;
1685   end;
1686
1687   TfdS3tcDtx3RGBA = class(TFormatDescriptor)
1688     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1689     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1690     constructor Create; override;
1691   end;
1692
1693   TfdS3tcDtx5RGBA = class(TFormatDescriptor)
1694     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1695     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1696     constructor Create; override;
1697   end;
1698
1699 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1700   TbmpBitfieldFormat = class(TFormatDescriptor)
1701   private
1702     procedure SetRedMask  (const aValue: QWord);
1703     procedure SetGreenMask(const aValue: QWord);
1704     procedure SetBlueMask (const aValue: QWord);
1705     procedure SetAlphaMask(const aValue: QWord);
1706
1707     procedure Update(aMask: QWord; out aRange: Cardinal; out aShift: Byte);
1708   public
1709     property RedMask:   QWord read GetRedMask   write SetRedMask;
1710     property GreenMask: QWord read GetGreenMask write SetGreenMask;
1711     property BlueMask:  QWord read GetBlueMask  write SetBlueMask;
1712     property AlphaMask: QWord read GetAlphaMask write SetAlphaMask;
1713
1714     property PixelSize: Single read fPixelSize write fPixelSize;
1715
1716     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1717     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1718   end;
1719
1720 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1721   TbmpColorTableEnty = packed record
1722     b, g, r, a: Byte;
1723   end;
1724   TbmpColorTable = array of TbmpColorTableEnty;
1725   TbmpColorTableFormat = class(TFormatDescriptor)
1726   private
1727     fColorTable: TbmpColorTable;
1728   public
1729     property PixelSize:  Single            read fPixelSize  write fPixelSize;
1730     property ColorTable: TbmpColorTable    read fColorTable write fColorTable;
1731     property Range:      TglBitmapColorRec read fRange      write fRange;
1732     property Shift:      TShiftRec         read fShift      write fShift;
1733     property Format:     TglBitmapFormat   read fFormat     write fFormat;
1734
1735     procedure CreateColorTable;
1736
1737     procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1738     procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1739     destructor Destroy; override;
1740   end;
1741
1742 const
1743   LUMINANCE_WEIGHT_R = 0.30;
1744   LUMINANCE_WEIGHT_G = 0.59;
1745   LUMINANCE_WEIGHT_B = 0.11;
1746
1747   ALPHA_WEIGHT_R = 0.30;
1748   ALPHA_WEIGHT_G = 0.59;
1749   ALPHA_WEIGHT_B = 0.11;
1750
1751   DEPTH_WEIGHT_R = 0.333333333;
1752   DEPTH_WEIGHT_G = 0.333333333;
1753   DEPTH_WEIGHT_B = 0.333333333;
1754
1755   UNSUPPORTED_FORMAT = 'the given format isn''t supported by this function.';
1756
1757   FORMAT_DESCRIPTOR_CLASSES: array[TglBitmapFormat] of TFormatDescriptorClass = (
1758     TfdEmpty,
1759
1760     TfdAlpha4,
1761     TfdAlpha8,
1762     TfdAlpha16,
1763
1764     TfdLuminance4,
1765     TfdLuminance8,
1766     TfdLuminance16,
1767
1768     TfdLuminance4Alpha4,
1769     TfdLuminance6Alpha2,
1770     TfdLuminance8Alpha8,
1771     TfdLuminance12Alpha4,
1772     TfdLuminance16Alpha16,
1773
1774     TfdR3G3B2,
1775     TfdRGBX4,
1776     TfdXRGB4,
1777     TfdR5G6B5,
1778     TfdRGB5X1,
1779     TfdX1RGB5,
1780     TfdRGB8,
1781     TfdRGBX8,
1782     TfdXRGB8,
1783     TfdRGB10X2,
1784     TfdX2RGB10,
1785     TfdRGB16,
1786
1787     TfdRGBA4,
1788     TfdARGB4,
1789     TfdRGB5A1,
1790     TfdA1RGB5,
1791     TfdRGBA8,
1792     TfdARGB8,
1793     TfdRGB10A2,
1794     TfdA2RGB10,
1795     TfdRGBA16,
1796
1797     TfdBGRX4,
1798     TfdXBGR4,
1799     TfdB5G6R5,
1800     TfdBGR5X1,
1801     TfdX1BGR5,
1802     TfdBGR8,
1803     TfdBGRX8,
1804     TfdXBGR8,
1805     TfdBGR10X2,
1806     TfdX2BGR10,
1807     TfdBGR16,
1808
1809     TfdBGRA4,
1810     TfdABGR4,
1811     TfdBGR5A1,
1812     TfdA1BGR5,
1813     TfdBGRA8,
1814     TfdABGR8,
1815     TfdBGR10A2,
1816     TfdA2BGR10,
1817     TfdBGRA16,
1818
1819     TfdDepth16,
1820     TfdDepth24,
1821     TfdDepth32,
1822
1823     TfdS3tcDtx1RGBA,
1824     TfdS3tcDtx3RGBA,
1825     TfdS3tcDtx5RGBA
1826   );
1827
1828 var
1829   FormatDescriptorCS: TCriticalSection;
1830   FormatDescriptors: array[TglBitmapFormat] of TFormatDescriptor;
1831
1832 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1833 constructor EglBitmapUnsupportedFormat.Create(const aFormat: TglBitmapFormat);
1834 begin
1835   inherited Create('unsupported format: ' + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
1836 end;
1837
1838 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1839 constructor EglBitmapUnsupportedFormat.Create(const aMsg: String; const aFormat: TglBitmapFormat);
1840 begin
1841   inherited Create(aMsg + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
1842 end;
1843
1844 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1845 function glBitmapPosition(X, Y: Integer): TglBitmapPixelPosition;
1846 begin
1847   result.Fields := [];
1848
1849   if X >= 0 then
1850     result.Fields := result.Fields + [ffX];
1851   if Y >= 0 then
1852     result.Fields := result.Fields + [ffY];
1853
1854   result.X := Max(0, X);
1855   result.Y := Max(0, Y);
1856 end;
1857
1858 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1859 function glBitmapColorRec(const r, g, b, a: Cardinal): TglBitmapColorRec;
1860 begin
1861   result.r := r;
1862   result.g := g;
1863   result.b := b;
1864   result.a := a;
1865 end;
1866
1867 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1868 function glBitmapColorRecCmp(const r1, r2: TglBitmapColorRec): Boolean;
1869 var
1870   i: Integer;
1871 begin
1872   result := false;
1873   for i := 0 to high(r1.arr) do
1874     if (r1.arr[i] <> r2.arr[i]) then
1875       exit;
1876   result := true;
1877 end;
1878
1879 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1880 function glBitmapShiftRec(const r, g, b, a: Byte): TShiftRec;
1881 begin
1882   result.r := r;
1883   result.g := g;
1884   result.b := b;
1885   result.a := a;
1886 end;
1887
1888 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1889 function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes;
1890 begin
1891   result := [];
1892
1893   if (aFormat in [
1894         //4 bbp
1895         tfLuminance4,
1896
1897         //8bpp
1898         tfR3G3B2, tfLuminance8,
1899
1900         //16bpp
1901         tfRGBX4, tfXRGB4, tfRGB5X1, tfX1RGB5, tfR5G6B5, tfRGB5A1, tfA1RGB5, tfRGBA4, tfARGB4,
1902         tfBGRX4, tfXBGR4, tfBGR5X1, tfX1BGR5, tfB5G6R5, tfBGR5A1, tfA1BGR5, tfBGRA4, tfABGR4,
1903
1904         //24bpp
1905         tfBGR8, tfRGB8,
1906
1907         //32bpp
1908         tfRGB10X2, tfX2RGB10, tfRGB10A2, tfA2RGB10, tfRGBA8, tfARGB8,
1909         tfBGR10X2, tfX2BGR10, tfBGR10A2, tfA2BGR10, tfBGRA8, tfABGR8]) then
1910     result := result + [ftBMP];
1911
1912   if (aFormat in [
1913         //8 bpp
1914         tfLuminance8, tfAlpha8,
1915
1916         //16 bpp
1917         tfLuminance16, tfLuminance8Alpha8,
1918         tfRGB5X1, tfX1RGB5, tfRGB5A1, tfA1RGB5, tfRGBA4, tfARGB4,
1919         tfBGR5X1, tfX1BGR5, tfBGR5A1, tfA1BGR5, tfBGRA4, tfABGR4,
1920
1921         //24 bpp
1922         tfRGB8, tfBGR8,
1923
1924         //32 bpp
1925         tfRGB10A2, tfRGBA8, tfBGR10A2, tfBGRA8]) then
1926     result := result + [ftTGA];
1927
1928   if (aFormat in [
1929         //8 bpp
1930         tfAlpha8, tfLuminance8, tfLuminance4Alpha4, tfLuminance6Alpha2,
1931         tfR3G3B2,
1932
1933         //16 bpp
1934         tfAlpha16, tfLuminance16, tfLuminance8Alpha8, tfLuminance12Alpha4,
1935         tfRGBX4, tfXRGB4, tfR5G6B5, tfRGB5X1, tfX1RGB5, tfRGBA4, tfARGB4, tfRGB5A1, tfA1RGB5,
1936         tfBGRX4, tfXBGR4, tfB5G6R5, tfBGR5X1, tfX1BGR5, tfBGRA4, tfABGR4, tfBGR5A1, tfA1BGR5,
1937
1938         //24 bpp
1939         tfRGB8, tfBGR8,
1940
1941         //32 bbp
1942         tfLuminance16Alpha16,
1943         tfRGBA8, tfRGB10A2,
1944         tfBGRA8, tfBGR10A2,
1945
1946         //compressed
1947         tfS3tcDtx1RGBA, tfS3tcDtx3RGBA, tfS3tcDtx5RGBA]) then
1948     result := result + [ftDDS];
1949
1950   {$IFDEF GLB_SUPPORT_PNG_WRITE}
1951   if aFormat in [
1952       tfAlpha8, tfLuminance8, tfLuminance8Alpha8,
1953       tfRGB8, tfRGBA8,
1954       tfBGR8, tfBGRA8] then
1955     result := result + [ftPNG];
1956   {$ENDIF}
1957
1958   {$IFDEF GLB_SUPPORT_JPEG_WRITE}
1959   if aFormat in [tfAlpha8, tfLuminance8, tfRGB8, tfBGR8] then
1960     result := result + [ftJPEG];
1961   {$ENDIF}
1962 end;
1963
1964 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1965 function IsPowerOfTwo(aNumber: Integer): Boolean;
1966 begin
1967   while (aNumber and 1) = 0 do
1968     aNumber := aNumber shr 1;
1969   result := aNumber = 1;
1970 end;
1971
1972 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1973 function GetTopMostBit(aBitSet: QWord): Integer;
1974 begin
1975   result := 0;
1976   while aBitSet > 0 do begin
1977     inc(result);
1978     aBitSet := aBitSet shr 1;
1979   end;
1980 end;
1981
1982 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1983 function CountSetBits(aBitSet: QWord): Integer;
1984 begin
1985   result := 0;
1986   while aBitSet > 0 do begin
1987     if (aBitSet and 1) = 1 then
1988       inc(result);
1989     aBitSet := aBitSet shr 1;
1990   end;
1991 end;
1992
1993 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1994 function LuminanceWeight(const aPixel: TglBitmapPixelData): Cardinal;
1995 begin
1996   result := Trunc(
1997     LUMINANCE_WEIGHT_R * aPixel.Data.r +
1998     LUMINANCE_WEIGHT_G * aPixel.Data.g +
1999     LUMINANCE_WEIGHT_B * aPixel.Data.b);
2000 end;
2001
2002 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2003 function DepthWeight(const aPixel: TglBitmapPixelData): Cardinal;
2004 begin
2005   result := Trunc(
2006     DEPTH_WEIGHT_R * aPixel.Data.r +
2007     DEPTH_WEIGHT_G * aPixel.Data.g +
2008     DEPTH_WEIGHT_B * aPixel.Data.b);
2009 end;
2010
2011 {$IFDEF GLB_NATIVE_OGL}
2012 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2013 //OpenGLInitialization///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2014 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2015 var
2016   GL_LibHandle: Pointer = nil;
2017
2018 function glbGetProcAddress(aProcName: PAnsiChar; aLibHandle: Pointer = nil; const aRaiseOnErr: Boolean = true): Pointer;
2019 begin
2020   if not Assigned(aLibHandle) then
2021     aLibHandle := GL_LibHandle;
2022
2023 {$IF DEFINED(GLB_WIN)}
2024   result := GetProcAddress({%H-}HMODULE(aLibHandle), aProcName);
2025   if Assigned(result) then
2026     exit;
2027
2028   if Assigned(wglGetProcAddress) then
2029     result := wglGetProcAddress(aProcName);
2030 {$ELSEIF DEFINED(GLB_LINUX)}
2031   if Assigned(glXGetProcAddress) then begin
2032     result := glXGetProcAddress(aProcName);
2033     if Assigned(result) then
2034       exit;
2035   end;
2036
2037   if Assigned(glXGetProcAddressARB) then begin
2038     result := glXGetProcAddressARB(aProcName);
2039     if Assigned(result) then
2040       exit;
2041   end;
2042
2043   result := dlsym(aLibHandle, aProcName);
2044 {$IFEND}
2045   if not Assigned(result) and aRaiseOnErr then
2046     raise EglBitmap.Create('unable to load procedure form library: ' + aProcName);
2047 end;
2048
2049 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
2050 var
2051   GLU_LibHandle: Pointer = nil;
2052   OpenGLInitialized: Boolean;
2053   InitOpenGLCS: TCriticalSection;
2054
2055 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2056 procedure glbInitOpenGL;
2057
2058   ////////////////////////////////////////////////////////////////////////////////
2059   function glbLoadLibrary(const aName: PChar): Pointer;
2060   begin
2061     {$IF DEFINED(GLB_WIN)}
2062     result := {%H-}Pointer(LoadLibrary(aName));
2063     {$ELSEIF DEFINED(GLB_LINUX)}
2064     result := dlopen(Name, RTLD_LAZY);
2065     {$ELSE}
2066     result := nil;
2067     {$IFEND}
2068   end;
2069
2070   ////////////////////////////////////////////////////////////////////////////////
2071   function glbFreeLibrary(const aLibHandle: Pointer): Boolean;
2072   begin
2073     result := false;
2074     if not Assigned(aLibHandle) then
2075       exit;
2076
2077     {$IF DEFINED(GLB_WIN)}
2078     Result := FreeLibrary({%H-}HINST(aLibHandle));
2079     {$ELSEIF DEFINED(GLB_LINUX)}
2080     Result := dlclose(aLibHandle) = 0;
2081     {$IFEND}
2082   end;
2083
2084 begin
2085   if Assigned(GL_LibHandle) then
2086     glbFreeLibrary(GL_LibHandle);
2087
2088   if Assigned(GLU_LibHandle) then
2089     glbFreeLibrary(GLU_LibHandle);
2090
2091   GL_LibHandle := glbLoadLibrary(libopengl);
2092   if not Assigned(GL_LibHandle) then
2093     raise EglBitmap.Create('unable to load library: ' + libopengl);
2094
2095   GLU_LibHandle := glbLoadLibrary(libglu);
2096   if not Assigned(GLU_LibHandle) then
2097     raise EglBitmap.Create('unable to load library: ' + libglu);
2098
2099 {$IF DEFINED(GLB_WIN)}
2100   wglGetProcAddress    := glbGetProcAddress('wglGetProcAddress');
2101 {$ELSEIF DEFINED(GLB_LINUX)}
2102   glXGetProcAddress    := glbGetProcAddress('glXGetProcAddress');
2103   glXGetProcAddressARB := glbGetProcAddress('glXGetProcAddressARB');
2104 {$IFEND}
2105
2106   glEnable := glbGetProcAddress('glEnable');
2107   glDisable := glbGetProcAddress('glDisable');
2108   glGetString := glbGetProcAddress('glGetString');
2109   glGetIntegerv := glbGetProcAddress('glGetIntegerv');
2110   glTexParameteri := glbGetProcAddress('glTexParameteri');
2111   glTexParameteriv := glbGetProcAddress('glTexParameteriv');
2112   glTexParameterfv := glbGetProcAddress('glTexParameterfv');
2113   glGetTexParameteriv := glbGetProcAddress('glGetTexParameteriv');
2114   glGetTexParameterfv := glbGetProcAddress('glGetTexParameterfv');
2115   glGetTexLevelParameteriv := glbGetProcAddress('glGetTexLevelParameteriv');
2116   glGetTexLevelParameterfv := glbGetProcAddress('glGetTexLevelParameterfv');
2117   glTexGeni := glbGetProcAddress('glTexGeni');
2118   glGenTextures := glbGetProcAddress('glGenTextures');
2119   glBindTexture := glbGetProcAddress('glBindTexture');
2120   glDeleteTextures := glbGetProcAddress('glDeleteTextures');
2121   glAreTexturesResident := glbGetProcAddress('glAreTexturesResident');
2122   glReadPixels := glbGetProcAddress('glReadPixels');
2123   glPixelStorei := glbGetProcAddress('glPixelStorei');
2124   glTexImage1D := glbGetProcAddress('glTexImage1D');
2125   glTexImage2D := glbGetProcAddress('glTexImage2D');
2126   glGetTexImage := glbGetProcAddress('glGetTexImage');
2127
2128   gluBuild1DMipmaps := glbGetProcAddress('gluBuild1DMipmaps', GLU_LibHandle);
2129   gluBuild2DMipmaps := glbGetProcAddress('gluBuild2DMipmaps', GLU_LibHandle);
2130 end;
2131 {$ENDIF}
2132
2133 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2134 procedure glbReadOpenGLExtensions;
2135 var
2136   Buffer: AnsiString;
2137   MajorVersion, MinorVersion: Integer;
2138
2139   ///////////////////////////////////////////////////////////////////////////////////////////
2140   procedure TrimVersionString(aBuffer: AnsiString; out aMajor, aMinor: Integer);
2141   var
2142     Separator: Integer;
2143   begin
2144     aMinor := 0;
2145     aMajor := 0;
2146
2147     Separator := Pos(AnsiString('.'), aBuffer);
2148     if (Separator > 1) and (Separator < Length(aBuffer)) and
2149        (aBuffer[Separator - 1] in ['0'..'9']) and
2150        (aBuffer[Separator + 1] in ['0'..'9']) then begin
2151
2152       Dec(Separator);
2153       while (Separator > 0) and (aBuffer[Separator] in ['0'..'9']) do
2154         Dec(Separator);
2155
2156       Delete(aBuffer, 1, Separator);
2157       Separator := Pos(AnsiString('.'), aBuffer) + 1;
2158
2159       while (Separator <= Length(aBuffer)) and (AnsiChar(aBuffer[Separator]) in ['0'..'9']) do
2160         Inc(Separator);
2161
2162       Delete(aBuffer, Separator, 255);
2163       Separator := Pos(AnsiString('.'), aBuffer);
2164
2165       aMajor := StrToInt(Copy(String(aBuffer), 1, Separator - 1));
2166       aMinor := StrToInt(Copy(String(aBuffer), Separator + 1, 1));
2167     end;
2168   end;
2169
2170   ///////////////////////////////////////////////////////////////////////////////////////////
2171   function CheckExtension(const Extension: AnsiString): Boolean;
2172   var
2173     ExtPos: Integer;
2174   begin
2175     ExtPos := Pos(Extension, Buffer);
2176     result := ExtPos > 0;
2177     if result then
2178       result := ((ExtPos + Length(Extension) - 1) = Length(Buffer)) or not (Buffer[ExtPos + Length(Extension)] in ['_', 'A'..'Z', 'a'..'z']);
2179   end;
2180
2181   ///////////////////////////////////////////////////////////////////////////////////////////
2182   function CheckVersion(const aMajor, aMinor: Integer): Boolean;
2183   begin
2184     result := (MajorVersion > aMajor) or ((MajorVersion = aMajor) and (MinorVersion >= aMinor));
2185   end;
2186
2187 begin
2188 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
2189   InitOpenGLCS.Enter;
2190   try
2191     if not OpenGLInitialized then begin
2192       glbInitOpenGL;
2193       OpenGLInitialized := true;
2194     end;
2195   finally
2196     InitOpenGLCS.Leave;
2197   end;
2198 {$ENDIF}
2199
2200   // Version
2201   Buffer := glGetString(GL_VERSION);
2202   TrimVersionString(Buffer, MajorVersion, MinorVersion);
2203
2204   GL_VERSION_1_2 := CheckVersion(1, 2);
2205   GL_VERSION_1_3 := CheckVersion(1, 3);
2206   GL_VERSION_1_4 := CheckVersion(1, 4);
2207   GL_VERSION_2_0 := CheckVersion(2, 0);
2208   GL_VERSION_3_3 := CheckVersion(3, 3);
2209
2210   // Extensions
2211   Buffer := glGetString(GL_EXTENSIONS);
2212   GL_ARB_texture_border_clamp       := CheckExtension('GL_ARB_texture_border_clamp');
2213   GL_ARB_texture_non_power_of_two   := CheckExtension('GL_ARB_texture_non_power_of_two');
2214   GL_ARB_texture_swizzle            := CheckExtension('GL_ARB_texture_swizzle');
2215   GL_ARB_texture_cube_map           := CheckExtension('GL_ARB_texture_cube_map');
2216   GL_ARB_texture_rectangle          := CheckExtension('GL_ARB_texture_rectangle');
2217   GL_ARB_texture_mirrored_repeat    := CheckExtension('GL_ARB_texture_mirrored_repeat');
2218   GL_EXT_texture_edge_clamp         := CheckExtension('GL_EXT_texture_edge_clamp');
2219   GL_EXT_texture_filter_anisotropic := CheckExtension('GL_EXT_texture_filter_anisotropic');
2220   GL_EXT_texture_rectangle          := CheckExtension('GL_EXT_texture_rectangle');
2221   GL_EXT_texture_swizzle            := CheckExtension('GL_EXT_texture_swizzle');
2222   GL_EXT_texture_cube_map           := CheckExtension('GL_EXT_texture_cube_map');
2223   GL_NV_texture_rectangle           := CheckExtension('GL_NV_texture_rectangle');
2224   GL_IBM_texture_mirrored_repeat    := CheckExtension('GL_IBM_texture_mirrored_repeat');
2225   GL_SGIS_generate_mipmap           := CheckExtension('GL_SGIS_generate_mipmap');
2226
2227   if GL_VERSION_1_3 then begin
2228     glCompressedTexImage1D  := glbGetProcAddress('glCompressedTexImage1D');
2229     glCompressedTexImage2D  := glbGetProcAddress('glCompressedTexImage2D');
2230     glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImage');
2231   end else begin
2232     glCompressedTexImage1D  := glbGetProcAddress('glCompressedTexImage1DARB',  nil, false);
2233     glCompressedTexImage2D  := glbGetProcAddress('glCompressedTexImage2DARB',  nil, false);
2234     glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImageARB', nil, false);
2235   end;
2236 end;
2237 {$ENDIF}
2238
2239 {$IFDEF GLB_SDL_IMAGE}
2240 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2241 // SDL Image Helper /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2242 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2243 function glBitmapRWseek(context: PSDL_RWops; offset: Integer; whence: Integer): Integer; cdecl;
2244 begin
2245   result := TStream(context^.unknown.data1).Seek(offset, whence);
2246 end;
2247
2248 function glBitmapRWread(context: PSDL_RWops; Ptr: Pointer; size: Integer; maxnum : Integer): Integer; cdecl;
2249 begin
2250   result := TStream(context^.unknown.data1).Read(Ptr^, size * maxnum);
2251 end;
2252
2253 function glBitmapRWwrite(context: PSDL_RWops; Ptr: Pointer; size: Integer; num: Integer): Integer; cdecl;
2254 begin
2255   result := TStream(context^.unknown.data1).Write(Ptr^, size * num);
2256 end;
2257
2258 function glBitmapRWclose(context: PSDL_RWops): Integer; cdecl;
2259 begin
2260   result := 0;
2261 end;
2262
2263 function glBitmapCreateRWops(Stream: TStream): PSDL_RWops;
2264 begin
2265   result := SDL_AllocRW;
2266
2267   if result = nil then
2268     raise EglBitmapException.Create('glBitmapCreateRWops - SDL_AllocRW failed.');
2269
2270   result^.seek := glBitmapRWseek;
2271   result^.read := glBitmapRWread;
2272   result^.write := glBitmapRWwrite;
2273   result^.close := glBitmapRWclose;
2274   result^.unknown.data1 := Stream;
2275 end;
2276 {$ENDIF}
2277
2278 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2279 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
2280 begin
2281   glBitmapDefaultDeleteTextureOnFree := aDeleteTextureOnFree;
2282 end;
2283
2284 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2285 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
2286 begin
2287   glBitmapDefaultFreeDataAfterGenTextures := aFreeData;
2288 end;
2289
2290 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2291 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
2292 begin
2293   glBitmapDefaultMipmap := aValue;
2294 end;
2295
2296 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2297 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
2298 begin
2299   glBitmapDefaultFormat := aFormat;
2300 end;
2301
2302 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2303 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
2304 begin
2305   glBitmapDefaultFilterMin := aMin;
2306   glBitmapDefaultFilterMag := aMag;
2307 end;
2308
2309 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2310 procedure glBitmapSetDefaultWrap(const S: Cardinal = GL_CLAMP_TO_EDGE; const T: Cardinal = GL_CLAMP_TO_EDGE; const R: Cardinal = GL_CLAMP_TO_EDGE);
2311 begin
2312   glBitmapDefaultWrapS := S;
2313   glBitmapDefaultWrapT := T;
2314   glBitmapDefaultWrapR := R;
2315 end;
2316
2317 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2318 procedure glBitmapSetDefaultSwizzle(const r: GLenum = GL_RED; g: GLenum = GL_GREEN; b: GLenum = GL_BLUE; a: GLenum = GL_ALPHA);
2319 begin
2320   glDefaultSwizzle[0] := r;
2321   glDefaultSwizzle[1] := g;
2322   glDefaultSwizzle[2] := b;
2323   glDefaultSwizzle[3] := a;
2324 end;
2325
2326 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2327 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
2328 begin
2329   result := glBitmapDefaultDeleteTextureOnFree;
2330 end;
2331
2332 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2333 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
2334 begin
2335   result := glBitmapDefaultFreeDataAfterGenTextures;
2336 end;
2337
2338 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2339 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
2340 begin
2341   result := glBitmapDefaultMipmap;
2342 end;
2343
2344 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2345 function glBitmapGetDefaultFormat: TglBitmapFormat;
2346 begin
2347   result := glBitmapDefaultFormat;
2348 end;
2349
2350 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2351 procedure glBitmapGetDefaultFilter(var aMin, aMag: GLenum);
2352 begin
2353   aMin := glBitmapDefaultFilterMin;
2354   aMag := glBitmapDefaultFilterMag;
2355 end;
2356
2357 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2358 procedure glBitmapGetDefaultTextureWrap(var S, T, R: GLenum);
2359 begin
2360   S := glBitmapDefaultWrapS;
2361   T := glBitmapDefaultWrapT;
2362   R := glBitmapDefaultWrapR;
2363 end;
2364
2365 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2366 procedure glBitmapGetDefaultSwizzle(var r, g, b, a: GLenum);
2367 begin
2368   r := glDefaultSwizzle[0];
2369   g := glDefaultSwizzle[1];
2370   b := glDefaultSwizzle[2];
2371   a := glDefaultSwizzle[3];
2372 end;
2373
2374 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2375 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2376 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2377 function TFormatDescriptor.GetRedMask: QWord;
2378 begin
2379   result := fRange.r shl fShift.r;
2380 end;
2381
2382 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2383 function TFormatDescriptor.GetGreenMask: QWord;
2384 begin
2385   result := fRange.g shl fShift.g;
2386 end;
2387
2388 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2389 function TFormatDescriptor.GetBlueMask: QWord;
2390 begin
2391   result := fRange.b shl fShift.b;
2392 end;
2393
2394 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2395 function TFormatDescriptor.GetAlphaMask: QWord;
2396 begin
2397   result := fRange.a shl fShift.a;
2398 end;
2399
2400 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2401 function TFormatDescriptor.GetIsCompressed: Boolean;
2402 begin
2403   result := fIsCompressed;
2404 end;
2405
2406 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2407 function TFormatDescriptor.GetHasRed: Boolean;
2408 begin
2409   result := (fRange.r > 0);
2410 end;
2411
2412 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2413 function TFormatDescriptor.GetHasGreen: Boolean;
2414 begin
2415   result := (fRange.g > 0);
2416 end;
2417
2418 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2419 function TFormatDescriptor.GetHasBlue: Boolean;
2420 begin
2421   result := (fRange.b > 0);
2422 end;
2423
2424 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2425 function TFormatDescriptor.GetHasAlpha: Boolean;
2426 begin
2427   result := (fRange.a > 0);
2428 end;
2429
2430 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2431 function TFormatDescriptor.GetRGBInverted: TglBitmapFormat;
2432 begin
2433   result := fRGBInverted;
2434 end;
2435
2436 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2437 function TFormatDescriptor.GetWithAlpha: TglBitmapFormat;
2438 begin
2439   result := fWithAlpha;
2440 end;
2441
2442 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2443 function TFormatDescriptor.GetWithoutAlpha: TglBitmapFormat;
2444 begin
2445   result := fWithoutAlpha;
2446 end;
2447
2448 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2449 function TFormatDescriptor.GetOpenGLFormat: TglBitmapFormat;
2450 begin
2451   result := fOpenGLFormat;
2452 end;
2453
2454 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2455 function TFormatDescriptor.GetUncompressed: TglBitmapFormat;
2456 begin
2457   result := fUncompressed;
2458 end;
2459
2460 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2461 function TFormatDescriptor.GetglFormat: GLenum;
2462 begin
2463   result := fglFormat;
2464 end;
2465
2466 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2467 function TFormatDescriptor.GetglInternalFormat: GLenum;
2468 begin
2469   result := fglInternalFormat;
2470 end;
2471
2472 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2473 function TFormatDescriptor.GetglDataFormat: GLenum;
2474 begin
2475   result := fglDataFormat;
2476 end;
2477
2478 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2479 function TFormatDescriptor.GetComponents: Integer;
2480 var
2481   i: Integer;
2482 begin
2483   result := 0;
2484   for i := 0 to 3 do
2485     if (fRange.arr[i] > 0) then
2486       inc(result);
2487 end;
2488
2489 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2490 function TFormatDescriptor.GetSize(const aSize: TglBitmapPixelPosition): Integer;
2491 var
2492   w, h: Integer;
2493 begin
2494   if (ffX in aSize.Fields) or (ffY in aSize.Fields) then begin
2495     w := Max(1, aSize.X);
2496     h := Max(1, aSize.Y);
2497     result := GetSize(w, h);
2498   end else
2499     result := 0;
2500 end;
2501
2502 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2503 function TFormatDescriptor.GetSize(const aWidth, aHeight: Integer): Integer;
2504 begin
2505   result := 0;
2506   if (aWidth <= 0) or (aHeight <= 0) then
2507     exit;
2508   result := Ceil(aWidth * aHeight * fPixelSize);
2509 end;
2510
2511 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2512 function TFormatDescriptor.CreateMappingData: Pointer;
2513 begin
2514   result := nil;
2515 end;
2516
2517 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2518 procedure TFormatDescriptor.FreeMappingData(var aMappingData: Pointer);
2519 begin
2520   //DUMMY
2521 end;
2522
2523 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2524 function TFormatDescriptor.IsEmpty: Boolean;
2525 begin
2526   result := (fFormat = tfEmpty);
2527 end;
2528
2529 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2530 function TFormatDescriptor.MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: QWord): Boolean;
2531 begin
2532   result := false;
2533   if (aRedMask = 0) and (aGreenMask = 0) and (aBlueMask = 0) and (aAlphaMask = 0) then
2534     raise EglBitmap.Create('FormatCheckFormat - All Masks are 0');
2535   if (aRedMask   <> RedMask) then
2536     exit;
2537   if (aGreenMask <> GreenMask) then
2538     exit;
2539   if (aBlueMask  <> BlueMask) then
2540     exit;
2541   if (aAlphaMask <> AlphaMask) then
2542     exit;
2543   result := true;
2544 end;
2545
2546 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2547 procedure TFormatDescriptor.PreparePixel(out aPixel: TglBitmapPixelData);
2548 begin
2549   FillChar(aPixel{%H-}, SizeOf(aPixel), 0);
2550   aPixel.Data   := fRange;
2551   aPixel.Range  := fRange;
2552   aPixel.Format := fFormat;
2553 end;
2554
2555 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2556 constructor TFormatDescriptor.Create;
2557 begin
2558   inherited Create;
2559
2560   fFormat       := tfEmpty;
2561   fWithAlpha    := tfEmpty;
2562   fWithoutAlpha := tfEmpty;
2563   fOpenGLFormat := tfEmpty;
2564   fRGBInverted  := tfEmpty;
2565   fUncompressed := tfEmpty;
2566
2567   fPixelSize    := 0.0;
2568   fIsCompressed := false;
2569
2570   fglFormat         := 0;
2571   fglInternalFormat := 0;
2572   fglDataFormat     := 0;
2573
2574   FillChar(fRange, 0, SizeOf(fRange));
2575   FillChar(fShift, 0, SizeOf(fShift));
2576 end;
2577
2578 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2579 //TfdAlpha_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2580 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2581 procedure TfdAlpha_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2582 begin
2583   aData^ := aPixel.Data.a;
2584   inc(aData);
2585 end;
2586
2587 procedure TfdAlpha_UB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2588 begin
2589   aPixel.Data.r := 0;
2590   aPixel.Data.g := 0;
2591   aPixel.Data.b := 0;
2592   aPixel.Data.a := aData^;
2593   inc(aData);
2594 end;
2595
2596 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2597 //TfdLuminance_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2598 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2599 procedure TfdLuminance_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2600 begin
2601   aData^ := LuminanceWeight(aPixel);
2602   inc(aData);
2603 end;
2604
2605 procedure TfdLuminance_UB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2606 begin
2607   aPixel.Data.r := aData^;
2608   aPixel.Data.g := aData^;
2609   aPixel.Data.b := aData^;
2610   aPixel.Data.a := 0;
2611   inc(aData);
2612 end;
2613
2614 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2615 //TfdUniversal_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2616 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2617 procedure TfdUniversal_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2618 var
2619   i: Integer;
2620 begin
2621   aData^ := 0;
2622   for i := 0 to 3 do
2623     if (fRange.arr[i] > 0) then
2624       aData^ := aData^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
2625   inc(aData);
2626 end;
2627
2628 procedure TfdUniversal_UB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2629 var
2630   i: Integer;
2631 begin
2632   for i := 0 to 3 do
2633     aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and fRange.arr[i];
2634   inc(aData);
2635 end;
2636
2637 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2638 //TfdLuminanceAlpha_UB2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2639 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2640 procedure TfdLuminanceAlpha_UB2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2641 begin
2642   inherited Map(aPixel, aData, aMapData);
2643   aData^ := aPixel.Data.a;
2644   inc(aData);
2645 end;
2646
2647 procedure TfdLuminanceAlpha_UB2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2648 begin
2649   inherited Unmap(aData, aPixel, aMapData);
2650   aPixel.Data.a := aData^;
2651   inc(aData);
2652 end;
2653
2654 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2655 //TfdRGB_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2656 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2657 procedure TfdRGB_UB3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2658 begin
2659   aData^ := aPixel.Data.b;
2660   inc(aData);
2661   aData^ := aPixel.Data.g;
2662   inc(aData);
2663   aData^ := aPixel.Data.r;
2664   inc(aData);
2665 end;
2666
2667 procedure TfdRGB_UB3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2668 begin
2669   aPixel.Data.b := aData^;
2670   inc(aData);
2671   aPixel.Data.g := aData^;
2672   inc(aData);
2673   aPixel.Data.r := aData^;
2674   inc(aData);
2675   aPixel.Data.a := 0;
2676 end;
2677
2678 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2679 //TfdBGR_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2680 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2681 procedure TfdBGR_UB3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2682 begin
2683   aData^ := aPixel.Data.r;
2684   inc(aData);
2685   aData^ := aPixel.Data.g;
2686   inc(aData);
2687   aData^ := aPixel.Data.b;
2688   inc(aData);
2689 end;
2690
2691 procedure TfdBGR_UB3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2692 begin
2693   aPixel.Data.r := aData^;
2694   inc(aData);
2695   aPixel.Data.g := aData^;
2696   inc(aData);
2697   aPixel.Data.b := aData^;
2698   inc(aData);
2699   aPixel.Data.a := 0;
2700 end;
2701
2702 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2703 //TfdAlpha_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2704 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2705 procedure TfdAlpha_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2706 begin
2707   PWord(aData)^ := aPixel.Data.a;
2708   inc(aData, 2);
2709 end;
2710
2711 procedure TfdAlpha_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2712 begin
2713   aPixel.Data.r := 0;
2714   aPixel.Data.g := 0;
2715   aPixel.Data.b := 0;
2716   aPixel.Data.a := PWord(aData)^;
2717   inc(aData, 2);
2718 end;
2719
2720 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2721 //TfdLuminance_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2722 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2723 procedure TfdLuminance_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2724 begin
2725   PWord(aData)^ := LuminanceWeight(aPixel);
2726   inc(aData, 2);
2727 end;
2728
2729 procedure TfdLuminance_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2730 begin
2731   aPixel.Data.r := PWord(aData)^;
2732   aPixel.Data.g := PWord(aData)^;
2733   aPixel.Data.b := PWord(aData)^;
2734   aPixel.Data.a := 0;
2735   inc(aData, 2);
2736 end;
2737
2738 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2739 //TfdUniversal_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2740 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2741 procedure TfdUniversal_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2742 var
2743   i: Integer;
2744 begin
2745   PWord(aData)^ := 0;
2746   for i := 0 to 3 do
2747     if (fRange.arr[i] > 0) then
2748       PWord(aData)^ := PWord(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
2749   inc(aData, 2);
2750 end;
2751
2752 procedure TfdUniversal_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2753 var
2754   i: Integer;
2755 begin
2756   for i := 0 to 3 do
2757     aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and fRange.arr[i];
2758   inc(aData, 2);
2759 end;
2760
2761 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2762 //TfdDepth_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2763 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2764 procedure TfdDepth_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2765 begin
2766   PWord(aData)^ := DepthWeight(aPixel);
2767   inc(aData, 2);
2768 end;
2769
2770 procedure TfdDepth_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2771 begin
2772   aPixel.Data.r := PWord(aData)^;
2773   aPixel.Data.g := PWord(aData)^;
2774   aPixel.Data.b := PWord(aData)^;
2775   aPixel.Data.a := PWord(aData)^;;
2776   inc(aData, 2);
2777 end;
2778
2779 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2780 //TfdLuminanceAlpha_US2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2781 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2782 procedure TfdLuminanceAlpha_US2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2783 begin
2784   inherited Map(aPixel, aData, aMapData);
2785   PWord(aData)^ := aPixel.Data.a;
2786   inc(aData, 2);
2787 end;
2788
2789 procedure TfdLuminanceAlpha_US2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2790 begin
2791   inherited Unmap(aData, aPixel, aMapData);
2792   aPixel.Data.a := PWord(aData)^;
2793   inc(aData, 2);
2794 end;
2795
2796 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2797 //TfdRGB_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2798 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2799 procedure TfdRGB_US3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2800 begin
2801   PWord(aData)^ := aPixel.Data.b;
2802   inc(aData, 2);
2803   PWord(aData)^ := aPixel.Data.g;
2804   inc(aData, 2);
2805   PWord(aData)^ := aPixel.Data.r;
2806   inc(aData, 2);
2807 end;
2808
2809 procedure TfdRGB_US3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2810 begin
2811   aPixel.Data.b := PWord(aData)^;
2812   inc(aData, 2);
2813   aPixel.Data.g := PWord(aData)^;
2814   inc(aData, 2);
2815   aPixel.Data.r := PWord(aData)^;
2816   inc(aData, 2);
2817   aPixel.Data.a := 0;
2818 end;
2819
2820 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2821 //TfdBGR_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2822 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2823 procedure TfdBGR_US3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2824 begin
2825   PWord(aData)^ := aPixel.Data.r;
2826   inc(aData, 2);
2827   PWord(aData)^ := aPixel.Data.g;
2828   inc(aData, 2);
2829   PWord(aData)^ := aPixel.Data.b;
2830   inc(aData, 2);
2831 end;
2832
2833 procedure TfdBGR_US3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2834 begin
2835   aPixel.Data.r := PWord(aData)^;
2836   inc(aData, 2);
2837   aPixel.Data.g := PWord(aData)^;
2838   inc(aData, 2);
2839   aPixel.Data.b := PWord(aData)^;
2840   inc(aData, 2);
2841   aPixel.Data.a := 0;
2842 end;
2843
2844 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2845 //TfdRGBA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2846 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2847 procedure TfdRGBA_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2848 begin
2849   PWord(aData)^ := aPixel.Data.a;
2850   inc(aData, 2);
2851   inherited Map(aPixel, aData, aMapData);
2852 end;
2853
2854 procedure TfdRGBA_US4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2855 begin
2856   aPixel.Data.a := PWord(aData)^;
2857   inc(aData, 2);
2858   inherited Unmap(aData, aPixel, aMapData);
2859 end;
2860
2861 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2862 //TfdARGB_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2863 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2864 procedure TfdARGB_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2865 begin
2866   inherited Map(aPixel, aData, aMapData);
2867   PWord(aData)^ := aPixel.Data.a;
2868   inc(aData, 2);
2869 end;
2870
2871 procedure TfdARGB_US4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2872 begin
2873   inherited Unmap(aData, aPixel, aMapData);
2874   aPixel.Data.a := PWord(aData)^;
2875   inc(aData, 2);
2876 end;
2877
2878 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2879 //TfdBGRA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2880 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2881 procedure TfdBGRA_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2882 begin
2883   PWord(aData)^ := aPixel.Data.a;
2884   inc(aData, 2);
2885   inherited Map(aPixel, aData, aMapData);
2886 end;
2887
2888 procedure TfdBGRA_US4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2889 begin
2890   aPixel.Data.a := PWord(aData)^;
2891   inc(aData, 2);
2892   inherited Unmap(aData, aPixel, aMapData);
2893 end;
2894
2895 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2896 //TfdABGR_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2897 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2898 procedure TfdABGR_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2899 begin
2900   inherited Map(aPixel, aData, aMapData);
2901   PWord(aData)^ := aPixel.Data.a;
2902   inc(aData, 2);
2903 end;
2904
2905 procedure TfdABGR_US4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2906 begin
2907   inherited Unmap(aData, aPixel, aMapData);
2908   aPixel.Data.a := PWord(aData)^;
2909   inc(aData, 2);
2910 end;
2911
2912 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2913 //TfdUniversal_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2914 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2915 procedure TfdUniversal_UI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2916 var
2917   i: Integer;
2918 begin
2919   PCardinal(aData)^ := 0;
2920   for i := 0 to 3 do
2921     if (fRange.arr[i] > 0) then
2922       PCardinal(aData)^ := PCardinal(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
2923   inc(aData, 4);
2924 end;
2925
2926 procedure TfdUniversal_UI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2927 var
2928   i: Integer;
2929 begin
2930   for i := 0 to 3 do
2931     aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and fRange.arr[i];
2932   inc(aData, 2);
2933 end;
2934
2935 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2936 //TfdDepth_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2937 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2938 procedure TfdDepth_UI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2939 begin
2940   PCardinal(aData)^ := DepthWeight(aPixel);
2941   inc(aData, 4);
2942 end;
2943
2944 procedure TfdDepth_UI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2945 begin
2946   aPixel.Data.r := PCardinal(aData)^;
2947   aPixel.Data.g := PCardinal(aData)^;
2948   aPixel.Data.b := PCardinal(aData)^;
2949   aPixel.Data.a := 0;
2950   inc(aData, 4);
2951 end;
2952
2953 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2954 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2955 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2956 constructor TfdAlpha4.Create;
2957 begin
2958   inherited Create;
2959   fPixelSize        := 1.0;
2960   fFormat           := tfAlpha4;
2961   fWithAlpha        := tfAlpha4;
2962   fOpenGLFormat     := tfAlpha4;
2963   fRange.a          := $FF;
2964   fglFormat         := GL_ALPHA;
2965   fglInternalFormat := GL_ALPHA4;
2966   fglDataFormat     := GL_UNSIGNED_BYTE;
2967 end;
2968
2969 constructor TfdAlpha8.Create;
2970 begin
2971   inherited Create;
2972   fPixelSize        := 1.0;
2973   fFormat           := tfAlpha8;
2974   fWithAlpha        := tfAlpha8;
2975   fOpenGLFormat     := tfAlpha8;
2976   fRange.a          := $FF;
2977   fglFormat         := GL_ALPHA;
2978   fglInternalFormat := GL_ALPHA8;
2979   fglDataFormat     := GL_UNSIGNED_BYTE;
2980 end;
2981
2982 constructor TfdAlpha16.Create;
2983 begin
2984   inherited Create;
2985   fPixelSize        := 2.0;
2986   fFormat           := tfAlpha16;
2987   fWithAlpha        := tfAlpha16;
2988   fOpenGLFormat     := tfAlpha16;
2989   fRange.a          := $FFFF;
2990   fglFormat         := GL_ALPHA;
2991   fglInternalFormat := GL_ALPHA16;
2992   fglDataFormat     := GL_UNSIGNED_SHORT;
2993 end;
2994
2995 constructor TfdLuminance4.Create;
2996 begin
2997   inherited Create;
2998   fPixelSize        := 1.0;
2999   fFormat           := tfLuminance4;
3000   fWithAlpha        := tfLuminance4Alpha4;
3001   fWithoutAlpha     := tfLuminance4;
3002   fOpenGLFormat     := tfLuminance4;
3003   fRange.r          := $FF;
3004   fRange.g          := $FF;
3005   fRange.b          := $FF;
3006   fglFormat         := GL_LUMINANCE;
3007   fglInternalFormat := GL_LUMINANCE4;
3008   fglDataFormat     := GL_UNSIGNED_BYTE;
3009 end;
3010
3011 constructor TfdLuminance8.Create;
3012 begin
3013   inherited Create;
3014   fPixelSize        := 1.0;
3015   fFormat           := tfLuminance8;
3016   fWithAlpha        := tfLuminance8Alpha8;
3017   fWithoutAlpha     := tfLuminance8;
3018   fOpenGLFormat     := tfLuminance8;
3019   fRange.r          := $FF;
3020   fRange.g          := $FF;
3021   fRange.b          := $FF;
3022   fglFormat         := GL_LUMINANCE;
3023   fglInternalFormat := GL_LUMINANCE8;
3024   fglDataFormat     := GL_UNSIGNED_BYTE;
3025 end;
3026
3027 constructor TfdLuminance16.Create;
3028 begin
3029   inherited Create;
3030   fPixelSize        := 2.0;
3031   fFormat           := tfLuminance16;
3032   fWithAlpha        := tfLuminance16Alpha16;
3033   fWithoutAlpha     := tfLuminance16;
3034   fOpenGLFormat     := tfLuminance16;
3035   fRange.r          := $FFFF;
3036   fRange.g          := $FFFF;
3037   fRange.b          := $FFFF;
3038   fglFormat         := GL_LUMINANCE;
3039   fglInternalFormat := GL_LUMINANCE16;
3040   fglDataFormat     := GL_UNSIGNED_SHORT;
3041 end;
3042
3043 constructor TfdLuminance4Alpha4.Create;
3044 begin
3045   inherited Create;
3046   fPixelSize        := 2.0;
3047   fFormat           := tfLuminance4Alpha4;
3048   fWithAlpha        := tfLuminance4Alpha4;
3049   fWithoutAlpha     := tfLuminance4;
3050   fOpenGLFormat     := tfLuminance4Alpha4;
3051   fRange.r          := $FF;
3052   fRange.g          := $FF;
3053   fRange.b          := $FF;
3054   fRange.a          := $FF;
3055   fShift.r          := 0;
3056   fShift.g          := 0;
3057   fShift.b          := 0;
3058   fShift.a          := 8;
3059   fglFormat         := GL_LUMINANCE_ALPHA;
3060   fglInternalFormat := GL_LUMINANCE4_ALPHA4;
3061   fglDataFormat     := GL_UNSIGNED_BYTE;
3062 end;
3063
3064 constructor TfdLuminance6Alpha2.Create;
3065 begin
3066   inherited Create;
3067   fPixelSize        := 2.0;
3068   fFormat           := tfLuminance6Alpha2;
3069   fWithAlpha        := tfLuminance6Alpha2;
3070   fWithoutAlpha     := tfLuminance8;
3071   fOpenGLFormat     := tfLuminance6Alpha2;
3072   fRange.r          := $FF;
3073   fRange.g          := $FF;
3074   fRange.b          := $FF;
3075   fRange.a          := $FF;
3076   fShift.r          := 0;
3077   fShift.g          := 0;
3078   fShift.b          := 0;
3079   fShift.a          := 8;
3080   fglFormat         := GL_LUMINANCE_ALPHA;
3081   fglInternalFormat := GL_LUMINANCE6_ALPHA2;
3082   fglDataFormat     := GL_UNSIGNED_BYTE;
3083 end;
3084
3085 constructor TfdLuminance8Alpha8.Create;
3086 begin
3087   inherited Create;
3088   fPixelSize        := 2.0;
3089   fFormat           := tfLuminance8Alpha8;
3090   fWithAlpha        := tfLuminance8Alpha8;
3091   fWithoutAlpha     := tfLuminance8;
3092   fOpenGLFormat     := tfLuminance8Alpha8;
3093   fRange.r          := $FF;
3094   fRange.g          := $FF;
3095   fRange.b          := $FF;
3096   fRange.a          := $FF;
3097   fShift.r          := 0;
3098   fShift.g          := 0;
3099   fShift.b          := 0;
3100   fShift.a          := 8;
3101   fglFormat         := GL_LUMINANCE_ALPHA;
3102   fglInternalFormat := GL_LUMINANCE8_ALPHA8;
3103   fglDataFormat     := GL_UNSIGNED_BYTE;
3104 end;
3105
3106 constructor TfdLuminance12Alpha4.Create;
3107 begin
3108   inherited Create;
3109   fPixelSize        := 4.0;
3110   fFormat           := tfLuminance12Alpha4;
3111   fWithAlpha        := tfLuminance12Alpha4;
3112   fWithoutAlpha     := tfLuminance16;
3113   fOpenGLFormat     := tfLuminance12Alpha4;
3114   fRange.r          := $FFFF;
3115   fRange.g          := $FFFF;
3116   fRange.b          := $FFFF;
3117   fRange.a          := $FFFF;
3118   fShift.r          := 0;
3119   fShift.g          := 0;
3120   fShift.b          := 0;
3121   fShift.a          := 16;
3122   fglFormat         := GL_LUMINANCE_ALPHA;
3123   fglInternalFormat := GL_LUMINANCE12_ALPHA4;
3124   fglDataFormat     := GL_UNSIGNED_SHORT;
3125 end;
3126
3127 constructor TfdLuminance16Alpha16.Create;
3128 begin
3129   inherited Create;
3130   fPixelSize        := 4.0;
3131   fFormat           := tfLuminance16Alpha16;
3132   fWithAlpha        := tfLuminance16Alpha16;
3133   fWithoutAlpha     := tfLuminance16;
3134   fOpenGLFormat     := tfLuminance16Alpha16;
3135   fRange.r          := $FFFF;
3136   fRange.g          := $FFFF;
3137   fRange.b          := $FFFF;
3138   fRange.a          := $FFFF;
3139   fShift.r          := 0;
3140   fShift.g          := 0;
3141   fShift.b          := 0;
3142   fShift.a          := 16;
3143   fglFormat         := GL_LUMINANCE_ALPHA;
3144   fglInternalFormat := GL_LUMINANCE16_ALPHA16;
3145   fglDataFormat     := GL_UNSIGNED_SHORT;
3146 end;
3147
3148 constructor TfdR3G3B2.Create;
3149 begin
3150   inherited Create;
3151   fPixelSize        := 1.0;
3152   fFormat           := tfR3G3B2;
3153   fWithAlpha        := tfRGBA4;
3154   fWithoutAlpha     := tfR3G3B2;
3155   fOpenGLFormat     := tfR3G3B2;
3156   fRGBInverted      := tfEmpty;
3157   fRange.r          := $07;
3158   fRange.g          := $07;
3159   fRange.b          := $04;
3160   fShift.r          := 5;
3161   fShift.g          := 2;
3162   fShift.b          := 0;
3163   fglFormat         := GL_RGB;
3164   fglInternalFormat := GL_R3_G3_B2;
3165   fglDataFormat     := GL_UNSIGNED_BYTE_3_3_2;
3166 end;
3167
3168 constructor TfdRGBX4.Create;
3169 begin
3170   inherited Create;
3171   fPixelSize        := 2.0;
3172   fFormat           := tfRGBX4;
3173   fWithAlpha        := tfRGBA4;
3174   fWithoutAlpha     := tfRGBX4;
3175   fOpenGLFormat     := tfRGBX4;
3176   fRGBInverted      := tfBGRX4;
3177   fRange.r          := $0F;
3178   fRange.g          := $0F;
3179   fRange.b          := $0F;
3180   fRange.a          := $00;
3181   fShift.r          := 12;
3182   fShift.g          :=  8;
3183   fShift.b          :=  4;
3184   fglFormat         := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3185   fglInternalFormat := GL_RGB4;
3186   fglDataFormat     := GL_UNSIGNED_SHORT_4_4_4_4;
3187 end;
3188
3189 constructor TfdXRGB4.Create;
3190 begin
3191   inherited Create;
3192   fPixelSize        := 2.0;
3193   fFormat           := tfXRGB4;
3194   fWithAlpha        := tfARGB4;
3195   fWithoutAlpha     := tfXRGB4;
3196   fOpenGLFormat     := tfXRGB4;
3197   fRGBInverted      := tfXBGR4;
3198   fRange.r          := $0F;
3199   fRange.g          := $0F;
3200   fRange.b          := $0F;
3201   fShift.r          := 8;
3202   fShift.g          := 4;
3203   fShift.b          := 0;
3204   fglFormat         := GL_BGRA;
3205   fglInternalFormat := GL_RGB4;
3206   fglDataFormat     := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3207 end;
3208
3209 constructor TfdR5G6B5.Create;
3210 begin
3211   inherited Create;
3212   fPixelSize        := 2.0;
3213   fFormat           := tfR5G6B5;
3214   fWithAlpha        := tfRGB5A1;
3215   fWithoutAlpha     := tfR5G6B5;
3216   fOpenGLFormat     := tfR5G6B5;
3217   fRGBInverted      := tfB5G6R5;
3218   fRange.r          := $1F;
3219   fRange.g          := $3F;
3220   fRange.b          := $1F;
3221   fShift.r          := 11;
3222   fShift.g          := 5;
3223   fShift.b          := 0;
3224   fglFormat         := GL_RGB;
3225   fglInternalFormat := GL_RGB565;
3226   fglDataFormat     := GL_UNSIGNED_SHORT_5_6_5;
3227 end;
3228
3229 constructor TfdRGB5X1.Create;
3230 begin
3231   inherited Create;
3232   fPixelSize        := 2.0;
3233   fFormat           := tfRGB5X1;
3234   fWithAlpha        := tfRGB5A1;
3235   fWithoutAlpha     := tfRGB5X1;
3236   fOpenGLFormat     := tfRGB5X1;
3237   fRGBInverted      := tfBGR5X1;
3238   fRange.r          := $1F;
3239   fRange.g          := $1F;
3240   fRange.b          := $1F;
3241   fShift.r          := 11;
3242   fShift.g          :=  6;
3243   fShift.b          :=  1;
3244   fglFormat         := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3245   fglInternalFormat := GL_RGB5;
3246   fglDataFormat     := GL_UNSIGNED_SHORT_5_5_5_1;
3247 end;
3248
3249 constructor TfdX1RGB5.Create;
3250 begin
3251   inherited Create;
3252   fPixelSize        := 2.0;
3253   fFormat           := tfX1RGB5;
3254   fWithAlpha        := tfA1RGB5;
3255   fWithoutAlpha     := tfX1RGB5;
3256   fOpenGLFormat     := tfX1RGB5;
3257   fRGBInverted      := tfX1BGR5;
3258   fRange.r          := $1F;
3259   fRange.g          := $1F;
3260   fRange.b          := $1F;
3261   fShift.r          := 10;
3262   fShift.g          :=  5;
3263   fShift.b          :=  0;
3264   fglFormat         := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3265   fglInternalFormat := GL_RGB5;
3266   fglDataFormat     := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3267 end;
3268
3269 constructor TfdRGB8.Create;
3270 begin
3271   inherited Create;
3272   fPixelSize        := 3.0;
3273   fFormat           := tfRGB8;
3274   fWithAlpha        := tfRGBA8;
3275   fWithoutAlpha     := tfRGB8;
3276   fOpenGLFormat     := tfRGB8;
3277   fRGBInverted      := tfBGR8;
3278   fRange.r          := $FF;
3279   fRange.g          := $FF;
3280   fRange.b          := $FF;
3281   fShift.r          := 16;
3282   fShift.g          :=  8;
3283   fShift.b          :=  0;
3284   fglFormat         := GL_BGR;    // reverse byte order to match little endianess
3285   fglInternalFormat := GL_RGB8;   // as if u interpret the 3 bytes as unsigned integer
3286   fglDataFormat     := GL_UNSIGNED_BYTE;
3287 end;
3288
3289 constructor TfdRGBX8.Create;
3290 begin
3291   inherited Create;
3292   fPixelSize        := 4.0;
3293   fFormat           := tfRGBX8;
3294   fWithAlpha        := tfRGBA8;
3295   fWithoutAlpha     := tfRGBX8;
3296   fOpenGLFormat     := tfRGB8;
3297   fRGBInverted      := tfBGRX8;
3298   fRange.r          := $FF;
3299   fRange.g          := $FF;
3300   fRange.b          := $FF;
3301   fShift.r          := 24;
3302   fShift.g          := 16;
3303   fShift.b          := 8;
3304   fglFormat         := GL_RGBA;  //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3305   fglInternalFormat := GL_RGB8;
3306   fglDataFormat     := GL_UNSIGNED_INT_8_8_8_8;
3307 end;
3308
3309 constructor TfdXRGB8.Create;
3310 begin
3311   inherited Create;
3312   fPixelSize        := 4.0;
3313   fFormat           := tfXRGB8;
3314   fWithAlpha        := tfXRGB8;
3315   fWithoutAlpha     := tfXRGB8;
3316   fOpenGLFormat     := tfRGB8;
3317   fRGBInverted      := tfXBGR8;
3318   fRange.r          := $FF;
3319   fRange.g          := $FF;
3320   fRange.b          := $FF;
3321   fShift.r          := 16;
3322   fShift.g          :=  8;
3323   fShift.b          :=  0;
3324   fglFormat         := GL_BGRA;  //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3325   fglInternalFormat := GL_RGB8;
3326   fglDataFormat     := GL_UNSIGNED_INT_8_8_8_8_REV;
3327 end;
3328
3329 constructor TfdRGB10X2.Create;
3330 begin
3331   inherited Create;
3332   fPixelSize        := 3.0;
3333   fFormat           := tfRGB10X2;
3334   fWithAlpha        := tfRGB10A2;
3335   fWithoutAlpha     := tfRGB10X2;
3336   fOpenGLFormat     := tfRGB10X2;
3337   fRGBInverted      := tfBGR10X2;
3338   fRange.r          := $03FF;
3339   fRange.g          := $03FF;
3340   fRange.b          := $03FF;
3341   fShift.r          := 22;
3342   fShift.g          := 12;
3343   fShift.b          :=  2;
3344   fglFormat         := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3345   fglInternalFormat := GL_RGB10;
3346   fglDataFormat     := GL_UNSIGNED_INT_10_10_10_2;
3347 end;
3348
3349 constructor TfdX2RGB10.Create;
3350 begin
3351   inherited Create;
3352   fPixelSize        := 3.0;
3353   fFormat           := tfX2RGB10;
3354   fWithAlpha        := tfA2RGB10;
3355   fWithoutAlpha     := tfX2RGB10;
3356   fOpenGLFormat     := tfX2RGB10;
3357   fRGBInverted      := tfX2BGR10;
3358   fRange.r          := $03FF;
3359   fRange.g          := $03FF;
3360   fRange.b          := $03FF;
3361   fShift.r          := 20;
3362   fShift.g          := 10;
3363   fShift.b          :=  0;
3364   fglFormat         := GL_BGRA;  //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3365   fglInternalFormat := GL_RGB10;
3366   fglDataFormat     := GL_UNSIGNED_INT_2_10_10_10_REV;
3367 end;
3368
3369 constructor TfdRGB16.Create;
3370 begin
3371   inherited Create;
3372   fPixelSize        := 6.0;
3373   fFormat           := tfRGB16;
3374   fWithAlpha        := tfRGBA16;
3375   fWithoutAlpha     := tfRGB16;
3376   fOpenGLFormat     := tfRGB16;
3377   fRGBInverted      := tfBGR16;
3378   fRange.r          := $FFFF;
3379   fRange.g          := $FFFF;
3380   fRange.b          := $FFFF;
3381   fShift.r          := 32;
3382   fShift.g          := 16;
3383   fShift.b          :=  0;
3384   fglFormat         := GL_BGR;     // reverse byte order to match little endianess
3385   fglInternalFormat := GL_RGB16;   // as if u interpret the 3 bytes as unsigned integer
3386   fglDataFormat     := GL_UNSIGNED_SHORT;
3387 end;
3388
3389 constructor TfdRGBA4.Create;
3390 begin
3391   inherited Create;
3392   fPixelSize        := 2.0;
3393   fFormat           := tfRGBA4;
3394   fWithAlpha        := tfRGBA4;
3395   fWithoutAlpha     := tfRGBX4;
3396   fOpenGLFormat     := tfRGBA4;
3397   fRGBInverted      := tfBGRA4;
3398   fRange.r          := $0F;
3399   fRange.g          := $0F;
3400   fRange.b          := $0F;
3401   fRange.a          := $0F;
3402   fShift.r          := 12;
3403   fShift.g          :=  8;
3404   fShift.b          :=  4;
3405   fShift.a          :=  0;
3406   fglFormat         := GL_RGBA;
3407   fglInternalFormat := GL_RGBA4;
3408   fglDataFormat     := GL_UNSIGNED_SHORT_4_4_4_4;
3409 end;
3410
3411 constructor TfdARGB4.Create;
3412 begin
3413   inherited Create;
3414   fPixelSize        := 2.0;
3415   fFormat           := tfARGB4;
3416   fWithAlpha        := tfARGB4;
3417   fWithoutAlpha     := tfXRGB4;
3418   fOpenGLFormat     := tfARGB4;
3419   fRGBInverted      := tfABGR4;
3420   fRange.r          := $0F;
3421   fRange.g          := $0F;
3422   fRange.b          := $0F;
3423   fRange.a          := $0F;
3424   fShift.r          :=  8;
3425   fShift.g          :=  4;
3426   fShift.b          :=  0;
3427   fShift.a          := 12;
3428   fglFormat         := GL_BGRA;
3429   fglInternalFormat := GL_RGBA4;
3430   fglDataFormat     := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3431 end;
3432
3433 constructor TfdRGB5A1.Create;
3434 begin
3435   inherited Create;
3436   fPixelSize        := 2.0;
3437   fFormat           := tfRGB5A1;
3438   fWithAlpha        := tfRGB5A1;
3439   fWithoutAlpha     := tfRGB5X1;
3440   fOpenGLFormat     := tfRGB5A1;
3441   fRGBInverted      := tfBGR5A1;
3442   fRange.r          := $1F;
3443   fRange.g          := $1F;
3444   fRange.b          := $1F;
3445   fRange.a          := $01;
3446   fShift.r          := 11;
3447   fShift.g          :=  6;
3448   fShift.b          :=  1;
3449   fShift.a          :=  0;
3450   fglFormat         := GL_RGBA;
3451   fglInternalFormat := GL_RGB5_A1;
3452   fglDataFormat     := GL_UNSIGNED_SHORT_5_5_5_1;
3453 end;
3454
3455 constructor TfdA1RGB5.Create;
3456 begin
3457   inherited Create;
3458   fPixelSize        := 2.0;
3459   fFormat           := tfA1RGB5;
3460   fWithAlpha        := tfA1RGB5;
3461   fWithoutAlpha     := tfX1RGB5;
3462   fOpenGLFormat     := tfA1RGB5;
3463   fRGBInverted      := tfA1BGR5;
3464   fRange.r          := $1F;
3465   fRange.g          := $1F;
3466   fRange.b          := $1F;
3467   fRange.a          := $01;
3468   fShift.r          := 10;
3469   fShift.g          :=  5;
3470   fShift.b          :=  0;
3471   fShift.a          := 15;
3472   fglFormat         := GL_BGRA;
3473   fglInternalFormat := GL_RGB5_A1;
3474   fglDataFormat     := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3475 end;
3476
3477 constructor TfdRGBA8.Create;
3478 begin
3479   inherited Create;
3480   fPixelSize        := 4.0;
3481   fFormat           := tfRGBA8;
3482   fWithAlpha        := tfRGBA8;
3483   fWithoutAlpha     := tfRGB8;
3484   fOpenGLFormat     := tfRGBA8;
3485   fRGBInverted      := tfBGRA8;
3486   fRange.r          := $FF;
3487   fRange.g          := $FF;
3488   fRange.b          := $FF;
3489   fRange.a          := $FF;
3490   fShift.r          := 24;
3491   fShift.g          := 16;
3492   fShift.b          :=  8;
3493   fShift.a          :=  0;
3494   fglFormat         := GL_RGBA;
3495   fglInternalFormat := GL_RGBA8;
3496   fglDataFormat     := GL_UNSIGNED_INT_8_8_8_8;
3497 end;
3498
3499 constructor TfdARGB8.Create;
3500 begin
3501   inherited Create;
3502   fPixelSize        := 4.0;
3503   fFormat           := tfARGB8;
3504   fWithAlpha        := tfARGB8;
3505   fWithoutAlpha     := tfRGB8;
3506   fOpenGLFormat     := tfARGB8;
3507   fRGBInverted      := tfABGR8;
3508   fRange.r          := $FF;
3509   fRange.g          := $FF;
3510   fRange.b          := $FF;
3511   fRange.a          := $FF;
3512   fShift.r          := 16;
3513   fShift.g          :=  8;
3514   fShift.b          :=  0;
3515   fShift.a          := 24;
3516   fglFormat         := GL_BGRA;
3517   fglInternalFormat := GL_RGBA8;
3518   fglDataFormat     := GL_UNSIGNED_INT_8_8_8_8_REV;
3519 end;
3520
3521 constructor TfdRGB10A2.Create;
3522 begin
3523   inherited Create;
3524   fPixelSize        := 3.0;
3525   fFormat           := tfRGB10A2;
3526   fWithAlpha        := tfRGB10A2;
3527   fWithoutAlpha     := tfRGB10X2;
3528   fOpenGLFormat     := tfRGB10A2;
3529   fRGBInverted      := tfBGR10A2;
3530   fRange.r          := $03FF;
3531   fRange.g          := $03FF;
3532   fRange.b          := $03FF;
3533   fRange.a          := $0003;
3534   fShift.r          := 22;
3535   fShift.g          := 12;
3536   fShift.b          :=  2;
3537   fShift.a          :=  0;
3538   fglFormat         := GL_RGBA;
3539   fglInternalFormat := GL_RGB10_A2;
3540   fglDataFormat     := GL_UNSIGNED_INT_10_10_10_2;
3541 end;
3542
3543 constructor TfdA2RGB10.Create;
3544 begin
3545   inherited Create;
3546   fPixelSize        := 3.0;
3547   fFormat           := tfA2RGB10;
3548   fWithAlpha        := tfA2RGB10;
3549   fWithoutAlpha     := tfX2RGB10;
3550   fOpenGLFormat     := tfA2RGB10;
3551   fRGBInverted      := tfA2BGR10;
3552   fRange.r          := $03FF;
3553   fRange.g          := $03FF;
3554   fRange.b          := $03FF;
3555   fRange.a          := $0003;
3556   fShift.r          := 20;
3557   fShift.g          := 10;
3558   fShift.b          :=  0;
3559   fShift.a          := 30;
3560   fglFormat         := GL_BGRA;
3561   fglInternalFormat := GL_RGB10_A2;
3562   fglDataFormat     := GL_UNSIGNED_INT_2_10_10_10_REV;
3563 end;
3564
3565 constructor TfdRGBA16.Create;
3566 begin
3567   inherited Create;
3568   fPixelSize        := 8.0;
3569   fFormat           := tfRGBA16;
3570   fWithAlpha        := tfRGBA16;
3571   fWithoutAlpha     := tfRGB16;
3572   fOpenGLFormat     := tfRGBA16;
3573   fRGBInverted      := tfBGRA16;
3574   fRange.r          := $FFFF;
3575   fRange.g          := $FFFF;
3576   fRange.b          := $FFFF;
3577   fRange.a          := $FFFF;
3578   fShift.r          := 48;
3579   fShift.g          := 32;
3580   fShift.b          := 16;
3581   fShift.a          :=  0;
3582   fglFormat         := GL_BGRA;     // reverse byte order to match little endianess
3583   fglInternalFormat := GL_RGBA16;   // as if u interpret the 3 bytes as unsigned integer
3584   fglDataFormat     := GL_UNSIGNED_SHORT;
3585 end;
3586
3587 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3588 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3589 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3590 constructor TfdBGRX4.Create;
3591 begin
3592   inherited Create;
3593   fPixelSize        := 2.0;
3594   fFormat           := tfBGRX4;
3595   fWithAlpha        := tfBGRA4;
3596   fWithoutAlpha     := tfBGRX4;
3597   fOpenGLFormat     := tfBGRX4;
3598   fRGBInverted      := tfRGBX4;
3599   fRange.r          := $0F;
3600   fRange.g          := $0F;
3601   fRange.b          := $0F;
3602   fShift.r          :=  4;
3603   fShift.g          :=  8;
3604   fShift.b          := 12;
3605   fglFormat         := GL_BGRA;  //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3606   fglInternalFormat := GL_RGB4;
3607   fglDataFormat     := GL_UNSIGNED_SHORT_4_4_4_4;
3608 end;
3609
3610 constructor TfdXBGR4.Create;
3611 begin
3612   inherited Create;
3613   fPixelSize        := 2.0;
3614   fFormat           := tfXBGR4;
3615   fWithAlpha        := tfABGR4;
3616   fWithoutAlpha     := tfXBGR4;
3617   fOpenGLFormat     := tfXBGR4;
3618   fRGBInverted      := tfXRGB4;
3619   fRange.r          := $0F;
3620   fRange.g          := $0F;
3621   fRange.b          := $0F;
3622   fRange.a          := $0F;
3623   fShift.r          := 0;
3624   fShift.g          := 4;
3625   fShift.b          := 8;
3626   fglFormat         := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3627   fglInternalFormat := GL_RGB4;
3628   fglDataFormat     := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3629 end;
3630
3631 constructor TfdB5G6R5.Create;
3632 begin
3633   inherited Create;
3634   fPixelSize        := 2.0;
3635   fFormat           := tfB5G6R5;
3636   fWithAlpha        := tfBGR5A1;
3637   fWithoutAlpha     := tfB5G6R5;
3638   fOpenGLFormat     := tfB5G6R5;
3639   fRGBInverted      := tfR5G6B5;
3640   fRange.r          := $1F;
3641   fRange.g          := $3F;
3642   fRange.b          := $1F;
3643   fShift.r          :=  0;
3644   fShift.g          :=  5;
3645   fShift.b          := 11;
3646   fglFormat         := GL_RGB;
3647   fglInternalFormat := GL_RGB565;
3648   fglDataFormat     := GL_UNSIGNED_SHORT_5_6_5_REV;
3649 end;
3650
3651 constructor TfdBGR5X1.Create;
3652 begin
3653   inherited Create;
3654   fPixelSize        := 2.0;
3655   fFormat           := tfBGR5X1;
3656   fWithAlpha        := tfBGR5A1;
3657   fWithoutAlpha     := tfBGR5X1;
3658   fOpenGLFormat     := tfBGR5X1;
3659   fRGBInverted      := tfRGB5X1;
3660   fRange.r          := $1F;
3661   fRange.g          := $1F;
3662   fRange.b          := $1F;
3663   fShift.r          :=  1;
3664   fShift.g          :=  6;
3665   fShift.b          := 11;
3666   fglFormat         := GL_BGRA;
3667   fglInternalFormat := GL_RGB5;
3668   fglDataFormat     := GL_UNSIGNED_SHORT_5_5_5_1;
3669 end;
3670
3671 constructor TfdX1BGR5.Create;
3672 begin
3673   inherited Create;
3674   fPixelSize        := 2.0;
3675   fFormat           := tfX1BGR5;
3676   fWithAlpha        := tfA1BGR5;
3677   fWithoutAlpha     := tfX1BGR5;
3678   fOpenGLFormat     := tfX1BGR5;
3679   fRGBInverted      := tfX1RGB5;
3680   fRange.r          := $1F;
3681   fRange.g          := $1F;
3682   fRange.b          := $1F;
3683   fShift.r          :=  0;
3684   fShift.g          :=  5;
3685   fShift.b          := 10;
3686   fglFormat         := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3687   fglInternalFormat := GL_RGB5;
3688   fglDataFormat     := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3689 end;
3690
3691 constructor TfdBGR8.Create;
3692 begin
3693   inherited Create;
3694   fPixelSize        := 3.0;
3695   fFormat           := tfBGR8;
3696   fWithAlpha        := tfBGRA8;
3697   fWithoutAlpha     := tfBGR8;
3698   fOpenGLFormat     := tfBGR8;
3699   fRGBInverted      := tfRGB8;
3700   fRange.r          := $FF;
3701   fRange.g          := $FF;
3702   fRange.b          := $FF;
3703   fShift.r          :=  0;
3704   fShift.g          :=  8;
3705   fShift.b          := 16;
3706   fglFormat         := GL_RGB;      // reverse byte order to match little endianess
3707   fglInternalFormat := GL_RGB8;     // as if u interpret the 3 bytes as unsigned integer
3708   fglDataFormat     := GL_UNSIGNED_BYTE;
3709 end;
3710
3711 constructor TfdBGRX8.Create;
3712 begin
3713   inherited Create;
3714   fPixelSize        := 4.0;
3715   fFormat           := tfBGRX8;
3716   fWithAlpha        := tfBGRA8;
3717   fWithoutAlpha     := tfBGRX8;
3718   fOpenGLFormat     := tfBGRX8;
3719   fRGBInverted      := tfRGBX8;
3720   fRange.r          := $FF;
3721   fRange.g          := $FF;
3722   fRange.b          := $FF;
3723   fShift.r          :=  8;
3724   fShift.g          := 16;
3725   fShift.b          := 24;
3726   fglFormat         := GL_BGRA;  //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3727   fglInternalFormat := GL_RGB8;
3728   fglDataFormat     := GL_UNSIGNED_INT_8_8_8_8;
3729 end;
3730
3731 constructor TfdXBGR8.Create;
3732 begin
3733   inherited Create;
3734   fPixelSize        := 4.0;
3735   fFormat           := tfXBGR8;
3736   fWithAlpha        := tfABGR8;
3737   fWithoutAlpha     := tfXBGR8;
3738   fOpenGLFormat     := tfXBGR8;
3739   fRGBInverted      := tfXRGB8;
3740   fRange.r          := $FF;
3741   fRange.g          := $FF;
3742   fRange.b          := $FF;
3743   fShift.r          :=  0;
3744   fShift.g          :=  8;
3745   fShift.b          := 16;
3746   fglFormat         := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3747   fglInternalFormat := GL_RGB8;
3748   fglDataFormat     := GL_UNSIGNED_INT_8_8_8_8_REV;
3749 end;
3750
3751 constructor TfdBGR10X2.Create;
3752 begin
3753   inherited Create;
3754   fPixelSize        := 3.0;
3755   fFormat           := tfBGR10X2;
3756   fWithAlpha        := tfBGR10A2;
3757   fWithoutAlpha     := tfBGR10X2;
3758   fOpenGLFormat     := tfBGR10X2;
3759   fRGBInverted      := tfRGB10X2;
3760   fRange.r          := $03FF;
3761   fRange.g          := $03FF;
3762   fRange.b          := $03FF;
3763   fShift.r          :=  2;
3764   fShift.g          := 12;
3765   fShift.b          := 22;
3766   fglFormat         := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3767   fglInternalFormat := GL_RGB10;
3768   fglDataFormat     := GL_UNSIGNED_INT_10_10_10_2;
3769 end;
3770
3771 constructor TfdX2BGR10.Create;
3772 begin
3773   inherited Create;
3774   fPixelSize        := 3.0;
3775   fFormat           := tfX2BGR10;
3776   fWithAlpha        := tfA2BGR10;
3777   fWithoutAlpha     := tfX2BGR10;
3778   fOpenGLFormat     := tfX2BGR10;
3779   fRGBInverted      := tfX2RGB10;
3780   fRange.r          := $03FF;
3781   fRange.g          := $03FF;
3782   fRange.b          := $03FF;
3783   fShift.r          :=  0;
3784   fShift.g          := 10;
3785   fShift.b          := 20;
3786   fglFormat         := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3787   fglInternalFormat := GL_RGB10;
3788   fglDataFormat     := GL_UNSIGNED_INT_2_10_10_10_REV;
3789 end;
3790
3791 constructor TfdBGR16.Create;
3792 begin
3793   inherited Create;
3794   fPixelSize        := 6.0;
3795   fFormat           := tfBGR16;
3796   fWithAlpha        := tfBGRA16;
3797   fWithoutAlpha     := tfBGR16;
3798   fOpenGLFormat     := tfBGR16;
3799   fRGBInverted      := tfRGB16;
3800   fRange.r          := $FFFF;
3801   fRange.g          := $FFFF;
3802   fRange.b          := $FFFF;
3803   fShift.r          :=  0;
3804   fShift.g          := 16;
3805   fShift.b          := 32;
3806   fglFormat         := GL_RGB;      // reverse byte order to match little endianess
3807   fglInternalFormat := GL_RGB16;    // as if u interpret the 3 bytes as unsigned integer
3808   fglDataFormat     := GL_UNSIGNED_SHORT;
3809 end;
3810
3811 constructor TfdBGRA4.Create;
3812 begin
3813   inherited Create;
3814   fPixelSize        := 2.0;
3815   fFormat           := tfBGRA4;
3816   fWithAlpha        := tfBGRA4;
3817   fWithoutAlpha     := tfBGRX4;
3818   fOpenGLFormat     := tfBGRA4;
3819   fRGBInverted      := tfRGBA4;
3820   fRange.r          := $0F;
3821   fRange.g          := $0F;
3822   fRange.b          := $0F;
3823   fRange.a          := $0F;
3824   fShift.r          :=  4;
3825   fShift.g          :=  8;
3826   fShift.b          := 12;
3827   fShift.a          :=  0;
3828   fglFormat         := GL_BGRA;
3829   fglInternalFormat := GL_RGBA4;
3830   fglDataFormat     := GL_UNSIGNED_SHORT_4_4_4_4;
3831 end;
3832
3833 constructor TfdABGR4.Create;
3834 begin
3835   inherited Create;
3836   fPixelSize        := 2.0;
3837   fFormat           := tfABGR4;
3838   fWithAlpha        := tfABGR4;
3839   fWithoutAlpha     := tfXBGR4;
3840   fOpenGLFormat     := tfABGR4;
3841   fRGBInverted      := tfARGB4;
3842   fRange.r          := $0F;
3843   fRange.g          := $0F;
3844   fRange.b          := $0F;
3845   fRange.a          := $0F;
3846   fShift.r          :=  0;
3847   fShift.g          :=  4;
3848   fShift.b          :=  8;
3849   fShift.a          := 12;
3850   fglFormat         := GL_RGBA;
3851   fglInternalFormat := GL_RGBA4;
3852   fglDataFormat     := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3853 end;
3854
3855 constructor TfdBGR5A1.Create;
3856 begin
3857   inherited Create;
3858   fPixelSize        := 2.0;
3859   fFormat           := tfBGR5A1;
3860   fWithAlpha        := tfBGR5A1;
3861   fWithoutAlpha     := tfBGR5X1;
3862   fOpenGLFormat     := tfBGR5A1;
3863   fRGBInverted      := tfRGB5A1;
3864   fRange.r          := $1F;
3865   fRange.g          := $1F;
3866   fRange.b          := $1F;
3867   fRange.a          := $01;
3868   fShift.r          :=  1;
3869   fShift.g          :=  6;
3870   fShift.b          := 11;
3871   fShift.a          :=  0;
3872   fglFormat         := GL_BGRA;
3873   fglInternalFormat := GL_RGB5_A1;
3874   fglDataFormat     := GL_UNSIGNED_SHORT_5_5_5_1;
3875 end;
3876
3877 constructor TfdA1BGR5.Create;
3878 begin
3879   inherited Create;
3880   fPixelSize        := 2.0;
3881   fFormat           := tfA1BGR5;
3882   fWithAlpha        := tfA1BGR5;
3883   fWithoutAlpha     := tfX1BGR5;
3884   fOpenGLFormat     := tfA1BGR5;
3885   fRGBInverted      := tfA1RGB5;
3886   fRange.r          := $1F;
3887   fRange.g          := $1F;
3888   fRange.b          := $1F;
3889   fRange.a          := $01;
3890   fShift.r          :=  0;
3891   fShift.g          :=  5;
3892   fShift.b          := 10;
3893   fShift.a          := 15;
3894   fglFormat         := GL_RGBA;
3895   fglInternalFormat := GL_RGB5_A1;
3896   fglDataFormat     := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3897 end;
3898
3899 constructor TfdBGRA8.Create;
3900 begin
3901   inherited Create;
3902   fPixelSize        := 4.0;
3903   fFormat           := tfBGRA8;
3904   fWithAlpha        := tfBGRA8;
3905   fWithoutAlpha     := tfBGR8;
3906   fOpenGLFormat     := tfBGRA8;
3907   fRGBInverted      := tfRGBA8;
3908   fRange.r          := $FF;
3909   fRange.g          := $FF;
3910   fRange.b          := $FF;
3911   fRange.a          := $FF;
3912   fShift.r          :=  8;
3913   fShift.g          := 16;
3914   fShift.b          := 24;
3915   fShift.a          :=  0;
3916   fglFormat         := GL_BGRA;
3917   fglInternalFormat := GL_RGBA8;
3918   fglDataFormat     := GL_UNSIGNED_INT_8_8_8_8;
3919 end;
3920
3921 constructor TfdABGR8.Create;
3922 begin
3923   inherited Create;
3924   fPixelSize        := 4.0;
3925   fFormat           := tfABGR8;
3926   fWithAlpha        := tfABGR8;
3927   fWithoutAlpha     := tfBGR8;
3928   fOpenGLFormat     := tfABGR8;
3929   fRGBInverted      := tfARGB8;
3930   fRange.r          := $FF;
3931   fRange.g          := $FF;
3932   fRange.b          := $FF;
3933   fRange.a          := $FF;
3934   fShift.r          :=  0;
3935   fShift.g          :=  8;
3936   fShift.b          := 16;
3937   fShift.a          := 24;
3938   fglFormat         := GL_RGBA;
3939   fglInternalFormat := GL_RGBA8;
3940   fglDataFormat     := GL_UNSIGNED_INT_8_8_8_8_REV;
3941 end;
3942
3943 constructor TfdBGR10A2.Create;
3944 begin
3945   inherited Create;
3946   fPixelSize        := 3.0;
3947   fFormat           := tfBGR10A2;
3948   fWithAlpha        := tfBGR10A2;
3949   fWithoutAlpha     := tfBGR10X2;
3950   fOpenGLFormat     := tfBGR10A2;
3951   fRGBInverted      := tfRGB10A2;
3952   fRange.r          := $03FF;
3953   fRange.g          := $03FF;
3954   fRange.b          := $03FF;
3955   fRange.a          := $0003;
3956   fShift.r          :=  2;
3957   fShift.g          := 12;