1 { glBitmap by Steffen Xonna aka Lossy eX (2003-2008)
2 http://www.opengl24.de/index.php?cat=header&file=glbitmap
4 modified by Delphi OpenGL Community (http://delphigl.com/) (2013)
6 The contents of this file are used with permission, subject to
7 the Mozilla Public License Version 1.1 (the "License"); you may
8 not use this file except in compliance with the License. You may
9 obtain a copy of the License at
10 http://www.mozilla.org/MPL/MPL-1.1.html
12 The glBitmap is a Delphi/FPC unit that contains several wrapper classes
13 to manage OpenGL texture objects. Below you can find a list of the main
14 functionality of this classes:
15 - load texture data from file (e.g. BMP, TGA, DDS, PNG, JPEG, ...)
16 - load texture data from several other image objects (e.g. TBitmap, TLazIntfImage, SDL Surface)
17 - save texture data to file (e.g. BMP, TGA, DDS, PNG, JPEG, ...)
18 - save texture data to several other image objects (e.g. TBitmap, TLazIntfImage, SDL Surface)
19 - support for many texture formats (e.g. RGB8, BGR8, RGBA8, BGRA8, ...)
20 - manage texture properties (e.g. Filter, Clamp, Mipmap, ...)
21 - upload texture data to video card
22 - download texture data from video card
23 - manipulate texture data (e.g. add alpha, remove alpha, convert to other format, switch RGB, ...) }
27 // Please uncomment the defines below to configure the glBitmap to your preferences.
28 // If you have configured the unit you can uncomment the warning above.
29 {.$MESSAGE error 'Hey. I''m the glBitmap.pas and i need to be configured. My master tell me your preferences! ;)'}
31 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
32 // Preferences ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
33 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
34 // enable support for OpenGL ES 1.1
35 {.$DEFINE OPENGL_ES_1_1}
37 // enable support for OpenGL ES 2.0
38 {.$DEFINE OPENGL_ES_2_0}
40 // enable support for OpenGL ES 3.0
41 {.$DEFINE OPENGL_ES_3_0}
43 // enable support for all OpenGL ES extensions
44 {.$DEFINE OPENGL_ES_EXT}
48 // activate to enable the support for SDL_surfaces
51 // activate to enable the support for Delphi (including support for Delphi's (not Lazarus') TBitmap)
54 // activate to enable the support for TLazIntfImage from Lazarus
55 {.$DEFINE GLB_LAZARUS}
59 // activate to enable the support of SDL_image to load files. (READ ONLY)
60 // If you enable SDL_image all other libraries will be ignored!
61 {.$DEFINE GLB_SDL_IMAGE}
65 // activate to enable Lazarus TPortableNetworkGraphic support
66 // if you enable this pngImage and libPNG will be ignored
67 {.$DEFINE GLB_LAZ_PNG}
69 // activate to enable png support with the unit pngimage -> http://pngdelphi.sourceforge.net/
70 // if you enable pngimage the libPNG will be ignored
71 {.$DEFINE GLB_PNGIMAGE}
73 // activate to use the libPNG -> http://www.libpng.org/
74 // You will need an aditional header -> http://www.opengl24.de/index.php?cat=header&file=libpng
75 {.$DEFINE GLB_LIB_PNG}
79 // activate to enable Lazarus TJPEGImage support
80 // if you enable this delphi jpegs and libJPEG will be ignored
81 {.$DEFINE GLB_LAZ_JPEG}
83 // if you enable delphi jpegs the libJPEG will be ignored
84 {.$DEFINE GLB_DELPHI_JPEG}
86 // activate to use the libJPEG -> http://www.ijg.org/
87 // You will need an aditional header -> http://www.opengl24.de/index.php?cat=header&file=libjpeg
88 {.$DEFINE GLB_LIB_JPEG}
91 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
92 // PRIVATE: do not change anything! //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
93 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
109 {$IF DEFINED(WIN32) or DEFINED(WIN64) or DEFINED(WINDOWS)}
111 {$ELSEIF DEFINED(LINUX)}
116 {$IF DEFINED(OPENGL_ES_EXT)} {$DEFINE OPENGL_ES_1_1} {$IFEND}
117 {$IF DEFINED(OPENGL_ES_3_0)} {$DEFINE OPENGL_ES_2_0} {$IFEND}
118 {$IF DEFINED(OPENGL_ES_2_0)} {$DEFINE OPENGL_ES_1_1} {$IFEND}
119 {$IF DEFINED(OPENGL_ES_1_1)} {$DEFINE OPENGL_ES} {$IFEND}
121 // checking define combinations
123 {$IFDEF GLB_SDL_IMAGE}
125 {$MESSAGE warn 'SDL_image won''t work without SDL. SDL will be activated.'}
130 {$MESSAGE warn 'The Lazarus TPortableNetworkGraphics will be ignored because you are using SDL_image.'}
134 {$IFDEF GLB_PNGIMAGE}
135 {$MESSAGE warn 'The unit pngimage will be ignored because you are using SDL_image.'}
136 {$undef GLB_PNGIMAGE}
139 {$IFDEF GLB_LAZ_JPEG}
140 {$MESSAGE warn 'The Lazarus TJPEGImage will be ignored because you are using SDL_image.'}
141 {$undef GLB_LAZ_JPEG}
144 {$IFDEF GLB_DELPHI_JPEG}
145 {$MESSAGE warn 'The unit JPEG will be ignored because you are using SDL_image.'}
146 {$undef GLB_DELPHI_JPEG}
150 {$MESSAGE warn 'The library libPNG will be ignored because you are using SDL_image.'}
154 {$IFDEF GLB_LIB_JPEG}
155 {$MESSAGE warn 'The library libJPEG will be ignored because you are using SDL_image.'}
156 {$undef GLB_LIB_JPEG}
159 {$DEFINE GLB_SUPPORT_PNG_READ}
160 {$DEFINE GLB_SUPPORT_JPEG_READ}
163 // Lazarus TPortableNetworkGraphic
165 {$IFNDEF GLB_LAZARUS}
166 {$MESSAGE warn 'Lazarus TPortableNetworkGraphic won''t work without Lazarus. Lazarus will be activated.'}
167 {$DEFINE GLB_LAZARUS}
170 {$IFDEF GLB_PNGIMAGE}
171 {$MESSAGE warn 'The pngimage will be ignored if you are using Lazarus TPortableNetworkGraphic.'}
172 {$undef GLB_PNGIMAGE}
176 {$MESSAGE warn 'The library libPNG will be ignored if you are using Lazarus TPortableNetworkGraphic.'}
180 {$DEFINE GLB_SUPPORT_PNG_READ}
181 {$DEFINE GLB_SUPPORT_PNG_WRITE}
185 {$IFDEF GLB_PNGIMAGE}
187 {$MESSAGE warn 'The library libPNG will be ignored if you are using pngimage.'}
191 {$DEFINE GLB_SUPPORT_PNG_READ}
192 {$DEFINE GLB_SUPPORT_PNG_WRITE}
197 {$DEFINE GLB_SUPPORT_PNG_READ}
198 {$DEFINE GLB_SUPPORT_PNG_WRITE}
201 // Lazarus TJPEGImage
202 {$IFDEF GLB_LAZ_JPEG}
203 {$IFNDEF GLB_LAZARUS}
204 {$MESSAGE warn 'Lazarus TJPEGImage won''t work without Lazarus. Lazarus will be activated.'}
205 {$DEFINE GLB_LAZARUS}
208 {$IFDEF GLB_DELPHI_JPEG}
209 {$MESSAGE warn 'The Delphi JPEGImage will be ignored if you are using the Lazarus TJPEGImage.'}
210 {$undef GLB_DELPHI_JPEG}
213 {$IFDEF GLB_LIB_JPEG}
214 {$MESSAGE warn 'The library libJPEG will be ignored if you are using the Lazarus TJPEGImage.'}
215 {$undef GLB_LIB_JPEG}
218 {$DEFINE GLB_SUPPORT_JPEG_READ}
219 {$DEFINE GLB_SUPPORT_JPEG_WRITE}
223 {$IFDEF GLB_DELPHI_JPEG}
224 {$IFDEF GLB_LIB_JPEG}
225 {$MESSAGE warn 'The library libJPEG will be ignored if you are using the unit JPEG.'}
226 {$undef GLB_LIB_JPEG}
229 {$DEFINE GLB_SUPPORT_JPEG_READ}
230 {$DEFINE GLB_SUPPORT_JPEG_WRITE}
234 {$IFDEF GLB_LIB_JPEG}
235 {$DEFINE GLB_SUPPORT_JPEG_READ}
236 {$DEFINE GLB_SUPPORT_JPEG_WRITE}
250 {$IFDEF OPENGL_ES} dglOpenGLES,
251 {$ELSE} dglOpenGL, {$ENDIF}
253 {$IF DEFINED(GLB_WIN) AND
254 DEFINED(GLB_DELPHI)} windows, {$IFEND}
256 {$IFDEF GLB_SDL} SDL, {$ENDIF}
257 {$IFDEF GLB_LAZARUS} IntfGraphics, GraphType, Graphics, {$ENDIF}
258 {$IFDEF GLB_DELPHI} Dialogs, Graphics, Types, {$ENDIF}
260 {$IFDEF GLB_SDL_IMAGE} SDL_image, {$ENDIF}
261 {$IFDEF GLB_PNGIMAGE} pngimage, {$ENDIF}
262 {$IFDEF GLB_LIB_PNG} libPNG, {$ENDIF}
263 {$IFDEF GLB_DELPHI_JPEG} JPEG, {$ENDIF}
264 {$IFDEF GLB_LIB_JPEG} libJPEG, {$ENDIF}
270 QWord = System.UInt64;
278 { type that describes the format of the data stored in a texture.
279 the name of formats is composed of the following constituents:
281 - channel (e.g. R, G, B, A or Alpha, Luminance or X (reserved))
282 - width of the chanel in bit (4, 8, 16, ...)
283 - data type (e.g. ub, us, ui)
284 - number of elements of data types }
288 tfAlpha4ub1, //< 1 x unsigned byte
289 tfAlpha8ub1, //< 1 x unsigned byte
290 tfAlpha16us1, //< 1 x unsigned short
292 tfLuminance4ub1, //< 1 x unsigned byte
293 tfLuminance8ub1, //< 1 x unsigned byte
294 tfLuminance16us1, //< 1 x unsigned short
296 tfLuminance4Alpha4ub2, //< 1 x unsigned byte (lum), 1 x unsigned byte (alpha)
297 tfLuminance6Alpha2ub2, //< 1 x unsigned byte (lum), 1 x unsigned byte (alpha)
298 tfLuminance8Alpha8ub2, //< 1 x unsigned byte (lum), 1 x unsigned byte (alpha)
299 tfLuminance12Alpha4us2, //< 1 x unsigned short (lum), 1 x unsigned short (alpha)
300 tfLuminance16Alpha16us2, //< 1 x unsigned short (lum), 1 x unsigned short (alpha)
302 tfR3G3B2ub1, //< 1 x unsigned byte (3bit red, 3bit green, 2bit blue)
303 tfRGBX4us1, //< 1 x unsigned short (4bit red, 4bit green, 4bit blue, 4bit reserverd)
304 tfXRGB4us1, //< 1 x unsigned short (4bit reserved, 4bit red, 4bit green, 4bit blue)
305 tfR5G6B5us1, //< 1 x unsigned short (5bit red, 6bit green, 5bit blue)
306 tfRGB5X1us1, //< 1 x unsigned short (5bit red, 5bit green, 5bit blue, 1bit reserved)
307 tfX1RGB5us1, //< 1 x unsigned short (1bit reserved, 5bit red, 5bit green, 5bit blue)
308 tfRGB8ub3, //< 1 x unsigned byte (red), 1 x unsigned byte (green), 1 x unsigned byte (blue)
309 tfRGBX8ui1, //< 1 x unsigned int (8bit red, 8bit green, 8bit blue, 8bit reserved)
310 tfXRGB8ui1, //< 1 x unsigned int (8bit reserved, 8bit red, 8bit green, 8bit blue)
311 tfRGB10X2ui1, //< 1 x unsigned int (10bit red, 10bit green, 10bit blue, 2bit reserved)
312 tfX2RGB10ui1, //< 1 x unsigned int (2bit reserved, 10bit red, 10bit green, 10bit blue)
313 tfRGB16us3, //< 1 x unsigned short (red), 1 x unsigned short (green), 1 x unsigned short (blue)
315 tfRGBA4us1, //< 1 x unsigned short (4bit red, 4bit green, 4bit blue, 4bit alpha)
316 tfARGB4us1, //< 1 x unsigned short (4bit alpha, 4bit red, 4bit green, 4bit blue)
317 tfRGB5A1us1, //< 1 x unsigned short (5bit red, 5bit green, 5bit blue, 1bit alpha)
318 tfA1RGB5us1, //< 1 x unsigned short (1bit alpha, 5bit red, 5bit green, 5bit blue)
319 tfRGBA8ui1, //< 1 x unsigned int (8bit red, 8bit green, 8bit blue, 8 bit alpha)
320 tfARGB8ui1, //< 1 x unsigned int (8 bit alpha, 8bit red, 8bit green, 8bit blue)
321 tfRGBA8ub4, //< 1 x unsigned byte (red), 1 x unsigned byte (green), 1 x unsigned byte (blue), 1 x unsigned byte (alpha)
322 tfRGB10A2ui1, //< 1 x unsigned int (10bit red, 10bit green, 10bit blue, 2bit alpha)
323 tfA2RGB10ui1, //< 1 x unsigned int (2bit alpha, 10bit red, 10bit green, 10bit blue)
324 tfRGBA16us4, //< 1 x unsigned short (red), 1 x unsigned short (green), 1 x unsigned short (blue), 1 x unsigned short (alpha)
326 tfBGRX4us1, //< 1 x unsigned short (4bit blue, 4bit green, 4bit red, 4bit reserved)
327 tfXBGR4us1, //< 1 x unsigned short (4bit reserved, 4bit blue, 4bit green, 4bit red)
328 tfB5G6R5us1, //< 1 x unsigned short (5bit blue, 6bit green, 5bit red)
329 tfBGR5X1us1, //< 1 x unsigned short (5bit blue, 5bit green, 5bit red, 1bit reserved)
330 tfX1BGR5us1, //< 1 x unsigned short (1bit reserved, 5bit blue, 5bit green, 5bit red)
331 tfBGR8ub3, //< 1 x unsigned byte (blue), 1 x unsigned byte (green), 1 x unsigned byte (red)
332 tfBGRX8ui1, //< 1 x unsigned int (8bit blue, 8bit green, 8bit red, 8bit reserved)
333 tfXBGR8ui1, //< 1 x unsigned int (8bit reserved, 8bit blue, 8bit green, 8bit red)
334 tfBGR10X2ui1, //< 1 x unsigned int (10bit blue, 10bit green, 10bit red, 2bit reserved)
335 tfX2BGR10ui1, //< 1 x unsigned int (2bit reserved, 10bit blue, 10bit green, 10bit red)
336 tfBGR16us3, //< 1 x unsigned short (blue), 1 x unsigned short (green), 1 x unsigned short (red)
338 tfBGRA4us1, //< 1 x unsigned short (4bit blue, 4bit green, 4bit red, 4bit alpha)
339 tfABGR4us1, //< 1 x unsigned short (4bit alpha, 4bit blue, 4bit green, 4bit red)
340 tfBGR5A1us1, //< 1 x unsigned short (5bit blue, 5bit green, 5bit red, 1bit alpha)
341 tfA1BGR5us1, //< 1 x unsigned short (1bit alpha, 5bit blue, 5bit green, 5bit red)
342 tfBGRA8ui1, //< 1 x unsigned int (8bit blue, 8bit green, 8bit red, 8bit alpha)
343 tfABGR8ui1, //< 1 x unsigned int (8bit alpha, 8bit blue, 8bit green, 8bit red)
344 tfBGRA8ub4, //< 1 x unsigned byte (blue), 1 x unsigned byte (green), 1 x unsigned byte (red), 1 x unsigned byte (alpha)
345 tfBGR10A2ui1, //< 1 x unsigned int (10bit blue, 10bit green, 10bit red, 2bit alpha)
346 tfA2BGR10ui1, //< 1 x unsigned int (2bit alpha, 10bit blue, 10bit green, 10bit red)
347 tfBGRA16us4, //< 1 x unsigned short (blue), 1 x unsigned short (green), 1 x unsigned short (red), 1 x unsigned short (alpha)
349 tfDepth16us1, //< 1 x unsigned short (depth)
350 tfDepth24ui1, //< 1 x unsigned int (depth)
351 tfDepth32ui1, //< 1 x unsigned int (depth)
358 { type to define suitable file formats }
359 TglBitmapFileType = (
360 {$IFDEF GLB_SUPPORT_PNG_WRITE} ftPNG, {$ENDIF} //< Portable Network Graphic file (PNG)
361 {$IFDEF GLB_SUPPORT_JPEG_WRITE}ftJPEG, {$ENDIF} //< JPEG file
362 ftDDS, //< Direct Draw Surface file (DDS)
363 ftTGA, //< Targa Image File (TGA)
364 ftBMP, //< Windows Bitmap File (BMP)
365 ftRAW); //< glBitmap RAW file format
366 TglBitmapFileTypes = set of TglBitmapFileType;
368 { possible mipmap types }
370 mmNone, //< no mipmaps
371 mmMipmap, //< normal mipmaps
372 mmMipmapGlu); //< mipmaps generated with glu functions
374 { possible normal map functions }
375 TglBitmapNormalMapFunc = (
381 ////////////////////////////////////////////////////////////////////////////////////////////////////
382 EglBitmap = class(Exception); //< glBitmap exception
383 EglBitmapNotSupported = class(Exception); //< exception for not supported functions
384 EglBitmapSizeToLarge = class(EglBitmap); //< exception for to large textures
385 EglBitmapNonPowerOfTwo = class(EglBitmap); //< exception for non power of two textures
386 EglBitmapUnsupportedFormat = class(EglBitmap) //< exception for unsupporetd formats
388 constructor Create(const aFormat: TglBitmapFormat); overload;
389 constructor Create(const aMsg: String; const aFormat: TglBitmapFormat); overload;
392 ////////////////////////////////////////////////////////////////////////////////////////////////////
393 { record that stores 4 unsigned integer values }
394 TglBitmapRec4ui = packed record
396 0: (r, g, b, a: Cardinal);
397 1: (arr: array[0..3] of Cardinal);
400 { record that stores 4 unsigned byte values }
401 TglBitmapRec4ub = packed record
403 0: (r, g, b, a: Byte);
404 1: (arr: array[0..3] of Byte);
407 { record that stores 4 unsigned long integer values }
408 TglBitmapRec4ul = packed record
410 0: (r, g, b, a: QWord);
411 1: (arr: array[0..3] of QWord);
414 { describes the properties of a given texture data format }
415 TglBitmapFormatDescriptor = class(TObject)
418 fBytesPerPixel: Single; //< number of bytes for each pixel
419 fChannelCount: Integer; //< number of color channels
420 fMask: TglBitmapRec4ul; //< bitmask for each color channel
421 fRange: TglBitmapRec4ui; //< maximal value of each color channel
423 { @return @true if the format has a red color channel, @false otherwise }
424 function GetHasRed: Boolean;
426 { @return @true if the format has a green color channel, @false otherwise }
427 function GetHasGreen: Boolean;
429 { @return @true if the format has a blue color channel, @false otherwise }
430 function GetHasBlue: Boolean;
432 { @return @true if the format has a alpha color channel, @false otherwise }
433 function GetHasAlpha: Boolean;
435 { @return @true if the format has any color color channel, @false otherwise }
436 function GetHasColor: Boolean;
438 { @return @true if the format is a grayscale format, @false otherwise }
439 function GetIsGrayscale: Boolean;
441 fFormat: TglBitmapFormat; //< format this descriptor belongs to
442 fWithAlpha: TglBitmapFormat; //< suitable format with alpha channel
443 fWithoutAlpha: TglBitmapFormat; //< suitable format without alpha channel
444 fOpenGLFormat: TglBitmapFormat; //< suitable format that is supported by OpenGL
445 fRGBInverted: TglBitmapFormat; //< suitable format with inverted RGB channels
446 fUncompressed: TglBitmapFormat; //< suitable format with uncompressed data
448 fBitsPerPixel: Integer; //< number of bits per pixel
449 fIsCompressed: Boolean; //< @true if the format is compressed, @false otherwise
451 fPrecision: TglBitmapRec4ub; //< number of bits for each color channel
452 fShift: TglBitmapRec4ub; //< bit offset for each color channel
454 fglFormat: GLenum; //< OpenGL format enum (e.g. GL_RGB)
455 fglInternalFormat: GLenum; //< OpenGL internal format enum (e.g. GL_RGB8)
456 fglDataFormat: GLenum; //< OpenGL data format enum (e.g. GL_UNSIGNED_BYTE)
458 { set values for this format descriptor }
459 procedure SetValues; virtual;
461 { calculate cached values }
462 procedure CalcValues;
464 property Format: TglBitmapFormat read fFormat; //< format this descriptor belongs to
465 property ChannelCount: Integer read fChannelCount; //< number of color channels
466 property IsCompressed: Boolean read fIsCompressed; //< @true if the format is compressed, @false otherwise
467 property BitsPerPixel: Integer read fBitsPerPixel; //< number of bytes per pixel
468 property BytesPerPixel: Single read fBytesPerPixel; //< number of bits per pixel
470 property Precision: TglBitmapRec4ub read fPrecision; //< number of bits for each color channel
471 property Shift: TglBitmapRec4ub read fShift; //< bit offset for each color channel
472 property Range: TglBitmapRec4ui read fRange; //< maximal value of each color channel
473 property Mask: TglBitmapRec4ul read fMask; //< bitmask for each color channel
475 property RGBInverted: TglBitmapFormat read fRGBInverted; //< suitable format with inverted RGB channels
476 property WithAlpha: TglBitmapFormat read fWithAlpha; //< suitable format with alpha channel
477 property WithoutAlpha: TglBitmapFormat read fWithAlpha; //< suitable format without alpha channel
478 property OpenGLFormat: TglBitmapFormat read fOpenGLFormat; //< suitable format that is supported by OpenGL
479 property Uncompressed: TglBitmapFormat read fUncompressed; //< suitable format with uncompressed data
481 property glFormat: GLenum read fglFormat; //< OpenGL format enum (e.g. GL_RGB)
482 property glInternalFormat: GLenum read fglInternalFormat; //< OpenGL internal format enum (e.g. GL_RGB8)
483 property glDataFormat: GLenum read fglDataFormat; //< OpenGL data format enum (e.g. GL_UNSIGNED_BYTE)
485 property HasRed: Boolean read GetHasRed; //< @true if the format has a red color channel, @false otherwise
486 property HasGreen: Boolean read GetHasGreen; //< @true if the format has a green color channel, @false otherwise
487 property HasBlue: Boolean read GetHasBlue; //< @true if the format has a blue color channel, @false otherwise
488 property HasAlpha: Boolean read GetHasAlpha; //< @true if the format has a alpha color channel, @false otherwise
489 property HasColor: Boolean read GetHasColor; //< @true if the format has any color color channel, @false otherwise
490 property IsGrayscale: Boolean read GetIsGrayscale; //< @true if the format is a grayscale format, @false otherwise
495 { get the format descriptor by a given OpenGL internal format
496 @param aInternalFormat OpenGL internal format to get format descriptor for
497 @returns suitable format descriptor or tfEmpty-Descriptor }
498 class function GetByFormat(const aInternalFormat: GLenum): TglBitmapFormatDescriptor;
501 ////////////////////////////////////////////////////////////////////////////////////////////////////
502 { structure to store pixel data in }
503 TglBitmapPixelData = packed record
504 Data: TglBitmapRec4ui; //< color data for each color channel
505 Range: TglBitmapRec4ui; //< maximal color value for each channel
506 Format: TglBitmapFormat; //< format of the pixel
508 PglBitmapPixelData = ^TglBitmapPixelData;
510 TglBitmapSizeFields = set of (ffX, ffY);
511 TglBitmapSize = packed record
512 Fields: TglBitmapSizeFields;
516 TglBitmapPixelPosition = TglBitmapSize;
518 ////////////////////////////////////////////////////////////////////////////////////////////////////
521 { structure to store data for converting in }
522 TglBitmapFunctionRec = record
523 Sender: TglBitmap; //< texture object that stores the data to convert
524 Size: TglBitmapSize; //< size of the texture
525 Position: TglBitmapPixelPosition; //< position of the currently pixel
526 Source: TglBitmapPixelData; //< pixel data of the current pixel
527 Dest: TglBitmapPixelData; //< new data of the pixel (must be filled in)
528 Args: Pointer; //< user defined args that was passed to the convert function
531 { callback to use for converting texture data }
532 TglBitmapFunction = procedure(var FuncRec: TglBitmapFunctionRec);
534 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
535 { base class for all glBitmap classes. used to manage OpenGL texture objects
536 and to load, save and manipulate texture data }
539 { @returns format descriptor that describes the format of the stored data }
540 function GetFormatDesc: TglBitmapFormatDescriptor;
542 fID: GLuint; //< name of the OpenGL texture object
543 fTarget: GLuint; //< texture target (e.g. GL_TEXTURE_2D)
544 fAnisotropic: Integer; //< anisotropic level
545 fDeleteTextureOnFree: Boolean; //< delete OpenGL texture object when this object is destroyed
546 fFreeDataOnDestroy: Boolean; //< free stored data when this object is destroyed
547 fFreeDataAfterGenTexture: Boolean; //< free stored data after data was uploaded to video card
548 fData: PByte; //< data of this texture
550 fIsResident: GLboolean; //< @true if OpenGL texture object has data, @false otherwise
552 fBorderColor: array[0..3] of Single; //< color of the texture border
554 fDimension: TglBitmapSize; //< size of this texture
555 fMipMap: TglBitmapMipMap; //< mipmap type
556 fFormat: TglBitmapFormat; //< format the texture data is stored in
559 fPixelSize: Integer; //< size of one pixel (in byte)
560 fRowSize: Integer; //< size of one pixel row (in byte)
563 fFilterMin: GLenum; //< min filter to apply to the texture
564 fFilterMag: GLenum; //< mag filter to apply to the texture
567 fWrapS: GLenum; //< texture wrapping for x axis
568 fWrapT: GLenum; //< texture wrapping for y axis
569 fWrapR: GLenum; //< texture wrapping for z axis
571 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
573 fSwizzle: array[0..3] of GLenum; //< color channel swizzle
577 fFilename: String; //< filename the texture was load from
578 fCustomName: String; //< user defined name
579 fCustomNameW: WideString; //< user defined name
580 fCustomData: Pointer; //< user defined data
583 { @returns the actual width of the texture }
584 function GetWidth: Integer; virtual;
586 { @returns the actual height of the texture }
587 function GetHeight: Integer; virtual;
589 { @returns the width of the texture or 1 if the width is zero }
590 function GetFileWidth: Integer; virtual;
592 { @returns the height of the texture or 1 if the height is zero }
593 function GetFileHeight: Integer; virtual;
596 { set a new value for fCustomData }
597 procedure SetCustomData(const aValue: Pointer);
599 { set a new value for fCustomName }
600 procedure SetCustomName(const aValue: String);
602 { set a new value for fCustomNameW }
603 procedure SetCustomNameW(const aValue: WideString);
605 { set new value for fFreeDataOnDestroy }
606 procedure SetFreeDataOnDestroy(const aValue: Boolean);
608 { set new value for fDeleteTextureOnFree }
609 procedure SetDeleteTextureOnFree(const aValue: Boolean);
611 { set new value for the data format. only possible if new format has the same pixel size.
612 if you want to convert the texture data, see ConvertTo function }
613 procedure SetFormat(const aValue: TglBitmapFormat);
615 { set new value for fFreeDataAfterGenTexture }
616 procedure SetFreeDataAfterGenTexture(const aValue: Boolean);
618 { set name of OpenGL texture object }
619 procedure SetID(const aValue: Cardinal);
621 { set new value for fMipMap }
622 procedure SetMipMap(const aValue: TglBitmapMipMap);
624 { set new value for target }
625 procedure SetTarget(const aValue: Cardinal);
627 { set new value for fAnisotrophic }
628 procedure SetAnisotropic(const aValue: Integer);
631 { create OpenGL texture object (delete exisiting object if exists) }
634 { setup texture parameters }
635 procedure SetupParameters({$IFNDEF OPENGL_ES}out aBuildWithGlu: Boolean{$ENDIF});
637 { set data pointer of texture data
638 @param aData pointer to new texture data (be carefull, aData could be freed by this function)
639 @param aFormat format of the data stored at aData
640 @param aWidth width of the texture data
641 @param aHeight height of the texture data }
642 procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
643 const aWidth: Integer = -1; const aHeight: Integer = -1); virtual;
645 { generate texture (upload texture data to video card)
646 @param aTestTextureSize test texture size before uploading and raise exception if something is wrong }
647 procedure GenTexture(const aTestTextureSize: Boolean = true); virtual; abstract;
649 { flip texture horizontal
650 @returns @true in success, @false otherwise }
651 function FlipHorz: Boolean; virtual;
653 { flip texture vertical
654 @returns @true in success, @false otherwise }
655 function FlipVert: Boolean; virtual;
658 property Width: Integer read GetWidth; //< the actual width of the texture
659 property Height: Integer read GetHeight; //< the actual height of the texture
661 property FileWidth: Integer read GetFileWidth; //< the width of the texture or 1 if the width is zero
662 property FileHeight: Integer read GetFileHeight; //< the height of the texture or 1 if the height is zero
664 property ID: Cardinal read fID write SetID; //< name of the OpenGL texture object
665 property Target: Cardinal read fTarget write SetTarget; //< texture target (e.g. GL_TEXTURE_2D)
666 property Format: TglBitmapFormat read fFormat write SetFormat; //< format the texture data is stored in
667 property MipMap: TglBitmapMipMap read fMipMap write SetMipMap; //< mipmap type
668 property Anisotropic: Integer read fAnisotropic write SetAnisotropic; //< anisotropic level
670 property FormatDesc: TglBitmapFormatDescriptor read GetFormatDesc; //< format descriptor that describes the format of the stored data
672 property Filename: String read fFilename; //< filename the texture was load from
673 property CustomName: String read fCustomName write SetCustomName; //< user defined name (use at will)
674 property CustomNameW: WideString read fCustomNameW write SetCustomNameW; //< user defined name (as WideString; use at will)
675 property CustomData: Pointer read fCustomData write SetCustomData; //< user defined data (use at will)
677 property DeleteTextureOnFree: Boolean read fDeleteTextureOnFree write SetDeleteTextureOnFree; //< delete texture object when this object is destroyed
678 property FreeDataOnDestroy: Boolean read fFreeDataOnDestroy write SetFreeDataOnDestroy; //< free stored data when this object is destroyed
679 property FreeDataAfterGenTexture: Boolean read fFreeDataAfterGenTexture write SetFreeDataAfterGenTexture; //< free stored data after it is uplaoded to video card
681 property Dimension: TglBitmapSize read fDimension; //< size of the texture
682 property Data: PByte read fData; //< texture data (or @nil if unset)
684 property IsResident: GLboolean read fIsResident; //< @true if OpenGL texture object has data, @false otherwise
687 { this method is called after the constructor and sets the default values of this object }
688 procedure AfterConstruction; override;
690 { this method is called before the destructor and does some cleanup }
691 procedure BeforeDestruction; override;
693 { splits a resource identifier into the resource and it's type
694 @param aResource resource identifier to split and store name in
695 @param aResType type of the resource }
696 procedure PrepareResType(var aResource: String; var aResType: PChar);
699 { load a texture from a file
700 @param aFilename file to load texuture from }
701 procedure LoadFromFile(const aFilename: String);
703 { load a texture from a stream
704 @param aStream stream to load texture from }
705 procedure LoadFromStream(const aStream: TStream); virtual;
707 { use a function to generate texture data
708 @param aSize size of the texture
709 @param aFunc callback to use for generation
710 @param aFormat format of the texture data
711 @param aArgs user defined paramaters (use at will) }
712 procedure LoadFromFunc(const aSize: TglBitmapSize; const aFunc: TglBitmapFunction;
713 const aFormat: TglBitmapFormat; const aArgs: Pointer = nil);
715 { load a texture from a resource
716 @param aInstance resource handle
717 @param aResource resource indentifier
718 @param aResType resource type (if known) }
719 procedure LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil);
721 { load a texture from a resource id
722 @param aInstance resource handle
723 @param aResource resource ID
724 @param aResType resource type }
725 procedure LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
728 { save texture data to a file
729 @param aFilename filename to store texture in
730 @param aFileType file type to store data into }
731 procedure SaveToFile(const aFilename: String; const aFileType: TglBitmapFileType);
733 { save texture data to a stream
734 @param aFilename filename to store texture in
735 @param aFileType file type to store data into }
736 procedure SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType); virtual;
739 { convert texture data using a user defined callback
740 @param aFunc callback to use for converting
741 @param aCreateTemp create a temporary buffer to use for converting
742 @param aArgs user defined paramters (use at will)
743 @returns @true if converting was successful, @false otherwise }
744 function Convert(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer = nil): Boolean; overload;
746 { convert texture data using a user defined callback
747 @param aSource glBitmap to read data from
748 @param aFunc callback to use for converting
749 @param aCreateTemp create a temporary buffer to use for converting
750 @param aFormat format of the new data
751 @param aArgs user defined paramters (use at will)
752 @returns @true if converting was successful, @false otherwise }
753 function Convert(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
754 const aFormat: TglBitmapFormat; const aArgs: Pointer = nil): Boolean; overload;
756 { convert texture data using a specific format
757 @param aFormat new format of texture data
758 @returns @true if converting was successful, @false otherwise }
759 function ConvertTo(const aFormat: TglBitmapFormat): Boolean; virtual;
763 { assign texture data to SDL surface
764 @param aSurface SDL surface to write data to
765 @returns @true on success, @false otherwise }
766 function AssignToSurface(out aSurface: PSDL_Surface): Boolean;
768 { assign texture data from SDL surface
769 @param aSurface SDL surface to read data from
770 @returns @true on success, @false otherwise }
771 function AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
773 { assign alpha channel data to SDL surface
774 @param aSurface SDL surface to write alpha channel data to
775 @returns @true on success, @false otherwise }
776 function AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
778 { assign alpha channel data from SDL surface
779 @param aSurface SDL surface to read data from
780 @param aFunc callback to use for converting
781 @param aArgs user defined parameters (use at will)
782 @returns @true on success, @false otherwise }
783 function AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
788 { assign texture data to TBitmap object
789 @param aBitmap TBitmap to write data to
790 @returns @true on success, @false otherwise }
791 function AssignToBitmap(const aBitmap: TBitmap): Boolean;
793 { assign texture data from TBitmap object
794 @param aBitmap TBitmap to read data from
795 @returns @true on success, @false otherwise }
796 function AssignFromBitmap(const aBitmap: TBitmap): Boolean;
798 { assign alpha channel data to TBitmap object
799 @param aBitmap TBitmap to write data to
800 @returns @true on success, @false otherwise }
801 function AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
803 { assign alpha channel data from TBitmap object
804 @param aBitmap TBitmap to read data from
805 @param aFunc callback to use for converting
806 @param aArgs user defined parameters (use at will)
807 @returns @true on success, @false otherwise }
808 function AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
813 { assign texture data to TLazIntfImage object
814 @param aImage TLazIntfImage to write data to
815 @returns @true on success, @false otherwise }
816 function AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
818 { assign texture data from TLazIntfImage object
819 @param aImage TLazIntfImage to read data from
820 @returns @true on success, @false otherwise }
821 function AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
823 { assign alpha channel data to TLazIntfImage object
824 @param aImage TLazIntfImage to write data to
825 @returns @true on success, @false otherwise }
826 function AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
828 { assign alpha channel data from TLazIntfImage object
829 @param aImage TLazIntfImage to read data from
830 @param aFunc callback to use for converting
831 @param aArgs user defined parameters (use at will)
832 @returns @true on success, @false otherwise }
833 function AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
837 { load alpha channel data from resource
838 @param aInstance resource handle
839 @param aResource resource ID
840 @param aResType resource type
841 @param aFunc callback to use for converting
842 @param aArgs user defined parameters (use at will)
843 @returns @true on success, @false otherwise }
844 function AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
846 { load alpha channel data from resource ID
847 @param aInstance resource handle
848 @param aResourceID resource ID
849 @param aResType resource type
850 @param aFunc callback to use for converting
851 @param aArgs user defined parameters (use at will)
852 @returns @true on success, @false otherwise }
853 function AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
855 { add alpha channel data from function
856 @param aFunc callback to get data from
857 @param aArgs user defined parameters (use at will)
858 @returns @true on success, @false otherwise }
859 function AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer = nil): Boolean; virtual;
861 { add alpha channel data from file (macro for: new glBitmap, LoadFromFile, AddAlphaFromGlBitmap)
862 @param aFilename file to load alpha channel data from
863 @param aFunc callback to use for converting
864 @param aArgs user defined parameters (use at will)
865 @returns @true on success, @false otherwise }
866 function AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
868 { add alpha channel data from stream (macro for: new glBitmap, LoadFromStream, AddAlphaFromGlBitmap)
869 @param aStream stream to load alpha channel data from
870 @param aFunc callback to use for converting
871 @param aArgs user defined parameters (use at will)
872 @returns @true on success, @false otherwise }
873 function AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
875 { add alpha channel data from existing glBitmap object
876 @param aBitmap TglBitmap to copy alpha channel data from
877 @param aFunc callback to use for converting
878 @param aArgs user defined parameters (use at will)
879 @returns @true on success, @false otherwise }
880 function AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
882 { add alpha to pixel if the pixels color is greter than the given color value
883 @param aRed red threshold (0-255)
884 @param aGreen green threshold (0-255)
885 @param aBlue blue threshold (0-255)
886 @param aDeviatation accepted deviatation (0-255)
887 @returns @true on success, @false otherwise }
888 function AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte = 0): Boolean;
890 { add alpha to pixel if the pixels color is greter than the given color value
891 @param aRed red threshold (0-Range.r)
892 @param aGreen green threshold (0-Range.g)
893 @param aBlue blue threshold (0-Range.b)
894 @param aDeviatation accepted deviatation (0-max(Range.rgb))
895 @returns @true on success, @false otherwise }
896 function AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal = 0): Boolean;
898 { add alpha to pixel if the pixels color is greter than the given color value
899 @param aRed red threshold (0.0-1.0)
900 @param aGreen green threshold (0.0-1.0)
901 @param aBlue blue threshold (0.0-1.0)
902 @param aDeviatation accepted deviatation (0.0-1.0)
903 @returns @true on success, @false otherwise }
904 function AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single = 0): Boolean;
906 { add a constand alpha value to all pixels
907 @param aAlpha alpha value to add (0-255)
908 @returns @true on success, @false otherwise }
909 function AddAlphaFromValue(const aAlpha: Byte): Boolean;
911 { add a constand alpha value to all pixels
912 @param aAlpha alpha value to add (0-max(Range.rgb))
913 @returns @true on success, @false otherwise }
914 function AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
916 { add a constand alpha value to all pixels
917 @param aAlpha alpha value to add (0.0-1.0)
918 @returns @true on success, @false otherwise }
919 function AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
921 { remove alpha channel
922 @returns @true on success, @false otherwise }
923 function RemoveAlpha: Boolean; virtual;
926 { create a clone of the current object
927 @returns clone of this object}
928 function Clone: TglBitmap;
930 { invert color data (xor)
931 @param aUseRGB xor each color channel
932 @param aUseAlpha xor alpha channel }
933 procedure Invert(const aUseRGB: Boolean = true; const aUseAlpha: Boolean = false);
935 { free texture stored data }
939 { set the new value for texture border color
940 @param aRed red color for border (0.0-1.0)
941 @param aGreen green color for border (0.0-1.0)
942 @param aBlue blue color for border (0.0-1.0)
943 @param aAlpha alpha color for border (0.0-1.0) }
944 procedure SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
948 { fill complete texture with one color
949 @param aRed red color for border (0-255)
950 @param aGreen green color for border (0-255)
951 @param aBlue blue color for border (0-255)
952 @param aAlpha alpha color for border (0-255) }
953 procedure FillWithColor(const aRed, aGreen, aBlue: Byte; const aAlpha: Byte = 255);
955 { fill complete texture with one color
956 @param aRed red color for border (0-Range.r)
957 @param aGreen green color for border (0-Range.g)
958 @param aBlue blue color for border (0-Range.b)
959 @param aAlpha alpha color for border (0-Range.a) }
960 procedure FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal = $FFFFFFFF);
962 { fill complete texture with one color
963 @param aRed red color for border (0.0-1.0)
964 @param aGreen green color for border (0.0-1.0)
965 @param aBlue blue color for border (0.0-1.0)
966 @param aAlpha alpha color for border (0.0-1.0) }
967 procedure FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single = 1.0);
970 { set new texture filer
971 @param aMin min filter
972 @param aMag mag filter }
973 procedure SetFilter(const aMin, aMag: GLenum);
975 { set new texture wrapping
976 @param S texture wrapping for x axis
977 @param T texture wrapping for y axis
978 @param R texture wrapping for z axis }
980 const S: GLenum = GL_CLAMP_TO_EDGE;
981 const T: GLenum = GL_CLAMP_TO_EDGE;
982 const R: GLenum = GL_CLAMP_TO_EDGE);
984 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
986 @param r swizzle for red channel
987 @param g swizzle for green channel
988 @param b swizzle for blue channel
989 @param a swizzle for alpha channel }
990 procedure SetSwizzle(const r, g, b, a: GLenum);
995 @param aEnableTextureUnit enable texture unit for this texture (e.g. glEnable(GL_TEXTURE_2D)) }
996 procedure Bind(const aEnableTextureUnit: Boolean = true); virtual;
999 @param aDisableTextureUnit disable texture unit for this texture (e.g. glEnable(GL_TEXTURE_2D)) }
1000 procedure Unbind(const aDisableTextureUnit: Boolean = true); virtual;
1003 { constructor - created an empty texture }
1004 constructor Create; overload;
1006 { constructor - creates a texture and load it from a file
1007 @param aFilename file to load texture from }
1008 constructor Create(const aFileName: String); overload;
1010 { constructor - creates a texture and load it from a stream
1011 @param aStream stream to load texture from }
1012 constructor Create(const aStream: TStream); overload;
1014 { constructor - creates a texture with the given size, format and data
1015 @param aSize size of the texture
1016 @param aFormat format of the given data
1017 @param aData texture data - be carefull: the data will now be managed by the glBitmap object,
1018 you can control this by setting DeleteTextureOnFree, FreeDataOnDestroy and FreeDataAfterGenTexture }
1019 constructor Create(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat; aData: PByte = nil); overload;
1021 { constructor - creates a texture with the given size and format and uses the given callback to create the data
1022 @param aSize size of the texture
1023 @param aFormat format of the given data
1024 @param aFunc callback to use for generating the data
1025 @param aArgs user defined parameters (use at will) }
1026 constructor Create(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer = nil); overload;
1028 { constructor - creates a texture and loads it from a resource
1029 @param aInstance resource handle
1030 @param aResource resource indentifier
1031 @param aResType resource type (if known) }
1032 constructor Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil); overload;
1034 { constructor - creates a texture and loads it from a resource
1035 @param aInstance resource handle
1036 @param aResourceID resource ID
1037 @param aResType resource type (if known) }
1038 constructor Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar); overload;
1041 {$IFDEF GLB_SUPPORT_PNG_READ}
1042 { try to load a PNG from a stream
1043 @param aStream stream to load PNG from
1044 @returns @true on success, @false otherwise }
1045 function LoadPNG(const aStream: TStream): Boolean; virtual;
1048 {$ifdef GLB_SUPPORT_PNG_WRITE}
1049 { save texture data as PNG to stream
1050 @param aStream stream to save data to}
1051 procedure SavePNG(const aStream: TStream); virtual;
1054 {$IFDEF GLB_SUPPORT_JPEG_READ}
1055 { try to load a JPEG from a stream
1056 @param aStream stream to load JPEG from
1057 @returns @true on success, @false otherwise }
1058 function LoadJPEG(const aStream: TStream): Boolean; virtual;
1061 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
1062 { save texture data as JPEG to stream
1063 @param aStream stream to save data to}
1064 procedure SaveJPEG(const aStream: TStream); virtual;
1067 { try to load a RAW image from a stream
1068 @param aStream stream to load RAW image from
1069 @returns @true on success, @false otherwise }
1070 function LoadRAW(const aStream: TStream): Boolean;
1072 { save texture data as RAW image to stream
1073 @param aStream stream to save data to}
1074 procedure SaveRAW(const aStream: TStream);
1076 { try to load a BMP from a stream
1077 @param aStream stream to load BMP from
1078 @returns @true on success, @false otherwise }
1079 function LoadBMP(const aStream: TStream): Boolean;
1081 { save texture data as BMP to stream
1082 @param aStream stream to save data to}
1083 procedure SaveBMP(const aStream: TStream);
1085 { try to load a TGA from a stream
1086 @param aStream stream to load TGA from
1087 @returns @true on success, @false otherwise }
1088 function LoadTGA(const aStream: TStream): Boolean;
1090 { save texture data as TGA to stream
1091 @param aStream stream to save data to}
1092 procedure SaveTGA(const aStream: TStream);
1094 { try to load a DDS from a stream
1095 @param aStream stream to load DDS from
1096 @returns @true on success, @false otherwise }
1097 function LoadDDS(const aStream: TStream): Boolean;
1099 { save texture data as DDS to stream
1100 @param aStream stream to save data to}
1101 procedure SaveDDS(const aStream: TStream);
1104 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1105 {$IF NOT DEFINED(OPENGL_ES)}
1106 { wrapper class for 1-dimensional textures (OpenGL target = GL_TEXTURE_1D }
1107 TglBitmap1D = class(TglBitmap)
1109 { set data pointer of texture data
1110 @param aData pointer to new texture data (be carefull, aData could be freed by this function)
1111 @param aFormat format of the data stored at aData
1112 @param aWidth width of the texture data
1113 @param aHeight height of the texture data }
1114 procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat; const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
1116 { upload the texture data to video card
1117 @param aBuildWithGlu use glu functions to build mipmaps }
1118 procedure UploadData(const aBuildWithGlu: Boolean);
1120 property Width; //< actual with of the texture
1122 { this method is called after constructor and initializes the object }
1123 procedure AfterConstruction; override;
1125 { flip texture horizontally
1126 @returns @true on success, @fals otherwise }
1127 function FlipHorz: Boolean; override;
1129 { generate texture (create texture object if not exist, set texture parameters and upload data
1130 @param aTestTextureSize check the size of the texture and throw exception if something is wrong }
1131 procedure GenTexture(const aTestTextureSize: Boolean = true); override;
1135 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1136 { wrapper class for 2-dimensional textures (OpenGL target = GL_TEXTURE_2D) }
1137 TglBitmap2D = class(TglBitmap)
1139 fLines: array of PByte; //< array to store scanline entry points in
1141 { get a specific scanline
1142 @param aIndex index of the scanline to return
1143 @returns scanline at position aIndex or @nil }
1144 function GetScanline(const aIndex: Integer): Pointer;
1146 { set data pointer of texture data
1147 @param aData pointer to new texture data (be carefull, aData could be freed by this function)
1148 @param aFormat format of the data stored at aData
1149 @param aWidth width of the texture data
1150 @param aHeight height of the texture data }
1151 procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
1152 const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
1154 { upload the texture data to video card
1155 @param aTarget target o upload data to (e.g. GL_TEXTURE_2D)
1156 @param aBuildWithGlu use glu functions to build mipmaps }
1157 procedure UploadData(const aTarget: GLenum{$IFNDEF OPENGL_ES}; const aBuildWithGlu: Boolean{$ENDIF});
1159 property Width; //< actual width of the texture
1160 property Height; //< actual height of the texture
1161 property Scanline[const aIndex: Integer]: Pointer read GetScanline; //< scanline to access texture data directly
1163 { this method is called after constructor and initializes the object }
1164 procedure AfterConstruction; override;
1166 { copy a part of the frame buffer top the texture
1167 @param aTop topmost pixel to copy
1168 @param aLeft leftmost pixel to copy
1169 @param aRight rightmost pixel to copy
1170 @param aBottom bottommost pixel to copy
1171 @param aFormat format to store data in }
1172 procedure GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
1175 { downlaod texture data from OpenGL texture object }
1176 procedure GetDataFromTexture;
1179 { generate texture (create texture object if not exist, set texture parameters and upload data)
1180 @param aTestTextureSize check the size of the texture and throw exception if something is wrong }
1181 procedure GenTexture(const aTestTextureSize: Boolean = true); override;
1183 { flip texture horizontally
1184 @returns @true on success, @false otherwise }
1185 function FlipHorz: Boolean; override;
1187 { flip texture vertically
1188 @returns @true on success, @false otherwise }
1189 function FlipVert: Boolean; override;
1191 { create normal map from texture data
1192 @param aFunc normal map function to generate normalmap with
1193 @param aScale scale of the normale stored in the normal map
1194 @param aUseAlpha generate normalmap from alpha channel data (if present) }
1195 procedure GenerateNormalMap(const aFunc: TglBitmapNormalMapFunc = nm3x3;
1196 const aScale: Single = 2; const aUseAlpha: Boolean = false);
1199 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1200 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
1201 { wrapper class for cube maps (OpenGL target = GL_TEXTURE_CUBE_MAP) }
1202 TglBitmapCubeMap = class(TglBitmap2D)
1205 fGenMode: Integer; //< generation mode for the cube map (e.g. GL_REFLECTION_MAP)
1208 { generate texture (create texture object if not exist, set texture parameters and upload data
1209 do not call directly for cubemaps, use GenerateCubeMap instead
1210 @param aTestTextureSize check the size of the texture and throw exception if something is wrong }
1211 procedure GenTexture(const aTestTextureSize: Boolean = true); reintroduce;
1213 { this method is called after constructor and initializes the object }
1214 procedure AfterConstruction; override;
1216 { generate texture (create texture object if not exist, set texture parameters and upload data
1217 @param aCubeTarget cube map target to upload data to (e.g. GL_TEXTURE_CUBE_MAP_POSITIVE_X)
1218 @param aTestTextureSize check the size of the texture and throw exception if something is wrong }
1219 procedure GenerateCubeMap(const aCubeTarget: Cardinal; const aTestTextureSize: Boolean = true);
1222 @param aEnableTexCoordsGen enable cube map generator
1223 @param aEnableTextureUnit enable texture unit }
1224 procedure Bind({$IFNDEF OPENGL_ES}const aEnableTexCoordsGen: Boolean = true;{$ENDIF} const aEnableTextureUnit: Boolean = true); reintroduce; virtual;
1227 @param aDisableTexCoordsGen disable cube map generator
1228 @param aDisableTextureUnit disable texture unit }
1229 procedure Unbind({$IFNDEF OPENGL_ES}const aDisableTexCoordsGen: Boolean = true;{$ENDIF} const aDisableTextureUnit: Boolean = true); reintroduce; virtual;
1233 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
1234 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1235 { wrapper class for cube normal maps }
1236 TglBitmapNormalMap = class(TglBitmapCubeMap)
1238 { this method is called after constructor and initializes the object }
1239 procedure AfterConstruction; override;
1241 { create cube normal map from texture data and upload it to video card
1242 @param aSize size of each cube map texture
1243 @param aTestTextureSize check texture size when uploading and throw exception if something is wrong }
1244 procedure GenerateNormalMap(const aSize: Integer = 32; const aTestTextureSize: Boolean = true);
1249 NULL_SIZE: TglBitmapSize = (Fields: []; X: 0; Y: 0);
1251 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
1252 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
1253 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
1254 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
1255 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
1256 procedure glBitmapSetDefaultWrap(
1257 const S: Cardinal = GL_CLAMP_TO_EDGE;
1258 const T: Cardinal = GL_CLAMP_TO_EDGE;
1259 const R: Cardinal = GL_CLAMP_TO_EDGE);
1261 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
1262 procedure glBitmapSetDefaultSwizzle(const r: GLenum = GL_RED; g: GLenum = GL_GREEN; b: GLenum = GL_BLUE; a: GLenum = GL_ALPHA);
1265 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
1266 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
1267 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
1268 function glBitmapGetDefaultFormat: TglBitmapFormat;
1269 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
1270 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
1271 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
1272 procedure glBitmapGetDefaultSwizzle(var r, g, b, a: GLenum);
1275 function glBitmapSize(X: Integer = -1; Y: Integer = -1): TglBitmapSize;
1276 function glBitmapPosition(X: Integer = -1; Y: Integer = -1): TglBitmapPixelPosition;
1277 function glBitmapRec4ub(const r, g, b, a: Byte): TglBitmapRec4ub;
1278 function glBitmapRec4ui(const r, g, b, a: Cardinal): TglBitmapRec4ui;
1279 function glBitmapRec4ul(const r, g, b, a: QWord): TglBitmapRec4ul;
1280 function glBitmapRec4ubCompare(const r1, r2: TglBitmapRec4ub): Boolean;
1281 function glBitmapRec4uiCompare(const r1, r2: TglBitmapRec4ui): Boolean;
1283 function glBitmapCreateTestTexture(const aFormat: TglBitmapFormat): TglBitmap2D;
1286 function CreateGrayPalette: HPALETTE;
1292 Math, syncobjs, typinfo
1293 {$IF DEFINED(GLB_SUPPORT_JPEG_READ) AND DEFINED(GLB_LAZ_JPEG)}, FPReadJPEG{$IFEND};
1297 glBitmapDefaultDeleteTextureOnFree: Boolean;
1298 glBitmapDefaultFreeDataAfterGenTextures: Boolean;
1299 glBitmapDefaultFormat: TglBitmapFormat;
1300 glBitmapDefaultMipmap: TglBitmapMipMap;
1301 glBitmapDefaultFilterMin: Cardinal;
1302 glBitmapDefaultFilterMag: Cardinal;
1303 glBitmapDefaultWrapS: Cardinal;
1304 glBitmapDefaultWrapT: Cardinal;
1305 glBitmapDefaultWrapR: Cardinal;
1306 glDefaultSwizzle: array[0..3] of GLenum;
1308 ////////////////////////////////////////////////////////////////////////////////////////////////////
1310 TFormatDescriptor = class(TglBitmapFormatDescriptor)
1312 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); virtual; abstract;
1313 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); virtual; abstract;
1315 function GetSize(const aSize: TglBitmapSize): Integer; overload; virtual;
1316 function GetSize(const aWidth, aHeight: Integer): Integer; overload; virtual;
1318 function CreateMappingData: Pointer; virtual;
1319 procedure FreeMappingData(var aMappingData: Pointer); virtual;
1321 function IsEmpty: Boolean; virtual;
1322 function MaskMatch(const aMask: TglBitmapRec4ul): Boolean; virtual;
1324 procedure PreparePixel(out aPixel: TglBitmapPixelData); virtual;
1326 constructor Create; virtual;
1328 class procedure Init;
1329 class function Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
1330 class function GetAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
1331 class function GetFromMask(const aMask: TglBitmapRec4ul; const aBitCount: Integer = 0): TFormatDescriptor;
1332 class function GetFromPrecShift(const aPrec, aShift: TglBitmapRec4ub; const aBitCount: Integer): TFormatDescriptor;
1333 class procedure Clear;
1334 class procedure Finalize;
1336 TFormatDescriptorClass = class of TFormatDescriptor;
1338 TfdEmpty = class(TFormatDescriptor);
1340 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1341 TfdAlphaUB1 = class(TFormatDescriptor) //1* unsigned byte
1342 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1343 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1346 TfdLuminanceUB1 = class(TFormatDescriptor) //1* unsigned byte
1347 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1348 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1351 TfdUniversalUB1 = class(TFormatDescriptor) //1* unsigned byte
1352 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1353 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1356 TfdLuminanceAlphaUB2 = class(TfdLuminanceUB1) //2* unsigned byte
1357 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1358 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1361 TfdRGBub3 = class(TFormatDescriptor) //3* unsigned byte
1362 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1363 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1366 TfdBGRub3 = class(TFormatDescriptor) //3* unsigned byte (inverse)
1367 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1368 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1371 TfdRGBAub4 = class(TfdRGBub3) //3* unsigned byte
1372 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1373 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1376 TfdBGRAub4 = class(TfdBGRub3) //3* unsigned byte (inverse)
1377 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1378 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1381 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1382 TfdAlphaUS1 = class(TFormatDescriptor) //1* unsigned short
1383 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1384 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1387 TfdLuminanceUS1 = class(TFormatDescriptor) //1* unsigned short
1388 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1389 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1392 TfdUniversalUS1 = class(TFormatDescriptor) //1* unsigned short
1393 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1394 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1397 TfdDepthUS1 = class(TFormatDescriptor) //1* unsigned short
1398 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1399 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1402 TfdLuminanceAlphaUS2 = class(TfdLuminanceUS1) //2* unsigned short
1403 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1404 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1407 TfdRGBus3 = class(TFormatDescriptor) //3* unsigned short
1408 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1409 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1412 TfdBGRus3 = class(TFormatDescriptor) //3* unsigned short (inverse)
1413 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1414 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1417 TfdRGBAus4 = class(TfdRGBus3) //4* unsigned short
1418 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1419 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1422 TfdARGBus4 = class(TfdRGBus3) //4* unsigned short
1423 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1424 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1427 TfdBGRAus4 = class(TfdBGRus3) //4* unsigned short (inverse)
1428 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1429 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1432 TfdABGRus4 = class(TfdBGRus3) //4* unsigned short (inverse)
1433 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1434 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1437 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1438 TfdUniversalUI1 = class(TFormatDescriptor) //1* unsigned int
1439 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1440 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1443 TfdDepthUI1 = class(TFormatDescriptor) //1* unsigned int
1444 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1445 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1448 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1449 TfdAlpha4ub1 = class(TfdAlphaUB1)
1450 procedure SetValues; override;
1453 TfdAlpha8ub1 = class(TfdAlphaUB1)
1454 procedure SetValues; override;
1457 TfdAlpha16us1 = class(TfdAlphaUS1)
1458 procedure SetValues; override;
1461 TfdLuminance4ub1 = class(TfdLuminanceUB1)
1462 procedure SetValues; override;
1465 TfdLuminance8ub1 = class(TfdLuminanceUB1)
1466 procedure SetValues; override;
1469 TfdLuminance16us1 = class(TfdLuminanceUS1)
1470 procedure SetValues; override;
1473 TfdLuminance4Alpha4ub2 = class(TfdLuminanceAlphaUB2)
1474 procedure SetValues; override;
1477 TfdLuminance6Alpha2ub2 = class(TfdLuminanceAlphaUB2)
1478 procedure SetValues; override;
1481 TfdLuminance8Alpha8ub2 = class(TfdLuminanceAlphaUB2)
1482 procedure SetValues; override;
1485 TfdLuminance12Alpha4us2 = class(TfdLuminanceAlphaUS2)
1486 procedure SetValues; override;
1489 TfdLuminance16Alpha16us2 = class(TfdLuminanceAlphaUS2)
1490 procedure SetValues; override;
1493 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1494 TfdR3G3B2ub1 = class(TfdUniversalUB1)
1495 procedure SetValues; override;
1498 TfdRGBX4us1 = class(TfdUniversalUS1)
1499 procedure SetValues; override;
1502 TfdXRGB4us1 = class(TfdUniversalUS1)
1503 procedure SetValues; override;
1506 TfdR5G6B5us1 = class(TfdUniversalUS1)
1507 procedure SetValues; override;
1510 TfdRGB5X1us1 = class(TfdUniversalUS1)
1511 procedure SetValues; override;
1514 TfdX1RGB5us1 = class(TfdUniversalUS1)
1515 procedure SetValues; override;
1518 TfdRGB8ub3 = class(TfdRGBub3)
1519 procedure SetValues; override;
1522 TfdRGBX8ui1 = class(TfdUniversalUI1)
1523 procedure SetValues; override;
1526 TfdXRGB8ui1 = class(TfdUniversalUI1)
1527 procedure SetValues; override;
1530 TfdRGB10X2ui1 = class(TfdUniversalUI1)
1531 procedure SetValues; override;
1534 TfdX2RGB10ui1 = class(TfdUniversalUI1)
1535 procedure SetValues; override;
1538 TfdRGB16us3 = class(TfdRGBus3)
1539 procedure SetValues; override;
1542 TfdRGBA4us1 = class(TfdUniversalUS1)
1543 procedure SetValues; override;
1546 TfdARGB4us1 = class(TfdUniversalUS1)
1547 procedure SetValues; override;
1550 TfdRGB5A1us1 = class(TfdUniversalUS1)
1551 procedure SetValues; override;
1554 TfdA1RGB5us1 = class(TfdUniversalUS1)
1555 procedure SetValues; override;
1558 TfdRGBA8ui1 = class(TfdUniversalUI1)
1559 procedure SetValues; override;
1562 TfdARGB8ui1 = class(TfdUniversalUI1)
1563 procedure SetValues; override;
1566 TfdRGBA8ub4 = class(TfdRGBAub4)
1567 procedure SetValues; override;
1570 TfdRGB10A2ui1 = class(TfdUniversalUI1)
1571 procedure SetValues; override;
1574 TfdA2RGB10ui1 = class(TfdUniversalUI1)
1575 procedure SetValues; override;
1578 TfdRGBA16us4 = class(TfdRGBAus4)
1579 procedure SetValues; override;
1582 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1583 TfdBGRX4us1 = class(TfdUniversalUS1)
1584 procedure SetValues; override;
1587 TfdXBGR4us1 = class(TfdUniversalUS1)
1588 procedure SetValues; override;
1591 TfdB5G6R5us1 = class(TfdUniversalUS1)
1592 procedure SetValues; override;
1595 TfdBGR5X1us1 = class(TfdUniversalUS1)
1596 procedure SetValues; override;
1599 TfdX1BGR5us1 = class(TfdUniversalUS1)
1600 procedure SetValues; override;
1603 TfdBGR8ub3 = class(TfdBGRub3)
1604 procedure SetValues; override;
1607 TfdBGRX8ui1 = class(TfdUniversalUI1)
1608 procedure SetValues; override;
1611 TfdXBGR8ui1 = class(TfdUniversalUI1)
1612 procedure SetValues; override;
1615 TfdBGR10X2ui1 = class(TfdUniversalUI1)
1616 procedure SetValues; override;
1619 TfdX2BGR10ui1 = class(TfdUniversalUI1)
1620 procedure SetValues; override;
1623 TfdBGR16us3 = class(TfdBGRus3)
1624 procedure SetValues; override;
1627 TfdBGRA4us1 = class(TfdUniversalUS1)
1628 procedure SetValues; override;
1631 TfdABGR4us1 = class(TfdUniversalUS1)
1632 procedure SetValues; override;
1635 TfdBGR5A1us1 = class(TfdUniversalUS1)
1636 procedure SetValues; override;
1639 TfdA1BGR5us1 = class(TfdUniversalUS1)
1640 procedure SetValues; override;
1643 TfdBGRA8ui1 = class(TfdUniversalUI1)
1644 procedure SetValues; override;
1647 TfdABGR8ui1 = class(TfdUniversalUI1)
1648 procedure SetValues; override;
1651 TfdBGRA8ub4 = class(TfdBGRAub4)
1652 procedure SetValues; override;
1655 TfdBGR10A2ui1 = class(TfdUniversalUI1)
1656 procedure SetValues; override;
1659 TfdA2BGR10ui1 = class(TfdUniversalUI1)
1660 procedure SetValues; override;
1663 TfdBGRA16us4 = class(TfdBGRAus4)
1664 procedure SetValues; override;
1667 TfdDepth16us1 = class(TfdDepthUS1)
1668 procedure SetValues; override;
1671 TfdDepth24ui1 = class(TfdDepthUI1)
1672 procedure SetValues; override;
1675 TfdDepth32ui1 = class(TfdDepthUI1)
1676 procedure SetValues; override;
1679 TfdS3tcDtx1RGBA = class(TFormatDescriptor)
1680 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1681 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1682 procedure SetValues; override;
1685 TfdS3tcDtx3RGBA = class(TFormatDescriptor)
1686 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1687 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1688 procedure SetValues; override;
1691 TfdS3tcDtx5RGBA = class(TFormatDescriptor)
1692 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1693 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1694 procedure SetValues; override;
1697 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1698 TbmpBitfieldFormat = class(TFormatDescriptor)
1700 procedure SetCustomValues(const aBPP: Integer; aMask: TglBitmapRec4ul); overload;
1701 procedure SetCustomValues(const aBBP: Integer; const aPrec, aShift: TglBitmapRec4ub); overload;
1702 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1703 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1706 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1707 TbmpColorTableEnty = packed record
1710 TbmpColorTable = array of TbmpColorTableEnty;
1711 TbmpColorTableFormat = class(TFormatDescriptor)
1713 fBitsPerPixel: Integer;
1714 fColorTable: TbmpColorTable;
1716 procedure SetValues; override;
1718 property ColorTable: TbmpColorTable read fColorTable write fColorTable;
1719 property BitsPerPixel: Integer read fBitsPerPixel write fBitsPerPixel;
1721 procedure SetCustomValues(const aFormat: TglBitmapFormat; const aBPP: Integer; const aPrec, aShift: TglBitmapRec4ub); overload;
1722 procedure CalcValues;
1723 procedure CreateColorTable;
1725 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1726 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1727 destructor Destroy; override;
1731 LUMINANCE_WEIGHT_R = 0.30;
1732 LUMINANCE_WEIGHT_G = 0.59;
1733 LUMINANCE_WEIGHT_B = 0.11;
1735 ALPHA_WEIGHT_R = 0.30;
1736 ALPHA_WEIGHT_G = 0.59;
1737 ALPHA_WEIGHT_B = 0.11;
1739 DEPTH_WEIGHT_R = 0.333333333;
1740 DEPTH_WEIGHT_G = 0.333333333;
1741 DEPTH_WEIGHT_B = 0.333333333;
1743 FORMAT_DESCRIPTOR_CLASSES: array[TglBitmapFormat] of TFormatDescriptorClass = (
1754 TfdLuminance4Alpha4ub2,
1755 TfdLuminance6Alpha2ub2,
1756 TfdLuminance8Alpha8ub2,
1757 TfdLuminance12Alpha4us2,
1758 TfdLuminance16Alpha16us2,
1817 FormatDescriptorCS: TCriticalSection;
1818 FormatDescriptors: array[TglBitmapFormat] of TFormatDescriptor;
1820 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1821 constructor EglBitmapUnsupportedFormat.Create(const aFormat: TglBitmapFormat);
1823 inherited Create('unsupported format: ' + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
1826 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1827 constructor EglBitmapUnsupportedFormat.Create(const aMsg: String; const aFormat: TglBitmapFormat);
1829 inherited Create(aMsg + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
1832 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1833 function glBitmapSize(X: Integer; Y: Integer): TglBitmapSize;
1835 result.Fields := [];
1837 result.Fields := result.Fields + [ffX];
1839 result.Fields := result.Fields + [ffY];
1840 result.X := Max(0, X);
1841 result.Y := Max(0, Y);
1844 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1845 function glBitmapPosition(X: Integer; Y: Integer): TglBitmapPixelPosition;
1847 result := glBitmapSize(X, Y);
1850 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1851 function glBitmapRec4ub(const r, g, b, a: Byte): TglBitmapRec4ub;
1859 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1860 function glBitmapRec4ui(const r, g, b, a: Cardinal): TglBitmapRec4ui;
1868 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1869 function glBitmapRec4ul(const r, g, b, a: QWord): TglBitmapRec4ul;
1877 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1878 function glBitmapRec4ubCompare(const r1, r2: TglBitmapRec4ub): Boolean;
1883 for i := 0 to high(r1.arr) do
1884 if (r1.arr[i] <> r2.arr[i]) then
1889 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1890 function glBitmapRec4uiCompare(const r1, r2: TglBitmapRec4ui): Boolean;
1895 for i := 0 to high(r1.arr) do
1896 if (r1.arr[i] <> r2.arr[i]) then
1901 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1902 function glBitmapCreateTestTexture(const aFormat: TglBitmapFormat): TglBitmap2D;
1904 desc: TFormatDescriptor;
1908 px: TglBitmapPixelData;
1911 desc := TFormatDescriptor.Get(aFormat);
1912 if (desc.IsCompressed) or (desc.glFormat = 0) then
1915 p := GetMemory(ceil(25 * desc.BytesPerPixel)); // 5 x 5 pixel
1916 md := desc.CreateMappingData;
1919 desc.PreparePixel(px);
1921 for x := 0 to 4 do begin
1922 px.Data := glBitmapRec4ui(0, 0, 0, 0);
1923 for i := 0 to 3 do begin
1924 if ((y < 3) and (y = i)) or
1925 ((y = 3) and (i < 3)) or
1926 ((y = 4) and (i = 3))
1928 px.Data.arr[i] := Trunc(px.Range.arr[i] / 4 * x)
1929 else if ((y < 4) and (i = 3)) or
1930 ((y = 4) and (i < 3))
1932 px.Data.arr[i] := px.Range.arr[i]
1934 px.Data.arr[i] := 0; //px.Range.arr[i];
1936 desc.Map(px, tmp, md);
1939 desc.FreeMappingData(md);
1942 result := TglBitmap2D.Create(glBitmapPosition(5, 5), aFormat, p);
1943 result.FreeDataOnDestroy := true;
1944 result.FreeDataAfterGenTexture := false;
1945 result.SetFilter(GL_NEAREST, GL_NEAREST);
1948 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1949 function glBitmapShiftRec(const r, g, b, a: Byte): TglBitmapRec4ub;
1957 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1958 function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes;
1964 tfAlpha4ub1, tfAlpha8ub1,
1965 tfLuminance4ub1, tfLuminance8ub1, tfR3G3B2ub1,
1968 tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
1969 tfRGBX4us1, tfXRGB4us1, tfRGB5X1us1, tfX1RGB5us1, tfR5G6B5us1, tfRGB5A1us1, tfA1RGB5us1, tfRGBA4us1, tfARGB4us1,
1970 tfBGRX4us1, tfXBGR4us1, tfBGR5X1us1, tfX1BGR5us1, tfB5G6R5us1, tfBGR5A1us1, tfA1BGR5us1, tfBGRA4us1, tfABGR4us1,
1973 tfBGR8ub3, tfRGB8ub3,
1976 tfRGBX8ui1, tfXRGB8ui1, tfRGB10X2ui1, tfX2RGB10ui1, tfRGBA8ui1, tfARGB8ui1, tfRGBA8ub4, tfRGB10A2ui1, tfA2RGB10ui1,
1977 tfBGRX8ui1, tfXBGR8ui1, tfBGR10X2ui1, tfX2BGR10ui1, tfBGRA8ui1, tfABGR8ui1, tfBGRA8ub4, tfBGR10A2ui1, tfA2BGR10ui1])
1979 result := result + [ ftBMP ];
1983 tfAlpha4ub1, tfAlpha8ub1, tfLuminance4ub1, tfLuminance8ub1,
1986 tfAlpha16us1, tfLuminance16us1,
1987 tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
1988 tfX1RGB5us1, tfARGB4us1, tfA1RGB5us1, tfDepth16us1,
1994 tfX2RGB10ui1, tfARGB8ui1, tfBGRA8ub4, tfA2RGB10ui1,
1995 tfDepth24ui1, tfDepth32ui1])
1997 result := result + [ftTGA];
1999 if not (aFormat in [tfEmpty, tfRGB16us3, tfBGR16us3]) then
2000 result := result + [ftDDS];
2002 {$IFDEF GLB_SUPPORT_PNG_WRITE}
2004 tfAlpha8ub1, tfLuminance8ub1, tfLuminance8Alpha8ub2,
2005 tfRGB8ub3, tfRGBA8ui1,
2006 tfBGR8ub3, tfBGRA8ui1] then
2007 result := result + [ftPNG];
2010 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
2011 if aFormat in [tfAlpha8ub1, tfLuminance8ub1, tfRGB8ub3, tfBGR8ub3] then
2012 result := result + [ftJPEG];
2016 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2017 function IsPowerOfTwo(aNumber: Integer): Boolean;
2019 while (aNumber and 1) = 0 do
2020 aNumber := aNumber shr 1;
2021 result := aNumber = 1;
2024 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2025 function GetTopMostBit(aBitSet: QWord): Integer;
2028 while aBitSet > 0 do begin
2030 aBitSet := aBitSet shr 1;
2034 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2035 function CountSetBits(aBitSet: QWord): Integer;
2038 while aBitSet > 0 do begin
2039 if (aBitSet and 1) = 1 then
2041 aBitSet := aBitSet shr 1;
2045 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2046 function LuminanceWeight(const aPixel: TglBitmapPixelData): Cardinal;
2049 LUMINANCE_WEIGHT_R * aPixel.Data.r +
2050 LUMINANCE_WEIGHT_G * aPixel.Data.g +
2051 LUMINANCE_WEIGHT_B * aPixel.Data.b);
2054 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2055 function DepthWeight(const aPixel: TglBitmapPixelData): Cardinal;
2058 DEPTH_WEIGHT_R * aPixel.Data.r +
2059 DEPTH_WEIGHT_G * aPixel.Data.g +
2060 DEPTH_WEIGHT_B * aPixel.Data.b);
2063 {$IFDEF GLB_SDL_IMAGE}
2064 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2065 // SDL Image Helper /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2066 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2067 function glBitmapRWseek(context: PSDL_RWops; offset: Integer; whence: Integer): Integer; cdecl;
2069 result := TStream(context^.unknown.data1).Seek(offset, whence);
2072 function glBitmapRWread(context: PSDL_RWops; Ptr: Pointer; size: Integer; maxnum : Integer): Integer; cdecl;
2074 result := TStream(context^.unknown.data1).Read(Ptr^, size * maxnum);
2077 function glBitmapRWwrite(context: PSDL_RWops; Ptr: Pointer; size: Integer; num: Integer): Integer; cdecl;
2079 result := TStream(context^.unknown.data1).Write(Ptr^, size * num);
2082 function glBitmapRWclose(context: PSDL_RWops): Integer; cdecl;
2087 function glBitmapCreateRWops(Stream: TStream): PSDL_RWops;
2089 result := SDL_AllocRW;
2091 if result = nil then
2092 raise EglBitmap.Create('glBitmapCreateRWops - SDL_AllocRW failed.');
2094 result^.seek := glBitmapRWseek;
2095 result^.read := glBitmapRWread;
2096 result^.write := glBitmapRWwrite;
2097 result^.close := glBitmapRWclose;
2098 result^.unknown.data1 := Stream;
2102 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2103 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
2105 glBitmapDefaultDeleteTextureOnFree := aDeleteTextureOnFree;
2108 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2109 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
2111 glBitmapDefaultFreeDataAfterGenTextures := aFreeData;
2114 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2115 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
2117 glBitmapDefaultMipmap := aValue;
2120 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2121 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
2123 glBitmapDefaultFormat := aFormat;
2126 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2127 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
2129 glBitmapDefaultFilterMin := aMin;
2130 glBitmapDefaultFilterMag := aMag;
2133 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2134 procedure glBitmapSetDefaultWrap(const S: Cardinal = GL_CLAMP_TO_EDGE; const T: Cardinal = GL_CLAMP_TO_EDGE; const R: Cardinal = GL_CLAMP_TO_EDGE);
2136 glBitmapDefaultWrapS := S;
2137 glBitmapDefaultWrapT := T;
2138 glBitmapDefaultWrapR := R;
2141 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2142 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
2143 procedure glBitmapSetDefaultSwizzle(const r: GLenum = GL_RED; g: GLenum = GL_GREEN; b: GLenum = GL_BLUE; a: GLenum = GL_ALPHA);
2145 glDefaultSwizzle[0] := r;
2146 glDefaultSwizzle[1] := g;
2147 glDefaultSwizzle[2] := b;
2148 glDefaultSwizzle[3] := a;
2152 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2153 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
2155 result := glBitmapDefaultDeleteTextureOnFree;
2158 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2159 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
2161 result := glBitmapDefaultFreeDataAfterGenTextures;
2164 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2165 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
2167 result := glBitmapDefaultMipmap;
2170 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2171 function glBitmapGetDefaultFormat: TglBitmapFormat;
2173 result := glBitmapDefaultFormat;
2176 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2177 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
2179 aMin := glBitmapDefaultFilterMin;
2180 aMag := glBitmapDefaultFilterMag;
2183 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2184 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
2186 S := glBitmapDefaultWrapS;
2187 T := glBitmapDefaultWrapT;
2188 R := glBitmapDefaultWrapR;
2191 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
2192 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2193 procedure glBitmapGetDefaultSwizzle(var r, g, b, a: GLenum);
2195 r := glDefaultSwizzle[0];
2196 g := glDefaultSwizzle[1];
2197 b := glDefaultSwizzle[2];
2198 a := glDefaultSwizzle[3];
2202 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2203 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2204 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2205 function TFormatDescriptor.GetSize(const aSize: TglBitmapSize): Integer;
2209 if (ffX in aSize.Fields) or (ffY in aSize.Fields) then begin
2210 w := Max(1, aSize.X);
2211 h := Max(1, aSize.Y);
2212 result := GetSize(w, h);
2217 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2218 function TFormatDescriptor.GetSize(const aWidth, aHeight: Integer): Integer;
2221 if (aWidth <= 0) or (aHeight <= 0) then
2223 result := Ceil(aWidth * aHeight * BytesPerPixel);
2226 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2227 function TFormatDescriptor.CreateMappingData: Pointer;
2232 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2233 procedure TFormatDescriptor.FreeMappingData(var aMappingData: Pointer);
2238 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2239 function TFormatDescriptor.IsEmpty: Boolean;
2241 result := (fFormat = tfEmpty);
2244 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2245 function TFormatDescriptor.MaskMatch(const aMask: TglBitmapRec4ul): Boolean;
2251 if (aMask.r = 0) and (aMask.g = 0) and (aMask.b = 0) and (aMask.a = 0) then
2252 raise EglBitmap.Create('FormatCheckFormat - All Masks are 0');
2255 if (aMask.arr[i] <> m.arr[i]) then
2260 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2261 procedure TFormatDescriptor.PreparePixel(out aPixel: TglBitmapPixelData);
2263 FillChar(aPixel{%H-}, SizeOf(aPixel), 0);
2264 aPixel.Data := Range;
2265 aPixel.Format := fFormat;
2266 aPixel.Range := Range;
2269 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2270 constructor TFormatDescriptor.Create;
2275 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2276 //TfdAlpha_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2277 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2278 procedure TfdAlphaUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2280 aData^ := aPixel.Data.a;
2284 procedure TfdAlphaUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2289 aPixel.Data.a := aData^;
2293 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2294 //TfdLuminance_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2295 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2296 procedure TfdLuminanceUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2298 aData^ := LuminanceWeight(aPixel);
2302 procedure TfdLuminanceUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2304 aPixel.Data.r := aData^;
2305 aPixel.Data.g := aData^;
2306 aPixel.Data.b := aData^;
2311 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2312 //TfdUniversal_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2313 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2314 procedure TfdUniversalUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2320 if (Range.arr[i] > 0) then
2321 aData^ := aData^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
2325 procedure TfdUniversalUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2330 aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and Range.arr[i];
2334 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2335 //TfdLuminanceAlpha_UB2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2336 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2337 procedure TfdLuminanceAlphaUB2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2339 inherited Map(aPixel, aData, aMapData);
2340 aData^ := aPixel.Data.a;
2344 procedure TfdLuminanceAlphaUB2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2346 inherited Unmap(aData, aPixel, aMapData);
2347 aPixel.Data.a := aData^;
2351 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2352 //TfdRGB_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2353 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2354 procedure TfdRGBub3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2356 aData^ := aPixel.Data.r;
2358 aData^ := aPixel.Data.g;
2360 aData^ := aPixel.Data.b;
2364 procedure TfdRGBub3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2366 aPixel.Data.r := aData^;
2368 aPixel.Data.g := aData^;
2370 aPixel.Data.b := aData^;
2375 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2376 //TfdBGR_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2377 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2378 procedure TfdBGRub3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2380 aData^ := aPixel.Data.b;
2382 aData^ := aPixel.Data.g;
2384 aData^ := aPixel.Data.r;
2388 procedure TfdBGRub3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2390 aPixel.Data.b := aData^;
2392 aPixel.Data.g := aData^;
2394 aPixel.Data.r := aData^;
2399 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2400 //TfdRGBA_UB4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2401 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2402 procedure TfdRGBAub4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2404 inherited Map(aPixel, aData, aMapData);
2405 aData^ := aPixel.Data.a;
2409 procedure TfdRGBAub4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2411 inherited Unmap(aData, aPixel, aMapData);
2412 aPixel.Data.a := aData^;
2416 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2417 //TfdBGRA_UB4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2418 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2419 procedure TfdBGRAub4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2421 inherited Map(aPixel, aData, aMapData);
2422 aData^ := aPixel.Data.a;
2426 procedure TfdBGRAub4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2428 inherited Unmap(aData, aPixel, aMapData);
2429 aPixel.Data.a := aData^;
2433 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2434 //TfdAlpha_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2435 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2436 procedure TfdAlphaUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2438 PWord(aData)^ := aPixel.Data.a;
2442 procedure TfdAlphaUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2447 aPixel.Data.a := PWord(aData)^;
2451 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2452 //TfdLuminance_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2453 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2454 procedure TfdLuminanceUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2456 PWord(aData)^ := LuminanceWeight(aPixel);
2460 procedure TfdLuminanceUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2462 aPixel.Data.r := PWord(aData)^;
2463 aPixel.Data.g := PWord(aData)^;
2464 aPixel.Data.b := PWord(aData)^;
2469 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2470 //TfdUniversal_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2471 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2472 procedure TfdUniversalUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2478 if (Range.arr[i] > 0) then
2479 PWord(aData)^ := PWord(aData)^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
2483 procedure TfdUniversalUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2488 aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and Range.arr[i];
2492 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2493 //TfdDepth_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2494 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2495 procedure TfdDepthUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2497 PWord(aData)^ := DepthWeight(aPixel);
2501 procedure TfdDepthUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2503 aPixel.Data.r := PWord(aData)^;
2504 aPixel.Data.g := PWord(aData)^;
2505 aPixel.Data.b := PWord(aData)^;
2506 aPixel.Data.a := PWord(aData)^;;
2510 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2511 //TfdLuminanceAlpha_US2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2512 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2513 procedure TfdLuminanceAlphaUS2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2515 inherited Map(aPixel, aData, aMapData);
2516 PWord(aData)^ := aPixel.Data.a;
2520 procedure TfdLuminanceAlphaUS2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2522 inherited Unmap(aData, aPixel, aMapData);
2523 aPixel.Data.a := PWord(aData)^;
2527 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2528 //TfdRGB_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2529 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2530 procedure TfdRGBus3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2532 PWord(aData)^ := aPixel.Data.r;
2534 PWord(aData)^ := aPixel.Data.g;
2536 PWord(aData)^ := aPixel.Data.b;
2540 procedure TfdRGBus3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2542 aPixel.Data.r := PWord(aData)^;
2544 aPixel.Data.g := PWord(aData)^;
2546 aPixel.Data.b := PWord(aData)^;
2551 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2552 //TfdBGR_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2553 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2554 procedure TfdBGRus3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2556 PWord(aData)^ := aPixel.Data.b;
2558 PWord(aData)^ := aPixel.Data.g;
2560 PWord(aData)^ := aPixel.Data.r;
2564 procedure TfdBGRus3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2566 aPixel.Data.b := PWord(aData)^;
2568 aPixel.Data.g := PWord(aData)^;
2570 aPixel.Data.r := PWord(aData)^;
2575 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2576 //TfdRGBA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2577 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2578 procedure TfdRGBAus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2580 inherited Map(aPixel, aData, aMapData);
2581 PWord(aData)^ := aPixel.Data.a;
2585 procedure TfdRGBAus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2587 inherited Unmap(aData, aPixel, aMapData);
2588 aPixel.Data.a := PWord(aData)^;
2592 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2593 //TfdARGB_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2594 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2595 procedure TfdARGBus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2597 PWord(aData)^ := aPixel.Data.a;
2599 inherited Map(aPixel, aData, aMapData);
2602 procedure TfdARGBus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2604 aPixel.Data.a := PWord(aData)^;
2606 inherited Unmap(aData, aPixel, aMapData);
2609 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2610 //TfdBGRA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2611 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2612 procedure TfdBGRAus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2614 inherited Map(aPixel, aData, aMapData);
2615 PWord(aData)^ := aPixel.Data.a;
2619 procedure TfdBGRAus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2621 inherited Unmap(aData, aPixel, aMapData);
2622 aPixel.Data.a := PWord(aData)^;
2626 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2627 //TfdABGR_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2628 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2629 procedure TfdABGRus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2631 PWord(aData)^ := aPixel.Data.a;
2633 inherited Map(aPixel, aData, aMapData);
2636 procedure TfdABGRus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2638 aPixel.Data.a := PWord(aData)^;
2640 inherited Unmap(aData, aPixel, aMapData);
2643 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2644 //TfdUniversal_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2645 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2646 procedure TfdUniversalUI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2650 PCardinal(aData)^ := 0;
2652 if (Range.arr[i] > 0) then
2653 PCardinal(aData)^ := PCardinal(aData)^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
2657 procedure TfdUniversalUI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2662 aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and Range.arr[i];
2666 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2667 //TfdDepth_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2668 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2669 procedure TfdDepthUI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2671 PCardinal(aData)^ := DepthWeight(aPixel);
2675 procedure TfdDepthUI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2677 aPixel.Data.r := PCardinal(aData)^;
2678 aPixel.Data.g := PCardinal(aData)^;
2679 aPixel.Data.b := PCardinal(aData)^;
2680 aPixel.Data.a := PCardinal(aData)^;
2684 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2685 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2686 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2687 procedure TfdAlpha4ub1.SetValues;
2689 inherited SetValues;
2691 fFormat := tfAlpha4ub1;
2692 fWithAlpha := tfAlpha4ub1;
2693 fPrecision := glBitmapRec4ub(0, 0, 0, 8);
2694 fShift := glBitmapRec4ub(0, 0, 0, 0);
2696 fOpenGLFormat := tfAlpha4ub1;
2697 fglFormat := GL_ALPHA;
2698 fglInternalFormat := GL_ALPHA4;
2699 fglDataFormat := GL_UNSIGNED_BYTE;
2701 fOpenGLFormat := tfAlpha8ub1;
2705 procedure TfdAlpha8ub1.SetValues;
2707 inherited SetValues;
2709 fFormat := tfAlpha8ub1;
2710 fWithAlpha := tfAlpha8ub1;
2711 fPrecision := glBitmapRec4ub(0, 0, 0, 8);
2712 fShift := glBitmapRec4ub(0, 0, 0, 0);
2713 fOpenGLFormat := tfAlpha8ub1;
2714 fglFormat := GL_ALPHA;
2715 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_ALPHA8{$ELSE}GL_ALPHA{$ENDIF};
2716 fglDataFormat := GL_UNSIGNED_BYTE;
2719 procedure TfdAlpha16us1.SetValues;
2721 inherited SetValues;
2722 fBitsPerPixel := 16;
2723 fFormat := tfAlpha16us1;
2724 fWithAlpha := tfAlpha16us1;
2725 fPrecision := glBitmapRec4ub(0, 0, 0, 16);
2726 fShift := glBitmapRec4ub(0, 0, 0, 0);
2728 fOpenGLFormat := tfAlpha16us1;
2729 fglFormat := GL_ALPHA;
2730 fglInternalFormat := GL_ALPHA16;
2731 fglDataFormat := GL_UNSIGNED_SHORT;
2733 fOpenGLFormat := tfAlpha8ub1;
2737 procedure TfdLuminance4ub1.SetValues;
2739 inherited SetValues;
2741 fFormat := tfLuminance4ub1;
2742 fWithAlpha := tfLuminance4Alpha4ub2;
2743 fWithoutAlpha := tfLuminance4ub1;
2744 fPrecision := glBitmapRec4ub(8, 8, 8, 0);
2745 fShift := glBitmapRec4ub(0, 0, 0, 0);
2747 fOpenGLFormat := tfLuminance4ub1;
2748 fglFormat := GL_LUMINANCE;
2749 fglInternalFormat := GL_LUMINANCE4;
2750 fglDataFormat := GL_UNSIGNED_BYTE;
2752 fOpenGLFormat := tfLuminance8ub1;
2756 procedure TfdLuminance8ub1.SetValues;
2758 inherited SetValues;
2760 fFormat := tfLuminance8ub1;
2761 fWithAlpha := tfLuminance8Alpha8ub2;
2762 fWithoutAlpha := tfLuminance8ub1;
2763 fOpenGLFormat := tfLuminance8ub1;
2764 fPrecision := glBitmapRec4ub(8, 8, 8, 0);
2765 fShift := glBitmapRec4ub(0, 0, 0, 0);
2766 fglFormat := GL_LUMINANCE;
2767 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_LUMINANCE8{$ELSE}GL_LUMINANCE{$ENDIF};
2768 fglDataFormat := GL_UNSIGNED_BYTE;
2771 procedure TfdLuminance16us1.SetValues;
2773 inherited SetValues;
2774 fBitsPerPixel := 16;
2775 fFormat := tfLuminance16us1;
2776 fWithAlpha := tfLuminance16Alpha16us2;
2777 fWithoutAlpha := tfLuminance16us1;
2778 fPrecision := glBitmapRec4ub(16, 16, 16, 0);
2779 fShift := glBitmapRec4ub( 0, 0, 0, 0);
2781 fOpenGLFormat := tfLuminance16us1;
2782 fglFormat := GL_LUMINANCE;
2783 fglInternalFormat := GL_LUMINANCE16;
2784 fglDataFormat := GL_UNSIGNED_SHORT;
2786 fOpenGLFormat := tfLuminance8ub1;
2790 procedure TfdLuminance4Alpha4ub2.SetValues;
2792 inherited SetValues;
2793 fBitsPerPixel := 16;
2794 fFormat := tfLuminance4Alpha4ub2;
2795 fWithAlpha := tfLuminance4Alpha4ub2;
2796 fWithoutAlpha := tfLuminance4ub1;
2797 fPrecision := glBitmapRec4ub(8, 8, 8, 8);
2798 fShift := glBitmapRec4ub(0, 0, 0, 8);
2800 fOpenGLFormat := tfLuminance4Alpha4ub2;
2801 fglFormat := GL_LUMINANCE_ALPHA;
2802 fglInternalFormat := GL_LUMINANCE4_ALPHA4;
2803 fglDataFormat := GL_UNSIGNED_BYTE;
2805 fOpenGLFormat := tfLuminance8Alpha8ub2;
2809 procedure TfdLuminance6Alpha2ub2.SetValues;
2811 inherited SetValues;
2812 fBitsPerPixel := 16;
2813 fFormat := tfLuminance6Alpha2ub2;
2814 fWithAlpha := tfLuminance6Alpha2ub2;
2815 fWithoutAlpha := tfLuminance8ub1;
2816 fPrecision := glBitmapRec4ub(8, 8, 8, 8);
2817 fShift := glBitmapRec4ub(0, 0, 0, 8);
2819 fOpenGLFormat := tfLuminance6Alpha2ub2;
2820 fglFormat := GL_LUMINANCE_ALPHA;
2821 fglInternalFormat := GL_LUMINANCE6_ALPHA2;
2822 fglDataFormat := GL_UNSIGNED_BYTE;
2824 fOpenGLFormat := tfLuminance8Alpha8ub2;
2828 procedure TfdLuminance8Alpha8ub2.SetValues;
2830 inherited SetValues;
2831 fBitsPerPixel := 16;
2832 fFormat := tfLuminance8Alpha8ub2;
2833 fWithAlpha := tfLuminance8Alpha8ub2;
2834 fWithoutAlpha := tfLuminance8ub1;
2835 fOpenGLFormat := tfLuminance8Alpha8ub2;
2836 fPrecision := glBitmapRec4ub(8, 8, 8, 8);
2837 fShift := glBitmapRec4ub(0, 0, 0, 8);
2838 fglFormat := GL_LUMINANCE_ALPHA;
2839 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_LUMINANCE8_ALPHA8{$ELSE}GL_LUMINANCE_ALPHA{$ENDIF};
2840 fglDataFormat := GL_UNSIGNED_BYTE;
2843 procedure TfdLuminance12Alpha4us2.SetValues;
2845 inherited SetValues;
2846 fBitsPerPixel := 32;
2847 fFormat := tfLuminance12Alpha4us2;
2848 fWithAlpha := tfLuminance12Alpha4us2;
2849 fWithoutAlpha := tfLuminance16us1;
2850 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
2851 fShift := glBitmapRec4ub( 0, 0, 0, 16);
2853 fOpenGLFormat := tfLuminance12Alpha4us2;
2854 fglFormat := GL_LUMINANCE_ALPHA;
2855 fglInternalFormat := GL_LUMINANCE12_ALPHA4;
2856 fglDataFormat := GL_UNSIGNED_SHORT;
2858 fOpenGLFormat := tfLuminance8Alpha8ub2;
2862 procedure TfdLuminance16Alpha16us2.SetValues;
2864 inherited SetValues;
2865 fBitsPerPixel := 32;
2866 fFormat := tfLuminance16Alpha16us2;
2867 fWithAlpha := tfLuminance16Alpha16us2;
2868 fWithoutAlpha := tfLuminance16us1;
2869 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
2870 fShift := glBitmapRec4ub( 0, 0, 0, 16);
2872 fOpenGLFormat := tfLuminance16Alpha16us2;
2873 fglFormat := GL_LUMINANCE_ALPHA;
2874 fglInternalFormat := GL_LUMINANCE16_ALPHA16;
2875 fglDataFormat := GL_UNSIGNED_SHORT;
2877 fOpenGLFormat := tfLuminance8Alpha8ub2;
2881 procedure TfdR3G3B2ub1.SetValues;
2883 inherited SetValues;
2885 fFormat := tfR3G3B2ub1;
2886 fWithAlpha := tfRGBA4us1;
2887 fWithoutAlpha := tfR3G3B2ub1;
2888 fRGBInverted := tfEmpty;
2889 fPrecision := glBitmapRec4ub(3, 3, 2, 0);
2890 fShift := glBitmapRec4ub(5, 2, 0, 0);
2892 fOpenGLFormat := tfR3G3B2ub1;
2893 fglFormat := GL_RGB;
2894 fglInternalFormat := GL_R3_G3_B2;
2895 fglDataFormat := GL_UNSIGNED_BYTE_3_3_2;
2897 fOpenGLFormat := tfR5G6B5us1;
2901 procedure TfdRGBX4us1.SetValues;
2903 inherited SetValues;
2904 fBitsPerPixel := 16;
2905 fFormat := tfRGBX4us1;
2906 fWithAlpha := tfRGBA4us1;
2907 fWithoutAlpha := tfRGBX4us1;
2908 fRGBInverted := tfBGRX4us1;
2909 fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
2910 fShift := glBitmapRec4ub(12, 8, 4, 0);
2912 fOpenGLFormat := tfRGBX4us1;
2913 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
2914 fglInternalFormat := GL_RGB4;
2915 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
2917 fOpenGLFormat := tfR5G6B5us1;
2921 procedure TfdXRGB4us1.SetValues;
2923 inherited SetValues;
2924 fBitsPerPixel := 16;
2925 fFormat := tfXRGB4us1;
2926 fWithAlpha := tfARGB4us1;
2927 fWithoutAlpha := tfXRGB4us1;
2928 fRGBInverted := tfXBGR4us1;
2929 fPrecision := glBitmapRec4ub(4, 4, 4, 0);
2930 fShift := glBitmapRec4ub(8, 4, 0, 0);
2932 fOpenGLFormat := tfXRGB4us1;
2933 fglFormat := GL_BGRA;
2934 fglInternalFormat := GL_RGB4;
2935 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
2937 fOpenGLFormat := tfR5G6B5us1;
2941 procedure TfdR5G6B5us1.SetValues;
2943 inherited SetValues;
2944 fBitsPerPixel := 16;
2945 fFormat := tfR5G6B5us1;
2946 fWithAlpha := tfRGB5A1us1;
2947 fWithoutAlpha := tfR5G6B5us1;
2948 fRGBInverted := tfB5G6R5us1;
2949 fPrecision := glBitmapRec4ub( 5, 6, 5, 0);
2950 fShift := glBitmapRec4ub(11, 5, 0, 0);
2951 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
2952 fOpenGLFormat := tfR5G6B5us1;
2953 fglFormat := GL_RGB;
2954 fglInternalFormat := GL_RGB565;
2955 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5;
2957 fOpenGLFormat := tfRGB8ub3;
2961 procedure TfdRGB5X1us1.SetValues;
2963 inherited SetValues;
2964 fBitsPerPixel := 16;
2965 fFormat := tfRGB5X1us1;
2966 fWithAlpha := tfRGB5A1us1;
2967 fWithoutAlpha := tfRGB5X1us1;
2968 fRGBInverted := tfBGR5X1us1;
2969 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
2970 fShift := glBitmapRec4ub(11, 6, 1, 0);
2972 fOpenGLFormat := tfRGB5X1us1;
2973 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
2974 fglInternalFormat := GL_RGB5;
2975 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
2977 fOpenGLFormat := tfR5G6B5us1;
2981 procedure TfdX1RGB5us1.SetValues;
2983 inherited SetValues;
2984 fBitsPerPixel := 16;
2985 fFormat := tfX1RGB5us1;
2986 fWithAlpha := tfA1RGB5us1;
2987 fWithoutAlpha := tfX1RGB5us1;
2988 fRGBInverted := tfX1BGR5us1;
2989 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
2990 fShift := glBitmapRec4ub(10, 5, 0, 0);
2992 fOpenGLFormat := tfX1RGB5us1;
2993 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
2994 fglInternalFormat := GL_RGB5;
2995 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
2997 fOpenGLFormat := tfR5G6B5us1;
3001 procedure TfdRGB8ub3.SetValues;
3003 inherited SetValues;
3004 fBitsPerPixel := 24;
3005 fFormat := tfRGB8ub3;
3006 fWithAlpha := tfRGBA8ub4;
3007 fWithoutAlpha := tfRGB8ub3;
3008 fRGBInverted := tfBGR8ub3;
3009 fPrecision := glBitmapRec4ub(8, 8, 8, 0);
3010 fShift := glBitmapRec4ub(0, 8, 16, 0);
3011 fOpenGLFormat := tfRGB8ub3;
3012 fglFormat := GL_RGB;
3013 fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}GL_RGB8{$ELSE}GL_RGB{$IFEND};
3014 fglDataFormat := GL_UNSIGNED_BYTE;
3017 procedure TfdRGBX8ui1.SetValues;
3019 inherited SetValues;
3020 fBitsPerPixel := 32;
3021 fFormat := tfRGBX8ui1;
3022 fWithAlpha := tfRGBA8ui1;
3023 fWithoutAlpha := tfRGBX8ui1;
3024 fRGBInverted := tfBGRX8ui1;
3025 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3026 fShift := glBitmapRec4ub(24, 16, 8, 0);
3028 fOpenGLFormat := tfRGBX8ui1;
3029 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3030 fglInternalFormat := GL_RGB8;
3031 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3033 fOpenGLFormat := tfRGB8ub3;
3037 procedure TfdXRGB8ui1.SetValues;
3039 inherited SetValues;
3040 fBitsPerPixel := 32;
3041 fFormat := tfXRGB8ui1;
3042 fWithAlpha := tfXRGB8ui1;
3043 fWithoutAlpha := tfXRGB8ui1;
3044 fOpenGLFormat := tfXRGB8ui1;
3045 fRGBInverted := tfXBGR8ui1;
3046 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3047 fShift := glBitmapRec4ub(16, 8, 0, 0);
3049 fOpenGLFormat := tfXRGB8ui1;
3050 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3051 fglInternalFormat := GL_RGB8;
3052 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3054 fOpenGLFormat := tfRGB8ub3;
3058 procedure TfdRGB10X2ui1.SetValues;
3060 inherited SetValues;
3061 fBitsPerPixel := 32;
3062 fFormat := tfRGB10X2ui1;
3063 fWithAlpha := tfRGB10A2ui1;
3064 fWithoutAlpha := tfRGB10X2ui1;
3065 fRGBInverted := tfBGR10X2ui1;
3066 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3067 fShift := glBitmapRec4ub(22, 12, 2, 0);
3069 fOpenGLFormat := tfRGB10X2ui1;
3070 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3071 fglInternalFormat := GL_RGB10;
3072 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3074 fOpenGLFormat := tfRGB16us3;
3078 procedure TfdX2RGB10ui1.SetValues;
3080 inherited SetValues;
3081 fBitsPerPixel := 32;
3082 fFormat := tfX2RGB10ui1;
3083 fWithAlpha := tfA2RGB10ui1;
3084 fWithoutAlpha := tfX2RGB10ui1;
3085 fRGBInverted := tfX2BGR10ui1;
3086 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3087 fShift := glBitmapRec4ub(20, 10, 0, 0);
3089 fOpenGLFormat := tfX2RGB10ui1;
3090 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3091 fglInternalFormat := GL_RGB10;
3092 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3094 fOpenGLFormat := tfRGB16us3;
3098 procedure TfdRGB16us3.SetValues;
3100 inherited SetValues;
3101 fBitsPerPixel := 48;
3102 fFormat := tfRGB16us3;
3103 fWithAlpha := tfRGBA16us4;
3104 fWithoutAlpha := tfRGB16us3;
3105 fRGBInverted := tfBGR16us3;
3106 fPrecision := glBitmapRec4ub(16, 16, 16, 0);
3107 fShift := glBitmapRec4ub( 0, 16, 32, 0);
3108 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
3109 fOpenGLFormat := tfRGB16us3;
3110 fglFormat := GL_RGB;
3111 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_RGB16{$ELSE}GL_RGB16UI{$ENDIF};
3112 fglDataFormat := GL_UNSIGNED_SHORT;
3114 fOpenGLFormat := tfRGB8ub3;
3118 procedure TfdRGBA4us1.SetValues;
3120 inherited SetValues;
3121 fBitsPerPixel := 16;
3122 fFormat := tfRGBA4us1;
3123 fWithAlpha := tfRGBA4us1;
3124 fWithoutAlpha := tfRGBX4us1;
3125 fOpenGLFormat := tfRGBA4us1;
3126 fRGBInverted := tfBGRA4us1;
3127 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3128 fShift := glBitmapRec4ub(12, 8, 4, 0);
3129 fglFormat := GL_RGBA;
3130 fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}GL_RGBA8{$ELSE}GL_RGBA{$IFEND};
3131 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3134 procedure TfdARGB4us1.SetValues;
3136 inherited SetValues;
3137 fBitsPerPixel := 16;
3138 fFormat := tfARGB4us1;
3139 fWithAlpha := tfARGB4us1;
3140 fWithoutAlpha := tfXRGB4us1;
3141 fRGBInverted := tfABGR4us1;
3142 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3143 fShift := glBitmapRec4ub( 8, 4, 0, 12);
3145 fOpenGLFormat := tfARGB4us1;
3146 fglFormat := GL_BGRA;
3147 fglInternalFormat := GL_RGBA4;
3148 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3150 fOpenGLFormat := tfRGBA4us1;
3154 procedure TfdRGB5A1us1.SetValues;
3156 inherited SetValues;
3157 fBitsPerPixel := 16;
3158 fFormat := tfRGB5A1us1;
3159 fWithAlpha := tfRGB5A1us1;
3160 fWithoutAlpha := tfRGB5X1us1;
3161 fOpenGLFormat := tfRGB5A1us1;
3162 fRGBInverted := tfBGR5A1us1;
3163 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3164 fShift := glBitmapRec4ub(11, 6, 1, 0);
3165 fglFormat := GL_RGBA;
3166 fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}GL_RGB5_A1{$ELSE}GL_RGBA{$IFEND};
3167 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3170 procedure TfdA1RGB5us1.SetValues;
3172 inherited SetValues;
3173 fBitsPerPixel := 16;
3174 fFormat := tfA1RGB5us1;
3175 fWithAlpha := tfA1RGB5us1;
3176 fWithoutAlpha := tfX1RGB5us1;
3177 fRGBInverted := tfA1BGR5us1;
3178 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3179 fShift := glBitmapRec4ub(10, 5, 0, 15);
3181 fOpenGLFormat := tfA1RGB5us1;
3182 fglFormat := GL_BGRA;
3183 fglInternalFormat := GL_RGB5_A1;
3184 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3186 fOpenGLFormat := tfRGB5A1us1;
3190 procedure TfdRGBA8ui1.SetValues;
3192 inherited SetValues;
3193 fBitsPerPixel := 32;
3194 fFormat := tfRGBA8ui1;
3195 fWithAlpha := tfRGBA8ui1;
3196 fWithoutAlpha := tfRGBX8ui1;
3197 fRGBInverted := tfBGRA8ui1;
3198 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3199 fShift := glBitmapRec4ub(24, 16, 8, 0);
3201 fOpenGLFormat := tfRGBA8ui1;
3202 fglFormat := GL_RGBA;
3203 fglInternalFormat := GL_RGBA8;
3204 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3206 fOpenGLFormat := tfRGBA8ub4;
3210 procedure TfdARGB8ui1.SetValues;
3212 inherited SetValues;
3213 fBitsPerPixel := 32;
3214 fFormat := tfARGB8ui1;
3215 fWithAlpha := tfARGB8ui1;
3216 fWithoutAlpha := tfXRGB8ui1;
3217 fRGBInverted := tfABGR8ui1;
3218 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3219 fShift := glBitmapRec4ub(16, 8, 0, 24);
3221 fOpenGLFormat := tfARGB8ui1;
3222 fglFormat := GL_BGRA;
3223 fglInternalFormat := GL_RGBA8;
3224 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3226 fOpenGLFormat := tfRGBA8ub4;
3230 procedure TfdRGBA8ub4.SetValues;
3232 inherited SetValues;
3233 fBitsPerPixel := 32;
3234 fFormat := tfRGBA8ub4;
3235 fWithAlpha := tfRGBA8ub4;
3236 fWithoutAlpha := tfRGB8ub3;
3237 fOpenGLFormat := tfRGBA8ub4;
3238 fRGBInverted := tfBGRA8ub4;
3239 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3240 fShift := glBitmapRec4ub( 0, 8, 16, 24);
3241 fglFormat := GL_RGBA;
3242 fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}GL_RGBA8{$ELSE}GL_RGBA{$IFEND};
3243 fglDataFormat := GL_UNSIGNED_BYTE;
3246 procedure TfdRGB10A2ui1.SetValues;
3248 inherited SetValues;
3249 fBitsPerPixel := 32;
3250 fFormat := tfRGB10A2ui1;
3251 fWithAlpha := tfRGB10A2ui1;
3252 fWithoutAlpha := tfRGB10X2ui1;
3253 fRGBInverted := tfBGR10A2ui1;
3254 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3255 fShift := glBitmapRec4ub(22, 12, 2, 0);
3257 fOpenGLFormat := tfRGB10A2ui1;
3258 fglFormat := GL_RGBA;
3259 fglInternalFormat := GL_RGB10_A2;
3260 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3262 fOpenGLFormat := tfA2RGB10ui1;
3266 procedure TfdA2RGB10ui1.SetValues;
3268 inherited SetValues;
3269 fBitsPerPixel := 32;
3270 fFormat := tfA2RGB10ui1;
3271 fWithAlpha := tfA2RGB10ui1;
3272 fWithoutAlpha := tfX2RGB10ui1;
3273 fRGBInverted := tfA2BGR10ui1;
3274 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3275 fShift := glBitmapRec4ub(20, 10, 0, 30);
3276 {$IF NOT DEFINED(OPENGL_ES)}
3277 fOpenGLFormat := tfA2RGB10ui1;
3278 fglFormat := GL_BGRA;
3279 fglInternalFormat := GL_RGB10_A2;
3280 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3281 {$ELSEIF DEFINED(OPENGL_ES_3_0)}
3282 fOpenGLFormat := tfA2RGB10ui1;
3283 fglFormat := GL_RGBA;
3284 fglInternalFormat := GL_RGB10_A2;
3285 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3287 fOpenGLFormat := tfRGBA8ui1;
3291 procedure TfdRGBA16us4.SetValues;
3293 inherited SetValues;
3294 fBitsPerPixel := 64;
3295 fFormat := tfRGBA16us4;
3296 fWithAlpha := tfRGBA16us4;
3297 fWithoutAlpha := tfRGB16us3;
3298 fRGBInverted := tfBGRA16us4;
3299 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3300 fShift := glBitmapRec4ub( 0, 16, 32, 48);
3301 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
3302 fOpenGLFormat := tfRGBA16us4;
3303 fglFormat := GL_RGBA;
3304 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_RGBA16{$ELSE}GL_RGBA16UI{$ENDIF};
3305 fglDataFormat := GL_UNSIGNED_SHORT;
3307 fOpenGLFormat := tfRGBA8ub4;
3311 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3312 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3313 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3314 procedure TfdBGRX4us1.SetValues;
3316 inherited SetValues;
3317 fBitsPerPixel := 16;
3318 fFormat := tfBGRX4us1;
3319 fWithAlpha := tfBGRA4us1;
3320 fWithoutAlpha := tfBGRX4us1;
3321 fRGBInverted := tfRGBX4us1;
3322 fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
3323 fShift := glBitmapRec4ub( 4, 8, 12, 0);
3325 fOpenGLFormat := tfBGRX4us1;
3326 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3327 fglInternalFormat := GL_RGB4;
3328 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3330 fOpenGLFormat := tfR5G6B5us1;
3334 procedure TfdXBGR4us1.SetValues;
3336 inherited SetValues;
3337 fBitsPerPixel := 16;
3338 fFormat := tfXBGR4us1;
3339 fWithAlpha := tfABGR4us1;
3340 fWithoutAlpha := tfXBGR4us1;
3341 fRGBInverted := tfXRGB4us1;
3342 fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
3343 fShift := glBitmapRec4ub( 0, 4, 8, 0);
3345 fOpenGLFormat := tfXBGR4us1;
3346 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3347 fglInternalFormat := GL_RGB4;
3348 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3350 fOpenGLFormat := tfR5G6B5us1;
3354 procedure TfdB5G6R5us1.SetValues;
3356 inherited SetValues;
3357 fBitsPerPixel := 16;
3358 fFormat := tfB5G6R5us1;
3359 fWithAlpha := tfBGR5A1us1;
3360 fWithoutAlpha := tfB5G6R5us1;
3361 fRGBInverted := tfR5G6B5us1;
3362 fPrecision := glBitmapRec4ub( 5, 6, 5, 0);
3363 fShift := glBitmapRec4ub( 0, 5, 11, 0);
3365 fOpenGLFormat := tfB5G6R5us1;
3366 fglFormat := GL_RGB;
3367 fglInternalFormat := GL_RGB565;
3368 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5_REV;
3370 fOpenGLFormat := tfR5G6B5us1;
3374 procedure TfdBGR5X1us1.SetValues;
3376 inherited SetValues;
3377 fBitsPerPixel := 16;
3378 fFormat := tfBGR5X1us1;
3379 fWithAlpha := tfBGR5A1us1;
3380 fWithoutAlpha := tfBGR5X1us1;
3381 fRGBInverted := tfRGB5X1us1;
3382 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
3383 fShift := glBitmapRec4ub( 1, 6, 11, 0);
3385 fOpenGLFormat := tfBGR5X1us1;
3386 fglFormat := GL_BGRA;
3387 fglInternalFormat := GL_RGB5;
3388 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3390 fOpenGLFormat := tfR5G6B5us1;
3394 procedure TfdX1BGR5us1.SetValues;
3396 inherited SetValues;
3397 fBitsPerPixel := 16;
3398 fFormat := tfX1BGR5us1;
3399 fWithAlpha := tfA1BGR5us1;
3400 fWithoutAlpha := tfX1BGR5us1;
3401 fRGBInverted := tfX1RGB5us1;
3402 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
3403 fShift := glBitmapRec4ub( 0, 5, 10, 0);
3405 fOpenGLFormat := tfX1BGR5us1;
3406 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3407 fglInternalFormat := GL_RGB5;
3408 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3410 fOpenGLFormat := tfR5G6B5us1;
3414 procedure TfdBGR8ub3.SetValues;
3416 inherited SetValues;
3417 fBitsPerPixel := 24;
3418 fFormat := tfBGR8ub3;
3419 fWithAlpha := tfBGRA8ub4;
3420 fWithoutAlpha := tfBGR8ub3;
3421 fRGBInverted := tfRGB8ub3;
3422 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3423 fShift := glBitmapRec4ub(16, 8, 0, 0);
3425 fOpenGLFormat := tfBGR8ub3;
3426 fglFormat := GL_BGR;
3427 fglInternalFormat := GL_RGB8;
3428 fglDataFormat := GL_UNSIGNED_BYTE;
3430 fOpenGLFormat := tfRGB8ub3;
3434 procedure TfdBGRX8ui1.SetValues;
3436 inherited SetValues;
3437 fBitsPerPixel := 32;
3438 fFormat := tfBGRX8ui1;
3439 fWithAlpha := tfBGRA8ui1;
3440 fWithoutAlpha := tfBGRX8ui1;
3441 fRGBInverted := tfRGBX8ui1;
3442 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3443 fShift := glBitmapRec4ub( 8, 16, 24, 0);
3445 fOpenGLFormat := tfBGRX8ui1;
3446 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3447 fglInternalFormat := GL_RGB8;
3448 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3450 fOpenGLFormat := tfRGB8ub3;
3454 procedure TfdXBGR8ui1.SetValues;
3456 inherited SetValues;
3457 fBitsPerPixel := 32;
3458 fFormat := tfXBGR8ui1;
3459 fWithAlpha := tfABGR8ui1;
3460 fWithoutAlpha := tfXBGR8ui1;
3461 fRGBInverted := tfXRGB8ui1;
3462 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3463 fShift := glBitmapRec4ub( 0, 8, 16, 0);
3465 fOpenGLFormat := tfXBGR8ui1;
3466 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3467 fglInternalFormat := GL_RGB8;
3468 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3470 fOpenGLFormat := tfRGB8ub3;
3474 procedure TfdBGR10X2ui1.SetValues;
3476 inherited SetValues;
3477 fBitsPerPixel := 32;
3478 fFormat := tfBGR10X2ui1;
3479 fWithAlpha := tfBGR10A2ui1;
3480 fWithoutAlpha := tfBGR10X2ui1;
3481 fRGBInverted := tfRGB10X2ui1;
3482 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3483 fShift := glBitmapRec4ub( 2, 12, 22, 0);
3485 fOpenGLFormat := tfBGR10X2ui1;
3486 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3487 fglInternalFormat := GL_RGB10;
3488 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3490 fOpenGLFormat := tfRGB16us3;
3494 procedure TfdX2BGR10ui1.SetValues;
3496 inherited SetValues;
3497 fBitsPerPixel := 32;
3498 fFormat := tfX2BGR10ui1;
3499 fWithAlpha := tfA2BGR10ui1;
3500 fWithoutAlpha := tfX2BGR10ui1;
3501 fRGBInverted := tfX2RGB10ui1;
3502 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3503 fShift := glBitmapRec4ub( 0, 10, 20, 0);
3505 fOpenGLFormat := tfX2BGR10ui1;
3506 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3507 fglInternalFormat := GL_RGB10;
3508 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3510 fOpenGLFormat := tfRGB16us3;
3514 procedure TfdBGR16us3.SetValues;
3516 inherited SetValues;
3517 fBitsPerPixel := 48;
3518 fFormat := tfBGR16us3;
3519 fWithAlpha := tfBGRA16us4;
3520 fWithoutAlpha := tfBGR16us3;
3521 fRGBInverted := tfRGB16us3;
3522 fPrecision := glBitmapRec4ub(16, 16, 16, 0);
3523 fShift := glBitmapRec4ub(32, 16, 0, 0);
3525 fOpenGLFormat := tfBGR16us3;
3526 fglFormat := GL_BGR;
3527 fglInternalFormat := GL_RGB16;
3528 fglDataFormat := GL_UNSIGNED_SHORT;
3530 fOpenGLFormat := tfRGB16us3;
3534 procedure TfdBGRA4us1.SetValues;
3536 inherited SetValues;
3537 fBitsPerPixel := 16;
3538 fFormat := tfBGRA4us1;
3539 fWithAlpha := tfBGRA4us1;
3540 fWithoutAlpha := tfBGRX4us1;
3541 fRGBInverted := tfRGBA4us1;
3542 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3543 fShift := glBitmapRec4ub( 4, 8, 12, 0);
3545 fOpenGLFormat := tfBGRA4us1;
3546 fglFormat := GL_BGRA;
3547 fglInternalFormat := GL_RGBA4;
3548 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3550 fOpenGLFormat := tfRGBA4us1;
3554 procedure TfdABGR4us1.SetValues;
3556 inherited SetValues;
3557 fBitsPerPixel := 16;
3558 fFormat := tfABGR4us1;
3559 fWithAlpha := tfABGR4us1;
3560 fWithoutAlpha := tfXBGR4us1;
3561 fRGBInverted := tfARGB4us1;
3562 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3563 fShift := glBitmapRec4ub( 0, 4, 8, 12);
3565 fOpenGLFormat := tfABGR4us1;
3566 fglFormat := GL_RGBA;
3567 fglInternalFormat := GL_RGBA4;
3568 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3570 fOpenGLFormat := tfRGBA4us1;
3574 procedure TfdBGR5A1us1.SetValues;
3576 inherited SetValues;
3577 fBitsPerPixel := 16;
3578 fFormat := tfBGR5A1us1;
3579 fWithAlpha := tfBGR5A1us1;
3580 fWithoutAlpha := tfBGR5X1us1;
3581 fRGBInverted := tfRGB5A1us1;
3582 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3583 fShift := glBitmapRec4ub( 1, 6, 11, 0);
3585 fOpenGLFormat := tfBGR5A1us1;
3586 fglFormat := GL_BGRA;
3587 fglInternalFormat := GL_RGB5_A1;
3588 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3590 fOpenGLFormat := tfRGB5A1us1;
3594 procedure TfdA1BGR5us1.SetValues;
3596 inherited SetValues;
3597 fBitsPerPixel := 16;
3598 fFormat := tfA1BGR5us1;
3599 fWithAlpha := tfA1BGR5us1;
3600 fWithoutAlpha := tfX1BGR5us1;
3601 fRGBInverted := tfA1RGB5us1;
3602 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3603 fShift := glBitmapRec4ub( 0, 5, 10, 15);
3605 fOpenGLFormat := tfA1BGR5us1;
3606 fglFormat := GL_RGBA;
3607 fglInternalFormat := GL_RGB5_A1;
3608 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3610 fOpenGLFormat := tfRGB5A1us1;
3614 procedure TfdBGRA8ui1.SetValues;
3616 inherited SetValues;
3617 fBitsPerPixel := 32;
3618 fFormat := tfBGRA8ui1;
3619 fWithAlpha := tfBGRA8ui1;
3620 fWithoutAlpha := tfBGRX8ui1;
3621 fRGBInverted := tfRGBA8ui1;
3622 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3623 fShift := glBitmapRec4ub( 8, 16, 24, 0);
3625 fOpenGLFormat := tfBGRA8ui1;
3626 fglFormat := GL_BGRA;
3627 fglInternalFormat := GL_RGBA8;
3628 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3630 fOpenGLFormat := tfRGBA8ub4;
3634 procedure TfdABGR8ui1.SetValues;
3636 inherited SetValues;
3637 fBitsPerPixel := 32;
3638 fFormat := tfABGR8ui1;
3639 fWithAlpha := tfABGR8ui1;
3640 fWithoutAlpha := tfXBGR8ui1;
3641 fRGBInverted := tfARGB8ui1;
3642 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3643 fShift := glBitmapRec4ub( 0, 8, 16, 24);
3645 fOpenGLFormat := tfABGR8ui1;
3646 fglFormat := GL_RGBA;
3647 fglInternalFormat := GL_RGBA8;
3648 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3650 fOpenGLFormat := tfRGBA8ub4
3654 procedure TfdBGRA8ub4.SetValues;
3656 inherited SetValues;
3657 fBitsPerPixel := 32;
3658 fFormat := tfBGRA8ub4;
3659 fWithAlpha := tfBGRA8ub4;
3660 fWithoutAlpha := tfBGR8ub3;
3661 fRGBInverted := tfRGBA8ub4;
3662 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3663 fShift := glBitmapRec4ub(16, 8, 0, 24);
3665 fOpenGLFormat := tfBGRA8ub4;
3666 fglFormat := GL_BGRA;
3667 fglInternalFormat := GL_RGBA8;
3668 fglDataFormat := GL_UNSIGNED_BYTE;
3670 fOpenGLFormat := tfRGBA8ub4;
3674 procedure TfdBGR10A2ui1.SetValues;
3676 inherited SetValues;
3677 fBitsPerPixel := 32;
3678 fFormat := tfBGR10A2ui1;
3679 fWithAlpha := tfBGR10A2ui1;
3680 fWithoutAlpha := tfBGR10X2ui1;
3681 fRGBInverted := tfRGB10A2ui1;
3682 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3683 fShift := glBitmapRec4ub( 2, 12, 22, 0);
3685 fOpenGLFormat := tfBGR10A2ui1;
3686 fglFormat := GL_BGRA;
3687 fglInternalFormat := GL_RGB10_A2;
3688 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3690 fOpenGLFormat := tfA2RGB10ui1;
3694 procedure TfdA2BGR10ui1.SetValues;
3696 inherited SetValues;
3697 fBitsPerPixel := 32;
3698 fFormat := tfA2BGR10ui1;
3699 fWithAlpha := tfA2BGR10ui1;
3700 fWithoutAlpha := tfX2BGR10ui1;
3701 fRGBInverted := tfA2RGB10ui1;
3702 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3703 fShift := glBitmapRec4ub( 0, 10, 20, 30);
3705 fOpenGLFormat := tfA2BGR10ui1;
3706 fglFormat := GL_RGBA;
3707 fglInternalFormat := GL_RGB10_A2;
3708 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3710 fOpenGLFormat := tfA2RGB10ui1;
3714 procedure TfdBGRA16us4.SetValues;
3716 inherited SetValues;
3717 fBitsPerPixel := 64;
3718 fFormat := tfBGRA16us4;
3719 fWithAlpha := tfBGRA16us4;
3720 fWithoutAlpha := tfBGR16us3;
3721 fRGBInverted := tfRGBA16us4;
3722 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3723 fShift := glBitmapRec4ub(32, 16, 0, 48);
3725 fOpenGLFormat := tfBGRA16us4;
3726 fglFormat := GL_BGRA;
3727 fglInternalFormat := GL_RGBA16;
3728 fglDataFormat := GL_UNSIGNED_SHORT;
3730 fOpenGLFormat := tfRGBA16us4;
3734 procedure TfdDepth16us1.SetValues;
3736 inherited SetValues;
3737 fBitsPerPixel := 16;
3738 fFormat := tfDepth16us1;
3739 fWithoutAlpha := tfDepth16us1;
3740 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3741 fShift := glBitmapRec4ub( 0, 0, 0, 0);
3742 {$IF NOT DEFINED (OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
3743 fOpenGLFormat := tfDepth16us1;
3744 fglFormat := GL_DEPTH_COMPONENT;
3745 fglInternalFormat := GL_DEPTH_COMPONENT16;
3746 fglDataFormat := GL_UNSIGNED_SHORT;
3750 procedure TfdDepth24ui1.SetValues;
3752 inherited SetValues;
3753 fBitsPerPixel := 32;
3754 fFormat := tfDepth24ui1;
3755 fWithoutAlpha := tfDepth24ui1;
3756 fOpenGLFormat := tfDepth24ui1;
3757 fPrecision := glBitmapRec4ub(32, 32, 32, 32);
3758 fShift := glBitmapRec4ub( 0, 0, 0, 0);
3759 {$IF NOT DEFINED (OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
3760 fOpenGLFormat := tfDepth24ui1;
3761 fglFormat := GL_DEPTH_COMPONENT;
3762 fglInternalFormat := GL_DEPTH_COMPONENT24;
3763 fglDataFormat := GL_UNSIGNED_INT;
3767 procedure TfdDepth32ui1.SetValues;
3769 inherited SetValues;
3770 fBitsPerPixel := 32;
3771 fFormat := tfDepth32ui1;
3772 fWithoutAlpha := tfDepth32ui1;
3773 fPrecision := glBitmapRec4ub(32, 32, 32, 32);
3774 fShift := glBitmapRec4ub( 0, 0, 0, 0);
3775 {$IF NOT DEFINED(OPENGL_ES)}
3776 fOpenGLFormat := tfDepth32ui1;
3777 fglFormat := GL_DEPTH_COMPONENT;
3778 fglInternalFormat := GL_DEPTH_COMPONENT32;
3779 fglDataFormat := GL_UNSIGNED_INT;
3780 {$ELSEIF DEFINED(OPENGL_ES_3_0)}
3781 fOpenGLFormat := tfDepth24ui1;
3782 {$ELSEIF DEFINED(OPENGL_ES_2_0)}
3783 fOpenGLFormat := tfDepth16us1;
3787 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3788 //TfdS3tcDtx1RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3789 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3790 procedure TfdS3tcDtx1RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3792 raise EglBitmap.Create('mapping for compressed formats is not supported');
3795 procedure TfdS3tcDtx1RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3797 raise EglBitmap.Create('mapping for compressed formats is not supported');
3800 procedure TfdS3tcDtx1RGBA.SetValues;
3802 inherited SetValues;
3803 fFormat := tfS3tcDtx1RGBA;
3804 fWithAlpha := tfS3tcDtx1RGBA;
3805 fUncompressed := tfRGB5A1us1;
3807 fIsCompressed := true;
3809 fOpenGLFormat := tfS3tcDtx1RGBA;
3810 fglFormat := GL_COMPRESSED_RGBA;
3811 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
3812 fglDataFormat := GL_UNSIGNED_BYTE;
3814 fOpenGLFormat := fUncompressed;
3818 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3819 //TfdS3tcDtx3RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3820 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3821 procedure TfdS3tcDtx3RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3823 raise EglBitmap.Create('mapping for compressed formats is not supported');
3826 procedure TfdS3tcDtx3RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3828 raise EglBitmap.Create('mapping for compressed formats is not supported');
3831 procedure TfdS3tcDtx3RGBA.SetValues;
3833 inherited SetValues;
3834 fFormat := tfS3tcDtx3RGBA;
3835 fWithAlpha := tfS3tcDtx3RGBA;
3836 fUncompressed := tfRGBA8ub4;
3838 fIsCompressed := true;
3840 fOpenGLFormat := tfS3tcDtx3RGBA;
3841 fglFormat := GL_COMPRESSED_RGBA;
3842 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
3843 fglDataFormat := GL_UNSIGNED_BYTE;
3845 fOpenGLFormat := fUncompressed;
3849 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3850 //TfdS3tcDtx5RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3851 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3852 procedure TfdS3tcDtx5RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3854 raise EglBitmap.Create('mapping for compressed formats is not supported');
3857 procedure TfdS3tcDtx5RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3859 raise EglBitmap.Create('mapping for compressed formats is not supported');
3862 procedure TfdS3tcDtx5RGBA.SetValues;
3864 inherited SetValues;
3865 fFormat := tfS3tcDtx3RGBA;
3866 fWithAlpha := tfS3tcDtx3RGBA;
3867 fUncompressed := tfRGBA8ub4;
3869 fIsCompressed := true;
3871 fOpenGLFormat := tfS3tcDtx3RGBA;
3872 fglFormat := GL_COMPRESSED_RGBA;
3873 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
3874 fglDataFormat := GL_UNSIGNED_BYTE;
3876 fOpenGLFormat := fUncompressed;
3880 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3881 //TglBitmapFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3882 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3883 function TglBitmapFormatDescriptor.GetHasRed: Boolean;
3885 result := (fPrecision.r > 0);
3888 function TglBitmapFormatDescriptor.GetHasGreen: Boolean;
3890 result := (fPrecision.g > 0);
3893 function TglBitmapFormatDescriptor.GetHasBlue: Boolean;
3895 result := (fPrecision.b > 0);
3898 function TglBitmapFormatDescriptor.GetHasAlpha: Boolean;
3900 result := (fPrecision.a > 0);
3903 function TglBitmapFormatDescriptor.GetHasColor: Boolean;
3905 result := HasRed or HasGreen or HasBlue;
3908 function TglBitmapFormatDescriptor.GetIsGrayscale: Boolean;
3910 result := (Mask.r = Mask.g) and (Mask.g = Mask.b) and (Mask.r > 0);
3913 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3914 procedure TglBitmapFormatDescriptor.SetValues;
3917 fWithAlpha := tfEmpty;
3918 fWithoutAlpha := tfEmpty;
3919 fOpenGLFormat := tfEmpty;
3920 fRGBInverted := tfEmpty;
3921 fUncompressed := tfEmpty;
3924 fIsCompressed := false;
3927 fglInternalFormat := 0;
3930 FillChar(fPrecision, 0, SizeOf(fPrecision));
3931 FillChar(fShift, 0, SizeOf(fShift));
3934 procedure TglBitmapFormatDescriptor.CalcValues;
3938 fBytesPerPixel := fBitsPerPixel / 8;
3940 for i := 0 to 3 do begin
3941 if (fPrecision.arr[i] > 0) then
3943 fRange.arr[i] := (1 shl fPrecision.arr[i]) - 1;
3944 fMask.arr[i] := fRange.arr[i] shl fShift.arr[i];
3948 constructor TglBitmapFormatDescriptor.Create;
3955 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3956 class function TglBitmapFormatDescriptor.GetByFormat(const aInternalFormat: GLenum): TglBitmapFormatDescriptor;
3960 for f := Low(TglBitmapFormat) to High(TglBitmapFormat) do begin
3961 result := TFormatDescriptor.Get(f);
3962 if (result.glInternalFormat = aInternalFormat) then
3965 result := TFormatDescriptor.Get(tfEmpty);
3968 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3969 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3970 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3971 class procedure TFormatDescriptor.Init;
3973 if not Assigned(FormatDescriptorCS) then
3974 FormatDescriptorCS := TCriticalSection.Create;
3977 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3978 class function TFormatDescriptor.Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
3980 FormatDescriptorCS.Enter;
3982 result := FormatDescriptors[aFormat];
3983 if not Assigned(result) then begin
3984 result := FORMAT_DESCRIPTOR_CLASSES[aFormat].Create;
3985 FormatDescriptors[aFormat] := result;
3988 FormatDescriptorCS.Leave;
3992 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3993 class function TFormatDescriptor.GetAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
3995 result := Get(Get(aFormat).WithAlpha);
3998 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3999 class function TFormatDescriptor.GetFromMask(const aMask: TglBitmapRec4ul; const aBitCount: Integer): TFormatDescriptor;
4001 ft: TglBitmapFormat;
4003 // find matching format with OpenGL support
4004 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
4006 if (result.MaskMatch(aMask)) and
4007 (result.glFormat <> 0) and
4008 (result.glInternalFormat <> 0) and
4009 ((aBitCount = 0) or (aBitCount = result.BitsPerPixel))
4014 // find matching format without OpenGL Support
4015 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
4017 if result.MaskMatch(aMask) and ((aBitCount = 0) or (aBitCount = result.BitsPerPixel)) then
4021 result := TFormatDescriptor.Get(tfEmpty);
4024 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4025 class function TFormatDescriptor.GetFromPrecShift(const aPrec, aShift: TglBitmapRec4ub; const aBitCount: Integer): TFormatDescriptor;
4027 ft: TglBitmapFormat;
4029 // find matching format with OpenGL support
4030 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
4032 if glBitmapRec4ubCompare(result.Shift, aShift) and
4033 glBitmapRec4ubCompare(result.Precision, aPrec) and
4034 (result.glFormat <> 0) and
4035 (result.glInternalFormat <> 0) and
4036 ((aBitCount = 0) or (aBitCount = result.BitsPerPixel))
4041 // find matching format without OpenGL Support
4042 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
4044 if glBitmapRec4ubCompare(result.Shift, aShift) and
4045 glBitmapRec4ubCompare(result.Precision, aPrec) and
4046 ((aBitCount = 0) or (aBitCount = result.BitsPerPixel)) then
4050 result := TFormatDescriptor.Get(tfEmpty);
4053 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4054 class procedure TFormatDescriptor.Clear;
4058 FormatDescriptorCS.Enter;
4060 for f := low(FormatDescriptors) to high(FormatDescriptors) do
4061 FreeAndNil(FormatDescriptors[f]);
4063 FormatDescriptorCS.Leave;
4067 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4068 class procedure TFormatDescriptor.Finalize;
4071 FreeAndNil(FormatDescriptorCS);
4074 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4075 //TBitfieldFormat/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4076 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4077 procedure TbmpBitfieldFormat.SetCustomValues(const aBPP: Integer; aMask: TglBitmapRec4ul);
4081 for i := 0 to 3 do begin
4083 while (aMask.arr[i] > 0) and (aMask.arr[i] and 1 > 0) do begin
4084 aMask.arr[i] := aMask.arr[i] shr 1;
4087 fPrecision.arr[i] := CountSetBits(aMask.arr[i]);
4092 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4093 procedure TbmpBitfieldFormat.SetCustomValues(const aBBP: Integer; const aPrec, aShift: TglBitmapRec4ub);
4095 fBitsPerPixel := aBBP;
4096 fPrecision := aPrec;
4101 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4102 procedure TbmpBitfieldFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4107 ((aPixel.Data.r and Range.r) shl Shift.r) or
4108 ((aPixel.Data.g and Range.g) shl Shift.g) or
4109 ((aPixel.Data.b and Range.b) shl Shift.b) or
4110 ((aPixel.Data.a and Range.a) shl Shift.a);
4111 case BitsPerPixel of
4113 16: PWord(aData)^ := data;
4114 32: PCardinal(aData)^ := data;
4115 64: PQWord(aData)^ := data;
4117 raise EglBitmap.CreateFmt('invalid pixel size: %d', [BitsPerPixel]);
4119 inc(aData, Round(BytesPerPixel));
4122 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4123 procedure TbmpBitfieldFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4128 case BitsPerPixel of
4130 16: data := PWord(aData)^;
4131 32: data := PCardinal(aData)^;
4132 64: data := PQWord(aData)^;
4134 raise EglBitmap.CreateFmt('invalid pixel size: %d', [BitsPerPixel]);
4137 aPixel.Data.arr[i] := (data shr fShift.arr[i]) and Range.arr[i];
4138 inc(aData, Round(BytesPerPixel));
4141 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4142 //TColorTableFormat///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4143 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4144 procedure TbmpColorTableFormat.SetValues;
4146 inherited SetValues;
4147 fShift := glBitmapRec4ub(8, 8, 8, 0);
4150 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4151 procedure TbmpColorTableFormat.SetCustomValues(const aFormat: TglBitmapFormat; const aBPP: Integer; const aPrec, aShift: TglBitmapRec4ub);
4154 fBitsPerPixel := aBPP;
4155 fPrecision := aPrec;
4160 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4161 procedure TbmpColorTableFormat.CalcValues;
4163 inherited CalcValues;
4166 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4167 procedure TbmpColorTableFormat.CreateColorTable;
4171 SetLength(fColorTable, 256);
4172 if not HasColor then begin
4174 for i := 0 to High(fColorTable) do begin
4175 fColorTable[i].r := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
4176 fColorTable[i].g := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
4177 fColorTable[i].b := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
4178 fColorTable[i].a := 0;
4182 for i := 0 to High(fColorTable) do begin
4183 fColorTable[i].r := Round(((i shr Shift.r) and Range.r) / Range.r * 255);
4184 fColorTable[i].g := Round(((i shr Shift.g) and Range.g) / Range.g * 255);
4185 fColorTable[i].b := Round(((i shr Shift.b) and Range.b) / Range.b * 255);
4186 fColorTable[i].a := 0;
4191 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4192 procedure TbmpColorTableFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4194 if (BitsPerPixel <> 8) then
4195 raise EglBitmapUnsupportedFormat.Create('color table are only supported for 8bit formats');
4196 if not HasColor then
4198 aData^ := aPixel.Data.a
4202 ((aPixel.Data.r and Range.r) shl Shift.r) or
4203 ((aPixel.Data.g and Range.g) shl Shift.g) or
4204 ((aPixel.Data.b and Range.b) shl Shift.b));
4208 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4209 procedure TbmpColorTableFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4211 if (BitsPerPixel <> 8) then
4212 raise EglBitmapUnsupportedFormat.Create('color table are only supported for 8bit formats');
4213 with fColorTable[aData^] do begin
4222 destructor TbmpColorTableFormat.Destroy;
4224 SetLength(fColorTable, 0);
4228 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4229 //TglBitmap - Helper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4230 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4231 procedure glBitmapConvertPixel(var aPixel: TglBitmapPixelData; const aSourceFD, aDestFD: TFormatDescriptor);
4235 for i := 0 to 3 do begin
4236 if (aSourceFD.Range.arr[i] <> aDestFD.Range.arr[i]) then begin
4237 if (aSourceFD.Range.arr[i] > 0) then
4238 aPixel.Data.arr[i] := Round(aPixel.Data.arr[i] / aSourceFD.Range.arr[i] * aDestFD.Range.arr[i])
4240 aPixel.Data.arr[i] := 0;
4245 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4246 procedure glBitmapConvertCopyFunc(var aFuncRec: TglBitmapFunctionRec);
4248 with aFuncRec do begin
4249 if (Source.Range.r > 0) then
4250 Dest.Data.r := Source.Data.r;
4251 if (Source.Range.g > 0) then
4252 Dest.Data.g := Source.Data.g;
4253 if (Source.Range.b > 0) then
4254 Dest.Data.b := Source.Data.b;
4255 if (Source.Range.a > 0) then
4256 Dest.Data.a := Source.Data.a;
4260 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4261 procedure glBitmapConvertCalculateRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
4265 with aFuncRec do begin
4267 if (Source.Range.arr[i] > 0) then
4268 Dest.Data.arr[i] := Round(Dest.Range.arr[i] * Source.Data.arr[i] / Source.Range.arr[i]);
4273 TShiftData = packed record
4275 0: (r, g, b, a: SmallInt);
4276 1: (arr: array[0..3] of SmallInt);
4278 PShiftData = ^TShiftData;
4280 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4281 procedure glBitmapConvertShiftRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
4287 if (Source.Range.arr[i] > 0) then
4288 Dest.Data.arr[i] := Source.Data.arr[i] shr PShiftData(Args)^.arr[i];
4291 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4292 procedure glBitmapInvertFunc(var aFuncRec: TglBitmapFunctionRec);
4294 with aFuncRec do begin
4295 Dest.Data := Source.Data;
4296 if ({%H-}PtrUInt(Args) and $1 > 0) then begin
4297 Dest.Data.r := Dest.Data.r xor Dest.Range.r;
4298 Dest.Data.g := Dest.Data.g xor Dest.Range.g;
4299 Dest.Data.b := Dest.Data.b xor Dest.Range.b;
4301 if ({%H-}PtrUInt(Args) and $2 > 0) then begin
4302 Dest.Data.a := Dest.Data.a xor Dest.Range.a;
4307 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4308 procedure glBitmapFillWithColorFunc(var aFuncRec: TglBitmapFunctionRec);
4312 with aFuncRec do begin
4314 Dest.Data.arr[i] := PglBitmapPixelData(Args)^.Data.arr[i];
4318 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4319 procedure glBitmapAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4323 with FuncRec do begin
4324 if (FuncRec.Args = nil) then begin //source has no alpha
4326 Source.Data.r / Source.Range.r * ALPHA_WEIGHT_R +
4327 Source.Data.g / Source.Range.g * ALPHA_WEIGHT_G +
4328 Source.Data.b / Source.Range.b * ALPHA_WEIGHT_B;
4329 Dest.Data.a := Round(Dest.Range.a * Temp);
4331 Dest.Data.a := Round(Source.Data.a / Source.Range.a * Dest.Range.a);
4335 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4336 procedure glBitmapColorKeyAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4338 PglBitmapPixelData = ^TglBitmapPixelData;
4340 with FuncRec do begin
4341 Dest.Data.r := Source.Data.r;
4342 Dest.Data.g := Source.Data.g;
4343 Dest.Data.b := Source.Data.b;
4345 with PglBitmapPixelData(Args)^ do
4346 if ((Dest.Data.r <= Data.r) and (Dest.Data.r >= Range.r) and
4347 (Dest.Data.g <= Data.g) and (Dest.Data.g >= Range.g) and
4348 (Dest.Data.b <= Data.b) and (Dest.Data.b >= Range.b)) then
4351 Dest.Data.a := Dest.Range.a;
4355 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4356 procedure glBitmapValueAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4358 with FuncRec do begin
4359 Dest.Data.r := Source.Data.r;
4360 Dest.Data.g := Source.Data.g;
4361 Dest.Data.b := Source.Data.b;
4362 Dest.Data.a := PCardinal(Args)^;
4366 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4367 procedure SwapRGB(aData: PByte; aWidth: Integer; const aHasAlpha: Boolean);
4370 TRGBPix = array [0..2] of byte;
4374 while aWidth > 0 do begin
4375 Temp := PRGBPix(aData)^[0];
4376 PRGBPix(aData)^[0] := PRGBPix(aData)^[2];
4377 PRGBPix(aData)^[2] := Temp;
4387 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4388 //TglBitmap - PROTECTED///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4389 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4390 function TglBitmap.GetFormatDesc: TglBitmapFormatDescriptor;
4392 result := TFormatDescriptor.Get(Format);
4395 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4396 function TglBitmap.GetWidth: Integer;
4398 if (ffX in fDimension.Fields) then
4399 result := fDimension.X
4404 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4405 function TglBitmap.GetHeight: Integer;
4407 if (ffY in fDimension.Fields) then
4408 result := fDimension.Y
4413 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4414 function TglBitmap.GetFileWidth: Integer;
4416 result := Max(1, Width);
4419 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4420 function TglBitmap.GetFileHeight: Integer;
4422 result := Max(1, Height);
4425 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4426 procedure TglBitmap.SetCustomData(const aValue: Pointer);
4428 if fCustomData = aValue then
4430 fCustomData := aValue;
4433 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4434 procedure TglBitmap.SetCustomName(const aValue: String);
4436 if fCustomName = aValue then
4438 fCustomName := aValue;
4441 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4442 procedure TglBitmap.SetCustomNameW(const aValue: WideString);
4444 if fCustomNameW = aValue then
4446 fCustomNameW := aValue;
4449 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4450 procedure TglBitmap.SetFreeDataOnDestroy(const aValue: Boolean);
4452 if fFreeDataOnDestroy = aValue then
4454 fFreeDataOnDestroy := aValue;
4457 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4458 procedure TglBitmap.SetDeleteTextureOnFree(const aValue: Boolean);
4460 if fDeleteTextureOnFree = aValue then
4462 fDeleteTextureOnFree := aValue;
4465 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4466 procedure TglBitmap.SetFormat(const aValue: TglBitmapFormat);
4468 if fFormat = aValue then
4470 if TFormatDescriptor.Get(Format).BitsPerPixel <> TFormatDescriptor.Get(aValue).BitsPerPixel then
4471 raise EglBitmapUnsupportedFormat.Create(Format);
4472 SetDataPointer(fData, aValue, Width, Height); //be careful, Data could be freed by this method
4475 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4476 procedure TglBitmap.SetFreeDataAfterGenTexture(const aValue: Boolean);
4478 if fFreeDataAfterGenTexture = aValue then
4480 fFreeDataAfterGenTexture := aValue;
4483 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4484 procedure TglBitmap.SetID(const aValue: Cardinal);
4486 if fID = aValue then
4491 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4492 procedure TglBitmap.SetMipMap(const aValue: TglBitmapMipMap);
4494 if fMipMap = aValue then
4499 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4500 procedure TglBitmap.SetTarget(const aValue: Cardinal);
4502 if fTarget = aValue then
4507 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4508 procedure TglBitmap.SetAnisotropic(const aValue: Integer);
4509 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_EXT)}
4511 MaxAnisotropic: Integer;
4514 fAnisotropic := aValue;
4515 if (ID > 0) then begin
4516 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_EXT)}
4517 if GL_EXT_texture_filter_anisotropic then begin
4518 if fAnisotropic > 0 then begin
4520 glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @MaxAnisotropic);
4521 if aValue > MaxAnisotropic then
4522 fAnisotropic := MaxAnisotropic;
4523 glTexParameteri(Target, GL_TEXTURE_MAX_ANISOTROPY_EXT, fAnisotropic);
4534 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4535 procedure TglBitmap.CreateID;
4538 glDeleteTextures(1, @fID);
4539 glGenTextures(1, @fID);
4543 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4544 procedure TglBitmap.SetupParameters({$IFNDEF OPENGL_ES}out aBuildWithGlu: Boolean{$ENDIF});
4546 // Set Up Parameters
4547 SetWrap(fWrapS, fWrapT, fWrapR);
4548 SetFilter(fFilterMin, fFilterMag);
4549 SetAnisotropic(fAnisotropic);
4552 SetBorderColor(fBorderColor[0], fBorderColor[1], fBorderColor[2], fBorderColor[3]);
4553 if (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
4554 SetSwizzle(fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
4558 // Mip Maps Generation Mode
4559 aBuildWithGlu := false;
4560 if (MipMap = mmMipmap) then begin
4561 if (GL_VERSION_1_4 or GL_SGIS_generate_mipmap) then
4562 glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE)
4564 aBuildWithGlu := true;
4565 end else if (MipMap = mmMipmapGlu) then
4566 aBuildWithGlu := true;
4568 if (MipMap = mmMipmap) then
4569 glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE);
4573 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4574 procedure TglBitmap.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
4575 const aWidth: Integer; const aHeight: Integer);
4579 if (Data <> aData) then begin
4580 if (Assigned(Data)) then
4585 if not Assigned(fData) then begin
4589 FillChar(fDimension, SizeOf(fDimension), 0);
4590 if aWidth <> -1 then begin
4591 fDimension.Fields := fDimension.Fields + [ffX];
4592 fDimension.X := aWidth;
4595 if aHeight <> -1 then begin
4596 fDimension.Fields := fDimension.Fields + [ffY];
4597 fDimension.Y := aHeight;
4600 s := TFormatDescriptor.Get(aFormat).BytesPerPixel;
4602 fPixelSize := Ceil(s);
4603 fRowSize := Ceil(s * aWidth);
4607 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4608 function TglBitmap.FlipHorz: Boolean;
4613 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4614 function TglBitmap.FlipVert: Boolean;
4619 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4620 //TglBitmap - PUBLIC//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4621 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4622 procedure TglBitmap.AfterConstruction;
4624 inherited AfterConstruction;
4629 fIsResident := false;
4632 fMipMap := glBitmapDefaultMipmap;
4633 fFreeDataAfterGenTexture := glBitmapGetDefaultFreeDataAfterGenTexture;
4634 fDeleteTextureOnFree := glBitmapGetDefaultDeleteTextureOnFree;
4636 glBitmapGetDefaultFilter (fFilterMin, fFilterMag);
4637 glBitmapGetDefaultTextureWrap(fWrapS, fWrapT, fWrapR);
4639 glBitmapGetDefaultSwizzle (fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
4643 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4644 procedure TglBitmap.BeforeDestruction;
4648 if fFreeDataOnDestroy then begin
4650 SetDataPointer(NewData, tfEmpty); //be careful, Data could be freed by this method
4652 if (fID > 0) and fDeleteTextureOnFree then
4653 glDeleteTextures(1, @fID);
4654 inherited BeforeDestruction;
4657 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4658 procedure TglBitmap.PrepareResType(var aResource: String; var aResType: PChar);
4662 if not Assigned(aResType) then begin
4663 TempPos := Pos('.', aResource);
4664 aResType := PChar(UpperCase(Copy(aResource, TempPos + 1, Length(aResource) - TempPos)));
4665 aResource := UpperCase(Copy(aResource, 0, TempPos -1));
4669 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4670 procedure TglBitmap.LoadFromFile(const aFilename: String);
4674 if not FileExists(aFilename) then
4675 raise EglBitmap.Create('file does not exist: ' + aFilename);
4676 fFilename := aFilename;
4677 fs := TFileStream.Create(fFilename, fmOpenRead);
4686 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4687 procedure TglBitmap.LoadFromStream(const aStream: TStream);
4689 {$IFDEF GLB_SUPPORT_PNG_READ}
4690 if not LoadPNG(aStream) then
4692 {$IFDEF GLB_SUPPORT_JPEG_READ}
4693 if not LoadJPEG(aStream) then
4695 if not LoadDDS(aStream) then
4696 if not LoadTGA(aStream) then
4697 if not LoadBMP(aStream) then
4698 if not LoadRAW(aStream) then
4699 raise EglBitmap.Create('LoadFromStream - Couldn''t load Stream. It''s possible to be an unknow Streamtype.');
4702 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4703 procedure TglBitmap.LoadFromFunc(const aSize: TglBitmapSize; const aFunc: TglBitmapFunction;
4704 const aFormat: TglBitmapFormat; const aArgs: Pointer);
4709 size := TFormatDescriptor.Get(aFormat).GetSize(aSize);
4710 GetMem(tmpData, size);
4712 FillChar(tmpData^, size, #$FF);
4713 SetDataPointer(tmpData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
4715 if Assigned(tmpData) then
4719 Convert(Self, aFunc, false, aFormat, aArgs);
4722 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4723 procedure TglBitmap.LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar);
4725 rs: TResourceStream;
4727 PrepareResType(aResource, aResType);
4728 rs := TResourceStream.Create(aInstance, aResource, aResType);
4736 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4737 procedure TglBitmap.LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
4739 rs: TResourceStream;
4741 rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
4749 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4750 procedure TglBitmap.SaveToFile(const aFilename: String; const aFileType: TglBitmapFileType);
4754 fs := TFileStream.Create(aFileName, fmCreate);
4757 SaveToStream(fs, aFileType);
4763 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4764 procedure TglBitmap.SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType);
4767 {$IFDEF GLB_SUPPORT_PNG_WRITE}
4768 ftPNG: SavePNG(aStream);
4770 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
4771 ftJPEG: SaveJPEG(aStream);
4773 ftDDS: SaveDDS(aStream);
4774 ftTGA: SaveTGA(aStream);
4775 ftBMP: SaveBMP(aStream);
4776 ftRAW: SaveRAW(aStream);
4780 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4781 function TglBitmap.Convert(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer): Boolean;
4783 result := Convert(Self, aFunc, aCreateTemp, Format, aArgs);
4786 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4787 function TglBitmap.Convert(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
4788 const aFormat: TglBitmapFormat; const aArgs: Pointer): Boolean;
4790 DestData, TmpData, SourceData: pByte;
4791 TempHeight, TempWidth: Integer;
4792 SourceFD, DestFD: TFormatDescriptor;
4793 SourceMD, DestMD: Pointer;
4795 FuncRec: TglBitmapFunctionRec;
4797 Assert(Assigned(Data));
4798 Assert(Assigned(aSource));
4799 Assert(Assigned(aSource.Data));
4802 if Assigned(aSource.Data) and ((aSource.Height > 0) or (aSource.Width > 0)) then begin
4803 SourceFD := TFormatDescriptor.Get(aSource.Format);
4804 DestFD := TFormatDescriptor.Get(aFormat);
4806 if (SourceFD.IsCompressed) then
4807 raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', SourceFD.Format);
4808 if (DestFD.IsCompressed) then
4809 raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', DestFD.Format);
4811 // inkompatible Formats so CreateTemp
4812 if (SourceFD.BitsPerPixel <> DestFD.BitsPerPixel) then
4813 aCreateTemp := true;
4816 TempHeight := Max(1, aSource.Height);
4817 TempWidth := Max(1, aSource.Width);
4819 FuncRec.Sender := Self;
4820 FuncRec.Args := aArgs;
4823 if aCreateTemp then begin
4824 GetMem(TmpData, DestFD.GetSize(TempWidth, TempHeight));
4825 DestData := TmpData;
4830 SourceFD.PreparePixel(FuncRec.Source);
4831 DestFD.PreparePixel (FuncRec.Dest);
4833 SourceMD := SourceFD.CreateMappingData;
4834 DestMD := DestFD.CreateMappingData;
4836 FuncRec.Size := aSource.Dimension;
4837 FuncRec.Position.Fields := FuncRec.Size.Fields;
4840 SourceData := aSource.Data;
4841 FuncRec.Position.Y := 0;
4842 while FuncRec.Position.Y < TempHeight do begin
4843 FuncRec.Position.X := 0;
4844 while FuncRec.Position.X < TempWidth do begin
4845 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
4847 DestFD.Map(FuncRec.Dest, DestData, DestMD);
4848 inc(FuncRec.Position.X);
4850 inc(FuncRec.Position.Y);
4853 // Updating Image or InternalFormat
4855 SetDataPointer(TmpData, aFormat, aSource.Width, aSource.Height) //be careful, Data could be freed by this method
4856 else if (aFormat <> fFormat) then
4861 SourceFD.FreeMappingData(SourceMD);
4862 DestFD.FreeMappingData(DestMD);
4865 if aCreateTemp and Assigned(TmpData) then
4872 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4873 function TglBitmap.ConvertTo(const aFormat: TglBitmapFormat): Boolean;
4875 SourceFD, DestFD: TFormatDescriptor;
4876 SourcePD, DestPD: TglBitmapPixelData;
4877 ShiftData: TShiftData;
4879 function DataIsIdentical: Boolean;
4881 result := SourceFD.MaskMatch(DestFD.Mask);
4884 function CanCopyDirect: Boolean;
4887 ((SourcePD.Range.r = DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
4888 ((SourcePD.Range.g = DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
4889 ((SourcePD.Range.b = DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
4890 ((SourcePD.Range.a = DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
4893 function CanShift: Boolean;
4896 ((SourcePD.Range.r >= DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
4897 ((SourcePD.Range.g >= DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
4898 ((SourcePD.Range.b >= DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
4899 ((SourcePD.Range.a >= DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
4902 function GetShift(aSource, aDest: Cardinal) : ShortInt;
4905 while (aSource > aDest) and (aSource > 0) do begin
4907 aSource := aSource shr 1;
4912 if (aFormat <> fFormat) and (aFormat <> tfEmpty) then begin
4913 SourceFD := TFormatDescriptor.Get(Format);
4914 DestFD := TFormatDescriptor.Get(aFormat);
4916 if DataIsIdentical then begin
4922 SourceFD.PreparePixel(SourcePD);
4923 DestFD.PreparePixel (DestPD);
4925 if CanCopyDirect then
4926 result := Convert(Self, glBitmapConvertCopyFunc, false, aFormat)
4927 else if CanShift then begin
4928 ShiftData.r := GetShift(SourcePD.Range.r, DestPD.Range.r);
4929 ShiftData.g := GetShift(SourcePD.Range.g, DestPD.Range.g);
4930 ShiftData.b := GetShift(SourcePD.Range.b, DestPD.Range.b);
4931 ShiftData.a := GetShift(SourcePD.Range.a, DestPD.Range.a);
4932 result := Convert(Self, glBitmapConvertShiftRGBAFunc, false, aFormat, @ShiftData);
4934 result := Convert(Self, glBitmapConvertCalculateRGBAFunc, false, aFormat);
4940 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4941 function TglBitmap.AssignToSurface(out aSurface: PSDL_Surface): Boolean;
4943 Row, RowSize: Integer;
4944 SourceData, TmpData: PByte;
4946 FormatDesc: TFormatDescriptor;
4948 function GetRowPointer(Row: Integer): pByte;
4950 result := aSurface.pixels;
4951 Inc(result, Row * RowSize);
4957 FormatDesc := TFormatDescriptor.Get(Format);
4958 if FormatDesc.IsCompressed then
4959 raise EglBitmapUnsupportedFormat.Create(Format);
4961 if Assigned(Data) then begin
4962 case Trunc(FormatDesc.PixelSize) of
4968 raise EglBitmapUnsupportedFormat.Create(Format);
4971 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, TempDepth,
4972 FormatDesc.RedMask, FormatDesc.GreenMask, FormatDesc.BlueMask, FormatDesc.AlphaMask);
4974 RowSize := FormatDesc.GetSize(FileWidth, 1);
4976 for Row := 0 to FileHeight-1 do begin
4977 TmpData := GetRowPointer(Row);
4978 if Assigned(TmpData) then begin
4979 Move(SourceData^, TmpData^, RowSize);
4980 inc(SourceData, RowSize);
4987 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4988 function TglBitmap.AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
4990 pSource, pData, pTempData: PByte;
4991 Row, RowSize, TempWidth, TempHeight: Integer;
4992 IntFormat: TglBitmapFormat;
4993 fd: TFormatDescriptor;
4994 Mask: TglBitmapMask;
4996 function GetRowPointer(Row: Integer): pByte;
4998 result := aSurface^.pixels;
4999 Inc(result, Row * RowSize);
5004 if (Assigned(aSurface)) then begin
5005 with aSurface^.format^ do begin
5010 IntFormat := TFormatDescriptor.GetFromMask(Mask).Format;
5011 if (IntFormat = tfEmpty) then
5012 raise EglBitmap.Create('AssignFromSurface - Invalid Pixelformat.');
5015 fd := TFormatDescriptor.Get(IntFormat);
5016 TempWidth := aSurface^.w;
5017 TempHeight := aSurface^.h;
5018 RowSize := fd.GetSize(TempWidth, 1);
5019 GetMem(pData, TempHeight * RowSize);
5022 for Row := 0 to TempHeight -1 do begin
5023 pSource := GetRowPointer(Row);
5024 if (Assigned(pSource)) then begin
5025 Move(pSource^, pTempData^, RowSize);
5026 Inc(pTempData, RowSize);
5029 SetDataPointer(pData, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
5032 if Assigned(pData) then
5039 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5040 function TglBitmap.AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
5042 Row, Col, AlphaInterleave: Integer;
5043 pSource, pDest: PByte;
5045 function GetRowPointer(Row: Integer): pByte;
5047 result := aSurface.pixels;
5048 Inc(result, Row * Width);
5053 if Assigned(Data) then begin
5054 if Format in [tfAlpha8ub1, tfLuminance8Alpha8ub2, tfBGRA8ub4, tfRGBA8ub4] then begin
5055 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, 8, $FF, $FF, $FF, 0);
5057 AlphaInterleave := 0;
5059 tfLuminance8Alpha8ub2:
5060 AlphaInterleave := 1;
5061 tfBGRA8ub4, tfRGBA8ub4:
5062 AlphaInterleave := 3;
5066 for Row := 0 to Height -1 do begin
5067 pDest := GetRowPointer(Row);
5068 if Assigned(pDest) then begin
5069 for Col := 0 to Width -1 do begin
5070 Inc(pSource, AlphaInterleave);
5082 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5083 function TglBitmap.AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
5087 bmp := TglBitmap2D.Create;
5089 bmp.AssignFromSurface(aSurface);
5090 result := AddAlphaFromGlBitmap(bmp, aFunc, aArgs);
5098 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5099 function CreateGrayPalette: HPALETTE;
5104 GetMem(Pal, SizeOf(TLogPalette) + (SizeOf(TPaletteEntry) * 256));
5106 Pal.palVersion := $300;
5107 Pal.palNumEntries := 256;
5109 for Idx := 0 to Pal.palNumEntries - 1 do begin
5110 Pal.palPalEntry[Idx].peRed := Idx;
5111 Pal.palPalEntry[Idx].peGreen := Idx;
5112 Pal.palPalEntry[Idx].peBlue := Idx;
5113 Pal.palPalEntry[Idx].peFlags := 0;
5115 Result := CreatePalette(Pal^);
5119 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5120 function TglBitmap.AssignToBitmap(const aBitmap: TBitmap): Boolean;
5123 pSource, pData: PByte;
5126 if Assigned(Data) then begin
5127 if Assigned(aBitmap) then begin
5128 aBitmap.Width := Width;
5129 aBitmap.Height := Height;
5132 tfAlpha8ub1, tfLuminance8ub1: begin
5133 aBitmap.PixelFormat := pf8bit;
5134 aBitmap.Palette := CreateGrayPalette;
5137 aBitmap.PixelFormat := pf15bit;
5139 aBitmap.PixelFormat := pf16bit;
5140 tfRGB8ub3, tfBGR8ub3:
5141 aBitmap.PixelFormat := pf24bit;
5142 tfRGBA8ub4, tfBGRA8ub4:
5143 aBitmap.PixelFormat := pf32bit;
5145 raise EglBitmap.Create('AssignToBitmap - Invalid Pixelformat.');
5149 for Row := 0 to FileHeight -1 do begin
5150 pData := aBitmap.Scanline[Row];
5151 Move(pSource^, pData^, fRowSize);
5152 Inc(pSource, fRowSize);
5153 if (Format in [tfRGB8ub3, tfRGBA8ub4]) then // swap RGB(A) to BGR(A)
5154 SwapRGB(pData, FileWidth, Format = tfRGBA8ub4);
5161 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5162 function TglBitmap.AssignFromBitmap(const aBitmap: TBitmap): Boolean;
5164 pSource, pData, pTempData: PByte;
5165 Row, RowSize, TempWidth, TempHeight: Integer;
5166 IntFormat: TglBitmapFormat;
5170 if (Assigned(aBitmap)) then begin
5171 case aBitmap.PixelFormat of
5173 IntFormat := tfLuminance8ub1;
5175 IntFormat := tfRGB5A1us1;
5177 IntFormat := tfR5G6B5us1;
5179 IntFormat := tfBGR8ub3;
5181 IntFormat := tfBGRA8ub4;
5183 raise EglBitmap.Create('AssignFromBitmap - Invalid Pixelformat.');
5186 TempWidth := aBitmap.Width;
5187 TempHeight := aBitmap.Height;
5188 RowSize := TFormatDescriptor.Get(IntFormat).GetSize(TempWidth, 1);
5189 GetMem(pData, TempHeight * RowSize);
5192 for Row := 0 to TempHeight -1 do begin
5193 pSource := aBitmap.Scanline[Row];
5194 if (Assigned(pSource)) then begin
5195 Move(pSource^, pTempData^, RowSize);
5196 Inc(pTempData, RowSize);
5199 SetDataPointer(pData, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
5202 if Assigned(pData) then
5209 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5210 function TglBitmap.AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
5212 Row, Col, AlphaInterleave: Integer;
5213 pSource, pDest: PByte;
5217 if Assigned(Data) then begin
5218 if (Format in [tfAlpha8ub1, tfLuminance8Alpha8ub2, tfRGBA8ub4, tfBGRA8ub4]) then begin
5219 if Assigned(aBitmap) then begin
5220 aBitmap.PixelFormat := pf8bit;
5221 aBitmap.Palette := CreateGrayPalette;
5222 aBitmap.Width := Width;
5223 aBitmap.Height := Height;
5226 tfLuminance8Alpha8ub2:
5227 AlphaInterleave := 1;
5228 tfRGBA8ub4, tfBGRA8ub4:
5229 AlphaInterleave := 3;
5231 AlphaInterleave := 0;
5237 for Row := 0 to Height -1 do begin
5238 pDest := aBitmap.Scanline[Row];
5239 if Assigned(pDest) then begin
5240 for Col := 0 to Width -1 do begin
5241 Inc(pSource, AlphaInterleave);
5254 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5255 function TglBitmap.AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5259 tex := TglBitmap2D.Create;
5261 tex.AssignFromBitmap(ABitmap);
5262 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
5269 {$IFDEF GLB_LAZARUS}
5270 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5271 function TglBitmap.AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
5273 rid: TRawImageDescription;
5274 FormatDesc: TFormatDescriptor;
5276 if not Assigned(Data) then
5277 raise EglBitmap.Create('no pixel data assigned. load data before save');
5280 if not Assigned(aImage) or (Format = tfEmpty) then
5282 FormatDesc := TFormatDescriptor.Get(Format);
5283 if FormatDesc.IsCompressed then
5286 FillChar(rid{%H-}, SizeOf(rid), 0);
5287 if FormatDesc.IsGrayscale then
5288 rid.Format := ricfGray
5290 rid.Format := ricfRGBA;
5293 rid.Height := Height;
5294 rid.Depth := FormatDesc.BitsPerPixel;
5295 rid.BitOrder := riboBitsInOrder;
5296 rid.ByteOrder := riboLSBFirst;
5297 rid.LineOrder := riloTopToBottom;
5298 rid.LineEnd := rileTight;
5299 rid.BitsPerPixel := FormatDesc.BitsPerPixel;
5300 rid.RedPrec := CountSetBits(FormatDesc.Range.r);
5301 rid.GreenPrec := CountSetBits(FormatDesc.Range.g);
5302 rid.BluePrec := CountSetBits(FormatDesc.Range.b);
5303 rid.AlphaPrec := CountSetBits(FormatDesc.Range.a);
5304 rid.RedShift := FormatDesc.Shift.r;
5305 rid.GreenShift := FormatDesc.Shift.g;
5306 rid.BlueShift := FormatDesc.Shift.b;
5307 rid.AlphaShift := FormatDesc.Shift.a;
5309 rid.MaskBitsPerPixel := 0;
5310 rid.PaletteColorCount := 0;
5312 aImage.DataDescription := rid;
5315 if not Assigned(aImage.PixelData) then
5316 raise EglBitmap.Create('error while creating LazIntfImage');
5317 Move(Data^, aImage.PixelData^, FormatDesc.GetSize(Dimension));
5322 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5323 function TglBitmap.AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
5326 FormatDesc: TFormatDescriptor;
5330 Mask: TglBitmapRec4ul;
5332 procedure CopyConvert;
5334 bfFormat: TbmpBitfieldFormat;
5335 pSourceLine, pDestLine: PByte;
5336 pSourceMD, pDestMD: Pointer;
5337 Shift, Prec: TglBitmapRec4ub;
5339 pixel: TglBitmapPixelData;
5341 bfFormat := TbmpBitfieldFormat.Create;
5342 with aImage.DataDescription do begin
5344 Prec.g := GreenPrec;
5346 Prec.a := AlphaPrec;
5347 Shift.r := RedShift;
5348 Shift.g := GreenShift;
5349 Shift.b := BlueShift;
5350 Shift.a := AlphaShift;
5351 bfFormat.SetCustomValues(BitsPerPixel, Prec, Shift);
5353 pSourceMD := bfFormat.CreateMappingData;
5354 pDestMD := FormatDesc.CreateMappingData;
5356 for y := 0 to aImage.Height-1 do begin
5357 pSourceLine := aImage.PixelData + y {%H-}* aImage.DataDescription.BytesPerLine;
5358 pDestLine := ImageData + y * Round(FormatDesc.BytesPerPixel * aImage.Width);
5359 for x := 0 to aImage.Width-1 do begin
5360 bfFormat.Unmap(pSourceLine, pixel, pSourceMD);
5361 FormatDesc.Map(pixel, pDestLine, pDestMD);
5365 FormatDesc.FreeMappingData(pDestMD);
5366 bfFormat.FreeMappingData(pSourceMD);
5373 if not Assigned(aImage) then
5376 with aImage.DataDescription do begin
5377 Mask.r := (QWord(1 shl RedPrec )-1) shl RedShift;
5378 Mask.g := (QWord(1 shl GreenPrec)-1) shl GreenShift;
5379 Mask.b := (QWord(1 shl BluePrec )-1) shl BlueShift;
5380 Mask.a := (QWord(1 shl AlphaPrec)-1) shl AlphaShift;
5382 FormatDesc := TFormatDescriptor.GetFromMask(Mask);
5383 f := FormatDesc.Format;
5384 if (f = tfEmpty) then
5388 (FormatDesc.BitsPerPixel = aImage.DataDescription.Depth) and
5389 (aImage.DataDescription.BitsPerPixel = aImage.DataDescription.Depth);
5391 ImageSize := FormatDesc.GetSize(aImage.Width, aImage.Height);
5392 ImageData := GetMem(ImageSize);
5395 Move(aImage.PixelData^, ImageData^, ImageSize)
5398 SetDataPointer(ImageData, f, aImage.Width, aImage.Height); //be careful, Data could be freed by this method
5400 if Assigned(ImageData) then
5408 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5409 function TglBitmap.AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
5411 rid: TRawImageDescription;
5412 FormatDesc: TFormatDescriptor;
5413 Pixel: TglBitmapPixelData;
5419 if not Assigned(aImage) or (Format = tfEmpty) then
5421 FormatDesc := TFormatDescriptor.Get(Format);
5422 if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
5425 FillChar(rid{%H-}, SizeOf(rid), 0);
5426 rid.Format := ricfGray;
5428 rid.Height := Height;
5429 rid.Depth := CountSetBits(FormatDesc.Range.a);
5430 rid.BitOrder := riboBitsInOrder;
5431 rid.ByteOrder := riboLSBFirst;
5432 rid.LineOrder := riloTopToBottom;
5433 rid.LineEnd := rileTight;
5434 rid.BitsPerPixel := 8 * Ceil(rid.Depth / 8);
5435 rid.RedPrec := CountSetBits(FormatDesc.Range.a);
5440 rid.GreenShift := 0;
5442 rid.AlphaShift := 0;
5444 rid.MaskBitsPerPixel := 0;
5445 rid.PaletteColorCount := 0;
5447 aImage.DataDescription := rid;
5450 srcMD := FormatDesc.CreateMappingData;
5452 FormatDesc.PreparePixel(Pixel);
5454 dst := aImage.PixelData;
5455 for y := 0 to Height-1 do
5456 for x := 0 to Width-1 do begin
5457 FormatDesc.Unmap(src, Pixel, srcMD);
5458 case rid.BitsPerPixel of
5460 dst^ := Pixel.Data.a;
5464 PWord(dst)^ := Pixel.Data.a;
5468 PByteArray(dst)^[0] := PByteArray(@Pixel.Data.a)^[0];
5469 PByteArray(dst)^[1] := PByteArray(@Pixel.Data.a)^[1];
5470 PByteArray(dst)^[2] := PByteArray(@Pixel.Data.a)^[2];
5474 PCardinal(dst)^ := Pixel.Data.a;
5478 raise EglBitmapUnsupportedFormat.Create(Format);
5482 FormatDesc.FreeMappingData(srcMD);
5487 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5488 function TglBitmap.AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5492 tex := TglBitmap2D.Create;
5494 tex.AssignFromLazIntfImage(aImage);
5495 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
5502 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5503 function TglBitmap.AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar;
5504 const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5506 rs: TResourceStream;
5508 PrepareResType(aResource, aResType);
5509 rs := TResourceStream.Create(aInstance, aResource, aResType);
5511 result := AddAlphaFromStream(rs, aFunc, aArgs);
5517 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5518 function TglBitmap.AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
5519 const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5521 rs: TResourceStream;
5523 rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
5525 result := AddAlphaFromStream(rs, aFunc, aArgs);
5531 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5532 function TglBitmap.AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5534 if TFormatDescriptor.Get(Format).IsCompressed then
5535 raise EglBitmapUnsupportedFormat.Create(Format);
5536 result := Convert(Self, aFunc, false, TFormatDescriptor.Get(Format).WithAlpha, aArgs);
5539 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5540 function TglBitmap.AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5544 FS := TFileStream.Create(aFileName, fmOpenRead);
5546 result := AddAlphaFromStream(FS, aFunc, aArgs);
5552 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5553 function TglBitmap.AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5557 tex := TglBitmap2D.Create(aStream);
5559 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
5565 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5566 function TglBitmap.AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5568 DestData, DestData2, SourceData: pByte;
5569 TempHeight, TempWidth: Integer;
5570 SourceFD, DestFD: TFormatDescriptor;
5571 SourceMD, DestMD, DestMD2: Pointer;
5573 FuncRec: TglBitmapFunctionRec;
5577 Assert(Assigned(Data));
5578 Assert(Assigned(aBitmap));
5579 Assert(Assigned(aBitmap.Data));
5581 if ((aBitmap.Width = Width) and (aBitmap.Height = Height)) then begin
5582 result := ConvertTo(TFormatDescriptor.Get(Format).WithAlpha);
5584 SourceFD := TFormatDescriptor.Get(aBitmap.Format);
5585 DestFD := TFormatDescriptor.Get(Format);
5587 if not Assigned(aFunc) then begin
5588 aFunc := glBitmapAlphaFunc;
5589 FuncRec.Args := {%H-}Pointer(SourceFD.HasAlpha);
5591 FuncRec.Args := aArgs;
5594 TempHeight := aBitmap.FileHeight;
5595 TempWidth := aBitmap.FileWidth;
5597 FuncRec.Sender := Self;
5598 FuncRec.Size := Dimension;
5599 FuncRec.Position.Fields := FuncRec.Size.Fields;
5603 SourceData := aBitmap.Data;
5606 SourceFD.PreparePixel(FuncRec.Source);
5607 DestFD.PreparePixel (FuncRec.Dest);
5609 SourceMD := SourceFD.CreateMappingData;
5610 DestMD := DestFD.CreateMappingData;
5611 DestMD2 := DestFD.CreateMappingData;
5613 FuncRec.Position.Y := 0;
5614 while FuncRec.Position.Y < TempHeight do begin
5615 FuncRec.Position.X := 0;
5616 while FuncRec.Position.X < TempWidth do begin
5617 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
5618 DestFD.Unmap (DestData, FuncRec.Dest, DestMD);
5620 DestFD.Map(FuncRec.Dest, DestData2, DestMD2);
5621 inc(FuncRec.Position.X);
5623 inc(FuncRec.Position.Y);
5626 SourceFD.FreeMappingData(SourceMD);
5627 DestFD.FreeMappingData(DestMD);
5628 DestFD.FreeMappingData(DestMD2);
5633 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5634 function TglBitmap.AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte): Boolean;
5636 result := AddAlphaFromColorKeyFloat(aRed / $FF, aGreen / $FF, aBlue / $FF, aDeviation / $FF);
5639 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5640 function TglBitmap.AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal): Boolean;
5642 PixelData: TglBitmapPixelData;
5644 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5645 result := AddAlphaFromColorKeyFloat(
5646 aRed / PixelData.Range.r,
5647 aGreen / PixelData.Range.g,
5648 aBlue / PixelData.Range.b,
5649 aDeviation / Max(PixelData.Range.r, Max(PixelData.Range.g, PixelData.Range.b)));
5652 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5653 function TglBitmap.AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single): Boolean;
5655 values: array[0..2] of Single;
5658 PixelData: TglBitmapPixelData;
5660 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5661 with PixelData do begin
5663 values[1] := aGreen;
5666 for i := 0 to 2 do begin
5667 tmp := Trunc(Range.arr[i] * aDeviation);
5668 Data.arr[i] := Min(Range.arr[i], Trunc(Range.arr[i] * values[i] + tmp));
5669 Range.arr[i] := Max(0, Trunc(Range.arr[i] * values[i] - tmp));
5674 result := AddAlphaFromFunc(glBitmapColorKeyAlphaFunc, @PixelData);
5677 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5678 function TglBitmap.AddAlphaFromValue(const aAlpha: Byte): Boolean;
5680 result := AddAlphaFromValueFloat(aAlpha / $FF);
5683 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5684 function TglBitmap.AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
5686 PixelData: TglBitmapPixelData;
5688 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5689 result := AddAlphaFromValueFloat(aAlpha / PixelData.Range.a);
5692 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5693 function TglBitmap.AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
5695 PixelData: TglBitmapPixelData;
5697 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5699 Data.a := Min(Range.a, Max(0, Round(Range.a * aAlpha)));
5700 result := AddAlphaFromFunc(glBitmapValueAlphaFunc, @PixelData.Data.a);
5703 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5704 function TglBitmap.RemoveAlpha: Boolean;
5706 FormatDesc: TFormatDescriptor;
5709 FormatDesc := TFormatDescriptor.Get(Format);
5710 if Assigned(Data) then begin
5711 if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
5712 raise EglBitmapUnsupportedFormat.Create(Format);
5713 result := ConvertTo(FormatDesc.WithoutAlpha);
5717 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5718 function TglBitmap.Clone: TglBitmap;
5725 Temp := (ClassType.Create as TglBitmap);
5727 // copy texture data if assigned
5728 if Assigned(Data) then begin
5729 Size := TFormatDescriptor.Get(Format).GetSize(fDimension);
5730 GetMem(TempPtr, Size);
5732 Move(Data^, TempPtr^, Size);
5733 Temp.SetDataPointer(TempPtr, Format, Width, Height); //be careful, Data could be freed by this method
5735 if Assigned(TempPtr) then
5741 Temp.SetDataPointer(TempPtr, Format, Width, Height); //be careful, Data could be freed by this method
5746 Temp.fTarget := Target;
5747 Temp.fFormat := Format;
5748 Temp.fMipMap := MipMap;
5749 Temp.fAnisotropic := Anisotropic;
5750 Temp.fBorderColor := fBorderColor;
5751 Temp.fDeleteTextureOnFree := DeleteTextureOnFree;
5752 Temp.fFreeDataAfterGenTexture := FreeDataAfterGenTexture;
5753 Temp.fFilterMin := fFilterMin;
5754 Temp.fFilterMag := fFilterMag;
5755 Temp.fWrapS := fWrapS;
5756 Temp.fWrapT := fWrapT;
5757 Temp.fWrapR := fWrapR;
5758 Temp.fFilename := fFilename;
5759 Temp.fCustomName := fCustomName;
5760 Temp.fCustomNameW := fCustomNameW;
5761 Temp.fCustomData := fCustomData;
5770 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5771 procedure TglBitmap.Invert(const aUseRGB: Boolean; const aUseAlpha: Boolean);
5773 if aUseRGB or aUseAlpha then
5774 Convert(glBitmapInvertFunc, false, {%H-}Pointer(
5775 ((Byte(aUseAlpha) and 1) shl 1) or
5776 (Byte(aUseRGB) and 1) ));
5779 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5780 procedure TglBitmap.FreeData;
5785 SetDataPointer(TempPtr, tfEmpty); //be careful, Data could be freed by this method
5789 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5790 procedure TglBitmap.SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
5792 fBorderColor[0] := aRed;
5793 fBorderColor[1] := aGreen;
5794 fBorderColor[2] := aBlue;
5795 fBorderColor[3] := aAlpha;
5796 if (ID > 0) then begin
5798 glTexParameterfv(Target, GL_TEXTURE_BORDER_COLOR, @fBorderColor[0]);
5803 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5804 procedure TglBitmap.FillWithColor(const aRed, aGreen, aBlue: Byte;
5805 const aAlpha: Byte);
5807 FillWithColorFloat(aRed/$FF, aGreen/$FF, aBlue/$FF, aAlpha/$FF);
5810 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5811 procedure TglBitmap.FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal);
5813 PixelData: TglBitmapPixelData;
5815 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5817 aRed / PixelData.Range.r,
5818 aGreen / PixelData.Range.g,
5819 aBlue / PixelData.Range.b,
5820 aAlpha / PixelData.Range.a);
5823 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5824 procedure TglBitmap.FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single);
5826 PixelData: TglBitmapPixelData;
5828 TFormatDescriptor.Get(Format).PreparePixel(PixelData);
5829 with PixelData do begin
5830 Data.r := Max(0, Min(Range.r, Trunc(Range.r * aRed)));
5831 Data.g := Max(0, Min(Range.g, Trunc(Range.g * aGreen)));
5832 Data.b := Max(0, Min(Range.b, Trunc(Range.b * aBlue)));
5833 Data.a := Max(0, Min(Range.a, Trunc(Range.a * aAlpha)));
5835 Convert(glBitmapFillWithColorFunc, false, @PixelData);
5838 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5839 procedure TglBitmap.SetFilter(const aMin, aMag: GLenum);
5844 fFilterMin := GL_NEAREST;
5846 fFilterMin := GL_LINEAR;
5847 GL_NEAREST_MIPMAP_NEAREST:
5848 fFilterMin := GL_NEAREST_MIPMAP_NEAREST;
5849 GL_LINEAR_MIPMAP_NEAREST:
5850 fFilterMin := GL_LINEAR_MIPMAP_NEAREST;
5851 GL_NEAREST_MIPMAP_LINEAR:
5852 fFilterMin := GL_NEAREST_MIPMAP_LINEAR;
5853 GL_LINEAR_MIPMAP_LINEAR:
5854 fFilterMin := GL_LINEAR_MIPMAP_LINEAR;
5856 raise EglBitmap.Create('SetFilter - Unknow MIN filter.');
5862 fFilterMag := GL_NEAREST;
5864 fFilterMag := GL_LINEAR;
5866 raise EglBitmap.Create('SetFilter - Unknow MAG filter.');
5870 if (ID > 0) then begin
5872 glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, fFilterMag);
5874 if (MipMap = mmNone) {$IFNDEF OPENGL_ES}or (Target = GL_TEXTURE_RECTANGLE){$ENDIF} then begin
5876 GL_NEAREST, GL_LINEAR:
5877 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
5878 GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR:
5879 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5880 GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR:
5881 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5884 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
5888 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5889 procedure TglBitmap.SetWrap(const S: GLenum; const T: GLenum; const R: GLenum);
5891 procedure CheckAndSetWrap(const aValue: Cardinal; var aTarget: Cardinal);
5896 aTarget := GL_CLAMP;
5900 aTarget := GL_REPEAT;
5902 GL_CLAMP_TO_EDGE: begin
5904 if not GL_VERSION_1_2 and not GL_EXT_texture_edge_clamp then
5908 aTarget := GL_CLAMP_TO_EDGE;
5912 GL_CLAMP_TO_BORDER: begin
5913 if GL_VERSION_1_3 or GL_ARB_texture_border_clamp then
5914 aTarget := GL_CLAMP_TO_BORDER
5916 aTarget := GL_CLAMP;
5920 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
5921 GL_MIRRORED_REPEAT: begin
5923 if GL_VERSION_1_4 or GL_ARB_texture_mirrored_repeat or GL_IBM_texture_mirrored_repeat then
5925 if GL_VERSION_2_0 then
5927 aTarget := GL_MIRRORED_REPEAT
5929 raise EglBitmap.Create('SetWrap - Unsupported Texturewrap GL_MIRRORED_REPEAT (S).');
5933 raise EglBitmap.Create('SetWrap - Unknow Texturewrap');
5938 CheckAndSetWrap(S, fWrapS);
5939 CheckAndSetWrap(T, fWrapT);
5940 CheckAndSetWrap(R, fWrapR);
5942 if (ID > 0) then begin
5944 glTexParameteri(Target, GL_TEXTURE_WRAP_S, fWrapS);
5945 glTexParameteri(Target, GL_TEXTURE_WRAP_T, fWrapT);
5946 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
5947 {$IFDEF OPENGL_ES} if GL_VERSION_3_0 then{$ENDIF}
5948 glTexParameteri(Target, GL_TEXTURE_WRAP_R, fWrapR);
5953 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
5954 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5955 procedure TglBitmap.SetSwizzle(const r, g, b, a: GLenum);
5957 procedure CheckAndSetValue(const aValue: GLenum; const aIndex: Integer);
5959 if (aValue = GL_ZERO) or (aValue = GL_ONE) or (aValue = GL_ALPHA) or
5960 (aValue = GL_RED) or (aValue = GL_GREEN) or (aValue = GL_BLUE) then
5961 fSwizzle[aIndex] := aValue
5963 raise EglBitmap.Create('SetSwizzle - Unknow Swizle Value');
5968 if not (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
5969 raise EglBitmapNotSupported.Create('texture swizzle is not supported');
5971 if not GL_VERSION_3_0 then
5972 raise EglBitmapNotSupported.Create('texture swizzle is not supported');
5974 CheckAndSetValue(r, 0);
5975 CheckAndSetValue(g, 1);
5976 CheckAndSetValue(b, 2);
5977 CheckAndSetValue(a, 3);
5979 if (ID > 0) then begin
5982 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_RGBA, PGLint(@fSwizzle[0]));
5984 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_R, PGLint(@fSwizzle[0]));
5985 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_G, PGLint(@fSwizzle[1]));
5986 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_B, PGLint(@fSwizzle[2]));
5987 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_A, PGLint(@fSwizzle[3]));
5993 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5994 procedure TglBitmap.Bind(const aEnableTextureUnit: Boolean);
5996 if aEnableTextureUnit then
5999 glBindTexture(Target, ID);
6002 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6003 procedure TglBitmap.Unbind(const aDisableTextureUnit: Boolean);
6005 if aDisableTextureUnit then
6007 glBindTexture(Target, 0);
6010 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6011 constructor TglBitmap.Create;
6013 if (ClassType = TglBitmap) then
6014 raise EglBitmap.Create('Don''t create TglBitmap directly. Use one of the deviated classes (TglBitmap2D) instead.');
6016 fFormat := glBitmapGetDefaultFormat;
6017 fFreeDataOnDestroy := true;
6020 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6021 constructor TglBitmap.Create(const aFileName: String);
6024 LoadFromFile(aFileName);
6027 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6028 constructor TglBitmap.Create(const aStream: TStream);
6031 LoadFromStream(aStream);
6034 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6035 constructor TglBitmap.Create(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat; aData: PByte);
6040 if not Assigned(aData) then begin
6041 ImageSize := TFormatDescriptor.Get(aFormat).GetSize(aSize);
6042 GetMem(aData, ImageSize);
6044 FillChar(aData^, ImageSize, #$FF);
6045 SetDataPointer(aData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
6047 if Assigned(aData) then
6052 SetDataPointer(aData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
6056 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6057 constructor TglBitmap.Create(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer);
6060 LoadFromFunc(aSize, aFunc, aFormat, aArgs);
6063 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6064 constructor TglBitmap.Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar);
6067 LoadFromResource(aInstance, aResource, aResType);
6070 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6071 constructor TglBitmap.Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
6074 LoadFromResourceID(aInstance, aResourceID, aResType);
6077 {$IFDEF GLB_SUPPORT_PNG_READ}
6078 {$IF DEFINED(GLB_LAZ_PNG)}
6079 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6080 //PNG/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6081 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6082 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6085 PNG_MAGIC: String[MAGIC_LEN] = #$89#$50#$4E#$47#$0D#$0A#$1A#$0A;
6087 reader: TLazReaderPNG;
6088 intf: TLazIntfImage;
6090 magic: String[MAGIC_LEN];
6093 StreamPos := aStream.Position;
6095 SetLength(magic, MAGIC_LEN);
6096 aStream.Read(magic[1], MAGIC_LEN);
6097 aStream.Position := StreamPos;
6098 if (magic <> PNG_MAGIC) then begin
6103 intf := TLazIntfImage.Create(0, 0);
6104 reader := TLazReaderPNG.Create;
6106 reader.UpdateDescription := true;
6107 reader.ImageRead(aStream, intf);
6108 AssignFromLazIntfImage(intf);
6111 aStream.Position := StreamPos;
6120 {$ELSEIF DEFINED(GLB_SDL_IMAGE)}
6121 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6122 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6124 Surface: PSDL_Surface;
6128 RWops := glBitmapCreateRWops(aStream);
6130 if IMG_isPNG(RWops) > 0 then begin
6131 Surface := IMG_LoadPNG_RW(RWops);
6133 AssignFromSurface(Surface);
6136 SDL_FreeSurface(Surface);
6144 {$ELSEIF DEFINED(GLB_LIB_PNG)}
6145 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6146 procedure glBitmap_libPNG_read_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
6148 TStream(png_get_io_ptr(png)).Read(buffer^, size);
6151 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6152 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6155 signature: array [0..7] of byte;
6157 png_info: png_infop;
6159 TempHeight, TempWidth: Integer;
6160 Format: TglBitmapFormat;
6163 png_rows: array of pByte;
6164 Row, LineSize: Integer;
6168 if not init_libPNG then
6169 raise Exception.Create('LoadPNG - unable to initialize libPNG.');
6173 StreamPos := aStream.Position;
6174 aStream.Read(signature{%H-}, 8);
6175 aStream.Position := StreamPos;
6177 if png_check_sig(@signature, 8) <> 0 then begin
6179 png := png_create_read_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
6181 raise EglBitmapException.Create('LoadPng - couldn''t create read struct.');
6184 png_info := png_create_info_struct(png);
6185 if png_info = nil then begin
6186 png_destroy_read_struct(@png, nil, nil);
6187 raise EglBitmapException.Create('LoadPng - couldn''t create info struct.');
6190 // set read callback
6191 png_set_read_fn(png, aStream, glBitmap_libPNG_read_func);
6193 // read informations
6194 png_read_info(png, png_info);
6197 TempHeight := png_get_image_height(png, png_info);
6198 TempWidth := png_get_image_width(png, png_info);
6201 case png_get_color_type(png, png_info) of
6202 PNG_COLOR_TYPE_GRAY:
6203 Format := tfLuminance8ub1;
6204 PNG_COLOR_TYPE_GRAY_ALPHA:
6205 Format := tfLuminance8Alpha8us1;
6207 Format := tfRGB8ub3;
6208 PNG_COLOR_TYPE_RGB_ALPHA:
6209 Format := tfRGBA8ub4;
6211 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
6214 // cut upper 8 bit from 16 bit formats
6215 if png_get_bit_depth(png, png_info) > 8 then
6216 png_set_strip_16(png);
6218 // expand bitdepth smaller than 8
6219 if png_get_bit_depth(png, png_info) < 8 then
6220 png_set_expand(png);
6222 // allocating mem for scanlines
6223 LineSize := png_get_rowbytes(png, png_info);
6224 GetMem(png_data, TempHeight * LineSize);
6226 SetLength(png_rows, TempHeight);
6227 for Row := Low(png_rows) to High(png_rows) do begin
6228 png_rows[Row] := png_data;
6229 Inc(png_rows[Row], Row * LineSize);
6232 // read complete image into scanlines
6233 png_read_image(png, @png_rows[0]);
6236 png_read_end(png, png_info);
6238 // destroy read struct
6239 png_destroy_read_struct(@png, @png_info, nil);
6241 SetLength(png_rows, 0);
6244 SetDataPointer(png_data, Format, TempWidth, TempHeight); //be careful, Data could be freed by this method
6248 if Assigned(png_data) then
6258 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
6259 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6260 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6265 Row, Col, PixSize, LineSize: Integer;
6266 NewImage, pSource, pDest, pAlpha: pByte;
6267 PngFormat: TglBitmapFormat;
6268 FormatDesc: TFormatDescriptor;
6271 PngHeader: String[8] = #137#80#78#71#13#10#26#10;
6276 StreamPos := aStream.Position;
6277 aStream.Read(Header[0], SizeOf(Header));
6278 aStream.Position := StreamPos;
6280 {Test if the header matches}
6281 if Header = PngHeader then begin
6282 Png := TPNGObject.Create;
6284 Png.LoadFromStream(aStream);
6286 case Png.Header.ColorType of
6288 PngFormat := tfLuminance8ub1;
6289 COLOR_GRAYSCALEALPHA:
6290 PngFormat := tfLuminance8Alpha8us1;
6292 PngFormat := tfBGR8ub3;
6294 PngFormat := tfBGRA8ub4;
6296 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
6299 FormatDesc := TFormatDescriptor.Get(PngFormat);
6300 PixSize := Round(FormatDesc.PixelSize);
6301 LineSize := FormatDesc.GetSize(Png.Header.Width, 1);
6303 GetMem(NewImage, LineSize * Integer(Png.Header.Height));
6307 case Png.Header.ColorType of
6308 COLOR_RGB, COLOR_GRAYSCALE:
6310 for Row := 0 to Png.Height -1 do begin
6311 Move (Png.Scanline[Row]^, pDest^, LineSize);
6312 Inc(pDest, LineSize);
6315 COLOR_RGBALPHA, COLOR_GRAYSCALEALPHA:
6317 PixSize := PixSize -1;
6319 for Row := 0 to Png.Height -1 do begin
6320 pSource := Png.Scanline[Row];
6321 pAlpha := pByte(Png.AlphaScanline[Row]);
6323 for Col := 0 to Png.Width -1 do begin
6324 Move (pSource^, pDest^, PixSize);
6325 Inc(pSource, PixSize);
6326 Inc(pDest, PixSize);
6335 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
6338 SetDataPointer(NewImage, PngFormat, Png.Header.Width, Png.Header.Height); //be careful, Data could be freed by this method
6342 if Assigned(NewImage) then
6354 {$IFDEF GLB_SUPPORT_PNG_WRITE}
6355 {$IFDEF GLB_LIB_PNG}
6356 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6357 procedure glBitmap_libPNG_write_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
6359 TStream(png_get_io_ptr(png)).Write(buffer^, size);
6363 {$IF DEFINED(GLB_LAZ_PNG)}
6364 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6365 procedure TglBitmap.SavePNG(const aStream: TStream);
6367 png: TPortableNetworkGraphic;
6368 intf: TLazIntfImage;
6371 png := TPortableNetworkGraphic.Create;
6372 intf := TLazIntfImage.Create(0, 0);
6374 if not AssignToLazIntfImage(intf) then
6375 raise EglBitmap.Create('unable to create LazIntfImage from glBitmap');
6376 intf.GetRawImage(raw);
6377 png.LoadFromRawImage(raw, false);
6378 png.SaveToStream(aStream);
6385 {$ELSEIF DEFINED(GLB_LIB_PNG)}
6386 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6387 procedure TglBitmap.SavePNG(const aStream: TStream);
6390 png_info: png_infop;
6391 png_rows: array of pByte;
6395 FormatDesc: TFormatDescriptor;
6397 if not (ftPNG in FormatGetSupportedFiles(Format)) then
6398 raise EglBitmapUnsupportedFormat.Create(Format);
6400 if not init_libPNG then
6401 raise Exception.Create('unable to initialize libPNG.');
6405 tfAlpha8ub1, tfLuminance8ub1:
6406 ColorType := PNG_COLOR_TYPE_GRAY;
6407 tfLuminance8Alpha8us1:
6408 ColorType := PNG_COLOR_TYPE_GRAY_ALPHA;
6409 tfBGR8ub3, tfRGB8ub3:
6410 ColorType := PNG_COLOR_TYPE_RGB;
6411 tfBGRA8ub4, tfRGBA8ub4:
6412 ColorType := PNG_COLOR_TYPE_RGBA;
6414 raise EglBitmapUnsupportedFormat.Create(Format);
6417 FormatDesc := TFormatDescriptor.Get(Format);
6418 LineSize := FormatDesc.GetSize(Width, 1);
6420 // creating array for scanline
6421 SetLength(png_rows, Height);
6423 for Row := 0 to Height - 1 do begin
6424 png_rows[Row] := Data;
6425 Inc(png_rows[Row], Row * LineSize)
6429 png := png_create_write_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
6431 raise EglBitmapException.Create('SavePng - couldn''t create write struct.');
6434 png_info := png_create_info_struct(png);
6435 if png_info = nil then begin
6436 png_destroy_write_struct(@png, nil);
6437 raise EglBitmapException.Create('SavePng - couldn''t create info struct.');
6440 // set read callback
6441 png_set_write_fn(png, aStream, glBitmap_libPNG_write_func, nil);
6444 png_set_compression_level(png, 6);
6446 if Format in [tfBGR8ub3, tfBGRA8ub4] then
6449 png_set_IHDR(png, png_info, Width, Height, 8, ColorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
6450 png_write_info(png, png_info);
6451 png_write_image(png, @png_rows[0]);
6452 png_write_end(png, png_info);
6453 png_destroy_write_struct(@png, @png_info);
6455 SetLength(png_rows, 0);
6462 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
6463 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6464 procedure TglBitmap.SavePNG(const aStream: TStream);
6468 pSource, pDest: pByte;
6469 X, Y, PixSize: Integer;
6470 ColorType: Cardinal;
6476 if not (ftPNG in FormatGetSupportedFiles (Format)) then
6477 raise EglBitmapUnsupportedFormat.Create(Format);
6480 tfAlpha8ub1, tfLuminance8ub1: begin
6481 ColorType := COLOR_GRAYSCALE;
6485 tfLuminance8Alpha8us1: begin
6486 ColorType := COLOR_GRAYSCALEALPHA;
6490 tfBGR8ub3, tfRGB8ub3: begin
6491 ColorType := COLOR_RGB;
6495 tfBGRA8ub4, tfRGBA8ub4: begin
6496 ColorType := COLOR_RGBALPHA;
6501 raise EglBitmapUnsupportedFormat.Create(Format);
6504 Png := TPNGObject.CreateBlank(ColorType, 8, Width, Height);
6508 for Y := 0 to Height -1 do begin
6509 pDest := png.ScanLine[Y];
6510 for X := 0 to Width -1 do begin
6511 Move(pSource^, pDest^, PixSize);
6512 Inc(pDest, PixSize);
6513 Inc(pSource, PixSize);
6515 png.AlphaScanline[Y]^[X] := pSource^;
6520 // convert RGB line to BGR
6521 if Format in [tfRGB8ub3, tfRGBA8ub4] then begin
6522 pTemp := png.ScanLine[Y];
6523 for X := 0 to Width -1 do begin
6524 Temp := pByteArray(pTemp)^[0];
6525 pByteArray(pTemp)^[0] := pByteArray(pTemp)^[2];
6526 pByteArray(pTemp)^[2] := Temp;
6533 Png.CompressionLevel := 6;
6534 Png.SaveToStream(aStream);
6542 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6543 //JPEG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6544 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6545 {$IFDEF GLB_LIB_JPEG}
6547 glBitmap_libJPEG_source_mgr_ptr = ^glBitmap_libJPEG_source_mgr;
6548 glBitmap_libJPEG_source_mgr = record
6549 pub: jpeg_source_mgr;
6552 SrcBuffer: array [1..4096] of byte;
6555 glBitmap_libJPEG_dest_mgr_ptr = ^glBitmap_libJPEG_dest_mgr;
6556 glBitmap_libJPEG_dest_mgr = record
6557 pub: jpeg_destination_mgr;
6559 DestStream: TStream;
6560 DestBuffer: array [1..4096] of byte;
6563 procedure glBitmap_libJPEG_error_exit(cinfo: j_common_ptr); cdecl;
6569 procedure glBitmap_libJPEG_output_message(cinfo: j_common_ptr); cdecl;
6575 procedure glBitmap_libJPEG_init_source(cinfo: j_decompress_ptr); cdecl;
6580 procedure glBitmap_libJPEG_term_source(cinfo: j_decompress_ptr); cdecl;
6586 procedure glBitmap_libJPEG_init_destination(cinfo: j_compress_ptr); cdecl;
6592 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6593 function glBitmap_libJPEG_fill_input_buffer(cinfo: j_decompress_ptr): boolean; cdecl;
6595 src: glBitmap_libJPEG_source_mgr_ptr;
6598 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
6600 bytes := src^.SrcStream.Read(src^.SrcBuffer[1], 4096);
6601 if (bytes <= 0) then begin
6602 src^.SrcBuffer[1] := $FF;
6603 src^.SrcBuffer[2] := JPEG_EOI;
6607 src^.pub.next_input_byte := @(src^.SrcBuffer[1]);
6608 src^.pub.bytes_in_buffer := bytes;
6613 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6614 procedure glBitmap_libJPEG_skip_input_data(cinfo: j_decompress_ptr; num_bytes: Longint); cdecl;
6616 src: glBitmap_libJPEG_source_mgr_ptr;
6618 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
6620 if num_bytes > 0 then begin
6621 // wanted byte isn't in buffer so set stream position and read buffer
6622 if num_bytes > src^.pub.bytes_in_buffer then begin
6623 src^.SrcStream.Position := src^.SrcStream.Position + num_bytes - src^.pub.bytes_in_buffer;
6624 src^.pub.fill_input_buffer(cinfo);
6626 // wanted byte is in buffer so only skip
6627 inc(src^.pub.next_input_byte, num_bytes);
6628 dec(src^.pub.bytes_in_buffer, num_bytes);
6633 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6634 function glBitmap_libJPEG_empty_output_buffer(cinfo: j_compress_ptr): boolean; cdecl;
6636 dest: glBitmap_libJPEG_dest_mgr_ptr;
6638 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
6640 if dest^.pub.free_in_buffer < Cardinal(Length(dest^.DestBuffer)) then begin
6641 // write complete buffer
6642 dest^.DestStream.Write(dest^.DestBuffer[1], SizeOf(dest^.DestBuffer));
6645 dest^.pub.next_output_byte := @dest^.DestBuffer[1];
6646 dest^.pub.free_in_buffer := Length(dest^.DestBuffer);
6652 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6653 procedure glBitmap_libJPEG_term_destination(cinfo: j_compress_ptr); cdecl;
6656 dest: glBitmap_libJPEG_dest_mgr_ptr;
6658 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
6660 for Idx := Low(dest^.DestBuffer) to High(dest^.DestBuffer) do begin
6661 // check for endblock
6662 if (Idx < High(dest^.DestBuffer)) and (dest^.DestBuffer[Idx] = $FF) and (dest^.DestBuffer[Idx +1] = JPEG_EOI) then begin
6664 dest^.DestStream.Write(dest^.DestBuffer[Idx], 2);
6669 dest^.DestStream.Write(dest^.DestBuffer[Idx], 1);
6674 {$IFDEF GLB_SUPPORT_JPEG_READ}
6675 {$IF DEFINED(GLB_LAZ_JPEG)}
6676 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6677 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6680 JPEG_MAGIC: String[MAGIC_LEN] = #$FF#$D8;
6682 intf: TLazIntfImage;
6683 reader: TFPReaderJPEG;
6685 magic: String[MAGIC_LEN];
6688 StreamPos := aStream.Position;
6690 SetLength(magic, MAGIC_LEN);
6691 aStream.Read(magic[1], MAGIC_LEN);
6692 aStream.Position := StreamPos;
6693 if (magic <> JPEG_MAGIC) then begin
6698 reader := TFPReaderJPEG.Create;
6699 intf := TLazIntfImage.Create(0, 0);
6701 intf.DataDescription := GetDescriptionFromDevice(0, 0, 0);
6702 reader.ImageRead(aStream, intf);
6703 AssignFromLazIntfImage(intf);
6706 aStream.Position := StreamPos;
6715 {$ELSEIF DEFINED(GLB_SDL_IMAGE)}
6716 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6717 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6719 Surface: PSDL_Surface;
6724 RWops := glBitmapCreateRWops(aStream);
6726 if IMG_isJPG(RWops) > 0 then begin
6727 Surface := IMG_LoadJPG_RW(RWops);
6729 AssignFromSurface(Surface);
6732 SDL_FreeSurface(Surface);
6740 {$ELSEIF DEFINED(GLB_LIB_JPEG)}
6741 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6742 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6745 Temp: array[0..1]of Byte;
6747 jpeg: jpeg_decompress_struct;
6748 jpeg_err: jpeg_error_mgr;
6750 IntFormat: TglBitmapFormat;
6752 TempHeight, TempWidth: Integer;
6757 FormatDesc: TFormatDescriptor;
6761 if not init_libJPEG then
6762 raise Exception.Create('LoadJPG - unable to initialize libJPEG.');
6765 // reading first two bytes to test file and set cursor back to begin
6766 StreamPos := aStream.Position;
6767 aStream.Read({%H-}Temp[0], 2);
6768 aStream.Position := StreamPos;
6770 // if Bitmap then read file.
6771 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
6772 FillChar(jpeg{%H-}, SizeOf(jpeg_decompress_struct), $00);
6773 FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
6776 jpeg.err := jpeg_std_error(@jpeg_err);
6777 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
6778 jpeg_err.output_message := glBitmap_libJPEG_output_message;
6780 // decompression struct
6781 jpeg_create_decompress(@jpeg);
6783 // allocation space for streaming methods
6784 jpeg.src := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_source_mgr));
6786 // seeting up custom functions
6787 with glBitmap_libJPEG_source_mgr_ptr(jpeg.src)^ do begin
6788 pub.init_source := glBitmap_libJPEG_init_source;
6789 pub.fill_input_buffer := glBitmap_libJPEG_fill_input_buffer;
6790 pub.skip_input_data := glBitmap_libJPEG_skip_input_data;
6791 pub.resync_to_restart := jpeg_resync_to_restart; // use default method
6792 pub.term_source := glBitmap_libJPEG_term_source;
6794 pub.bytes_in_buffer := 0; // forces fill_input_buffer on first read
6795 pub.next_input_byte := nil; // until buffer loaded
6797 SrcStream := aStream;
6800 // set global decoding state
6801 jpeg.global_state := DSTATE_START;
6803 // read header of jpeg
6804 jpeg_read_header(@jpeg, false);
6806 // setting output parameter
6807 case jpeg.jpeg_color_space of
6810 jpeg.out_color_space := JCS_GRAYSCALE;
6811 IntFormat := tfLuminance8ub1;
6814 jpeg.out_color_space := JCS_RGB;
6815 IntFormat := tfRGB8ub3;
6819 jpeg_start_decompress(@jpeg);
6821 TempHeight := jpeg.output_height;
6822 TempWidth := jpeg.output_width;
6824 FormatDesc := TFormatDescriptor.Get(IntFormat);
6826 // creating new image
6827 GetMem(pImage, FormatDesc.GetSize(TempWidth, TempHeight));
6831 for Row := 0 to TempHeight -1 do begin
6832 jpeg_read_scanlines(@jpeg, @pTemp, 1);
6833 Inc(pTemp, FormatDesc.GetSize(TempWidth, 1));
6836 // finish decompression
6837 jpeg_finish_decompress(@jpeg);
6839 // destroy decompression
6840 jpeg_destroy_decompress(@jpeg);
6842 SetDataPointer(pImage, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
6846 if Assigned(pImage) then
6856 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
6857 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6858 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6863 Temp: array[0..1]of Byte;
6867 // reading first two bytes to test file and set cursor back to begin
6868 StreamPos := aStream.Position;
6869 aStream.Read(Temp[0], 2);
6870 aStream.Position := StreamPos;
6872 // if Bitmap then read file.
6873 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
6874 bmp := TBitmap.Create;
6876 jpg := TJPEGImage.Create;
6878 jpg.LoadFromStream(aStream);
6880 result := AssignFromBitmap(bmp);
6892 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
6893 {$IF DEFINED(GLB_LAZ_JPEG)}
6894 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6895 procedure TglBitmap.SaveJPEG(const aStream: TStream);
6898 intf: TLazIntfImage;
6901 jpeg := TJPEGImage.Create;
6902 intf := TLazIntfImage.Create(0, 0);
6904 if not AssignToLazIntfImage(intf) then
6905 raise EglBitmap.Create('unable to create LazIntfImage from glBitmap');
6906 intf.GetRawImage(raw);
6907 jpeg.LoadFromRawImage(raw, false);
6908 jpeg.SaveToStream(aStream);
6915 {$ELSEIF DEFINED(GLB_LIB_JPEG)}
6916 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6917 procedure TglBitmap.SaveJPEG(const aStream: TStream);
6919 jpeg: jpeg_compress_struct;
6920 jpeg_err: jpeg_error_mgr;
6922 pTemp, pTemp2: pByte;
6924 procedure CopyRow(pDest, pSource: pByte);
6928 for X := 0 to Width - 1 do begin
6929 pByteArray(pDest)^[0] := pByteArray(pSource)^[2];
6930 pByteArray(pDest)^[1] := pByteArray(pSource)^[1];
6931 pByteArray(pDest)^[2] := pByteArray(pSource)^[0];
6938 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
6939 raise EglBitmapUnsupportedFormat.Create(Format);
6941 if not init_libJPEG then
6942 raise Exception.Create('SaveJPG - unable to initialize libJPEG.');
6945 FillChar(jpeg{%H-}, SizeOf(jpeg_compress_struct), $00);
6946 FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
6949 jpeg.err := jpeg_std_error(@jpeg_err);
6950 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
6951 jpeg_err.output_message := glBitmap_libJPEG_output_message;
6953 // compression struct
6954 jpeg_create_compress(@jpeg);
6956 // allocation space for streaming methods
6957 jpeg.dest := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_dest_mgr));
6959 // seeting up custom functions
6960 with glBitmap_libJPEG_dest_mgr_ptr(jpeg.dest)^ do begin
6961 pub.init_destination := glBitmap_libJPEG_init_destination;
6962 pub.empty_output_buffer := glBitmap_libJPEG_empty_output_buffer;
6963 pub.term_destination := glBitmap_libJPEG_term_destination;
6965 pub.next_output_byte := @DestBuffer[1];
6966 pub.free_in_buffer := Length(DestBuffer);
6968 DestStream := aStream;
6971 // very important state
6972 jpeg.global_state := CSTATE_START;
6973 jpeg.image_width := Width;
6974 jpeg.image_height := Height;
6976 tfAlpha8ub1, tfLuminance8ub1: begin
6977 jpeg.input_components := 1;
6978 jpeg.in_color_space := JCS_GRAYSCALE;
6980 tfRGB8ub3, tfBGR8ub3: begin
6981 jpeg.input_components := 3;
6982 jpeg.in_color_space := JCS_RGB;
6986 jpeg_set_defaults(@jpeg);
6987 jpeg_set_quality(@jpeg, 95, true);
6988 jpeg_start_compress(@jpeg, true);
6991 if Format = tfBGR8ub3 then
6992 GetMem(pTemp2, fRowSize)
6997 for Row := 0 to jpeg.image_height -1 do begin
6999 if Format = tfBGR8ub3 then
7000 CopyRow(pTemp2, pTemp)
7005 jpeg_write_scanlines(@jpeg, @pTemp2, 1);
7006 inc(pTemp, fRowSize);
7010 if Format = tfBGR8ub3 then
7013 jpeg_finish_compress(@jpeg);
7014 jpeg_destroy_compress(@jpeg);
7020 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
7021 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7022 procedure TglBitmap.SaveJPEG(const aStream: TStream);
7027 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
7028 raise EglBitmapUnsupportedFormat.Create(Format);
7030 Bmp := TBitmap.Create;
7032 Jpg := TJPEGImage.Create;
7034 AssignToBitmap(Bmp);
7035 if (Format in [tfAlpha8ub1, tfLuminance8ub1]) then begin
7036 Jpg.Grayscale := true;
7037 Jpg.PixelFormat := jf8Bit;
7040 Jpg.SaveToStream(aStream);
7051 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7052 //RAW/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7053 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7055 RawHeader = packed record
7061 BitsPerPixel: Integer;
7062 Precision: TglBitmapRec4ub;
7063 Shift: TglBitmapRec4ub;
7066 function TglBitmap.LoadRAW(const aStream: TStream): Boolean;
7070 fd: TFormatDescriptor;
7074 StartPos := aStream.Position;
7075 aStream.Read(header{%H-}, SizeOf(header));
7076 if (header.Magic <> 'glBMP') then begin
7077 aStream.Position := StartPos;
7081 fd := TFormatDescriptor.GetFromPrecShift(header.Precision, header.Shift, header.BitsPerPixel);
7082 if (fd.Format = tfEmpty) then
7083 raise EglBitmapUnsupportedFormat.Create('no supported format found');
7085 buf := GetMemory(header.DataSize);
7086 aStream.Read(buf^, header.DataSize);
7087 SetDataPointer(buf, fd.Format, header.Width, header.Height);
7092 procedure TglBitmap.SaveRAW(const aStream: TStream);
7095 fd: TFormatDescriptor;
7097 fd := TFormatDescriptor.Get(Format);
7098 header.Magic := 'glBMP';
7099 header.Version := 1;
7100 header.Width := Width;
7101 header.Height := Height;
7102 header.DataSize := fd.GetSize(fDimension);
7103 header.BitsPerPixel := fd.BitsPerPixel;
7104 header.Precision := fd.Precision;
7105 header.Shift := fd.Shift;
7106 aStream.Write(header, SizeOf(header));
7107 aStream.Write(Data^, header.DataSize);
7110 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7111 //BMP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7112 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7119 BMP_COMP_BITFIELDS = 3;
7122 TBMPHeader = packed record
7127 bfOffBits: Cardinal;
7130 TBMPInfo = packed record
7136 biCompression: Cardinal;
7137 biSizeImage: Cardinal;
7138 biXPelsPerMeter: Longint;
7139 biYPelsPerMeter: Longint;
7140 biClrUsed: Cardinal;
7141 biClrImportant: Cardinal;
7144 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7145 function TglBitmap.LoadBMP(const aStream: TStream): Boolean;
7147 //////////////////////////////////////////////////////////////////////////////////////////////////
7148 function ReadInfo(out aInfo: TBMPInfo; out aMask: TglBitmapRec4ul): TglBitmapFormat;
7151 aStream.Read(aInfo{%H-}, SizeOf(aInfo));
7152 FillChar(aMask{%H-}, SizeOf(aMask), 0);
7155 case aInfo.biCompression of
7157 BMP_COMP_RLE8: begin
7158 raise EglBitmap.Create('RLE compression is not supported');
7160 BMP_COMP_BITFIELDS: begin
7161 if (aInfo.biBitCount = 16) or (aInfo.biBitCount = 32) then begin
7162 aStream.Read(aMask.r, SizeOf(aMask.r));
7163 aStream.Read(aMask.g, SizeOf(aMask.g));
7164 aStream.Read(aMask.b, SizeOf(aMask.b));
7165 aStream.Read(aMask.a, SizeOf(aMask.a));
7167 raise EglBitmap.Create('Bitfields are only supported for 16bit and 32bit formats');
7171 //get suitable format
7172 case aInfo.biBitCount of
7173 8: result := tfLuminance8ub1;
7174 16: result := tfX1RGB5us1;
7175 24: result := tfBGR8ub3;
7176 32: result := tfXRGB8ui1;
7180 function ReadColorTable(var aFormat: TglBitmapFormat; const aInfo: TBMPInfo): TbmpColorTableFormat;
7183 ColorTable: TbmpColorTable;
7186 if (aInfo.biBitCount >= 16) then
7188 aFormat := tfLuminance8ub1;
7189 c := aInfo.biClrUsed;
7191 c := 1 shl aInfo.biBitCount;
7192 SetLength(ColorTable, c);
7193 for i := 0 to c-1 do begin
7194 aStream.Read(ColorTable[i], SizeOf(TbmpColorTableEnty));
7195 if (ColorTable[i].r <> ColorTable[i].g) or (ColorTable[i].g <> ColorTable[i].b) then
7196 aFormat := tfRGB8ub3;
7199 result := TbmpColorTableFormat.Create;
7200 result.BitsPerPixel := aInfo.biBitCount;
7201 result.ColorTable := ColorTable;
7205 //////////////////////////////////////////////////////////////////////////////////////////////////
7206 function CheckBitfields(var aFormat: TglBitmapFormat; const aMask: TglBitmapRec4ul; const aInfo: TBMPInfo): TbmpBitfieldFormat;
7208 FormatDesc: TFormatDescriptor;
7211 if (aMask.r <> 0) or (aMask.g <> 0) or (aMask.b <> 0) or (aMask.a <> 0) then begin
7212 FormatDesc := TFormatDescriptor.GetFromMask(aMask);
7213 if (FormatDesc.Format = tfEmpty) then
7215 aFormat := FormatDesc.Format;
7216 if (aMask.a = 0) and TFormatDescriptor.Get(aFormat).HasAlpha then
7217 aFormat := TFormatDescriptor.Get(aFormat).WithoutAlpha;
7218 if (aMask.a <> 0) and not TFormatDescriptor.Get(aFormat).HasAlpha then
7219 aFormat := TFormatDescriptor.Get(aFormat).WithAlpha;
7221 result := TbmpBitfieldFormat.Create;
7222 result.SetCustomValues(aInfo.biBitCount, aMask);
7229 ImageSize, rbLineSize, wbLineSize, Padding, i: Integer;
7230 PaddingBuff: Cardinal;
7231 LineBuf, ImageData, TmpData: PByte;
7232 SourceMD, DestMD: Pointer;
7233 BmpFormat: TglBitmapFormat;
7236 Mask: TglBitmapRec4ul;
7241 SpecialFormat: TFormatDescriptor;
7242 FormatDesc: TFormatDescriptor;
7244 //////////////////////////////////////////////////////////////////////////////////////////////////
7245 procedure SpecialFormatReadLine(aData: PByte; aLineBuf: PByte);
7248 Pixel: TglBitmapPixelData;
7250 aStream.Read(aLineBuf^, rbLineSize);
7251 SpecialFormat.PreparePixel(Pixel);
7252 for i := 0 to Info.biWidth-1 do begin
7253 SpecialFormat.Unmap(aLineBuf, Pixel, SourceMD);
7254 glBitmapConvertPixel(Pixel, SpecialFormat, FormatDesc);
7255 FormatDesc.Map(Pixel, aData, DestMD);
7261 BmpFormat := tfEmpty;
7262 SpecialFormat := nil;
7268 StartPos := aStream.Position;
7269 aStream.Read(Header{%H-}, SizeOf(Header));
7271 if Header.bfType = BMP_MAGIC then begin
7273 BmpFormat := ReadInfo(Info, Mask);
7274 SpecialFormat := ReadColorTable(BmpFormat, Info);
7275 if not Assigned(SpecialFormat) then
7276 SpecialFormat := CheckBitfields(BmpFormat, Mask, Info);
7277 aStream.Position := StartPos + Header.bfOffBits;
7279 if (BmpFormat <> tfEmpty) then begin
7280 FormatDesc := TFormatDescriptor.Get(BmpFormat);
7281 rbLineSize := Round(Info.biWidth * Info.biBitCount / 8); //ReadBuffer LineSize
7282 wbLineSize := Trunc(Info.biWidth * FormatDesc.BytesPerPixel);
7283 Padding := (((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3) - rbLineSize;
7286 DestMD := FormatDesc.CreateMappingData;
7287 ImageSize := FormatDesc.GetSize(Info.biWidth, abs(Info.biHeight));
7288 GetMem(ImageData, ImageSize);
7289 if Assigned(SpecialFormat) then begin
7290 GetMem(LineBuf, rbLineSize); //tmp Memory for converting Bitfields
7291 SourceMD := SpecialFormat.CreateMappingData;
7296 FillChar(ImageData^, ImageSize, $FF);
7297 TmpData := ImageData;
7298 if (Info.biHeight > 0) then
7299 Inc(TmpData, wbLineSize * (Info.biHeight-1));
7300 for i := 0 to Abs(Info.biHeight)-1 do begin
7301 if Assigned(SpecialFormat) then
7302 SpecialFormatReadLine(TmpData, LineBuf) //if is special format read and convert data
7304 aStream.Read(TmpData^, wbLineSize); //else only read data
7305 if (Info.biHeight > 0) then
7306 dec(TmpData, wbLineSize)
7308 inc(TmpData, wbLineSize);
7309 aStream.Read(PaddingBuff{%H-}, Padding);
7311 SetDataPointer(ImageData, BmpFormat, Info.biWidth, abs(Info.biHeight)); //be careful, Data could be freed by this method
7314 if Assigned(LineBuf) then
7316 if Assigned(SourceMD) then
7317 SpecialFormat.FreeMappingData(SourceMD);
7318 FormatDesc.FreeMappingData(DestMD);
7321 if Assigned(ImageData) then
7326 raise EglBitmap.Create('LoadBMP - No suitable format found');
7328 aStream.Position := StartPos;
7332 FreeAndNil(SpecialFormat);
7335 else aStream.Position := StartPos;
7338 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7339 procedure TglBitmap.SaveBMP(const aStream: TStream);
7343 Converter: TFormatDescriptor;
7344 FormatDesc: TFormatDescriptor;
7345 SourceFD, DestFD: Pointer;
7346 pData, srcData, dstData, ConvertBuffer: pByte;
7348 Pixel: TglBitmapPixelData;
7349 ImageSize, wbLineSize, rbLineSize, Padding, LineIdx, PixelIdx: Integer;
7350 RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
7352 PaddingBuff: Cardinal;
7354 function GetLineWidth : Integer;
7356 result := ((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3;
7360 if not (ftBMP in FormatGetSupportedFiles(Format)) then
7361 raise EglBitmapUnsupportedFormat.Create(Format);
7364 FormatDesc := TFormatDescriptor.Get(Format);
7365 ImageSize := FormatDesc.GetSize(Dimension);
7367 FillChar(Header{%H-}, SizeOf(Header), 0);
7368 Header.bfType := BMP_MAGIC;
7369 Header.bfSize := SizeOf(Header) + SizeOf(Info) + ImageSize;
7370 Header.bfReserved1 := 0;
7371 Header.bfReserved2 := 0;
7372 Header.bfOffBits := SizeOf(Header) + SizeOf(Info);
7374 FillChar(Info{%H-}, SizeOf(Info), 0);
7375 Info.biSize := SizeOf(Info);
7376 Info.biWidth := Width;
7377 Info.biHeight := Height;
7379 Info.biCompression := BMP_COMP_RGB;
7380 Info.biSizeImage := ImageSize;
7384 tfAlpha4ub1, tfAlpha8ub1, tfLuminance4ub1, tfLuminance8ub1, tfR3G3B2ub1:
7386 Info.biBitCount := 8;
7387 Header.bfSize := Header.bfSize + 256 * SizeOf(Cardinal);
7388 Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal); //256 ColorTable entries
7389 Converter := TbmpColorTableFormat.Create;
7390 with (Converter as TbmpColorTableFormat) do begin
7391 SetCustomValues(fFormat, 1, FormatDesc.Precision, FormatDesc.Shift);
7396 tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
7397 tfRGBX4us1, tfXRGB4us1, tfRGB5X1us1, tfX1RGB5us1, tfR5G6B5us1, tfRGB5A1us1, tfA1RGB5us1, tfRGBA4us1, tfARGB4us1,
7398 tfBGRX4us1, tfXBGR4us1, tfBGR5X1us1, tfX1BGR5us1, tfB5G6R5us1, tfBGR5A1us1, tfA1BGR5us1, tfBGRA4us1, tfABGR4us1:
7400 Info.biBitCount := 16;
7401 Info.biCompression := BMP_COMP_BITFIELDS;
7404 tfBGR8ub3, tfRGB8ub3:
7406 Info.biBitCount := 24;
7407 if (Format = tfRGB8ub3) then
7408 Converter := TfdBGR8ub3.Create; //use BGR8 Format Descriptor to Swap RGB Values
7411 tfRGBX8ui1, tfXRGB8ui1, tfRGB10X2ui1, tfX2RGB10ui1, tfRGBA8ui1, tfARGB8ui1, tfRGBA8ub4, tfRGB10A2ui1, tfA2RGB10ui1,
7412 tfBGRX8ui1, tfXBGR8ui1, tfBGR10X2ui1, tfX2BGR10ui1, tfBGRA8ui1, tfABGR8ui1, tfBGRA8ub4, tfBGR10A2ui1, tfA2BGR10ui1:
7414 Info.biBitCount := 32;
7415 Info.biCompression := BMP_COMP_BITFIELDS;
7418 raise EglBitmapUnsupportedFormat.Create(Format);
7420 Info.biXPelsPerMeter := 2835;
7421 Info.biYPelsPerMeter := 2835;
7424 if Info.biCompression = BMP_COMP_BITFIELDS then begin
7425 Header.bfSize := Header.bfSize + 4 * SizeOf(Cardinal);
7426 Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal);
7428 RedMask := FormatDesc.Mask.r;
7429 GreenMask := FormatDesc.Mask.g;
7430 BlueMask := FormatDesc.Mask.b;
7431 AlphaMask := FormatDesc.Mask.a;
7435 aStream.Write(Header, SizeOf(Header));
7436 aStream.Write(Info, SizeOf(Info));
7439 if Assigned(Converter) and (Converter is TbmpColorTableFormat) then
7440 with (Converter as TbmpColorTableFormat) do
7441 aStream.Write(ColorTable[0].b,
7442 SizeOf(TbmpColorTableEnty) * Length(ColorTable));
7445 if Info.biCompression = BMP_COMP_BITFIELDS then begin
7446 aStream.Write(RedMask, SizeOf(Cardinal));
7447 aStream.Write(GreenMask, SizeOf(Cardinal));
7448 aStream.Write(BlueMask, SizeOf(Cardinal));
7449 aStream.Write(AlphaMask, SizeOf(Cardinal));
7453 rbLineSize := Round(Info.biWidth * FormatDesc.BytesPerPixel);
7454 wbLineSize := Round(Info.biWidth * Info.biBitCount / 8);
7455 Padding := GetLineWidth - wbLineSize;
7459 inc(pData, (Height-1) * rbLineSize);
7461 // prepare row buffer. But only for RGB because RGBA supports color masks
7462 // so it's possible to change color within the image.
7463 if Assigned(Converter) then begin
7464 FormatDesc.PreparePixel(Pixel);
7465 GetMem(ConvertBuffer, wbLineSize);
7466 SourceFD := FormatDesc.CreateMappingData;
7467 DestFD := Converter.CreateMappingData;
7469 ConvertBuffer := nil;
7472 for LineIdx := 0 to Height - 1 do begin
7474 if Assigned(Converter) then begin
7476 dstData := ConvertBuffer;
7477 for PixelIdx := 0 to Info.biWidth-1 do begin
7478 FormatDesc.Unmap(srcData, Pixel, SourceFD);
7479 glBitmapConvertPixel(Pixel, FormatDesc, Converter);
7480 Converter.Map(Pixel, dstData, DestFD);
7482 aStream.Write(ConvertBuffer^, wbLineSize);
7484 aStream.Write(pData^, rbLineSize);
7486 dec(pData, rbLineSize);
7487 if (Padding > 0) then
7488 aStream.Write(PaddingBuff, Padding);
7491 // destroy row buffer
7492 if Assigned(ConvertBuffer) then begin
7493 FormatDesc.FreeMappingData(SourceFD);
7494 Converter.FreeMappingData(DestFD);
7495 FreeMem(ConvertBuffer);
7499 if Assigned(Converter) then
7504 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7505 //TGA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7506 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7508 TTGAHeader = packed record
7512 //ColorMapSpec: Array[0..4] of Byte;
7513 ColorMapStart: Word;
7514 ColorMapLength: Word;
7515 ColorMapEntrySize: Byte;
7525 TGA_UNCOMPRESSED_RGB = 2;
7526 TGA_UNCOMPRESSED_GRAY = 3;
7527 TGA_COMPRESSED_RGB = 10;
7528 TGA_COMPRESSED_GRAY = 11;
7530 TGA_NONE_COLOR_TABLE = 0;
7532 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7533 function TglBitmap.LoadTGA(const aStream: TStream): Boolean;
7536 ImageData: System.PByte;
7537 StartPosition: Int64;
7538 PixelSize, LineSize: Integer;
7539 tgaFormat: TglBitmapFormat;
7540 FormatDesc: TFormatDescriptor;
7541 Counter: packed record
7543 low, high, dir: Integer;
7550 ////////////////////////////////////////////////////////////////////////////////////////
7551 procedure ReadUncompressed;
7554 buf, tmp1, tmp2: System.PByte;
7557 if (Counter.X.dir < 0) then
7558 GetMem(buf, LineSize);
7560 while (Counter.Y.low <> Counter.Y.high + counter.Y.dir) do begin
7562 inc(tmp1, (Counter.Y.low * LineSize)); //pointer to LineStart
7563 if (Counter.X.dir < 0) then begin //flip X
7564 aStream.Read(buf^, LineSize);
7566 inc(tmp2, LineSize - PixelSize); //pointer to last pixel in line
7567 for i := 0 to Header.Width-1 do begin //for all pixels in line
7568 for j := 0 to PixelSize-1 do begin //for all bytes in pixel
7573 dec(tmp2, 2*PixelSize); //move 2 backwards, because j-loop moved 1 forward
7576 aStream.Read(tmp1^, LineSize);
7577 inc(Counter.Y.low, Counter.Y.dir); //move to next line index
7580 if Assigned(buf) then
7585 ////////////////////////////////////////////////////////////////////////////////////////
7586 procedure ReadCompressed;
7588 /////////////////////////////////////////////////////////////////
7590 TmpData: System.PByte;
7591 LinePixelsRead: Integer;
7592 procedure CheckLine;
7594 if (LinePixelsRead >= Header.Width) then begin
7595 LinePixelsRead := 0;
7596 inc(Counter.Y.low, Counter.Y.dir); //next line index
7597 TmpData := ImageData;
7598 inc(TmpData, Counter.Y.low * LineSize); //set line
7599 if (Counter.X.dir < 0) then //if x flipped then
7600 inc(TmpData, LineSize - PixelSize); //set last pixel
7604 /////////////////////////////////////////////////////////////////
7607 CacheSize, CachePos: Integer;
7608 procedure CachedRead(out Buffer; Count: Integer);
7612 if (CachePos + Count > CacheSize) then begin
7613 //if buffer overflow save non read bytes
7615 if (CacheSize - CachePos > 0) then begin
7616 BytesRead := CacheSize - CachePos;
7617 Move(PByteArray(Cache)^[CachePos], Buffer{%H-}, BytesRead);
7618 inc(CachePos, BytesRead);
7621 //load cache from file
7622 CacheSize := Min(CACHE_SIZE, aStream.Size - aStream.Position);
7623 aStream.Read(Cache^, CacheSize);
7626 //read rest of requested bytes
7627 if (Count - BytesRead > 0) then begin
7628 Move(PByteArray(Cache)^[CachePos], TByteArray(Buffer)[BytesRead], Count - BytesRead);
7629 inc(CachePos, Count - BytesRead);
7632 //if no buffer overflow just read the data
7633 Move(PByteArray(Cache)^[CachePos], Buffer, Count);
7634 inc(CachePos, Count);
7638 procedure PixelToBuffer(const aData: PByte; var aBuffer: PByte);
7643 inc(aBuffer, Counter.X.dir);
7646 PWord(aBuffer)^ := PWord(aData)^;
7647 inc(aBuffer, 2 * Counter.X.dir);
7650 PByteArray(aBuffer)^[0] := PByteArray(aData)^[0];
7651 PByteArray(aBuffer)^[1] := PByteArray(aData)^[1];
7652 PByteArray(aBuffer)^[2] := PByteArray(aData)^[2];
7653 inc(aBuffer, 3 * Counter.X.dir);
7656 PCardinal(aBuffer)^ := PCardinal(aData)^;
7657 inc(aBuffer, 4 * Counter.X.dir);
7663 TotalPixelsToRead, TotalPixelsRead: Integer;
7665 buf: array [0..3] of Byte; //1 pixel is max 32bit long
7666 PixelRepeat: Boolean;
7667 PixelsToRead, PixelCount: Integer;
7672 TotalPixelsToRead := Header.Width * Header.Height;
7673 TotalPixelsRead := 0;
7674 LinePixelsRead := 0;
7676 GetMem(Cache, CACHE_SIZE);
7678 TmpData := ImageData;
7679 inc(TmpData, Counter.Y.low * LineSize); //set line
7680 if (Counter.X.dir < 0) then //if x flipped then
7681 inc(TmpData, LineSize - PixelSize); //set last pixel
7685 CachedRead(Temp, 1);
7686 PixelRepeat := (Temp and $80) > 0;
7687 PixelsToRead := (Temp and $7F) + 1;
7688 inc(TotalPixelsRead, PixelsToRead);
7691 CachedRead(buf[0], PixelSize);
7692 while (PixelsToRead > 0) do begin
7694 PixelCount := Min(Header.Width - LinePixelsRead, PixelsToRead); //max read to EOL or EOF
7695 while (PixelCount > 0) do begin
7696 if not PixelRepeat then
7697 CachedRead(buf[0], PixelSize);
7698 PixelToBuffer(@buf[0], TmpData);
7699 inc(LinePixelsRead);
7704 until (TotalPixelsRead >= TotalPixelsToRead);
7710 function IsGrayFormat: Boolean;
7712 result := Header.ImageType in [TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_GRAY];
7718 // reading header to test file and set cursor back to begin
7719 StartPosition := aStream.Position;
7720 aStream.Read(Header{%H-}, SizeOf(Header));
7722 // no colormapped files
7723 if (Header.ColorMapType = TGA_NONE_COLOR_TABLE) and (Header.ImageType in [
7724 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY]) then
7727 if Header.ImageID <> 0 then // skip image ID
7728 aStream.Position := aStream.Position + Header.ImageID;
7730 tgaFormat := tfEmpty;
7732 8: if IsGrayFormat then case (Header.ImageDesc and $F) of
7733 0: tgaFormat := tfLuminance8ub1;
7734 8: tgaFormat := tfAlpha8ub1;
7737 16: if IsGrayFormat then case (Header.ImageDesc and $F) of
7738 0: tgaFormat := tfLuminance16us1;
7739 8: tgaFormat := tfLuminance8Alpha8ub2;
7740 end else case (Header.ImageDesc and $F) of
7741 0: tgaFormat := tfX1RGB5us1;
7742 1: tgaFormat := tfA1RGB5us1;
7743 4: tgaFormat := tfARGB4us1;
7746 24: if not IsGrayFormat then case (Header.ImageDesc and $F) of
7747 0: tgaFormat := tfBGR8ub3;
7750 32: if IsGrayFormat then case (Header.ImageDesc and $F) of
7751 0: tgaFormat := tfDepth32ui1;
7752 end else case (Header.ImageDesc and $F) of
7753 0: tgaFormat := tfX2RGB10ui1;
7754 2: tgaFormat := tfA2RGB10ui1;
7755 8: tgaFormat := tfARGB8ui1;
7759 if (tgaFormat = tfEmpty) then
7760 raise EglBitmap.Create('LoadTga - unsupported format');
7762 FormatDesc := TFormatDescriptor.Get(tgaFormat);
7763 PixelSize := FormatDesc.GetSize(1, 1);
7764 LineSize := FormatDesc.GetSize(Header.Width, 1);
7766 GetMem(ImageData, LineSize * Header.Height);
7769 if ((Header.ImageDesc and (1 shl 4)) > 0) then begin
7770 Counter.X.low := Header.Height-1;;
7771 Counter.X.high := 0;
7772 Counter.X.dir := -1;
7775 Counter.X.high := Header.Height-1;
7780 if ((Header.ImageDesc and (1 shl 5)) > 0) then begin
7782 Counter.Y.high := Header.Height-1;
7785 Counter.Y.low := Header.Height-1;;
7786 Counter.Y.high := 0;
7787 Counter.Y.dir := -1;
7791 case Header.ImageType of
7792 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY:
7794 TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY:
7798 SetDataPointer(ImageData, tgaFormat, Header.Width, Header.Height); //be careful, Data could be freed by this method
7801 if Assigned(ImageData) then
7806 aStream.Position := StartPosition;
7809 else aStream.Position := StartPosition;
7812 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7813 procedure TglBitmap.SaveTGA(const aStream: TStream);
7817 FormatDesc: TFormatDescriptor;
7819 if not (ftTGA in FormatGetSupportedFiles(Format)) then
7820 raise EglBitmapUnsupportedFormat.Create(Format);
7823 FormatDesc := TFormatDescriptor.Get(Format);
7824 FillChar(Header{%H-}, SizeOf(Header), 0);
7825 Header.ImageDesc := CountSetBits(FormatDesc.Range.a) and $F;
7826 Header.Bpp := FormatDesc.BitsPerPixel;
7827 Header.Width := Width;
7828 Header.Height := Height;
7829 Header.ImageDesc := Header.ImageDesc or $20; //flip y
7830 if FormatDesc.IsGrayscale or (not FormatDesc.IsGrayscale and not FormatDesc.HasRed and FormatDesc.HasAlpha) then
7831 Header.ImageType := TGA_UNCOMPRESSED_GRAY
7833 Header.ImageType := TGA_UNCOMPRESSED_RGB;
7834 aStream.Write(Header, SizeOf(Header));
7837 Size := FormatDesc.GetSize(Dimension);
7838 aStream.Write(Data^, Size);
7841 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7842 //DDS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7843 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7845 DDS_MAGIC: Cardinal = $20534444;
7847 // DDS_header.dwFlags
7848 DDSD_CAPS = $00000001;
7849 DDSD_HEIGHT = $00000002;
7850 DDSD_WIDTH = $00000004;
7851 DDSD_PIXELFORMAT = $00001000;
7853 // DDS_header.sPixelFormat.dwFlags
7854 DDPF_ALPHAPIXELS = $00000001;
7855 DDPF_ALPHA = $00000002;
7856 DDPF_FOURCC = $00000004;
7857 DDPF_RGB = $00000040;
7858 DDPF_LUMINANCE = $00020000;
7860 // DDS_header.sCaps.dwCaps1
7861 DDSCAPS_TEXTURE = $00001000;
7863 // DDS_header.sCaps.dwCaps2
7864 DDSCAPS2_CUBEMAP = $00000200;
7866 D3DFMT_DXT1 = $31545844;
7867 D3DFMT_DXT3 = $33545844;
7868 D3DFMT_DXT5 = $35545844;
7871 TDDSPixelFormat = packed record
7875 dwRGBBitCount: Cardinal;
7876 dwRBitMask: Cardinal;
7877 dwGBitMask: Cardinal;
7878 dwBBitMask: Cardinal;
7879 dwABitMask: Cardinal;
7882 TDDSCaps = packed record
7886 dwReserved: Cardinal;
7889 TDDSHeader = packed record
7894 dwPitchOrLinearSize: Cardinal;
7896 dwMipMapCount: Cardinal;
7897 dwReserved: array[0..10] of Cardinal;
7898 PixelFormat: TDDSPixelFormat;
7900 dwReserved2: Cardinal;
7903 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7904 function TglBitmap.LoadDDS(const aStream: TStream): Boolean;
7907 Converter: TbmpBitfieldFormat;
7909 function GetDDSFormat: TglBitmapFormat;
7911 fd: TFormatDescriptor;
7913 Mask: TglBitmapRec4ul;
7914 Range: TglBitmapRec4ui;
7918 with Header.PixelFormat do begin
7920 if ((dwFlags and DDPF_FOURCC) > 0) then begin
7921 case Header.PixelFormat.dwFourCC of
7922 D3DFMT_DXT1: result := tfS3tcDtx1RGBA;
7923 D3DFMT_DXT3: result := tfS3tcDtx3RGBA;
7924 D3DFMT_DXT5: result := tfS3tcDtx5RGBA;
7926 end else if ((dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE or DDPF_ALPHA)) > 0) then begin
7928 if ((dwFlags and DDPF_LUMINANCE) = 0) then begin
7929 Mask.r := dwRBitMask;
7930 Mask.g := dwGBitMask;
7931 Mask.b := dwBBitMask;
7933 Mask.r := dwRBitMask;
7934 Mask.g := dwRBitMask;
7935 Mask.b := dwRBitMask;
7937 if (dwFlags and DDPF_ALPHAPIXELS > 0) then
7938 Mask.a := dwABitMask
7942 //find matching format
7943 fd := TFormatDescriptor.GetFromMask(Mask, dwRGBBitCount);
7944 result := fd.Format;
7945 if (result <> tfEmpty) then
7948 //find format with same Range
7950 Range.arr[i] := (2 shl CountSetBits(Mask.arr[i])) - 1;
7951 for result := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
7952 fd := TFormatDescriptor.Get(result);
7955 if (fd.Range.arr[i] <> Range.arr[i]) then begin
7963 //no format with same range found -> use default
7964 if (result = tfEmpty) then begin
7965 if (dwABitMask > 0) then
7966 result := tfRGBA8ui1
7968 result := tfRGB8ub3;
7971 Converter := TbmpBitfieldFormat.Create;
7972 Converter.SetCustomValues(dwRGBBitCount, glBitmapRec4ul(dwRBitMask, dwGBitMask, dwBBitMask, dwABitMask));
7979 x, y, LineSize, RowSize, Magic: Cardinal;
7980 NewImage, TmpData, RowData, SrcData: System.PByte;
7981 SourceMD, DestMD: Pointer;
7982 Pixel: TglBitmapPixelData;
7983 ddsFormat: TglBitmapFormat;
7984 FormatDesc: TFormatDescriptor;
7989 StreamPos := aStream.Position;
7992 aStream.Read(Magic{%H-}, sizeof(Magic));
7993 if (Magic <> DDS_MAGIC) then begin
7994 aStream.Position := StreamPos;
7999 aStream.Read(Header{%H-}, sizeof(Header));
8000 if (Header.dwSize <> SizeOf(Header)) or
8001 ((Header.dwFlags and (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) <>
8002 (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) then
8004 aStream.Position := StreamPos;
8008 if ((Header.Caps.dwCaps1 and DDSCAPS2_CUBEMAP) > 0) then
8009 raise EglBitmap.Create('LoadDDS - CubeMaps are not supported');
8011 ddsFormat := GetDDSFormat;
8013 if (ddsFormat = tfEmpty) then
8014 raise EglBitmap.Create('LoadDDS - unsupported Pixelformat found.');
8016 FormatDesc := TFormatDescriptor.Get(ddsFormat);
8017 LineSize := Trunc(Header.dwWidth * FormatDesc.BytesPerPixel);
8018 GetMem(NewImage, Header.dwHeight * LineSize);
8020 TmpData := NewImage;
8023 if Assigned(Converter) then begin
8024 RowSize := Round(Header.dwWidth * Header.PixelFormat.dwRGBBitCount / 8);
8025 GetMem(RowData, RowSize);
8026 SourceMD := Converter.CreateMappingData;
8027 DestMD := FormatDesc.CreateMappingData;
8029 for y := 0 to Header.dwHeight-1 do begin
8030 TmpData := NewImage;
8031 inc(TmpData, y * LineSize);
8033 aStream.Read(SrcData^, RowSize);
8034 for x := 0 to Header.dwWidth-1 do begin
8035 Converter.Unmap(SrcData, Pixel, SourceMD);
8036 glBitmapConvertPixel(Pixel, Converter, FormatDesc);
8037 FormatDesc.Map(Pixel, TmpData, DestMD);
8041 Converter.FreeMappingData(SourceMD);
8042 FormatDesc.FreeMappingData(DestMD);
8048 if ((Header.PixelFormat.dwFlags and DDPF_FOURCC) > 0) then begin
8049 RowSize := Header.dwPitchOrLinearSize div Header.dwWidth;
8050 for Y := 0 to Header.dwHeight-1 do begin
8051 aStream.Read(TmpData^, RowSize);
8052 Inc(TmpData, LineSize);
8057 if (Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE)) > 0 then begin
8058 RowSize := (Header.PixelFormat.dwRGBBitCount * Header.dwWidth) shr 3;
8059 for Y := 0 to Header.dwHeight-1 do begin
8060 aStream.Read(TmpData^, RowSize);
8061 Inc(TmpData, LineSize);
8064 raise EglBitmap.Create('LoadDDS - unsupported Pixelformat found.');
8066 SetDataPointer(NewImage, ddsFormat, Header.dwWidth, Header.dwHeight); //be careful, Data could be freed by this method
8069 if Assigned(NewImage) then
8074 FreeAndNil(Converter);
8078 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8079 procedure TglBitmap.SaveDDS(const aStream: TStream);
8082 FormatDesc: TFormatDescriptor;
8084 if not (ftDDS in FormatGetSupportedFiles(Format)) then
8085 raise EglBitmapUnsupportedFormat.Create(Format);
8087 FormatDesc := TFormatDescriptor.Get(Format);
8090 FillChar(Header{%H-}, SizeOf(Header), 0);
8091 Header.dwSize := SizeOf(Header);
8092 Header.dwFlags := DDSD_WIDTH or DDSD_HEIGHT or DDSD_CAPS or DDSD_PIXELFORMAT;
8094 Header.dwWidth := Max(1, Width);
8095 Header.dwHeight := Max(1, Height);
8098 Header.Caps.dwCaps1 := DDSCAPS_TEXTURE;
8101 Header.PixelFormat.dwSize := sizeof(Header);
8102 if (FormatDesc.IsCompressed) then begin
8103 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_FOURCC;
8105 tfS3tcDtx1RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT1;
8106 tfS3tcDtx3RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT3;
8107 tfS3tcDtx5RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT5;
8109 end else if not FormatDesc.HasColor and FormatDesc.HasAlpha then begin
8110 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHA;
8111 Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
8112 Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
8113 end else if FormatDesc.IsGrayscale then begin
8114 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_LUMINANCE;
8115 Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
8116 Header.PixelFormat.dwRBitMask := FormatDesc.Mask.r;
8117 Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
8119 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_RGB;
8120 Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
8121 Header.PixelFormat.dwRBitMask := FormatDesc.Mask.r;
8122 Header.PixelFormat.dwGBitMask := FormatDesc.Mask.g;
8123 Header.PixelFormat.dwBBitMask := FormatDesc.Mask.b;
8124 Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
8127 if (FormatDesc.HasAlpha) then
8128 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHAPIXELS;
8130 aStream.Write(DDS_MAGIC, sizeof(DDS_MAGIC));
8131 aStream.Write(Header, SizeOf(Header));
8132 aStream.Write(Data^, FormatDesc.GetSize(Dimension));
8136 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8137 //TglBitmap1D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8138 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8139 procedure TglBitmap1D.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
8140 const aWidth: Integer; const aHeight: Integer);
8145 if (aHeight > 1) then begin
8146 Size := TFormatDescriptor.Get(aFormat).GetSize(aWidth, 1);
8147 GetMem(pTemp, Size);
8149 Move(aData^, pTemp^, Size);
8158 inherited SetDataPointer(pTemp, aFormat, aWidth);
8161 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8162 function TglBitmap1D.FlipHorz: Boolean;
8165 pTempDest, pDest, pSource: PByte;
8167 result := inherited FlipHorz;
8168 if Assigned(Data) and not TFormatDescriptor.Get(Format).IsCompressed then begin
8170 GetMem(pDest, fRowSize);
8173 Inc(pTempDest, fRowSize);
8174 for Col := 0 to Width-1 do begin
8175 dec(pTempDest, fPixelSize); //dec before, because ptr is behind last byte of data
8176 Move(pSource^, pTempDest^, fPixelSize);
8177 Inc(pSource, fPixelSize);
8179 SetDataPointer(pDest, Format, Width); //be careful, Data could be freed by this method
8182 if Assigned(pDest) then
8189 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8190 procedure TglBitmap1D.UploadData(const aBuildWithGlu: Boolean);
8192 FormatDesc: TFormatDescriptor;
8195 FormatDesc := TFormatDescriptor.Get(Format);
8196 if (FormatDesc.glInternalFormat = 0) or (FormatDesc.glDataFormat = 0) then
8197 raise EglBitmap.Create('format is not supported by video adapter, please convert before uploading data');
8199 if FormatDesc.IsCompressed then begin
8200 if not Assigned(glCompressedTexImage1D) then
8201 raise EglBitmap.Create('compressed formats not supported by video adapter');
8202 glCompressedTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.GetSize(Width, 1), Data)
8203 end else if aBuildWithGlu then
8204 gluBuild1DMipmaps(Target, FormatDesc.glInternalFormat, Width, FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
8206 glTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
8209 if (FreeDataAfterGenTexture) then
8213 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8214 procedure TglBitmap1D.GenTexture(const aTestTextureSize: Boolean);
8216 BuildWithGlu, TexRec: Boolean;
8219 if Assigned(Data) then begin
8220 // Check Texture Size
8221 if (aTestTextureSize) then begin
8222 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
8224 if (Width > TexSize) then
8225 raise EglBitmapSizeToLarge.Create('TglBitmap1D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
8227 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and
8228 (Target = GL_TEXTURE_RECTANGLE);
8229 if not (IsPowerOfTwo(Width) or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
8230 raise EglBitmapNonPowerOfTwo.Create('TglBitmap1D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8234 SetupParameters(BuildWithGlu);
8235 UploadData(BuildWithGlu);
8236 glAreTexturesResident(1, @fID, @fIsResident);
8240 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8241 procedure TglBitmap1D.AfterConstruction;
8244 Target := GL_TEXTURE_1D;
8248 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8249 //TglBitmap2D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8250 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8251 function TglBitmap2D.GetScanline(const aIndex: Integer): Pointer;
8253 if (aIndex >= Low(fLines)) and (aIndex <= High(fLines)) then
8254 result := fLines[aIndex]
8259 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8260 procedure TglBitmap2D.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
8261 const aWidth: Integer; const aHeight: Integer);
8263 Idx, LineWidth: Integer;
8265 inherited SetDataPointer(aData, aFormat, aWidth, aHeight);
8267 if not TFormatDescriptor.Get(aFormat).IsCompressed then begin
8269 if Assigned(Data) then begin
8270 SetLength(fLines, GetHeight);
8271 LineWidth := Trunc(GetWidth * TFormatDescriptor.Get(Format).BytesPerPixel);
8273 for Idx := 0 to GetHeight-1 do begin
8274 fLines[Idx] := Data;
8275 Inc(fLines[Idx], Idx * LineWidth);
8278 else SetLength(fLines, 0);
8280 SetLength(fLines, 0);
8284 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8285 procedure TglBitmap2D.UploadData(const aTarget: GLenum{$IFNDEF OPENGL_ES}; const aBuildWithGlu: Boolean{$ENDIF});
8287 FormatDesc: TFormatDescriptor;
8289 FormatDesc := TFormatDescriptor.Get(Format);
8290 if (FormatDesc.glInternalFormat = 0) or (FormatDesc.glDataFormat = 0) then
8291 raise EglBitmap.Create('format is not supported by video adapter, please convert before uploading data');
8293 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
8295 if FormatDesc.IsCompressed then begin
8296 if not Assigned(glCompressedTexImage2D) then
8297 raise EglBitmap.Create('compressed formats not supported by video adapter');
8298 glCompressedTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0, FormatDesc.GetSize(fDimension), Data)
8300 end else if aBuildWithGlu then begin
8301 gluBuild2DMipmaps(aTarget, FormatDesc.ChannelCount, Width, Height,
8302 FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
8305 glTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0,
8306 FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
8310 if (FreeDataAfterGenTexture) then
8314 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8315 procedure TglBitmap2D.AfterConstruction;
8318 Target := GL_TEXTURE_2D;
8321 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8322 procedure TglBitmap2D.GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
8325 Size, w, h: Integer;
8326 FormatDesc: TFormatDescriptor;
8328 FormatDesc := TFormatDescriptor.Get(aFormat);
8329 if FormatDesc.IsCompressed then
8330 raise EglBitmapUnsupportedFormat.Create(aFormat);
8332 w := aRight - aLeft;
8333 h := aBottom - aTop;
8334 Size := FormatDesc.GetSize(w, h);
8337 glPixelStorei(GL_PACK_ALIGNMENT, 1);
8338 glReadPixels(aLeft, aTop, w, h, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
8339 SetDataPointer(Temp, aFormat, w, h); //be careful, Data could be freed by this method
8342 if Assigned(Temp) then
8349 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8350 procedure TglBitmap2D.GetDataFromTexture;
8353 TempWidth, TempHeight: Integer;
8354 TempIntFormat: GLint;
8355 IntFormat: TglBitmapFormat;
8356 FormatDesc: TFormatDescriptor;
8361 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_WIDTH, @TempWidth);
8362 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT, @TempHeight);
8363 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat);
8365 FormatDesc := (TglBitmapFormatDescriptor.GetByFormat(TempIntFormat) as TFormatDescriptor);
8366 IntFormat := FormatDesc.Format;
8368 // Getting data from OpenGL
8369 FormatDesc := TFormatDescriptor.Get(IntFormat);
8370 GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight));
8372 if FormatDesc.IsCompressed then begin
8373 if not Assigned(glGetCompressedTexImage) then
8374 raise EglBitmap.Create('compressed formats not supported by video adapter');
8375 glGetCompressedTexImage(Target, 0, Temp)
8377 glGetTexImage(Target, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
8378 SetDataPointer(Temp, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
8380 if Assigned(Temp) then
8387 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8388 procedure TglBitmap2D.GenTexture(const aTestTextureSize: Boolean);
8391 BuildWithGlu, TexRec: Boolean;
8396 if Assigned(Data) then begin
8397 // Check Texture Size
8398 if (aTestTextureSize) then begin
8399 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
8401 if ((Height > TexSize) or (Width > TexSize)) then
8402 raise EglBitmapSizeToLarge.Create('TglBitmap2D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
8404 PotTex := IsPowerOfTwo(Height) and IsPowerOfTwo(Width);
8405 {$IF NOT DEFINED(OPENGL_ES)}
8406 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and (Target = GL_TEXTURE_RECTANGLE);
8407 if not (PotTex or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
8408 raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8409 {$ELSEIF DEFINED(OPENGL_ES_EXT)}
8410 if not PotTex and not GL_OES_texture_npot then
8411 raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8414 raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8419 SetupParameters({$IFNDEF OPENGL_ES}BuildWithGlu{$ENDIF});
8420 UploadData(Target{$IFNDEF OPENGL_ES}, BuildWithGlu{$ENDIF});
8422 glAreTexturesResident(1, @fID, @fIsResident);
8427 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8428 function TglBitmap2D.FlipHorz: Boolean;
8431 TempDestData, DestData, SourceData: PByte;
8434 result := inherited FlipHorz;
8435 if Assigned(Data) then begin
8437 ImgSize := Height * fRowSize;
8438 GetMem(DestData, ImgSize);
8440 TempDestData := DestData;
8441 Dec(TempDestData, fRowSize + fPixelSize);
8442 for Row := 0 to Height -1 do begin
8443 Inc(TempDestData, fRowSize * 2);
8444 for Col := 0 to Width -1 do begin
8445 Move(SourceData^, TempDestData^, fPixelSize);
8446 Inc(SourceData, fPixelSize);
8447 Dec(TempDestData, fPixelSize);
8450 SetDataPointer(DestData, Format, Width, Height); //be careful, Data could be freed by this method
8453 if Assigned(DestData) then
8460 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8461 function TglBitmap2D.FlipVert: Boolean;
8464 TempDestData, DestData, SourceData: PByte;
8466 result := inherited FlipVert;
8467 if Assigned(Data) then begin
8469 GetMem(DestData, Height * fRowSize);
8471 TempDestData := DestData;
8472 Inc(TempDestData, Width * (Height -1) * fPixelSize);
8473 for Row := 0 to Height -1 do begin
8474 Move(SourceData^, TempDestData^, fRowSize);
8475 Dec(TempDestData, fRowSize);
8476 Inc(SourceData, fRowSize);
8478 SetDataPointer(DestData, Format, Width, Height); //be careful, Data could be freed by this method
8481 if Assigned(DestData) then
8488 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8489 //TglBitmap2D - ToNormalMap///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8490 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8492 TMatrixItem = record
8497 PglBitmapToNormalMapRec = ^TglBitmapToNormalMapRec;
8498 TglBitmapToNormalMapRec = Record
8500 Heights: array of Single;
8501 MatrixU : array of TMatrixItem;
8502 MatrixV : array of TMatrixItem;
8506 ONE_OVER_255 = 1 / 255;
8508 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8509 procedure glBitmapToNormalMapPrepareFunc(var FuncRec: TglBitmapFunctionRec);
8513 with FuncRec do begin
8515 Source.Data.r * LUMINANCE_WEIGHT_R +
8516 Source.Data.g * LUMINANCE_WEIGHT_G +
8517 Source.Data.b * LUMINANCE_WEIGHT_B;
8518 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Val * ONE_OVER_255;
8522 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8523 procedure glBitmapToNormalMapPrepareAlphaFunc(var FuncRec: TglBitmapFunctionRec);
8526 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Source.Data.a * ONE_OVER_255;
8529 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8530 procedure glBitmapToNormalMapFunc (var FuncRec: TglBitmapFunctionRec);
8532 TVec = Array[0..2] of Single;
8539 function GetHeight(X, Y: Integer): Single;
8541 with FuncRec do begin
8542 X := Max(0, Min(Size.X -1, X));
8543 Y := Max(0, Min(Size.Y -1, Y));
8544 result := PglBitmapToNormalMapRec(Args)^.Heights[Y * Size.X + X];
8549 with FuncRec do begin
8550 with PglBitmapToNormalMapRec(Args)^ do begin
8552 for Idx := Low(MatrixU) to High(MatrixU) do
8553 du := du + GetHeight(Position.X + MatrixU[Idx].X, Position.Y + MatrixU[Idx].Y) * MatrixU[Idx].W;
8556 for Idx := Low(MatrixU) to High(MatrixU) do
8557 dv := dv + GetHeight(Position.X + MatrixV[Idx].X, Position.Y + MatrixV[Idx].Y) * MatrixV[Idx].W;
8559 Vec[0] := -du * Scale;
8560 Vec[1] := -dv * Scale;
8565 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
8566 if Len <> 0 then begin
8567 Vec[0] := Vec[0] * Len;
8568 Vec[1] := Vec[1] * Len;
8569 Vec[2] := Vec[2] * Len;
8573 Dest.Data.r := Trunc((Vec[0] + 1) * 127.5);
8574 Dest.Data.g := Trunc((Vec[1] + 1) * 127.5);
8575 Dest.Data.b := Trunc((Vec[2] + 1) * 127.5);
8579 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8580 procedure TglBitmap2D.GenerateNormalMap(const aFunc: TglBitmapNormalMapFunc; const aScale: Single; const aUseAlpha: Boolean);
8582 Rec: TglBitmapToNormalMapRec;
8584 procedure SetEntry (var Matrix: array of TMatrixItem; Index, X, Y: Integer; W: Single);
8586 if (Index >= Low(Matrix)) and (Index <= High(Matrix)) then begin
8587 Matrix[Index].X := X;
8588 Matrix[Index].Y := Y;
8589 Matrix[Index].W := W;
8594 if TFormatDescriptor.Get(Format).IsCompressed then
8595 raise EglBitmapUnsupportedFormat.Create(Format);
8597 if aScale > 100 then
8599 else if aScale < -100 then
8602 Rec.Scale := aScale;
8604 SetLength(Rec.Heights, Width * Height);
8608 SetLength(Rec.MatrixU, 2);
8609 SetEntry(Rec.MatrixU, 0, -1, 0, -0.5);
8610 SetEntry(Rec.MatrixU, 1, 1, 0, 0.5);
8612 SetLength(Rec.MatrixV, 2);
8613 SetEntry(Rec.MatrixV, 0, 0, 1, 0.5);
8614 SetEntry(Rec.MatrixV, 1, 0, -1, -0.5);
8618 SetLength(Rec.MatrixU, 6);
8619 SetEntry(Rec.MatrixU, 0, -1, 1, -1.0);
8620 SetEntry(Rec.MatrixU, 1, -1, 0, -2.0);
8621 SetEntry(Rec.MatrixU, 2, -1, -1, -1.0);
8622 SetEntry(Rec.MatrixU, 3, 1, 1, 1.0);
8623 SetEntry(Rec.MatrixU, 4, 1, 0, 2.0);
8624 SetEntry(Rec.MatrixU, 5, 1, -1, 1.0);
8626 SetLength(Rec.MatrixV, 6);
8627 SetEntry(Rec.MatrixV, 0, -1, 1, 1.0);
8628 SetEntry(Rec.MatrixV, 1, 0, 1, 2.0);
8629 SetEntry(Rec.MatrixV, 2, 1, 1, 1.0);
8630 SetEntry(Rec.MatrixV, 3, -1, -1, -1.0);
8631 SetEntry(Rec.MatrixV, 4, 0, -1, -2.0);
8632 SetEntry(Rec.MatrixV, 5, 1, -1, -1.0);
8636 SetLength(Rec.MatrixU, 6);
8637 SetEntry(Rec.MatrixU, 0, -1, 1, -1/6);
8638 SetEntry(Rec.MatrixU, 1, -1, 0, -1/6);
8639 SetEntry(Rec.MatrixU, 2, -1, -1, -1/6);
8640 SetEntry(Rec.MatrixU, 3, 1, 1, 1/6);
8641 SetEntry(Rec.MatrixU, 4, 1, 0, 1/6);
8642 SetEntry(Rec.MatrixU, 5, 1, -1, 1/6);
8644 SetLength(Rec.MatrixV, 6);
8645 SetEntry(Rec.MatrixV, 0, -1, 1, 1/6);
8646 SetEntry(Rec.MatrixV, 1, 0, 1, 1/6);
8647 SetEntry(Rec.MatrixV, 2, 1, 1, 1/6);
8648 SetEntry(Rec.MatrixV, 3, -1, -1, -1/6);
8649 SetEntry(Rec.MatrixV, 4, 0, -1, -1/6);
8650 SetEntry(Rec.MatrixV, 5, 1, -1, -1/6);
8654 SetLength(Rec.MatrixU, 20);
8655 SetEntry(Rec.MatrixU, 0, -2, 2, -1 / 16);
8656 SetEntry(Rec.MatrixU, 1, -1, 2, -1 / 10);
8657 SetEntry(Rec.MatrixU, 2, 1, 2, 1 / 10);
8658 SetEntry(Rec.MatrixU, 3, 2, 2, 1 / 16);
8659 SetEntry(Rec.MatrixU, 4, -2, 1, -1 / 10);
8660 SetEntry(Rec.MatrixU, 5, -1, 1, -1 / 8);
8661 SetEntry(Rec.MatrixU, 6, 1, 1, 1 / 8);
8662 SetEntry(Rec.MatrixU, 7, 2, 1, 1 / 10);
8663 SetEntry(Rec.MatrixU, 8, -2, 0, -1 / 2.8);
8664 SetEntry(Rec.MatrixU, 9, -1, 0, -0.5);
8665 SetEntry(Rec.MatrixU, 10, 1, 0, 0.5);
8666 SetEntry(Rec.MatrixU, 11, 2, 0, 1 / 2.8);
8667 SetEntry(Rec.MatrixU, 12, -2, -1, -1 / 10);
8668 SetEntry(Rec.MatrixU, 13, -1, -1, -1 / 8);
8669 SetEntry(Rec.MatrixU, 14, 1, -1, 1 / 8);
8670 SetEntry(Rec.MatrixU, 15, 2, -1, 1 / 10);
8671 SetEntry(Rec.MatrixU, 16, -2, -2, -1 / 16);
8672 SetEntry(Rec.MatrixU, 17, -1, -2, -1 / 10);
8673 SetEntry(Rec.MatrixU, 18, 1, -2, 1 / 10);
8674 SetEntry(Rec.MatrixU, 19, 2, -2, 1 / 16);
8676 SetLength(Rec.MatrixV, 20);
8677 SetEntry(Rec.MatrixV, 0, -2, 2, 1 / 16);
8678 SetEntry(Rec.MatrixV, 1, -1, 2, 1 / 10);
8679 SetEntry(Rec.MatrixV, 2, 0, 2, 0.25);
8680 SetEntry(Rec.MatrixV, 3, 1, 2, 1 / 10);
8681 SetEntry(Rec.MatrixV, 4, 2, 2, 1 / 16);
8682 SetEntry(Rec.MatrixV, 5, -2, 1, 1 / 10);
8683 SetEntry(Rec.MatrixV, 6, -1, 1, 1 / 8);
8684 SetEntry(Rec.MatrixV, 7, 0, 1, 0.5);
8685 SetEntry(Rec.MatrixV, 8, 1, 1, 1 / 8);
8686 SetEntry(Rec.MatrixV, 9, 2, 1, 1 / 16);
8687 SetEntry(Rec.MatrixV, 10, -2, -1, -1 / 16);
8688 SetEntry(Rec.MatrixV, 11, -1, -1, -1 / 8);
8689 SetEntry(Rec.MatrixV, 12, 0, -1, -0.5);
8690 SetEntry(Rec.MatrixV, 13, 1, -1, -1 / 8);
8691 SetEntry(Rec.MatrixV, 14, 2, -1, -1 / 10);
8692 SetEntry(Rec.MatrixV, 15, -2, -2, -1 / 16);
8693 SetEntry(Rec.MatrixV, 16, -1, -2, -1 / 10);
8694 SetEntry(Rec.MatrixV, 17, 0, -2, -0.25);
8695 SetEntry(Rec.MatrixV, 18, 1, -2, -1 / 10);
8696 SetEntry(Rec.MatrixV, 19, 2, -2, -1 / 16);
8701 if aUseAlpha and TFormatDescriptor.Get(Format).HasAlpha then
8702 Convert(glBitmapToNormalMapPrepareAlphaFunc, false, @Rec)
8704 Convert(glBitmapToNormalMapPrepareFunc, false, @Rec);
8705 Convert(glBitmapToNormalMapFunc, false, @Rec);
8707 SetLength(Rec.Heights, 0);
8711 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
8712 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8713 //TglBitmapCubeMap////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8714 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8715 procedure TglBitmapCubeMap.GenTexture(const aTestTextureSize: Boolean);
8717 Assert(false, 'TglBitmapCubeMap.GenTexture - Don''t call GenTextures directly.');
8720 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8721 procedure TglBitmapCubeMap.AfterConstruction;
8726 if not (GL_VERSION_1_3 or GL_ARB_texture_cube_map or GL_EXT_texture_cube_map) then
8727 raise EglBitmap.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
8729 if not (GL_VERSION_2_0) then
8730 raise EglBitmap.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
8734 Target := GL_TEXTURE_CUBE_MAP;
8736 fGenMode := GL_REFLECTION_MAP;
8740 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8741 procedure TglBitmapCubeMap.GenerateCubeMap(const aCubeTarget: Cardinal; const aTestTextureSize: Boolean);
8744 BuildWithGlu: Boolean;
8748 if (aTestTextureSize) then begin
8749 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, @TexSize);
8751 if (Height > TexSize) or (Width > TexSize) then
8752 raise EglBitmapSizeToLarge.Create('TglBitmapCubeMap.GenerateCubeMap - The size for the Cubemap is to large. It''s may be not conform with the Hardware.');
8754 {$IF NOT DEFINED(OPENGL_ES)}
8755 if not ((IsPowerOfTwo(Height) and IsPowerOfTwo(Width)) or GL_VERSION_2_0 or GL_ARB_texture_non_power_of_two) then
8756 raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenerateCubeMap - Cubemaps dosn''t support non power of two texture.');
8757 {$ELSEIF DEFINED(OPENGL_ES_EXT)}
8758 if not (IsPowerOfTwo(Height) and IsPowerOfTwo(Width)) and not GL_OES_texture_npot then
8759 raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenerateCubeMap - Cubemaps dosn''t support non power of two texture.');
8761 if not (IsPowerOfTwo(Height) and IsPowerOfTwo(Width)) then
8762 raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenerateCubeMap - Cubemaps dosn''t support non power of two texture.');
8768 SetupParameters({$IFNDEF OPENGL_ES}BuildWithGlu{$ENDIF});
8769 UploadData(aCubeTarget{$IFNDEF OPENGL_ES}, BuildWithGlu{$ENDIF});
8772 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8773 procedure TglBitmapCubeMap.Bind({$IFNDEF OPENGL_ES}const aEnableTexCoordsGen: Boolean;{$ENDIF} const aEnableTextureUnit: Boolean);
8775 inherited Bind (aEnableTextureUnit);
8777 if aEnableTexCoordsGen then begin
8778 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, fGenMode);
8779 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, fGenMode);
8780 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, fGenMode);
8781 glEnable(GL_TEXTURE_GEN_S);
8782 glEnable(GL_TEXTURE_GEN_T);
8783 glEnable(GL_TEXTURE_GEN_R);
8788 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8789 procedure TglBitmapCubeMap.Unbind({$IFNDEF OPENGL_ES}const aDisableTexCoordsGen: Boolean;{$ENDIF} const aDisableTextureUnit: Boolean);
8791 inherited Unbind(aDisableTextureUnit);
8793 if aDisableTexCoordsGen then begin
8794 glDisable(GL_TEXTURE_GEN_S);
8795 glDisable(GL_TEXTURE_GEN_T);
8796 glDisable(GL_TEXTURE_GEN_R);
8802 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
8803 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8804 //TglBitmapNormalMap//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8805 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8807 TVec = Array[0..2] of Single;
8808 TglBitmapNormalMapGetVectorFunc = procedure (out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8810 PglBitmapNormalMapRec = ^TglBitmapNormalMapRec;
8811 TglBitmapNormalMapRec = record
8813 Func: TglBitmapNormalMapGetVectorFunc;
8816 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8817 procedure glBitmapNormalMapPosX(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8819 aVec[0] := aHalfSize;
8820 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8821 aVec[2] := - (aPosition.X + 0.5 - aHalfSize);
8824 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8825 procedure glBitmapNormalMapNegX(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8827 aVec[0] := - aHalfSize;
8828 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8829 aVec[2] := aPosition.X + 0.5 - aHalfSize;
8832 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8833 procedure glBitmapNormalMapPosY(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8835 aVec[0] := aPosition.X + 0.5 - aHalfSize;
8836 aVec[1] := aHalfSize;
8837 aVec[2] := aPosition.Y + 0.5 - aHalfSize;
8840 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8841 procedure glBitmapNormalMapNegY(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8843 aVec[0] := aPosition.X + 0.5 - aHalfSize;
8844 aVec[1] := - aHalfSize;
8845 aVec[2] := - (aPosition.Y + 0.5 - aHalfSize);
8848 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8849 procedure glBitmapNormalMapPosZ(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8851 aVec[0] := aPosition.X + 0.5 - aHalfSize;
8852 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8853 aVec[2] := aHalfSize;
8856 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8857 procedure glBitmapNormalMapNegZ(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8859 aVec[0] := - (aPosition.X + 0.5 - aHalfSize);
8860 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8861 aVec[2] := - aHalfSize;
8864 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8865 procedure glBitmapNormalMapFunc(var FuncRec: TglBitmapFunctionRec);
8871 with FuncRec do begin
8872 with PglBitmapNormalMapRec(Args)^ do begin
8873 Func(Vec, Position, HalfSize);
8876 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
8877 if Len <> 0 then begin
8878 Vec[0] := Vec[0] * Len;
8879 Vec[1] := Vec[1] * Len;
8880 Vec[2] := Vec[2] * Len;
8883 // Scale Vector and AddVectro
8884 Vec[0] := Vec[0] * 0.5 + 0.5;
8885 Vec[1] := Vec[1] * 0.5 + 0.5;
8886 Vec[2] := Vec[2] * 0.5 + 0.5;
8891 Dest.Data.arr[i] := Round(Vec[i] * 255);
8895 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8896 procedure TglBitmapNormalMap.AfterConstruction;
8900 fGenMode := GL_NORMAL_MAP;
8904 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8905 procedure TglBitmapNormalMap.GenerateNormalMap(const aSize: Integer; const aTestTextureSize: Boolean);
8907 Rec: TglBitmapNormalMapRec;
8908 SizeRec: TglBitmapSize;
8910 Rec.HalfSize := aSize div 2;
8911 FreeDataAfterGenTexture := false;
8913 SizeRec.Fields := [ffX, ffY];
8918 Rec.Func := glBitmapNormalMapPosX;
8919 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
8920 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X, aTestTextureSize);
8923 Rec.Func := glBitmapNormalMapNegX;
8924 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
8925 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, aTestTextureSize);
8928 Rec.Func := glBitmapNormalMapPosY;
8929 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
8930 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, aTestTextureSize);
8933 Rec.Func := glBitmapNormalMapNegY;
8934 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
8935 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, aTestTextureSize);
8938 Rec.Func := glBitmapNormalMapPosZ;
8939 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
8940 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, aTestTextureSize);
8943 Rec.Func := glBitmapNormalMapNegZ;
8944 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
8945 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, aTestTextureSize);
8950 glBitmapSetDefaultFormat (tfEmpty);
8951 glBitmapSetDefaultMipmap (mmMipmap);
8952 glBitmapSetDefaultFilter (GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
8953 glBitmapSetDefaultWrap (GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
8954 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
8955 glBitmapSetDefaultSwizzle(GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA);
8958 glBitmapSetDefaultFreeDataAfterGenTexture(true);
8959 glBitmapSetDefaultDeleteTextureOnFree (true);
8961 TFormatDescriptor.Init;
8964 TFormatDescriptor.Finalize;