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, ...) }
44 {$IF DEFINED(WIN32) or DEFINED(WIN64) or DEFINED(WINDOWS)}
46 {$ELSEIF DEFINED(LINUX)}
51 {$IF DEFINED(OPENGL_ES_EXT)} {$DEFINE OPENGL_ES_1_1} {$IFEND}
52 {$IF DEFINED(OPENGL_ES_3_0)} {$DEFINE OPENGL_ES_2_0} {$IFEND}
53 {$IF DEFINED(OPENGL_ES_2_0)} {$DEFINE OPENGL_ES_1_1} {$IFEND}
54 {$IF DEFINED(OPENGL_ES_1_1)} {$DEFINE OPENGL_ES} {$IFEND}
56 // checking define combinations
58 {$IFDEF GLB_SDL_IMAGE}
60 {$MESSAGE warn 'SDL_image won''t work without SDL. SDL will be activated.'}
65 {$MESSAGE warn 'The Lazarus TPortableNetworkGraphics will be ignored because you are using SDL_image.'}
70 {$MESSAGE warn 'The unit pngimage will be ignored because you are using SDL_image.'}
75 {$MESSAGE warn 'The Lazarus TJPEGImage will be ignored because you are using SDL_image.'}
79 {$IFDEF GLB_DELPHI_JPEG}
80 {$MESSAGE warn 'The unit JPEG will be ignored because you are using SDL_image.'}
81 {$undef GLB_DELPHI_JPEG}
85 {$MESSAGE warn 'The library libPNG will be ignored because you are using SDL_image.'}
90 {$MESSAGE warn 'The library libJPEG will be ignored because you are using SDL_image.'}
94 {$DEFINE GLB_SUPPORT_PNG_READ}
95 {$DEFINE GLB_SUPPORT_JPEG_READ}
98 // Lazarus TPortableNetworkGraphic
100 {$IFNDEF GLB_LAZARUS}
101 {$MESSAGE warn 'Lazarus TPortableNetworkGraphic won''t work without Lazarus. Lazarus will be activated.'}
102 {$DEFINE GLB_LAZARUS}
105 {$IFDEF GLB_PNGIMAGE}
106 {$MESSAGE warn 'The pngimage will be ignored if you are using Lazarus TPortableNetworkGraphic.'}
107 {$undef GLB_PNGIMAGE}
111 {$MESSAGE warn 'The library libPNG will be ignored if you are using Lazarus TPortableNetworkGraphic.'}
115 {$DEFINE GLB_SUPPORT_PNG_READ}
116 {$DEFINE GLB_SUPPORT_PNG_WRITE}
120 {$IFDEF GLB_PNGIMAGE}
122 {$MESSAGE warn 'The library libPNG will be ignored if you are using pngimage.'}
126 {$DEFINE GLB_SUPPORT_PNG_READ}
127 {$DEFINE GLB_SUPPORT_PNG_WRITE}
132 {$DEFINE GLB_SUPPORT_PNG_READ}
133 {$DEFINE GLB_SUPPORT_PNG_WRITE}
136 // Lazarus TJPEGImage
137 {$IFDEF GLB_LAZ_JPEG}
138 {$IFNDEF GLB_LAZARUS}
139 {$MESSAGE warn 'Lazarus TJPEGImage won''t work without Lazarus. Lazarus will be activated.'}
140 {$DEFINE GLB_LAZARUS}
143 {$IFDEF GLB_DELPHI_JPEG}
144 {$MESSAGE warn 'The Delphi JPEGImage will be ignored if you are using the Lazarus TJPEGImage.'}
145 {$undef GLB_DELPHI_JPEG}
148 {$IFDEF GLB_LIB_JPEG}
149 {$MESSAGE warn 'The library libJPEG will be ignored if you are using the Lazarus TJPEGImage.'}
150 {$undef GLB_LIB_JPEG}
153 {$DEFINE GLB_SUPPORT_JPEG_READ}
154 {$DEFINE GLB_SUPPORT_JPEG_WRITE}
158 {$IFDEF GLB_DELPHI_JPEG}
159 {$IFDEF GLB_LIB_JPEG}
160 {$MESSAGE warn 'The library libJPEG will be ignored if you are using the unit JPEG.'}
161 {$undef GLB_LIB_JPEG}
164 {$DEFINE GLB_SUPPORT_JPEG_READ}
165 {$DEFINE GLB_SUPPORT_JPEG_WRITE}
169 {$IFDEF GLB_LIB_JPEG}
170 {$DEFINE GLB_SUPPORT_JPEG_READ}
171 {$DEFINE GLB_SUPPORT_JPEG_WRITE}
187 {$IFDEF OPENGL_ES} dglOpenGLES,
188 {$ELSE} dglOpenGL, {$ENDIF}
190 {$IF DEFINED(GLB_WIN) AND
191 DEFINED(GLB_DELPHI)} windows, {$IFEND}
193 {$IFDEF GLB_SDL} SDL, {$ENDIF}
194 {$IFDEF GLB_LAZARUS} IntfGraphics, GraphType, Graphics, {$ENDIF}
195 {$IFDEF GLB_DELPHI} Dialogs, Graphics, Types, {$ENDIF}
197 {$IFDEF GLB_SDL_IMAGE} SDL_image, {$ENDIF}
198 {$IFDEF GLB_PNGIMAGE} pngimage, {$ENDIF}
199 {$IFDEF GLB_LIB_PNG} libPNG, {$ENDIF}
200 {$IFDEF GLB_DELPHI_JPEG} JPEG, {$ENDIF}
201 {$IFDEF GLB_LIB_JPEG} libJPEG, {$ENDIF}
207 QWord = System.UInt64;
215 { type that describes the format of the data stored in a texture.
216 the name of formats is composed of the following constituents:
218 - channel (e.g. R, G, B, A or Alpha, Luminance or X (reserved))
219 - width of the chanel in bit (4, 8, 16, ...)
220 - data type (e.g. ub, us, ui)
221 - number of elements of data types }
225 tfAlpha4ub1, //< 1 x unsigned byte
226 tfAlpha8ub1, //< 1 x unsigned byte
227 tfAlpha16us1, //< 1 x unsigned short
229 tfLuminance4ub1, //< 1 x unsigned byte
230 tfLuminance8ub1, //< 1 x unsigned byte
231 tfLuminance16us1, //< 1 x unsigned short
233 tfLuminance4Alpha4ub2, //< 1 x unsigned byte (lum), 1 x unsigned byte (alpha)
234 tfLuminance6Alpha2ub2, //< 1 x unsigned byte (lum), 1 x unsigned byte (alpha)
235 tfLuminance8Alpha8ub2, //< 1 x unsigned byte (lum), 1 x unsigned byte (alpha)
236 tfLuminance12Alpha4us2, //< 1 x unsigned short (lum), 1 x unsigned short (alpha)
237 tfLuminance16Alpha16us2, //< 1 x unsigned short (lum), 1 x unsigned short (alpha)
239 tfR3G3B2ub1, //< 1 x unsigned byte (3bit red, 3bit green, 2bit blue)
240 tfRGBX4us1, //< 1 x unsigned short (4bit red, 4bit green, 4bit blue, 4bit reserverd)
241 tfXRGB4us1, //< 1 x unsigned short (4bit reserved, 4bit red, 4bit green, 4bit blue)
242 tfR5G6B5us1, //< 1 x unsigned short (5bit red, 6bit green, 5bit blue)
243 tfRGB5X1us1, //< 1 x unsigned short (5bit red, 5bit green, 5bit blue, 1bit reserved)
244 tfX1RGB5us1, //< 1 x unsigned short (1bit reserved, 5bit red, 5bit green, 5bit blue)
245 tfRGB8ub3, //< 1 x unsigned byte (red), 1 x unsigned byte (green), 1 x unsigned byte (blue)
246 tfRGBX8ui1, //< 1 x unsigned int (8bit red, 8bit green, 8bit blue, 8bit reserved)
247 tfXRGB8ui1, //< 1 x unsigned int (8bit reserved, 8bit red, 8bit green, 8bit blue)
248 tfRGB10X2ui1, //< 1 x unsigned int (10bit red, 10bit green, 10bit blue, 2bit reserved)
249 tfX2RGB10ui1, //< 1 x unsigned int (2bit reserved, 10bit red, 10bit green, 10bit blue)
250 tfRGB16us3, //< 1 x unsigned short (red), 1 x unsigned short (green), 1 x unsigned short (blue)
252 tfRGBA4us1, //< 1 x unsigned short (4bit red, 4bit green, 4bit blue, 4bit alpha)
253 tfARGB4us1, //< 1 x unsigned short (4bit alpha, 4bit red, 4bit green, 4bit blue)
254 tfRGB5A1us1, //< 1 x unsigned short (5bit red, 5bit green, 5bit blue, 1bit alpha)
255 tfA1RGB5us1, //< 1 x unsigned short (1bit alpha, 5bit red, 5bit green, 5bit blue)
256 tfRGBA8ui1, //< 1 x unsigned int (8bit red, 8bit green, 8bit blue, 8 bit alpha)
257 tfARGB8ui1, //< 1 x unsigned int (8 bit alpha, 8bit red, 8bit green, 8bit blue)
258 tfRGBA8ub4, //< 1 x unsigned byte (red), 1 x unsigned byte (green), 1 x unsigned byte (blue), 1 x unsigned byte (alpha)
259 tfRGB10A2ui1, //< 1 x unsigned int (10bit red, 10bit green, 10bit blue, 2bit alpha)
260 tfA2RGB10ui1, //< 1 x unsigned int (2bit alpha, 10bit red, 10bit green, 10bit blue)
261 tfRGBA16us4, //< 1 x unsigned short (red), 1 x unsigned short (green), 1 x unsigned short (blue), 1 x unsigned short (alpha)
263 tfBGRX4us1, //< 1 x unsigned short (4bit blue, 4bit green, 4bit red, 4bit reserved)
264 tfXBGR4us1, //< 1 x unsigned short (4bit reserved, 4bit blue, 4bit green, 4bit red)
265 tfB5G6R5us1, //< 1 x unsigned short (5bit blue, 6bit green, 5bit red)
266 tfBGR5X1us1, //< 1 x unsigned short (5bit blue, 5bit green, 5bit red, 1bit reserved)
267 tfX1BGR5us1, //< 1 x unsigned short (1bit reserved, 5bit blue, 5bit green, 5bit red)
268 tfBGR8ub3, //< 1 x unsigned byte (blue), 1 x unsigned byte (green), 1 x unsigned byte (red)
269 tfBGRX8ui1, //< 1 x unsigned int (8bit blue, 8bit green, 8bit red, 8bit reserved)
270 tfXBGR8ui1, //< 1 x unsigned int (8bit reserved, 8bit blue, 8bit green, 8bit red)
271 tfBGR10X2ui1, //< 1 x unsigned int (10bit blue, 10bit green, 10bit red, 2bit reserved)
272 tfX2BGR10ui1, //< 1 x unsigned int (2bit reserved, 10bit blue, 10bit green, 10bit red)
273 tfBGR16us3, //< 1 x unsigned short (blue), 1 x unsigned short (green), 1 x unsigned short (red)
275 tfBGRA4us1, //< 1 x unsigned short (4bit blue, 4bit green, 4bit red, 4bit alpha)
276 tfABGR4us1, //< 1 x unsigned short (4bit alpha, 4bit blue, 4bit green, 4bit red)
277 tfBGR5A1us1, //< 1 x unsigned short (5bit blue, 5bit green, 5bit red, 1bit alpha)
278 tfA1BGR5us1, //< 1 x unsigned short (1bit alpha, 5bit blue, 5bit green, 5bit red)
279 tfBGRA8ui1, //< 1 x unsigned int (8bit blue, 8bit green, 8bit red, 8bit alpha)
280 tfABGR8ui1, //< 1 x unsigned int (8bit alpha, 8bit blue, 8bit green, 8bit red)
281 tfBGRA8ub4, //< 1 x unsigned byte (blue), 1 x unsigned byte (green), 1 x unsigned byte (red), 1 x unsigned byte (alpha)
282 tfBGR10A2ui1, //< 1 x unsigned int (10bit blue, 10bit green, 10bit red, 2bit alpha)
283 tfA2BGR10ui1, //< 1 x unsigned int (2bit alpha, 10bit blue, 10bit green, 10bit red)
284 tfBGRA16us4, //< 1 x unsigned short (blue), 1 x unsigned short (green), 1 x unsigned short (red), 1 x unsigned short (alpha)
286 tfDepth16us1, //< 1 x unsigned short (depth)
287 tfDepth24ui1, //< 1 x unsigned int (depth)
288 tfDepth32ui1, //< 1 x unsigned int (depth)
295 { type to define suitable file formats }
296 TglBitmapFileType = (
297 {$IFDEF GLB_SUPPORT_PNG_WRITE} ftPNG, {$ENDIF} //< Portable Network Graphic file (PNG)
298 {$IFDEF GLB_SUPPORT_JPEG_WRITE}ftJPEG, {$ENDIF} //< JPEG file
299 ftDDS, //< Direct Draw Surface file (DDS)
300 ftTGA, //< Targa Image File (TGA)
301 ftBMP, //< Windows Bitmap File (BMP)
302 ftRAW); //< glBitmap RAW file format
303 TglBitmapFileTypes = set of TglBitmapFileType;
305 { possible mipmap types }
307 mmNone, //< no mipmaps
308 mmMipmap, //< normal mipmaps
309 mmMipmapGlu); //< mipmaps generated with glu functions
311 { possible normal map functions }
312 TglBitmapNormalMapFunc = (
318 ////////////////////////////////////////////////////////////////////////////////////////////////////
319 EglBitmap = class(Exception); //< glBitmap exception
320 EglBitmapNotSupported = class(Exception); //< exception for not supported functions
321 EglBitmapSizeToLarge = class(EglBitmap); //< exception for to large textures
322 EglBitmapNonPowerOfTwo = class(EglBitmap); //< exception for non power of two textures
323 EglBitmapUnsupportedFormat = class(EglBitmap) //< exception for unsupporetd formats
325 constructor Create(const aFormat: TglBitmapFormat); overload;
326 constructor Create(const aMsg: String; const aFormat: TglBitmapFormat); overload;
329 ////////////////////////////////////////////////////////////////////////////////////////////////////
330 { record that stores 4 unsigned integer values }
331 TglBitmapRec4ui = packed record
333 0: (r, g, b, a: Cardinal);
334 1: (arr: array[0..3] of Cardinal);
337 { record that stores 4 unsigned byte values }
338 TglBitmapRec4ub = packed record
340 0: (r, g, b, a: Byte);
341 1: (arr: array[0..3] of Byte);
344 { record that stores 4 unsigned long integer values }
345 TglBitmapRec4ul = packed record
347 0: (r, g, b, a: QWord);
348 1: (arr: array[0..3] of QWord);
351 { structure to store pixel data in }
352 TglBitmapPixelData = packed record
353 Data: TglBitmapRec4ui; //< color data for each color channel
354 Range: TglBitmapRec4ui; //< maximal color value for each channel
355 Format: TglBitmapFormat; //< format of the pixel
357 PglBitmapPixelData = ^TglBitmapPixelData;
359 TglBitmapSizeFields = set of (ffX, ffY);
360 TglBitmapSize = packed record
361 Fields: TglBitmapSizeFields;
365 TglBitmapPixelPosition = TglBitmapSize;
367 { describes the properties of a given texture data format }
368 TglBitmapFormatDescriptor = class(TObject)
371 fBytesPerPixel: Single; //< number of bytes for each pixel
372 fChannelCount: Integer; //< number of color channels
373 fMask: TglBitmapRec4ul; //< bitmask for each color channel
374 fRange: TglBitmapRec4ui; //< maximal value of each color channel
376 { @return @true if the format has a red color channel, @false otherwise }
377 function GetHasRed: Boolean;
379 { @return @true if the format has a green color channel, @false otherwise }
380 function GetHasGreen: Boolean;
382 { @return @true if the format has a blue color channel, @false otherwise }
383 function GetHasBlue: Boolean;
385 { @return @true if the format has a alpha color channel, @false otherwise }
386 function GetHasAlpha: Boolean;
388 { @return @true if the format has any color color channel, @false otherwise }
389 function GetHasColor: Boolean;
391 { @return @true if the format is a grayscale format, @false otherwise }
392 function GetIsGrayscale: Boolean;
394 fFormat: TglBitmapFormat; //< format this descriptor belongs to
395 fWithAlpha: TglBitmapFormat; //< suitable format with alpha channel
396 fWithoutAlpha: TglBitmapFormat; //< suitable format without alpha channel
397 fOpenGLFormat: TglBitmapFormat; //< suitable format that is supported by OpenGL
398 fRGBInverted: TglBitmapFormat; //< suitable format with inverted RGB channels
399 fUncompressed: TglBitmapFormat; //< suitable format with uncompressed data
401 fBitsPerPixel: Integer; //< number of bits per pixel
402 fIsCompressed: Boolean; //< @true if the format is compressed, @false otherwise
404 fPrecision: TglBitmapRec4ub; //< number of bits for each color channel
405 fShift: TglBitmapRec4ub; //< bit offset for each color channel
407 fglFormat: GLenum; //< OpenGL format enum (e.g. GL_RGB)
408 fglInternalFormat: GLenum; //< OpenGL internal format enum (e.g. GL_RGB8)
409 fglDataFormat: GLenum; //< OpenGL data format enum (e.g. GL_UNSIGNED_BYTE)
411 { set values for this format descriptor }
412 procedure SetValues; virtual;
414 { calculate cached values }
415 procedure CalcValues;
417 property Format: TglBitmapFormat read fFormat; //< format this descriptor belongs to
418 property ChannelCount: Integer read fChannelCount; //< number of color channels
419 property IsCompressed: Boolean read fIsCompressed; //< @true if the format is compressed, @false otherwise
420 property BitsPerPixel: Integer read fBitsPerPixel; //< number of bytes per pixel
421 property BytesPerPixel: Single read fBytesPerPixel; //< number of bits per pixel
423 property Precision: TglBitmapRec4ub read fPrecision; //< number of bits for each color channel
424 property Shift: TglBitmapRec4ub read fShift; //< bit offset for each color channel
425 property Range: TglBitmapRec4ui read fRange; //< maximal value of each color channel
426 property Mask: TglBitmapRec4ul read fMask; //< bitmask for each color channel
428 property RGBInverted: TglBitmapFormat read fRGBInverted; //< suitable format with inverted RGB channels
429 property WithAlpha: TglBitmapFormat read fWithAlpha; //< suitable format with alpha channel
430 property WithoutAlpha: TglBitmapFormat read fWithAlpha; //< suitable format without alpha channel
431 property OpenGLFormat: TglBitmapFormat read fOpenGLFormat; //< suitable format that is supported by OpenGL
432 property Uncompressed: TglBitmapFormat read fUncompressed; //< suitable format with uncompressed data
434 property glFormat: GLenum read fglFormat; //< OpenGL format enum (e.g. GL_RGB)
435 property glInternalFormat: GLenum read fglInternalFormat; //< OpenGL internal format enum (e.g. GL_RGB8)
436 property glDataFormat: GLenum read fglDataFormat; //< OpenGL data format enum (e.g. GL_UNSIGNED_BYTE)
438 property HasRed: Boolean read GetHasRed; //< @true if the format has a red color channel, @false otherwise
439 property HasGreen: Boolean read GetHasGreen; //< @true if the format has a green color channel, @false otherwise
440 property HasBlue: Boolean read GetHasBlue; //< @true if the format has a blue color channel, @false otherwise
441 property HasAlpha: Boolean read GetHasAlpha; //< @true if the format has a alpha color channel, @false otherwise
442 property HasColor: Boolean read GetHasColor; //< @true if the format has any color color channel, @false otherwise
443 property IsGrayscale: Boolean read GetIsGrayscale; //< @true if the format is a grayscale format, @false otherwise
445 function GetSize(const aSize: TglBitmapSize): Integer; overload; virtual;
446 function GetSize(const aWidth, aHeight: Integer): Integer; overload; virtual;
451 { get the format descriptor by a given OpenGL internal format
452 @param aInternalFormat OpenGL internal format to get format descriptor for
453 @returns suitable format descriptor or tfEmpty-Descriptor }
454 class function GetByFormat(const aInternalFormat: GLenum): TglBitmapFormatDescriptor;
457 ////////////////////////////////////////////////////////////////////////////////////////////////////
458 TglBitmapData = class;
460 { structure to store data for converting in }
461 TglBitmapFunctionRec = record
462 Sender: TglBitmapData; //< texture object that stores the data to convert
463 Size: TglBitmapSize; //< size of the texture
464 Position: TglBitmapPixelPosition; //< position of the currently pixel
465 Source: TglBitmapPixelData; //< pixel data of the current pixel
466 Dest: TglBitmapPixelData; //< new data of the pixel (must be filled in)
467 Args: Pointer; //< user defined args that was passed to the convert function
470 { callback to use for converting texture data }
471 TglBitmapFunction = procedure(var FuncRec: TglBitmapFunctionRec);
473 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
474 { class to store texture data in. used to load, save and
475 manipulate data before assigned to texture object
476 all operations on a data object can be done from a background thread }
477 TglBitmapData = class
480 fData: PByte; //< texture data
481 fDimension: TglBitmapSize; //< pixel size of the data
482 fFormat: TglBitmapFormat; //< format the texture data is stored in
483 fFilename: String; //< file the data was load from
485 fScanlines: array of PByte; //< pointer to begin of each line
486 fHasScanlines: Boolean; //< @true if scanlines are initialized, @false otherwise
488 private { getter / setter }
490 { @returns the format descriptor suitable to the texture data format }
491 function GetFormatDescriptor: TglBitmapFormatDescriptor;
493 { @returns the width of the texture data (in pixel) or -1 if no data is set }
494 function GetWidth: Integer;
496 { @returns the height of the texture data (in pixel) or -1 if no data is set }
497 function GetHeight: Integer;
499 { get scanline at index aIndex
500 @returns Pointer to start of line or @nil }
501 function GetScanlines(const aIndex: Integer): PByte;
503 { set new value for the data format. only possible if new format has the same pixel size.
504 if you want to convert the texture data, see ConvertTo function }
505 procedure SetFormat(const aValue: TglBitmapFormat);
507 private { internal misc }
509 { splits a resource identifier into the resource and it's type
510 @param aResource resource identifier to split and store name in
511 @param aResType type of the resource }
512 procedure PrepareResType(var aResource: String; var aResType: PChar);
514 { updates scanlines array }
515 procedure UpdateScanlines;
517 private { internal load and save }
518 {$IFDEF GLB_SUPPORT_PNG_READ}
519 { try to load a PNG from a stream
520 @param aStream stream to load PNG from
521 @returns @true on success, @false otherwise }
522 function LoadPNG(const aStream: TStream): Boolean; virtual;
525 {$ifdef GLB_SUPPORT_PNG_WRITE}
526 { save texture data as PNG to stream
527 @param aStream stream to save data to}
528 procedure SavePNG(const aStream: TStream); virtual;
531 {$IFDEF GLB_SUPPORT_JPEG_READ}
532 { try to load a JPEG from a stream
533 @param aStream stream to load JPEG from
534 @returns @true on success, @false otherwise }
535 function LoadJPEG(const aStream: TStream): Boolean; virtual;
538 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
539 { save texture data as JPEG to stream
540 @param aStream stream to save data to}
541 procedure SaveJPEG(const aStream: TStream); virtual;
544 { try to load a RAW image from a stream
545 @param aStream stream to load RAW image from
546 @returns @true on success, @false otherwise }
547 function LoadRAW(const aStream: TStream): Boolean;
549 { save texture data as RAW image to stream
550 @param aStream stream to save data to}
551 procedure SaveRAW(const aStream: TStream);
553 { try to load a BMP from a stream
554 @param aStream stream to load BMP from
555 @returns @true on success, @false otherwise }
556 function LoadBMP(const aStream: TStream): Boolean;
558 { save texture data as BMP to stream
559 @param aStream stream to save data to}
560 procedure SaveBMP(const aStream: TStream);
562 { try to load a TGA from a stream
563 @param aStream stream to load TGA from
564 @returns @true on success, @false otherwise }
565 function LoadTGA(const aStream: TStream): Boolean;
567 { save texture data as TGA to stream
568 @param aStream stream to save data to}
569 procedure SaveTGA(const aStream: TStream);
571 { try to load a DDS from a stream
572 @param aStream stream to load DDS from
573 @returns @true on success, @false otherwise }
574 function LoadDDS(const aStream: TStream): Boolean;
576 { save texture data as DDS to stream
577 @param aStream stream to save data to}
578 procedure SaveDDS(const aStream: TStream);
580 public { properties }
581 property Data: PByte read fData; //< texture data (be carefull with this!)
582 property Dimension: TglBitmapSize read fDimension; //< size of the texture data (in pixel)
583 property Filename: String read fFilename; //< file the data was loaded from
584 property Width: Integer read GetWidth; //< width of the texture data (in pixel)
585 property Height: Integer read GetHeight; //< height of the texture data (in pixel)
586 property Format: TglBitmapFormat read fFormat write SetFormat; //< format the texture data is stored in
587 property Scanlines[const aIndex: Integer]: PByte read GetScanlines; //< pointer to begin of line at given index or @nil
589 property FormatDescriptor: TglBitmapFormatDescriptor read GetFormatDescriptor; //< descriptor object that describes the format of the stored data
593 { flip texture horizontal
594 @returns @true in success, @false otherwise }
595 function FlipHorz: Boolean; virtual;
597 { flip texture vertical
598 @returns @true in success, @false otherwise }
599 function FlipVert: Boolean; virtual;
603 { load a texture from a file
604 @param aFilename file to load texuture from }
605 procedure LoadFromFile(const aFilename: String);
607 { load a texture from a stream
608 @param aStream stream to load texture from }
609 procedure LoadFromStream(const aStream: TStream); virtual;
611 { use a function to generate texture data
612 @param aSize size of the texture
613 @param aFormat format of the texture data
614 @param aFunc callback to use for generation
615 @param aArgs user defined paramaters (use at will) }
616 procedure LoadFromFunc(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer = nil);
618 { load a texture from a resource
619 @param aInstance resource handle
620 @param aResource resource indentifier
621 @param aResType resource type (if known) }
622 procedure LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil);
624 { load a texture from a resource id
625 @param aInstance resource handle
626 @param aResource resource ID
627 @param aResType resource type }
628 procedure LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
632 { save texture data to a file
633 @param aFilename filename to store texture in
634 @param aFileType file type to store data into }
635 procedure SaveToFile(const aFilename: String; const aFileType: TglBitmapFileType);
637 { save texture data to a stream
638 @param aFilename filename to store texture in
639 @param aFileType file type to store data into }
640 procedure SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType); virtual;
644 { convert texture data using a user defined callback
645 @param aFunc callback to use for converting
646 @param aCreateTemp create a temporary buffer to use for converting
647 @param aArgs user defined paramters (use at will)
648 @returns @true if converting was successful, @false otherwise }
649 function Convert(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer = nil): Boolean; overload;
651 { convert texture data using a user defined callback
652 @param aSource glBitmap to read data from
653 @param aFunc callback to use for converting
654 @param aCreateTemp create a temporary buffer to use for converting
655 @param aFormat format of the new data
656 @param aArgs user defined paramters (use at will)
657 @returns @true if converting was successful, @false otherwise }
658 function Convert(const aSource: TglBitmapData; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
659 const aFormat: TglBitmapFormat; const aArgs: Pointer = nil): Boolean; overload;
661 { convert texture data using a specific format
662 @param aFormat new format of texture data
663 @returns @true if converting was successful, @false otherwise }
664 function ConvertTo(const aFormat: TglBitmapFormat): Boolean; virtual;
669 { assign texture data to SDL surface
670 @param aSurface SDL surface to write data to
671 @returns @true on success, @false otherwise }
672 function AssignToSurface(out aSurface: PSDL_Surface): Boolean;
674 { assign texture data from SDL surface
675 @param aSurface SDL surface to read data from
676 @returns @true on success, @false otherwise }
677 function AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
679 { assign alpha channel data to SDL surface
680 @param aSurface SDL surface to write alpha channel data to
681 @returns @true on success, @false otherwise }
682 function AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
684 { assign alpha channel data from SDL surface
685 @param aSurface SDL surface to read data from
686 @param aFunc callback to use for converting
687 @param aArgs user defined parameters (use at will)
688 @returns @true on success, @false otherwise }
689 function AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
695 { assign texture data to TBitmap object
696 @param aBitmap TBitmap to write data to
697 @returns @true on success, @false otherwise }
698 function AssignToBitmap(const aBitmap: TBitmap): Boolean;
700 { assign texture data from TBitmap object
701 @param aBitmap TBitmap to read data from
702 @returns @true on success, @false otherwise }
703 function AssignFromBitmap(const aBitmap: TBitmap): Boolean;
705 { assign alpha channel data to TBitmap object
706 @param aBitmap TBitmap to write data to
707 @returns @true on success, @false otherwise }
708 function AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
710 { assign alpha channel data from TBitmap object
711 @param aBitmap TBitmap to read data from
712 @param aFunc callback to use for converting
713 @param aArgs user defined parameters (use at will)
714 @returns @true on success, @false otherwise }
715 function AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
721 { assign texture data to TLazIntfImage object
722 @param aImage TLazIntfImage to write data to
723 @returns @true on success, @false otherwise }
724 function AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
726 { assign texture data from TLazIntfImage object
727 @param aImage TLazIntfImage to read data from
728 @returns @true on success, @false otherwise }
729 function AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
731 { assign alpha channel data to TLazIntfImage object
732 @param aImage TLazIntfImage to write data to
733 @returns @true on success, @false otherwise }
734 function AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
736 { assign alpha channel data from TLazIntfImage object
737 @param aImage TLazIntfImage to read data from
738 @param aFunc callback to use for converting
739 @param aArgs user defined parameters (use at will)
740 @returns @true on success, @false otherwise }
741 function AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
745 { load alpha channel data from resource
746 @param aInstance resource handle
747 @param aResource resource ID
748 @param aResType resource type
749 @param aFunc callback to use for converting
750 @param aArgs user defined parameters (use at will)
751 @returns @true on success, @false otherwise }
752 function AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
754 { load alpha channel data from resource ID
755 @param aInstance resource handle
756 @param aResourceID resource ID
757 @param aResType resource type
758 @param aFunc callback to use for converting
759 @param aArgs user defined parameters (use at will)
760 @returns @true on success, @false otherwise }
761 function AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
763 { add alpha channel data from function
764 @param aFunc callback to get data from
765 @param aArgs user defined parameters (use at will)
766 @returns @true on success, @false otherwise }
767 function AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer = nil): Boolean; virtual;
769 { add alpha channel data from file (macro for: new glBitmap, LoadFromFile, AddAlphaFromGlBitmap)
770 @param aFilename file to load alpha channel data from
771 @param aFunc callback to use for converting
772 @param aArgs SetFormat user defined parameters (use at will)
773 @returns @true on success, @false otherwise }
774 function AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
776 { add alpha channel data from stream (macro for: new glBitmap, LoadFromStream, AddAlphaFromGlBitmap)
777 @param aStream stream to load alpha channel data from
778 @param aFunc callback to use for converting
779 @param aArgs user defined parameters (use at will)
780 @returns @true on success, @false otherwise }
781 function AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
783 { add alpha channel data from existing glBitmap object
784 @param aBitmap TglBitmap to copy alpha channel data from
785 @param aFunc callback to use for converting
786 @param aArgs user defined parameters (use at will)
787 @returns @true on success, @false otherwise }
788 function AddAlphaFromDataObj(const aDataObj: TglBitmapData; aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
790 { add alpha to pixel if the pixels color is greter than the given color value
791 @param aRed red threshold (0-255)
792 @param aGreen green threshold (0-255)
793 @param aBlue blue threshold (0-255)
794 @param aDeviatation accepted deviatation (0-255)
795 @returns @true on success, @false otherwise }
796 function AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte = 0): Boolean;
798 { add alpha to pixel if the pixels color is greter than the given color value
799 @param aRed red threshold (0-Range.r)
800 @param aGreen green threshold (0-Range.g)
801 @param aBlue blue threshold (0-Range.b)
802 @param aDeviatation accepted deviatation (0-max(Range.rgb))
803 @returns @true on success, @false otherwise }
804 function AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal = 0): Boolean;
806 { add alpha to pixel if the pixels color is greter than the given color value
807 @param aRed red threshold (0.0-1.0)
808 @param aGreen green threshold (0.0-1.0)
809 @param aBlue blue threshold (0.0-1.0)
810 @param aDeviatation accepted deviatation (0.0-1.0)
811 @returns @true on success, @false otherwise }
812 function AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single = 0): Boolean;
814 { add a constand alpha value to all pixels
815 @param aAlpha alpha value to add (0-255)
816 @returns @true on success, @false otherwise }
817 function AddAlphaFromValue(const aAlpha: Byte): Boolean;
819 { add a constand alpha value to all pixels
820 @param aAlpha alpha value to add (0-max(Range.rgb))
821 @returns @true on success, @false otherwise }
822 function AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
824 { add a constand alpha value to all pixels
825 @param aAlpha alpha value to add (0.0-1.0)
826 @returns @true on success, @false otherwise }
827 function AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
829 { remove alpha channel
830 @returns @true on success, @false otherwise }
831 function RemoveAlpha: Boolean; virtual;
834 { fill complete texture with one color
835 @param aRed red color for border (0-255)
836 @param aGreen green color for border (0-255)
837 @param aBlue blue color for border (0-255)
838 @param aAlpha alpha color for border (0-255) }
839 procedure FillWithColor(const aRed, aGreen, aBlue: Byte; const aAlpha: Byte = 255);
841 { fill complete texture with one color
842 @param aRed red color for border (0-Range.r)
843 @param aGreen green color for border (0-Range.g)
844 @param aBlue blue color for border (0-Range.b)
845 @param aAlpha alpha color for border (0-Range.a) }
846 procedure FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal = $FFFFFFFF);
848 { fill complete texture with one color
849 @param aRed red color for border (0.0-1.0)
850 @param aGreen green color for border (0.0-1.0)
851 @param aBlue blue color for border (0.0-1.0)
852 @param aAlpha alpha color for border (0.0-1.0) }
853 procedure FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single = 1.0);
857 { set data pointer of texture data
858 @param aData pointer to new texture data
859 @param aFormat format of the data stored at aData
860 @param aWidth width of the texture data
861 @param aHeight height of the texture data }
862 procedure SetData(const aData: PByte; const aFormat: TglBitmapFormat;
863 const aWidth: Integer = -1; const aHeight: Integer = -1); virtual;
865 { create a clone of the current object
866 @returns clone of this object}
867 function Clone: TglBitmapData;
869 { invert color data (bitwise not)
870 @param aRed invert red channel
871 @param aGreen invert green channel
872 @param aBlue invert blue channel
873 @param aAlpha invert alpha channel }
874 procedure Invert(const aRed, aGreen, aBlue, aAlpha: Boolean);
876 { create normal map from texture data
877 @param aFunc normal map function to generate normalmap with
878 @param aScale scale of the normale stored in the normal map
879 @param aUseAlpha generate normalmap from alpha channel data (if present) }
880 procedure GenerateNormalMap(const aFunc: TglBitmapNormalMapFunc = nm3x3;
881 const aScale: Single = 2; const aUseAlpha: Boolean = false);
883 public { constructor }
885 { constructor - creates a texutre data object }
886 constructor Create; overload;
888 { constructor - creates a texture data object and loads it from a file
889 @param aFilename file to load texture from }
890 constructor Create(const aFileName: String); overload;
892 { constructor - creates a texture data object and loads it from a stream
893 @param aStream stream to load texture from }
894 constructor Create(const aStream: TStream); overload;
896 { constructor - creates a texture data object with the given size, format and data
897 @param aSize size of the texture
898 @param aFormat format of the given data
899 @param aData texture data - be carefull: the data will now be managed by the texture data object }
900 constructor Create(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat; aData: PByte = nil); overload;
902 { constructor - creates a texture data object with the given size and format and uses the given callback to create the data
903 @param aSize size of the texture
904 @param aFormat format of the given data
905 @param aFunc callback to use for generating the data
906 @param aArgs user defined parameters (use at will) }
907 constructor Create(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer = nil); overload;
909 { constructor - creates a texture data object and loads it from a resource
910 @param aInstance resource handle
911 @param aResource resource indentifier
912 @param aResType resource type (if known) }
913 constructor Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil); overload;
915 { constructor - creates a texture data object and loads it from a resource
916 @param aInstance resource handle
917 @param aResourceID resource ID
918 @param aResType resource type (if known) }
919 constructor Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar); overload;
922 destructor Destroy; override;
926 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
927 { base class for all glBitmap classes. used to manage OpenGL texture objects
928 all operations on a bitmap object must be done from the render thread }
931 fID: GLuint; //< name of the OpenGL texture object
932 fTarget: GLuint; //< texture target (e.g. GL_TEXTURE_2D)
933 fDeleteTextureOnFree: Boolean; //< delete OpenGL texture object when this object is destroyed
935 // texture properties
936 fFilterMin: GLenum; //< min filter to apply to the texture
937 fFilterMag: GLenum; //< mag filter to apply to the texture
938 fWrapS: GLenum; //< texture wrapping for x axis
939 fWrapT: GLenum; //< texture wrapping for y axis
940 fWrapR: GLenum; //< texture wrapping for z axis
941 fAnisotropic: Integer; //< anisotropic level
942 fBorderColor: array[0..3] of Single; //< color of the texture border
944 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
946 fSwizzle: array[0..3] of GLenum; //< color channel swizzle
949 fIsResident: GLboolean; //< @true if OpenGL texture object has data, @false otherwise
952 fDimension: TglBitmapSize; //< size of this texture
953 fMipMap: TglBitmapMipMap; //< mipmap type
956 fCustomData: Pointer; //< user defined data
957 fCustomName: String; //< user defined name
958 fCustomNameW: WideString; //< user defined name
960 { @returns the actual width of the texture }
961 function GetWidth: Integer; virtual;
963 { @returns the actual height of the texture }
964 function GetHeight: Integer; virtual;
967 { set a new value for fCustomData }
968 procedure SetCustomData(const aValue: Pointer);
970 { set a new value for fCustomName }
971 procedure SetCustomName(const aValue: String);
973 { set a new value for fCustomNameW }
974 procedure SetCustomNameW(const aValue: WideString);
976 { set new value for fDeleteTextureOnFree }
977 procedure SetDeleteTextureOnFree(const aValue: Boolean);
979 { set name of OpenGL texture object }
980 procedure SetID(const aValue: Cardinal);
982 { set new value for fMipMap }
983 procedure SetMipMap(const aValue: TglBitmapMipMap);
985 { set new value for target }
986 procedure SetTarget(const aValue: Cardinal);
988 { set new value for fAnisotrophic }
989 procedure SetAnisotropic(const aValue: Integer);
992 { create OpenGL texture object (delete exisiting object if exists) }
995 { setup texture parameters }
996 procedure SetupParameters({$IFNDEF OPENGL_ES}out aBuildWithGlu: Boolean{$ENDIF});
999 property Width: Integer read GetWidth; //< the actual width of the texture
1000 property Height: Integer read GetHeight; //< the actual height of the texture
1003 property ID: Cardinal read fID write SetID; //< name of the OpenGL texture object
1004 property Target: Cardinal read fTarget write SetTarget; //< texture target (e.g. GL_TEXTURE_2D)
1005 property DeleteTextureOnFree: Boolean read fDeleteTextureOnFree write SetDeleteTextureOnFree; //< delete texture object when this object is destroyed
1007 property MipMap: TglBitmapMipMap read fMipMap write SetMipMap; //< mipmap type
1008 property Anisotropic: Integer read fAnisotropic write SetAnisotropic; //< anisotropic level
1010 property CustomData: Pointer read fCustomData write SetCustomData; //< user defined data (use at will)
1011 property CustomName: String read fCustomName write SetCustomName; //< user defined name (use at will)
1012 property CustomNameW: WideString read fCustomNameW write SetCustomNameW; //< user defined name (as WideString; use at will)
1014 property Dimension: TglBitmapSize read fDimension; //< size of the texture
1016 property IsResident: GLboolean read fIsResident; //< @true if OpenGL texture object has data, @false otherwise
1019 { this method is called after the constructor and sets the default values of this object }
1020 procedure AfterConstruction; override;
1022 { this method is called before the destructor and does some cleanup }
1023 procedure BeforeDestruction; override;
1027 { set the new value for texture border color
1028 @param aRed red color for border (0.0-1.0)
1029 @param aGreen green color for border (0.0-1.0)
1030 @param aBlue blue color for border (0.0-1.0)
1031 @param aAlpha alpha color for border (0.0-1.0) }
1032 procedure SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
1036 { set new texture filer
1037 @param aMin min filter
1038 @param aMag mag filter }
1039 procedure SetFilter(const aMin, aMag: GLenum);
1041 { set new texture wrapping
1042 @param S texture wrapping for x axis
1043 @param T texture wrapping for y axis
1044 @param R texture wrapping for z axis }
1046 const S: GLenum = GL_CLAMP_TO_EDGE;
1047 const T: GLenum = GL_CLAMP_TO_EDGE;
1048 const R: GLenum = GL_CLAMP_TO_EDGE);
1050 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
1052 @param r swizzle for red channel
1053 @param g swizzle for green channel
1054 @param b swizzle for blue channel
1055 @param a swizzle for alpha channel }
1056 procedure SetSwizzle(const r, g, b, a: GLenum);
1061 @param aEnableTextureUnit enable texture unit for this texture (e.g. glEnable(GL_TEXTURE_2D)) }
1062 procedure Bind(const aEnableTextureUnit: Boolean = true); virtual;
1065 @param aDisableTextureUnit disable texture unit for this texture (e.g. glEnable(GL_TEXTURE_2D)) }
1066 procedure Unbind(const aDisableTextureUnit: Boolean = true); virtual;
1068 { upload texture data from given data object to video card
1069 @param aData texture data object that contains the actual data
1070 @param aCheckSize check size before upload and throw exception if something is wrong }
1071 procedure UploadData(const aDataObj: TglBitmapData; const aCheckSize: Boolean = true); virtual;
1074 { download texture data from video card and store it into given data object
1075 @returns @true when download was successfull, @false otherwise }
1076 function DownloadData(const aDataObj: TglBitmapData): Boolean; virtual;
1079 { constructor - creates an empty texture }
1080 constructor Create; overload;
1082 { constructor - creates an texture object and uploads the given data }
1083 constructor Create(const aData: TglBitmapData); overload;
1087 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1088 {$IF NOT DEFINED(OPENGL_ES)}
1089 { wrapper class for 1-dimensional textures (OpenGL target = GL_TEXTURE_1D
1090 all operations on a bitmap object must be done from the render thread }
1091 TglBitmap1D = class(TglBitmap)
1094 { upload the texture data to video card
1095 @param aDataObj texture data object that contains the actual data
1096 @param aBuildWithGlu use glu functions to build mipmaps }
1097 procedure UploadDataIntern(const aDataObj: TglBitmapData; const aBuildWithGlu: Boolean);
1100 property Width; //< actual with of the texture
1102 { this method is called after constructor and initializes the object }
1103 procedure AfterConstruction; override;
1105 { upload texture data from given data object to video card
1106 @param aData texture data object that contains the actual data
1107 @param aCheckSize check size before upload and throw exception if something is wrong }
1108 procedure UploadData(const aDataObj: TglBitmapData; const aCheckSize: Boolean = true); override;
1113 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1114 { wrapper class for 2-dimensional textures (OpenGL target = GL_TEXTURE_2D)
1115 all operations on a bitmap object must be done from the render thread }
1116 TglBitmap2D = class(TglBitmap)
1119 { upload the texture data to video card
1120 @param aDataObj texture data object that contains the actual data
1121 @param aTarget target o upload data to (e.g. GL_TEXTURE_2D)
1122 @param aBuildWithGlu use glu functions to build mipmaps }
1123 procedure UploadDataIntern(const aDataObj: TglBitmapData; const aTarget: GLenum
1124 {$IFNDEF OPENGL_ES}; const aBuildWithGlu: Boolean{$ENDIF});
1127 property Width; //< actual width of the texture
1128 property Height; //< actual height of the texture
1130 { this method is called after constructor and initializes the object }
1131 procedure AfterConstruction; override;
1133 { upload texture data from given data object to video card
1134 @param aData texture data object that contains the actual data
1135 @param aCheckSize check size before upload and throw exception if something is wrong }
1136 procedure UploadData(const aDataObj: TglBitmapData; const aCheckSize: Boolean = true); override;
1140 { copy a part of the frame buffer to the texture
1141 @param aTop topmost pixel to copy
1142 @param aLeft leftmost pixel to copy
1143 @param aRight rightmost pixel to copy
1144 @param aBottom bottommost pixel to copy
1145 @param aFormat format to store data in
1146 @param aDataObj texture data object to store the data in }
1147 class procedure GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat; const aDataObj: TglBitmapData);
1151 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1152 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
1153 { wrapper class for cube maps (OpenGL target = GL_TEXTURE_CUBE_MAP)
1154 all operations on a bitmap object must be done from the render thread }
1155 TglBitmapCubeMap = class(TglBitmap2D)
1158 fGenMode: Integer; //< generation mode for the cube map (e.g. GL_REFLECTION_MAP)
1162 { this method is called after constructor and initializes the object }
1163 procedure AfterConstruction; override;
1165 { upload texture data from given data object to video card
1166 @param aData texture data object that contains the actual data
1167 @param aCheckSize check size before upload and throw exception if something is wrong }
1168 procedure UploadData(const aDataObj: TglBitmapData; const aCheckSize: Boolean = true); override;
1170 { upload texture data from given data object to video card
1171 @param aData texture data object that contains the actual data
1172 @param aCubeTarget cube map target to upload data to (e.g. GL_TEXTURE_CUBE_MAP_POSITIVE_X)
1173 @param aCheckSize check size before upload and throw exception if something is wrong }
1174 procedure UploadCubeMap(const aDataObj: TglBitmapData; const aCubeTarget: Cardinal; const aCheckSize: Boolean);
1177 @param aEnableTexCoordsGen enable cube map generator
1178 @param aEnableTextureUnit enable texture unit }
1179 procedure Bind({$IFNDEF OPENGL_ES}const aEnableTexCoordsGen: Boolean = true;{$ENDIF} const aEnableTextureUnit: Boolean = true); reintroduce; virtual;
1182 @param aDisableTexCoordsGen disable cube map generator
1183 @param aDisableTextureUnit disable texture unit }
1184 procedure Unbind({$IFNDEF OPENGL_ES}const aDisableTexCoordsGen: Boolean = true;{$ENDIF} const aDisableTextureUnit: Boolean = true); reintroduce; virtual;
1188 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
1189 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1190 { wrapper class for cube normal maps
1191 all operations on a bitmap object must be done from the render thread }
1192 TglBitmapNormalMap = class(TglBitmapCubeMap)
1194 { this method is called after constructor and initializes the object }
1195 procedure AfterConstruction; override;
1197 { create cube normal map from texture data and upload it to video card
1198 @param aSize size of each cube map texture
1199 @param aCheckSize check size before upload and throw exception if something is wrong }
1200 procedure GenerateNormalMap(const aSize: Integer = 32; const aCheckSize: Boolean = true);
1205 NULL_SIZE: TglBitmapSize = (Fields: []; X: 0; Y: 0);
1207 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
1208 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
1209 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
1210 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
1211 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
1212 procedure glBitmapSetDefaultWrap(
1213 const S: Cardinal = GL_CLAMP_TO_EDGE;
1214 const T: Cardinal = GL_CLAMP_TO_EDGE;
1215 const R: Cardinal = GL_CLAMP_TO_EDGE);
1217 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
1218 procedure glBitmapSetDefaultSwizzle(const r: GLenum = GL_RED; g: GLenum = GL_GREEN; b: GLenum = GL_BLUE; a: GLenum = GL_ALPHA);
1221 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
1222 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
1223 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
1224 function glBitmapGetDefaultFormat: TglBitmapFormat;
1225 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
1226 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
1227 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
1228 procedure glBitmapGetDefaultSwizzle(var r, g, b, a: GLenum);
1231 function glBitmapSize(X: Integer = -1; Y: Integer = -1): TglBitmapSize;
1232 function glBitmapPosition(X: Integer = -1; Y: Integer = -1): TglBitmapPixelPosition;
1233 function glBitmapRec4ub(const r, g, b, a: Byte): TglBitmapRec4ub;
1234 function glBitmapRec4ui(const r, g, b, a: Cardinal): TglBitmapRec4ui;
1235 function glBitmapRec4ul(const r, g, b, a: QWord): TglBitmapRec4ul;
1236 function glBitmapRec4ubCompare(const r1, r2: TglBitmapRec4ub): Boolean;
1237 function glBitmapRec4uiCompare(const r1, r2: TglBitmapRec4ui): Boolean;
1239 function glBitmapCreateTestData(const aFormat: TglBitmapFormat): TglBitmapData;
1242 function CreateGrayPalette: HPALETTE;
1248 Math, syncobjs, typinfo
1249 {$IF DEFINED(GLB_SUPPORT_JPEG_READ) AND DEFINED(GLB_LAZ_JPEG)}, FPReadJPEG{$IFEND};
1253 glBitmapDefaultDeleteTextureOnFree: Boolean;
1254 glBitmapDefaultFreeDataAfterGenTextures: Boolean;
1255 glBitmapDefaultFormat: TglBitmapFormat;
1256 glBitmapDefaultMipmap: TglBitmapMipMap;
1257 glBitmapDefaultFilterMin: Cardinal;
1258 glBitmapDefaultFilterMag: Cardinal;
1259 glBitmapDefaultWrapS: Cardinal;
1260 glBitmapDefaultWrapT: Cardinal;
1261 glBitmapDefaultWrapR: Cardinal;
1262 glDefaultSwizzle: array[0..3] of GLenum;
1264 ////////////////////////////////////////////////////////////////////////////////////////////////////
1266 TFormatDescriptor = class(TglBitmapFormatDescriptor)
1268 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); virtual; abstract;
1269 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); virtual; abstract;
1271 function CreateMappingData: Pointer; virtual;
1272 procedure FreeMappingData(var aMappingData: Pointer); virtual;
1274 function IsEmpty: Boolean; virtual;
1275 function MaskMatch(const aMask: TglBitmapRec4ul): Boolean; virtual;
1277 procedure PreparePixel(out aPixel: TglBitmapPixelData); virtual;
1279 constructor Create; virtual;
1281 class procedure Init;
1282 class function Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
1283 class function GetAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
1284 class function GetFromMask(const aMask: TglBitmapRec4ul; const aBitCount: Integer = 0): TFormatDescriptor;
1285 class function GetFromPrecShift(const aPrec, aShift: TglBitmapRec4ub; const aBitCount: Integer): TFormatDescriptor;
1286 class procedure Clear;
1287 class procedure Finalize;
1289 TFormatDescriptorClass = class of TFormatDescriptor;
1291 TfdEmpty = class(TFormatDescriptor);
1293 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1294 TfdAlphaUB1 = class(TFormatDescriptor) //1* unsigned byte
1295 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1296 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1299 TfdLuminanceUB1 = class(TFormatDescriptor) //1* unsigned byte
1300 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1301 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1304 TfdUniversalUB1 = class(TFormatDescriptor) //1* unsigned byte
1305 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1306 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1309 TfdLuminanceAlphaUB2 = class(TfdLuminanceUB1) //2* unsigned byte
1310 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1311 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1314 TfdRGBub3 = class(TFormatDescriptor) //3* unsigned byte
1315 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1316 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1319 TfdBGRub3 = class(TFormatDescriptor) //3* unsigned byte (inverse)
1320 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1321 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1324 TfdRGBAub4 = class(TfdRGBub3) //3* unsigned byte
1325 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1326 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1329 TfdBGRAub4 = class(TfdBGRub3) //3* unsigned byte (inverse)
1330 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1331 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1334 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1335 TfdAlphaUS1 = class(TFormatDescriptor) //1* unsigned short
1336 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1337 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1340 TfdLuminanceUS1 = class(TFormatDescriptor) //1* unsigned short
1341 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1342 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1345 TfdUniversalUS1 = class(TFormatDescriptor) //1* unsigned short
1346 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1347 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1350 TfdDepthUS1 = class(TFormatDescriptor) //1* unsigned short
1351 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1352 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1355 TfdLuminanceAlphaUS2 = class(TfdLuminanceUS1) //2* unsigned short
1356 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1357 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1360 TfdRGBus3 = class(TFormatDescriptor) //3* unsigned short
1361 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1362 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1365 TfdBGRus3 = class(TFormatDescriptor) //3* unsigned short (inverse)
1366 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1367 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1370 TfdRGBAus4 = class(TfdRGBus3) //4* unsigned short
1371 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1372 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1375 TfdARGBus4 = class(TfdRGBus3) //4* unsigned short
1376 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1377 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1380 TfdBGRAus4 = class(TfdBGRus3) //4* unsigned short (inverse)
1381 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1382 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1385 TfdABGRus4 = class(TfdBGRus3) //4* unsigned short (inverse)
1386 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1387 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1390 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1391 TfdUniversalUI1 = class(TFormatDescriptor) //1* unsigned int
1392 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1393 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1396 TfdDepthUI1 = class(TFormatDescriptor) //1* unsigned int
1397 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1398 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1401 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1402 TfdAlpha4ub1 = class(TfdAlphaUB1)
1403 procedure SetValues; override;
1406 TfdAlpha8ub1 = class(TfdAlphaUB1)
1407 procedure SetValues; override;
1410 TfdAlpha16us1 = class(TfdAlphaUS1)
1411 procedure SetValues; override;
1414 TfdLuminance4ub1 = class(TfdLuminanceUB1)
1415 procedure SetValues; override;
1418 TfdLuminance8ub1 = class(TfdLuminanceUB1)
1419 procedure SetValues; override;
1422 TfdLuminance16us1 = class(TfdLuminanceUS1)
1423 procedure SetValues; override;
1426 TfdLuminance4Alpha4ub2 = class(TfdLuminanceAlphaUB2)
1427 procedure SetValues; override;
1430 TfdLuminance6Alpha2ub2 = class(TfdLuminanceAlphaUB2)
1431 procedure SetValues; override;
1434 TfdLuminance8Alpha8ub2 = class(TfdLuminanceAlphaUB2)
1435 procedure SetValues; override;
1438 TfdLuminance12Alpha4us2 = class(TfdLuminanceAlphaUS2)
1439 procedure SetValues; override;
1442 TfdLuminance16Alpha16us2 = class(TfdLuminanceAlphaUS2)
1443 procedure SetValues; override;
1446 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1447 TfdR3G3B2ub1 = class(TfdUniversalUB1)
1448 procedure SetValues; override;
1451 TfdRGBX4us1 = class(TfdUniversalUS1)
1452 procedure SetValues; override;
1455 TfdXRGB4us1 = class(TfdUniversalUS1)
1456 procedure SetValues; override;
1459 TfdR5G6B5us1 = class(TfdUniversalUS1)
1460 procedure SetValues; override;
1463 TfdRGB5X1us1 = class(TfdUniversalUS1)
1464 procedure SetValues; override;
1467 TfdX1RGB5us1 = class(TfdUniversalUS1)
1468 procedure SetValues; override;
1471 TfdRGB8ub3 = class(TfdRGBub3)
1472 procedure SetValues; override;
1475 TfdRGBX8ui1 = class(TfdUniversalUI1)
1476 procedure SetValues; override;
1479 TfdXRGB8ui1 = class(TfdUniversalUI1)
1480 procedure SetValues; override;
1483 TfdRGB10X2ui1 = class(TfdUniversalUI1)
1484 procedure SetValues; override;
1487 TfdX2RGB10ui1 = class(TfdUniversalUI1)
1488 procedure SetValues; override;
1491 TfdRGB16us3 = class(TfdRGBus3)
1492 procedure SetValues; override;
1495 TfdRGBA4us1 = class(TfdUniversalUS1)
1496 procedure SetValues; override;
1499 TfdARGB4us1 = class(TfdUniversalUS1)
1500 procedure SetValues; override;
1503 TfdRGB5A1us1 = class(TfdUniversalUS1)
1504 procedure SetValues; override;
1507 TfdA1RGB5us1 = class(TfdUniversalUS1)
1508 procedure SetValues; override;
1511 TfdRGBA8ui1 = class(TfdUniversalUI1)
1512 procedure SetValues; override;
1515 TfdARGB8ui1 = class(TfdUniversalUI1)
1516 procedure SetValues; override;
1519 TfdRGBA8ub4 = class(TfdRGBAub4)
1520 procedure SetValues; override;
1523 TfdRGB10A2ui1 = class(TfdUniversalUI1)
1524 procedure SetValues; override;
1527 TfdA2RGB10ui1 = class(TfdUniversalUI1)
1528 procedure SetValues; override;
1531 TfdRGBA16us4 = class(TfdRGBAus4)
1532 procedure SetValues; override;
1535 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1536 TfdBGRX4us1 = class(TfdUniversalUS1)
1537 procedure SetValues; override;
1540 TfdXBGR4us1 = class(TfdUniversalUS1)
1541 procedure SetValues; override;
1544 TfdB5G6R5us1 = class(TfdUniversalUS1)
1545 procedure SetValues; override;
1548 TfdBGR5X1us1 = class(TfdUniversalUS1)
1549 procedure SetValues; override;
1552 TfdX1BGR5us1 = class(TfdUniversalUS1)
1553 procedure SetValues; override;
1556 TfdBGR8ub3 = class(TfdBGRub3)
1557 procedure SetValues; override;
1560 TfdBGRX8ui1 = class(TfdUniversalUI1)
1561 procedure SetValues; override;
1564 TfdXBGR8ui1 = class(TfdUniversalUI1)
1565 procedure SetValues; override;
1568 TfdBGR10X2ui1 = class(TfdUniversalUI1)
1569 procedure SetValues; override;
1572 TfdX2BGR10ui1 = class(TfdUniversalUI1)
1573 procedure SetValues; override;
1576 TfdBGR16us3 = class(TfdBGRus3)
1577 procedure SetValues; override;
1580 TfdBGRA4us1 = class(TfdUniversalUS1)
1581 procedure SetValues; override;
1584 TfdABGR4us1 = class(TfdUniversalUS1)
1585 procedure SetValues; override;
1588 TfdBGR5A1us1 = class(TfdUniversalUS1)
1589 procedure SetValues; override;
1592 TfdA1BGR5us1 = class(TfdUniversalUS1)
1593 procedure SetValues; override;
1596 TfdBGRA8ui1 = class(TfdUniversalUI1)
1597 procedure SetValues; override;
1600 TfdABGR8ui1 = class(TfdUniversalUI1)
1601 procedure SetValues; override;
1604 TfdBGRA8ub4 = class(TfdBGRAub4)
1605 procedure SetValues; override;
1608 TfdBGR10A2ui1 = class(TfdUniversalUI1)
1609 procedure SetValues; override;
1612 TfdA2BGR10ui1 = class(TfdUniversalUI1)
1613 procedure SetValues; override;
1616 TfdBGRA16us4 = class(TfdBGRAus4)
1617 procedure SetValues; override;
1620 TfdDepth16us1 = class(TfdDepthUS1)
1621 procedure SetValues; override;
1624 TfdDepth24ui1 = class(TfdDepthUI1)
1625 procedure SetValues; override;
1628 TfdDepth32ui1 = class(TfdDepthUI1)
1629 procedure SetValues; override;
1632 TfdS3tcDtx1RGBA = class(TFormatDescriptor)
1633 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1634 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1635 procedure SetValues; override;
1638 TfdS3tcDtx3RGBA = class(TFormatDescriptor)
1639 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1640 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1641 procedure SetValues; override;
1644 TfdS3tcDtx5RGBA = class(TFormatDescriptor)
1645 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1646 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1647 procedure SetValues; override;
1650 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1651 TbmpBitfieldFormat = class(TFormatDescriptor)
1653 procedure SetCustomValues(const aBPP: Integer; aMask: TglBitmapRec4ul); overload;
1654 procedure SetCustomValues(const aBBP: Integer; const aPrec, aShift: TglBitmapRec4ub); overload;
1655 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1656 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1659 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1660 TbmpColorTableEnty = packed record
1663 TbmpColorTable = array of TbmpColorTableEnty;
1664 TbmpColorTableFormat = class(TFormatDescriptor)
1666 fColorTable: TbmpColorTable;
1668 procedure SetValues; override;
1670 property ColorTable: TbmpColorTable read fColorTable write fColorTable;
1672 procedure SetCustomValues(const aFormat: TglBitmapFormat; const aBPP: Integer; const aPrec, aShift: TglBitmapRec4ub); overload;
1673 procedure CalcValues;
1674 procedure CreateColorTable;
1676 function CreateMappingData: Pointer; override;
1677 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1678 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1679 destructor Destroy; override;
1683 LUMINANCE_WEIGHT_R = 0.30;
1684 LUMINANCE_WEIGHT_G = 0.59;
1685 LUMINANCE_WEIGHT_B = 0.11;
1687 ALPHA_WEIGHT_R = 0.30;
1688 ALPHA_WEIGHT_G = 0.59;
1689 ALPHA_WEIGHT_B = 0.11;
1691 DEPTH_WEIGHT_R = 0.333333333;
1692 DEPTH_WEIGHT_G = 0.333333333;
1693 DEPTH_WEIGHT_B = 0.333333333;
1695 FORMAT_DESCRIPTOR_CLASSES: array[TglBitmapFormat] of TFormatDescriptorClass = (
1706 TfdLuminance4Alpha4ub2,
1707 TfdLuminance6Alpha2ub2,
1708 TfdLuminance8Alpha8ub2,
1709 TfdLuminance12Alpha4us2,
1710 TfdLuminance16Alpha16us2,
1769 FormatDescriptorCS: TCriticalSection;
1770 FormatDescriptors: array[TglBitmapFormat] of TFormatDescriptor;
1772 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1773 constructor EglBitmapUnsupportedFormat.Create(const aFormat: TglBitmapFormat);
1775 inherited Create('unsupported format: ' + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
1778 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1779 constructor EglBitmapUnsupportedFormat.Create(const aMsg: String; const aFormat: TglBitmapFormat);
1781 inherited Create(aMsg + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
1784 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1785 function glBitmapSize(X: Integer; Y: Integer): TglBitmapSize;
1787 result.Fields := [];
1789 result.Fields := result.Fields + [ffX];
1791 result.Fields := result.Fields + [ffY];
1792 result.X := Max(0, X);
1793 result.Y := Max(0, Y);
1796 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1797 function glBitmapPosition(X: Integer; Y: Integer): TglBitmapPixelPosition;
1799 result := glBitmapSize(X, Y);
1802 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1803 function glBitmapRec4ub(const r, g, b, a: Byte): TglBitmapRec4ub;
1811 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1812 function glBitmapRec4ui(const r, g, b, a: Cardinal): TglBitmapRec4ui;
1820 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1821 function glBitmapRec4ul(const r, g, b, a: QWord): TglBitmapRec4ul;
1829 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1830 function glBitmapRec4ubCompare(const r1, r2: TglBitmapRec4ub): Boolean;
1835 for i := 0 to high(r1.arr) do
1836 if (r1.arr[i] <> r2.arr[i]) then
1841 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1842 function glBitmapRec4uiCompare(const r1, r2: TglBitmapRec4ui): Boolean;
1847 for i := 0 to high(r1.arr) do
1848 if (r1.arr[i] <> r2.arr[i]) then
1853 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1854 function glBitmapCreateTestData(const aFormat: TglBitmapFormat): TglBitmapData;
1856 desc: TFormatDescriptor;
1860 px: TglBitmapPixelData;
1863 desc := TFormatDescriptor.Get(aFormat);
1864 if (desc.IsCompressed) or (desc.glFormat = 0) then
1867 p := GetMemory(ceil(25 * desc.BytesPerPixel)); // 5 x 5 pixel
1868 md := desc.CreateMappingData;
1871 desc.PreparePixel(px);
1873 for x := 0 to 4 do begin
1874 px.Data := glBitmapRec4ui(0, 0, 0, 0);
1875 for i := 0 to 3 do begin
1876 if ((y < 3) and (y = i)) or
1877 ((y = 3) and (i < 3)) or
1878 ((y = 4) and (i = 3))
1880 px.Data.arr[i] := Trunc(px.Range.arr[i] / 4 * x)
1881 else if ((y < 4) and (i = 3)) or
1882 ((y = 4) and (i < 3))
1884 px.Data.arr[i] := px.Range.arr[i]
1886 px.Data.arr[i] := 0; //px.Range.arr[i];
1888 desc.Map(px, tmp, md);
1891 desc.FreeMappingData(md);
1894 result := TglBitmapData.Create(glBitmapPosition(5, 5), aFormat, p);
1897 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1898 function glBitmapShiftRec(const r, g, b, a: Byte): TglBitmapRec4ub;
1906 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1907 function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes;
1913 tfAlpha4ub1, tfAlpha8ub1,
1914 tfLuminance4ub1, tfLuminance8ub1, tfR3G3B2ub1,
1917 tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
1918 tfRGBX4us1, tfXRGB4us1, tfRGB5X1us1, tfX1RGB5us1, tfR5G6B5us1, tfRGB5A1us1, tfA1RGB5us1, tfRGBA4us1, tfARGB4us1,
1919 tfBGRX4us1, tfXBGR4us1, tfBGR5X1us1, tfX1BGR5us1, tfB5G6R5us1, tfBGR5A1us1, tfA1BGR5us1, tfBGRA4us1, tfABGR4us1,
1922 tfBGR8ub3, tfRGB8ub3,
1925 tfRGBX8ui1, tfXRGB8ui1, tfRGB10X2ui1, tfX2RGB10ui1, tfRGBA8ui1, tfARGB8ui1, tfRGBA8ub4, tfRGB10A2ui1, tfA2RGB10ui1,
1926 tfBGRX8ui1, tfXBGR8ui1, tfBGR10X2ui1, tfX2BGR10ui1, tfBGRA8ui1, tfABGR8ui1, tfBGRA8ub4, tfBGR10A2ui1, tfA2BGR10ui1])
1928 result := result + [ ftBMP ];
1932 tfAlpha4ub1, tfAlpha8ub1, tfLuminance4ub1, tfLuminance8ub1,
1935 tfAlpha16us1, tfLuminance16us1,
1936 tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
1937 tfX1RGB5us1, tfARGB4us1, tfA1RGB5us1, tfDepth16us1,
1943 tfX2RGB10ui1, tfARGB8ui1, tfBGRA8ub4, tfA2RGB10ui1,
1944 tfDepth24ui1, tfDepth32ui1])
1946 result := result + [ftTGA];
1948 if not (aFormat in [tfEmpty, tfRGB16us3, tfBGR16us3]) then
1949 result := result + [ftDDS];
1951 {$IFDEF GLB_SUPPORT_PNG_WRITE}
1953 tfAlpha8ub1, tfLuminance8ub1, tfLuminance8Alpha8ub2,
1954 tfRGB8ub3, tfRGBA8ui1,
1955 tfBGR8ub3, tfBGRA8ui1] then
1956 result := result + [ftPNG];
1959 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
1960 if aFormat in [tfAlpha8ub1, tfLuminance8ub1, tfRGB8ub3, tfBGR8ub3] then
1961 result := result + [ftJPEG];
1965 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1966 function IsPowerOfTwo(aNumber: Integer): Boolean;
1968 while (aNumber and 1) = 0 do
1969 aNumber := aNumber shr 1;
1970 result := aNumber = 1;
1973 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1974 function GetTopMostBit(aBitSet: QWord): Integer;
1977 while aBitSet > 0 do begin
1979 aBitSet := aBitSet shr 1;
1983 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1984 function CountSetBits(aBitSet: QWord): Integer;
1987 while aBitSet > 0 do begin
1988 if (aBitSet and 1) = 1 then
1990 aBitSet := aBitSet shr 1;
1994 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1995 function LuminanceWeight(const aPixel: TglBitmapPixelData): Cardinal;
1998 LUMINANCE_WEIGHT_R * aPixel.Data.r +
1999 LUMINANCE_WEIGHT_G * aPixel.Data.g +
2000 LUMINANCE_WEIGHT_B * aPixel.Data.b);
2003 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2004 function DepthWeight(const aPixel: TglBitmapPixelData): Cardinal;
2007 DEPTH_WEIGHT_R * aPixel.Data.r +
2008 DEPTH_WEIGHT_G * aPixel.Data.g +
2009 DEPTH_WEIGHT_B * aPixel.Data.b);
2012 {$IFDEF GLB_SDL_IMAGE}
2013 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2014 // SDL Image Helper /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2015 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2016 function glBitmapRWseek(context: PSDL_RWops; offset: Integer; whence: Integer): Integer; cdecl;
2018 result := TStream(context^.unknown.data1).Seek(offset, whence);
2021 function glBitmapRWread(context: PSDL_RWops; Ptr: Pointer; size: Integer; maxnum : Integer): Integer; cdecl;
2023 result := TStream(context^.unknown.data1).Read(Ptr^, size * maxnum);
2026 function glBitmapRWwrite(context: PSDL_RWops; Ptr: Pointer; size: Integer; num: Integer): Integer; cdecl;
2028 result := TStream(context^.unknown.data1).Write(Ptr^, size * num);
2031 function glBitmapRWclose(context: PSDL_RWops): Integer; cdecl;
2036 function glBitmapCreateRWops(Stream: TStream): PSDL_RWops;
2038 result := SDL_AllocRW;
2040 if result = nil then
2041 raise EglBitmap.Create('glBitmapCreateRWops - SDL_AllocRW failed.');
2043 result^.seek := glBitmapRWseek;
2044 result^.read := glBitmapRWread;
2045 result^.write := glBitmapRWwrite;
2046 result^.close := glBitmapRWclose;
2047 result^.unknown.data1 := Stream;
2051 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2052 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
2054 glBitmapDefaultDeleteTextureOnFree := aDeleteTextureOnFree;
2057 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2058 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
2060 glBitmapDefaultFreeDataAfterGenTextures := aFreeData;
2063 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2064 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
2066 glBitmapDefaultMipmap := aValue;
2069 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2070 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
2072 glBitmapDefaultFormat := aFormat;
2075 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2076 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
2078 glBitmapDefaultFilterMin := aMin;
2079 glBitmapDefaultFilterMag := aMag;
2082 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2083 procedure glBitmapSetDefaultWrap(const S: Cardinal = GL_CLAMP_TO_EDGE; const T: Cardinal = GL_CLAMP_TO_EDGE; const R: Cardinal = GL_CLAMP_TO_EDGE);
2085 glBitmapDefaultWrapS := S;
2086 glBitmapDefaultWrapT := T;
2087 glBitmapDefaultWrapR := R;
2090 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2091 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
2092 procedure glBitmapSetDefaultSwizzle(const r: GLenum = GL_RED; g: GLenum = GL_GREEN; b: GLenum = GL_BLUE; a: GLenum = GL_ALPHA);
2094 glDefaultSwizzle[0] := r;
2095 glDefaultSwizzle[1] := g;
2096 glDefaultSwizzle[2] := b;
2097 glDefaultSwizzle[3] := a;
2101 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2102 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
2104 result := glBitmapDefaultDeleteTextureOnFree;
2107 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2108 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
2110 result := glBitmapDefaultFreeDataAfterGenTextures;
2113 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2114 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
2116 result := glBitmapDefaultMipmap;
2119 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2120 function glBitmapGetDefaultFormat: TglBitmapFormat;
2122 result := glBitmapDefaultFormat;
2125 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2126 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
2128 aMin := glBitmapDefaultFilterMin;
2129 aMag := glBitmapDefaultFilterMag;
2132 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2133 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
2135 S := glBitmapDefaultWrapS;
2136 T := glBitmapDefaultWrapT;
2137 R := glBitmapDefaultWrapR;
2140 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
2141 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2142 procedure glBitmapGetDefaultSwizzle(var r, g, b, a: GLenum);
2144 r := glDefaultSwizzle[0];
2145 g := glDefaultSwizzle[1];
2146 b := glDefaultSwizzle[2];
2147 a := glDefaultSwizzle[3];
2151 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2152 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2153 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2154 function TFormatDescriptor.CreateMappingData: Pointer;
2159 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2160 procedure TFormatDescriptor.FreeMappingData(var aMappingData: Pointer);
2165 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2166 function TFormatDescriptor.IsEmpty: Boolean;
2168 result := (fFormat = tfEmpty);
2171 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2172 function TFormatDescriptor.MaskMatch(const aMask: TglBitmapRec4ul): Boolean;
2178 if (aMask.r = 0) and (aMask.g = 0) and (aMask.b = 0) and (aMask.a = 0) then
2179 raise EglBitmap.Create('FormatCheckFormat - All Masks are 0');
2182 if (aMask.arr[i] <> m.arr[i]) then
2187 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2188 procedure TFormatDescriptor.PreparePixel(out aPixel: TglBitmapPixelData);
2190 FillChar(aPixel{%H-}, SizeOf(aPixel), 0);
2191 aPixel.Data := Range;
2192 aPixel.Format := fFormat;
2193 aPixel.Range := Range;
2196 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2197 constructor TFormatDescriptor.Create;
2202 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2203 //TfdAlpha_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2204 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2205 procedure TfdAlphaUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2207 aData^ := aPixel.Data.a;
2211 procedure TfdAlphaUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2216 aPixel.Data.a := aData^;
2220 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2221 //TfdLuminance_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2222 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2223 procedure TfdLuminanceUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2225 aData^ := LuminanceWeight(aPixel);
2229 procedure TfdLuminanceUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2231 aPixel.Data.r := aData^;
2232 aPixel.Data.g := aData^;
2233 aPixel.Data.b := aData^;
2238 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2239 //TfdUniversal_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2240 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2241 procedure TfdUniversalUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2247 if (Range.arr[i] > 0) then
2248 aData^ := aData^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
2252 procedure TfdUniversalUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2257 aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and Range.arr[i];
2261 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2262 //TfdLuminanceAlpha_UB2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2263 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2264 procedure TfdLuminanceAlphaUB2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2266 inherited Map(aPixel, aData, aMapData);
2267 aData^ := aPixel.Data.a;
2271 procedure TfdLuminanceAlphaUB2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2273 inherited Unmap(aData, aPixel, aMapData);
2274 aPixel.Data.a := aData^;
2278 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2279 //TfdRGB_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2280 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2281 procedure TfdRGBub3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2283 aData^ := aPixel.Data.r;
2285 aData^ := aPixel.Data.g;
2287 aData^ := aPixel.Data.b;
2291 procedure TfdRGBub3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2293 aPixel.Data.r := aData^;
2295 aPixel.Data.g := aData^;
2297 aPixel.Data.b := aData^;
2302 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2303 //TfdBGR_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2304 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2305 procedure TfdBGRub3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2307 aData^ := aPixel.Data.b;
2309 aData^ := aPixel.Data.g;
2311 aData^ := aPixel.Data.r;
2315 procedure TfdBGRub3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2317 aPixel.Data.b := aData^;
2319 aPixel.Data.g := aData^;
2321 aPixel.Data.r := aData^;
2326 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2327 //TfdRGBA_UB4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2328 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2329 procedure TfdRGBAub4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2331 inherited Map(aPixel, aData, aMapData);
2332 aData^ := aPixel.Data.a;
2336 procedure TfdRGBAub4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2338 inherited Unmap(aData, aPixel, aMapData);
2339 aPixel.Data.a := aData^;
2343 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2344 //TfdBGRA_UB4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2345 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2346 procedure TfdBGRAub4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2348 inherited Map(aPixel, aData, aMapData);
2349 aData^ := aPixel.Data.a;
2353 procedure TfdBGRAub4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2355 inherited Unmap(aData, aPixel, aMapData);
2356 aPixel.Data.a := aData^;
2360 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2361 //TfdAlpha_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2362 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2363 procedure TfdAlphaUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2365 PWord(aData)^ := aPixel.Data.a;
2369 procedure TfdAlphaUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2374 aPixel.Data.a := PWord(aData)^;
2378 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2379 //TfdLuminance_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2380 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2381 procedure TfdLuminanceUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2383 PWord(aData)^ := LuminanceWeight(aPixel);
2387 procedure TfdLuminanceUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2389 aPixel.Data.r := PWord(aData)^;
2390 aPixel.Data.g := PWord(aData)^;
2391 aPixel.Data.b := PWord(aData)^;
2396 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2397 //TfdUniversal_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2398 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2399 procedure TfdUniversalUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2405 if (Range.arr[i] > 0) then
2406 PWord(aData)^ := PWord(aData)^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
2410 procedure TfdUniversalUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2415 aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and Range.arr[i];
2419 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2420 //TfdDepth_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2421 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2422 procedure TfdDepthUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2424 PWord(aData)^ := DepthWeight(aPixel);
2428 procedure TfdDepthUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2430 aPixel.Data.r := PWord(aData)^;
2431 aPixel.Data.g := PWord(aData)^;
2432 aPixel.Data.b := PWord(aData)^;
2433 aPixel.Data.a := PWord(aData)^;;
2437 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2438 //TfdLuminanceAlpha_US2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2439 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2440 procedure TfdLuminanceAlphaUS2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2442 inherited Map(aPixel, aData, aMapData);
2443 PWord(aData)^ := aPixel.Data.a;
2447 procedure TfdLuminanceAlphaUS2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2449 inherited Unmap(aData, aPixel, aMapData);
2450 aPixel.Data.a := PWord(aData)^;
2454 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2455 //TfdRGB_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2456 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2457 procedure TfdRGBus3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2459 PWord(aData)^ := aPixel.Data.r;
2461 PWord(aData)^ := aPixel.Data.g;
2463 PWord(aData)^ := aPixel.Data.b;
2467 procedure TfdRGBus3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2469 aPixel.Data.r := PWord(aData)^;
2471 aPixel.Data.g := PWord(aData)^;
2473 aPixel.Data.b := PWord(aData)^;
2478 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2479 //TfdBGR_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2480 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2481 procedure TfdBGRus3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2483 PWord(aData)^ := aPixel.Data.b;
2485 PWord(aData)^ := aPixel.Data.g;
2487 PWord(aData)^ := aPixel.Data.r;
2491 procedure TfdBGRus3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2493 aPixel.Data.b := PWord(aData)^;
2495 aPixel.Data.g := PWord(aData)^;
2497 aPixel.Data.r := PWord(aData)^;
2502 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2503 //TfdRGBA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2504 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2505 procedure TfdRGBAus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2507 inherited Map(aPixel, aData, aMapData);
2508 PWord(aData)^ := aPixel.Data.a;
2512 procedure TfdRGBAus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2514 inherited Unmap(aData, aPixel, aMapData);
2515 aPixel.Data.a := PWord(aData)^;
2519 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2520 //TfdARGB_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2521 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2522 procedure TfdARGBus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2524 PWord(aData)^ := aPixel.Data.a;
2526 inherited Map(aPixel, aData, aMapData);
2529 procedure TfdARGBus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2531 aPixel.Data.a := PWord(aData)^;
2533 inherited Unmap(aData, aPixel, aMapData);
2536 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2537 //TfdBGRA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2538 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2539 procedure TfdBGRAus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2541 inherited Map(aPixel, aData, aMapData);
2542 PWord(aData)^ := aPixel.Data.a;
2546 procedure TfdBGRAus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2548 inherited Unmap(aData, aPixel, aMapData);
2549 aPixel.Data.a := PWord(aData)^;
2553 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2554 //TfdABGR_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2555 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2556 procedure TfdABGRus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2558 PWord(aData)^ := aPixel.Data.a;
2560 inherited Map(aPixel, aData, aMapData);
2563 procedure TfdABGRus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2565 aPixel.Data.a := PWord(aData)^;
2567 inherited Unmap(aData, aPixel, aMapData);
2570 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2571 //TfdUniversal_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2572 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2573 procedure TfdUniversalUI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2577 PCardinal(aData)^ := 0;
2579 if (Range.arr[i] > 0) then
2580 PCardinal(aData)^ := PCardinal(aData)^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
2584 procedure TfdUniversalUI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2589 aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and Range.arr[i];
2593 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2594 //TfdDepth_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2595 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2596 procedure TfdDepthUI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2598 PCardinal(aData)^ := DepthWeight(aPixel);
2602 procedure TfdDepthUI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2604 aPixel.Data.r := PCardinal(aData)^;
2605 aPixel.Data.g := PCardinal(aData)^;
2606 aPixel.Data.b := PCardinal(aData)^;
2607 aPixel.Data.a := PCardinal(aData)^;
2611 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2612 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2613 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2614 procedure TfdAlpha4ub1.SetValues;
2616 inherited SetValues;
2618 fFormat := tfAlpha4ub1;
2619 fWithAlpha := tfAlpha4ub1;
2620 fPrecision := glBitmapRec4ub(0, 0, 0, 8);
2621 fShift := glBitmapRec4ub(0, 0, 0, 0);
2623 fOpenGLFormat := tfAlpha4ub1;
2624 fglFormat := GL_ALPHA;
2625 fglInternalFormat := GL_ALPHA4;
2626 fglDataFormat := GL_UNSIGNED_BYTE;
2628 fOpenGLFormat := tfAlpha8ub1;
2632 procedure TfdAlpha8ub1.SetValues;
2634 inherited SetValues;
2636 fFormat := tfAlpha8ub1;
2637 fWithAlpha := tfAlpha8ub1;
2638 fPrecision := glBitmapRec4ub(0, 0, 0, 8);
2639 fShift := glBitmapRec4ub(0, 0, 0, 0);
2640 fOpenGLFormat := tfAlpha8ub1;
2641 fglFormat := GL_ALPHA;
2642 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_ALPHA8{$ELSE}GL_ALPHA{$ENDIF};
2643 fglDataFormat := GL_UNSIGNED_BYTE;
2646 procedure TfdAlpha16us1.SetValues;
2648 inherited SetValues;
2649 fBitsPerPixel := 16;
2650 fFormat := tfAlpha16us1;
2651 fWithAlpha := tfAlpha16us1;
2652 fPrecision := glBitmapRec4ub(0, 0, 0, 16);
2653 fShift := glBitmapRec4ub(0, 0, 0, 0);
2655 fOpenGLFormat := tfAlpha16us1;
2656 fglFormat := GL_ALPHA;
2657 fglInternalFormat := GL_ALPHA16;
2658 fglDataFormat := GL_UNSIGNED_SHORT;
2660 fOpenGLFormat := tfAlpha8ub1;
2664 procedure TfdLuminance4ub1.SetValues;
2666 inherited SetValues;
2668 fFormat := tfLuminance4ub1;
2669 fWithAlpha := tfLuminance4Alpha4ub2;
2670 fWithoutAlpha := tfLuminance4ub1;
2671 fPrecision := glBitmapRec4ub(8, 8, 8, 0);
2672 fShift := glBitmapRec4ub(0, 0, 0, 0);
2674 fOpenGLFormat := tfLuminance4ub1;
2675 fglFormat := GL_LUMINANCE;
2676 fglInternalFormat := GL_LUMINANCE4;
2677 fglDataFormat := GL_UNSIGNED_BYTE;
2679 fOpenGLFormat := tfLuminance8ub1;
2683 procedure TfdLuminance8ub1.SetValues;
2685 inherited SetValues;
2687 fFormat := tfLuminance8ub1;
2688 fWithAlpha := tfLuminance8Alpha8ub2;
2689 fWithoutAlpha := tfLuminance8ub1;
2690 fOpenGLFormat := tfLuminance8ub1;
2691 fPrecision := glBitmapRec4ub(8, 8, 8, 0);
2692 fShift := glBitmapRec4ub(0, 0, 0, 0);
2693 fglFormat := GL_LUMINANCE;
2694 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_LUMINANCE8{$ELSE}GL_LUMINANCE{$ENDIF};
2695 fglDataFormat := GL_UNSIGNED_BYTE;
2698 procedure TfdLuminance16us1.SetValues;
2700 inherited SetValues;
2701 fBitsPerPixel := 16;
2702 fFormat := tfLuminance16us1;
2703 fWithAlpha := tfLuminance16Alpha16us2;
2704 fWithoutAlpha := tfLuminance16us1;
2705 fPrecision := glBitmapRec4ub(16, 16, 16, 0);
2706 fShift := glBitmapRec4ub( 0, 0, 0, 0);
2708 fOpenGLFormat := tfLuminance16us1;
2709 fglFormat := GL_LUMINANCE;
2710 fglInternalFormat := GL_LUMINANCE16;
2711 fglDataFormat := GL_UNSIGNED_SHORT;
2713 fOpenGLFormat := tfLuminance8ub1;
2717 procedure TfdLuminance4Alpha4ub2.SetValues;
2719 inherited SetValues;
2720 fBitsPerPixel := 16;
2721 fFormat := tfLuminance4Alpha4ub2;
2722 fWithAlpha := tfLuminance4Alpha4ub2;
2723 fWithoutAlpha := tfLuminance4ub1;
2724 fPrecision := glBitmapRec4ub(8, 8, 8, 8);
2725 fShift := glBitmapRec4ub(0, 0, 0, 8);
2727 fOpenGLFormat := tfLuminance4Alpha4ub2;
2728 fglFormat := GL_LUMINANCE_ALPHA;
2729 fglInternalFormat := GL_LUMINANCE4_ALPHA4;
2730 fglDataFormat := GL_UNSIGNED_BYTE;
2732 fOpenGLFormat := tfLuminance8Alpha8ub2;
2736 procedure TfdLuminance6Alpha2ub2.SetValues;
2738 inherited SetValues;
2739 fBitsPerPixel := 16;
2740 fFormat := tfLuminance6Alpha2ub2;
2741 fWithAlpha := tfLuminance6Alpha2ub2;
2742 fWithoutAlpha := tfLuminance8ub1;
2743 fPrecision := glBitmapRec4ub(8, 8, 8, 8);
2744 fShift := glBitmapRec4ub(0, 0, 0, 8);
2746 fOpenGLFormat := tfLuminance6Alpha2ub2;
2747 fglFormat := GL_LUMINANCE_ALPHA;
2748 fglInternalFormat := GL_LUMINANCE6_ALPHA2;
2749 fglDataFormat := GL_UNSIGNED_BYTE;
2751 fOpenGLFormat := tfLuminance8Alpha8ub2;
2755 procedure TfdLuminance8Alpha8ub2.SetValues;
2757 inherited SetValues;
2758 fBitsPerPixel := 16;
2759 fFormat := tfLuminance8Alpha8ub2;
2760 fWithAlpha := tfLuminance8Alpha8ub2;
2761 fWithoutAlpha := tfLuminance8ub1;
2762 fOpenGLFormat := tfLuminance8Alpha8ub2;
2763 fPrecision := glBitmapRec4ub(8, 8, 8, 8);
2764 fShift := glBitmapRec4ub(0, 0, 0, 8);
2765 fglFormat := GL_LUMINANCE_ALPHA;
2766 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_LUMINANCE8_ALPHA8{$ELSE}GL_LUMINANCE_ALPHA{$ENDIF};
2767 fglDataFormat := GL_UNSIGNED_BYTE;
2770 procedure TfdLuminance12Alpha4us2.SetValues;
2772 inherited SetValues;
2773 fBitsPerPixel := 32;
2774 fFormat := tfLuminance12Alpha4us2;
2775 fWithAlpha := tfLuminance12Alpha4us2;
2776 fWithoutAlpha := tfLuminance16us1;
2777 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
2778 fShift := glBitmapRec4ub( 0, 0, 0, 16);
2780 fOpenGLFormat := tfLuminance12Alpha4us2;
2781 fglFormat := GL_LUMINANCE_ALPHA;
2782 fglInternalFormat := GL_LUMINANCE12_ALPHA4;
2783 fglDataFormat := GL_UNSIGNED_SHORT;
2785 fOpenGLFormat := tfLuminance8Alpha8ub2;
2789 procedure TfdLuminance16Alpha16us2.SetValues;
2791 inherited SetValues;
2792 fBitsPerPixel := 32;
2793 fFormat := tfLuminance16Alpha16us2;
2794 fWithAlpha := tfLuminance16Alpha16us2;
2795 fWithoutAlpha := tfLuminance16us1;
2796 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
2797 fShift := glBitmapRec4ub( 0, 0, 0, 16);
2799 fOpenGLFormat := tfLuminance16Alpha16us2;
2800 fglFormat := GL_LUMINANCE_ALPHA;
2801 fglInternalFormat := GL_LUMINANCE16_ALPHA16;
2802 fglDataFormat := GL_UNSIGNED_SHORT;
2804 fOpenGLFormat := tfLuminance8Alpha8ub2;
2808 procedure TfdR3G3B2ub1.SetValues;
2810 inherited SetValues;
2812 fFormat := tfR3G3B2ub1;
2813 fWithAlpha := tfRGBA4us1;
2814 fWithoutAlpha := tfR3G3B2ub1;
2815 fRGBInverted := tfEmpty;
2816 fPrecision := glBitmapRec4ub(3, 3, 2, 0);
2817 fShift := glBitmapRec4ub(5, 2, 0, 0);
2819 fOpenGLFormat := tfR3G3B2ub1;
2820 fglFormat := GL_RGB;
2821 fglInternalFormat := GL_R3_G3_B2;
2822 fglDataFormat := GL_UNSIGNED_BYTE_3_3_2;
2824 fOpenGLFormat := tfR5G6B5us1;
2828 procedure TfdRGBX4us1.SetValues;
2830 inherited SetValues;
2831 fBitsPerPixel := 16;
2832 fFormat := tfRGBX4us1;
2833 fWithAlpha := tfRGBA4us1;
2834 fWithoutAlpha := tfRGBX4us1;
2835 fRGBInverted := tfBGRX4us1;
2836 fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
2837 fShift := glBitmapRec4ub(12, 8, 4, 0);
2839 fOpenGLFormat := tfRGBX4us1;
2840 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
2841 fglInternalFormat := GL_RGB4;
2842 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
2844 fOpenGLFormat := tfR5G6B5us1;
2848 procedure TfdXRGB4us1.SetValues;
2850 inherited SetValues;
2851 fBitsPerPixel := 16;
2852 fFormat := tfXRGB4us1;
2853 fWithAlpha := tfARGB4us1;
2854 fWithoutAlpha := tfXRGB4us1;
2855 fRGBInverted := tfXBGR4us1;
2856 fPrecision := glBitmapRec4ub(4, 4, 4, 0);
2857 fShift := glBitmapRec4ub(8, 4, 0, 0);
2859 fOpenGLFormat := tfXRGB4us1;
2860 fglFormat := GL_BGRA;
2861 fglInternalFormat := GL_RGB4;
2862 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
2864 fOpenGLFormat := tfR5G6B5us1;
2868 procedure TfdR5G6B5us1.SetValues;
2870 inherited SetValues;
2871 fBitsPerPixel := 16;
2872 fFormat := tfR5G6B5us1;
2873 fWithAlpha := tfRGB5A1us1;
2874 fWithoutAlpha := tfR5G6B5us1;
2875 fRGBInverted := tfB5G6R5us1;
2876 fPrecision := glBitmapRec4ub( 5, 6, 5, 0);
2877 fShift := glBitmapRec4ub(11, 5, 0, 0);
2878 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
2879 fOpenGLFormat := tfR5G6B5us1;
2880 fglFormat := GL_RGB;
2881 fglInternalFormat := GL_RGB565;
2882 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5;
2884 fOpenGLFormat := tfRGB8ub3;
2888 procedure TfdRGB5X1us1.SetValues;
2890 inherited SetValues;
2891 fBitsPerPixel := 16;
2892 fFormat := tfRGB5X1us1;
2893 fWithAlpha := tfRGB5A1us1;
2894 fWithoutAlpha := tfRGB5X1us1;
2895 fRGBInverted := tfBGR5X1us1;
2896 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
2897 fShift := glBitmapRec4ub(11, 6, 1, 0);
2899 fOpenGLFormat := tfRGB5X1us1;
2900 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
2901 fglInternalFormat := GL_RGB5;
2902 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
2904 fOpenGLFormat := tfR5G6B5us1;
2908 procedure TfdX1RGB5us1.SetValues;
2910 inherited SetValues;
2911 fBitsPerPixel := 16;
2912 fFormat := tfX1RGB5us1;
2913 fWithAlpha := tfA1RGB5us1;
2914 fWithoutAlpha := tfX1RGB5us1;
2915 fRGBInverted := tfX1BGR5us1;
2916 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
2917 fShift := glBitmapRec4ub(10, 5, 0, 0);
2919 fOpenGLFormat := tfX1RGB5us1;
2920 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
2921 fglInternalFormat := GL_RGB5;
2922 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
2924 fOpenGLFormat := tfR5G6B5us1;
2928 procedure TfdRGB8ub3.SetValues;
2930 inherited SetValues;
2931 fBitsPerPixel := 24;
2932 fFormat := tfRGB8ub3;
2933 fWithAlpha := tfRGBA8ub4;
2934 fWithoutAlpha := tfRGB8ub3;
2935 fRGBInverted := tfBGR8ub3;
2936 fPrecision := glBitmapRec4ub(8, 8, 8, 0);
2937 fShift := glBitmapRec4ub(0, 8, 16, 0);
2938 fOpenGLFormat := tfRGB8ub3;
2939 fglFormat := GL_RGB;
2940 fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}GL_RGB8{$ELSE}GL_RGB{$IFEND};
2941 fglDataFormat := GL_UNSIGNED_BYTE;
2944 procedure TfdRGBX8ui1.SetValues;
2946 inherited SetValues;
2947 fBitsPerPixel := 32;
2948 fFormat := tfRGBX8ui1;
2949 fWithAlpha := tfRGBA8ui1;
2950 fWithoutAlpha := tfRGBX8ui1;
2951 fRGBInverted := tfBGRX8ui1;
2952 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
2953 fShift := glBitmapRec4ub(24, 16, 8, 0);
2955 fOpenGLFormat := tfRGBX8ui1;
2956 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
2957 fglInternalFormat := GL_RGB8;
2958 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
2960 fOpenGLFormat := tfRGB8ub3;
2964 procedure TfdXRGB8ui1.SetValues;
2966 inherited SetValues;
2967 fBitsPerPixel := 32;
2968 fFormat := tfXRGB8ui1;
2969 fWithAlpha := tfXRGB8ui1;
2970 fWithoutAlpha := tfXRGB8ui1;
2971 fOpenGLFormat := tfXRGB8ui1;
2972 fRGBInverted := tfXBGR8ui1;
2973 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
2974 fShift := glBitmapRec4ub(16, 8, 0, 0);
2976 fOpenGLFormat := tfXRGB8ui1;
2977 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
2978 fglInternalFormat := GL_RGB8;
2979 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
2981 fOpenGLFormat := tfRGB8ub3;
2985 procedure TfdRGB10X2ui1.SetValues;
2987 inherited SetValues;
2988 fBitsPerPixel := 32;
2989 fFormat := tfRGB10X2ui1;
2990 fWithAlpha := tfRGB10A2ui1;
2991 fWithoutAlpha := tfRGB10X2ui1;
2992 fRGBInverted := tfBGR10X2ui1;
2993 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
2994 fShift := glBitmapRec4ub(22, 12, 2, 0);
2996 fOpenGLFormat := tfRGB10X2ui1;
2997 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
2998 fglInternalFormat := GL_RGB10;
2999 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3001 fOpenGLFormat := tfRGB16us3;
3005 procedure TfdX2RGB10ui1.SetValues;
3007 inherited SetValues;
3008 fBitsPerPixel := 32;
3009 fFormat := tfX2RGB10ui1;
3010 fWithAlpha := tfA2RGB10ui1;
3011 fWithoutAlpha := tfX2RGB10ui1;
3012 fRGBInverted := tfX2BGR10ui1;
3013 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3014 fShift := glBitmapRec4ub(20, 10, 0, 0);
3016 fOpenGLFormat := tfX2RGB10ui1;
3017 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3018 fglInternalFormat := GL_RGB10;
3019 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3021 fOpenGLFormat := tfRGB16us3;
3025 procedure TfdRGB16us3.SetValues;
3027 inherited SetValues;
3028 fBitsPerPixel := 48;
3029 fFormat := tfRGB16us3;
3030 fWithAlpha := tfRGBA16us4;
3031 fWithoutAlpha := tfRGB16us3;
3032 fRGBInverted := tfBGR16us3;
3033 fPrecision := glBitmapRec4ub(16, 16, 16, 0);
3034 fShift := glBitmapRec4ub( 0, 16, 32, 0);
3035 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
3036 fOpenGLFormat := tfRGB16us3;
3037 fglFormat := GL_RGB;
3038 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_RGB16{$ELSE}GL_RGB16UI{$ENDIF};
3039 fglDataFormat := GL_UNSIGNED_SHORT;
3041 fOpenGLFormat := tfRGB8ub3;
3045 procedure TfdRGBA4us1.SetValues;
3047 inherited SetValues;
3048 fBitsPerPixel := 16;
3049 fFormat := tfRGBA4us1;
3050 fWithAlpha := tfRGBA4us1;
3051 fWithoutAlpha := tfRGBX4us1;
3052 fOpenGLFormat := tfRGBA4us1;
3053 fRGBInverted := tfBGRA4us1;
3054 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3055 fShift := glBitmapRec4ub(12, 8, 4, 0);
3056 fglFormat := GL_RGBA;
3057 fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}GL_RGBA8{$ELSE}GL_RGBA{$IFEND};
3058 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3061 procedure TfdARGB4us1.SetValues;
3063 inherited SetValues;
3064 fBitsPerPixel := 16;
3065 fFormat := tfARGB4us1;
3066 fWithAlpha := tfARGB4us1;
3067 fWithoutAlpha := tfXRGB4us1;
3068 fRGBInverted := tfABGR4us1;
3069 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3070 fShift := glBitmapRec4ub( 8, 4, 0, 12);
3072 fOpenGLFormat := tfARGB4us1;
3073 fglFormat := GL_BGRA;
3074 fglInternalFormat := GL_RGBA4;
3075 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3077 fOpenGLFormat := tfRGBA4us1;
3081 procedure TfdRGB5A1us1.SetValues;
3083 inherited SetValues;
3084 fBitsPerPixel := 16;
3085 fFormat := tfRGB5A1us1;
3086 fWithAlpha := tfRGB5A1us1;
3087 fWithoutAlpha := tfRGB5X1us1;
3088 fOpenGLFormat := tfRGB5A1us1;
3089 fRGBInverted := tfBGR5A1us1;
3090 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3091 fShift := glBitmapRec4ub(11, 6, 1, 0);
3092 fglFormat := GL_RGBA;
3093 fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}GL_RGB5_A1{$ELSE}GL_RGBA{$IFEND};
3094 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3097 procedure TfdA1RGB5us1.SetValues;
3099 inherited SetValues;
3100 fBitsPerPixel := 16;
3101 fFormat := tfA1RGB5us1;
3102 fWithAlpha := tfA1RGB5us1;
3103 fWithoutAlpha := tfX1RGB5us1;
3104 fRGBInverted := tfA1BGR5us1;
3105 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3106 fShift := glBitmapRec4ub(10, 5, 0, 15);
3108 fOpenGLFormat := tfA1RGB5us1;
3109 fglFormat := GL_BGRA;
3110 fglInternalFormat := GL_RGB5_A1;
3111 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3113 fOpenGLFormat := tfRGB5A1us1;
3117 procedure TfdRGBA8ui1.SetValues;
3119 inherited SetValues;
3120 fBitsPerPixel := 32;
3121 fFormat := tfRGBA8ui1;
3122 fWithAlpha := tfRGBA8ui1;
3123 fWithoutAlpha := tfRGBX8ui1;
3124 fRGBInverted := tfBGRA8ui1;
3125 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3126 fShift := glBitmapRec4ub(24, 16, 8, 0);
3128 fOpenGLFormat := tfRGBA8ui1;
3129 fglFormat := GL_RGBA;
3130 fglInternalFormat := GL_RGBA8;
3131 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3133 fOpenGLFormat := tfRGBA8ub4;
3137 procedure TfdARGB8ui1.SetValues;
3139 inherited SetValues;
3140 fBitsPerPixel := 32;
3141 fFormat := tfARGB8ui1;
3142 fWithAlpha := tfARGB8ui1;
3143 fWithoutAlpha := tfXRGB8ui1;
3144 fRGBInverted := tfABGR8ui1;
3145 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3146 fShift := glBitmapRec4ub(16, 8, 0, 24);
3148 fOpenGLFormat := tfARGB8ui1;
3149 fglFormat := GL_BGRA;
3150 fglInternalFormat := GL_RGBA8;
3151 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3153 fOpenGLFormat := tfRGBA8ub4;
3157 procedure TfdRGBA8ub4.SetValues;
3159 inherited SetValues;
3160 fBitsPerPixel := 32;
3161 fFormat := tfRGBA8ub4;
3162 fWithAlpha := tfRGBA8ub4;
3163 fWithoutAlpha := tfRGB8ub3;
3164 fOpenGLFormat := tfRGBA8ub4;
3165 fRGBInverted := tfBGRA8ub4;
3166 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3167 fShift := glBitmapRec4ub( 0, 8, 16, 24);
3168 fglFormat := GL_RGBA;
3169 fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}GL_RGBA8{$ELSE}GL_RGBA{$IFEND};
3170 fglDataFormat := GL_UNSIGNED_BYTE;
3173 procedure TfdRGB10A2ui1.SetValues;
3175 inherited SetValues;
3176 fBitsPerPixel := 32;
3177 fFormat := tfRGB10A2ui1;
3178 fWithAlpha := tfRGB10A2ui1;
3179 fWithoutAlpha := tfRGB10X2ui1;
3180 fRGBInverted := tfBGR10A2ui1;
3181 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3182 fShift := glBitmapRec4ub(22, 12, 2, 0);
3184 fOpenGLFormat := tfRGB10A2ui1;
3185 fglFormat := GL_RGBA;
3186 fglInternalFormat := GL_RGB10_A2;
3187 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3189 fOpenGLFormat := tfA2RGB10ui1;
3193 procedure TfdA2RGB10ui1.SetValues;
3195 inherited SetValues;
3196 fBitsPerPixel := 32;
3197 fFormat := tfA2RGB10ui1;
3198 fWithAlpha := tfA2RGB10ui1;
3199 fWithoutAlpha := tfX2RGB10ui1;
3200 fRGBInverted := tfA2BGR10ui1;
3201 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3202 fShift := glBitmapRec4ub(20, 10, 0, 30);
3203 {$IF NOT DEFINED(OPENGL_ES)}
3204 fOpenGLFormat := tfA2RGB10ui1;
3205 fglFormat := GL_BGRA;
3206 fglInternalFormat := GL_RGB10_A2;
3207 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3208 {$ELSEIF DEFINED(OPENGL_ES_3_0)}
3209 fOpenGLFormat := tfA2RGB10ui1;
3210 fglFormat := GL_RGBA;
3211 fglInternalFormat := GL_RGB10_A2;
3212 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3214 fOpenGLFormat := tfRGBA8ui1;
3218 procedure TfdRGBA16us4.SetValues;
3220 inherited SetValues;
3221 fBitsPerPixel := 64;
3222 fFormat := tfRGBA16us4;
3223 fWithAlpha := tfRGBA16us4;
3224 fWithoutAlpha := tfRGB16us3;
3225 fRGBInverted := tfBGRA16us4;
3226 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3227 fShift := glBitmapRec4ub( 0, 16, 32, 48);
3228 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
3229 fOpenGLFormat := tfRGBA16us4;
3230 fglFormat := GL_RGBA;
3231 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_RGBA16{$ELSE}GL_RGBA16UI{$ENDIF};
3232 fglDataFormat := GL_UNSIGNED_SHORT;
3234 fOpenGLFormat := tfRGBA8ub4;
3238 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3239 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3240 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3241 procedure TfdBGRX4us1.SetValues;
3243 inherited SetValues;
3244 fBitsPerPixel := 16;
3245 fFormat := tfBGRX4us1;
3246 fWithAlpha := tfBGRA4us1;
3247 fWithoutAlpha := tfBGRX4us1;
3248 fRGBInverted := tfRGBX4us1;
3249 fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
3250 fShift := glBitmapRec4ub( 4, 8, 12, 0);
3252 fOpenGLFormat := tfBGRX4us1;
3253 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3254 fglInternalFormat := GL_RGB4;
3255 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3257 fOpenGLFormat := tfR5G6B5us1;
3261 procedure TfdXBGR4us1.SetValues;
3263 inherited SetValues;
3264 fBitsPerPixel := 16;
3265 fFormat := tfXBGR4us1;
3266 fWithAlpha := tfABGR4us1;
3267 fWithoutAlpha := tfXBGR4us1;
3268 fRGBInverted := tfXRGB4us1;
3269 fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
3270 fShift := glBitmapRec4ub( 0, 4, 8, 0);
3272 fOpenGLFormat := tfXBGR4us1;
3273 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3274 fglInternalFormat := GL_RGB4;
3275 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3277 fOpenGLFormat := tfR5G6B5us1;
3281 procedure TfdB5G6R5us1.SetValues;
3283 inherited SetValues;
3284 fBitsPerPixel := 16;
3285 fFormat := tfB5G6R5us1;
3286 fWithAlpha := tfBGR5A1us1;
3287 fWithoutAlpha := tfB5G6R5us1;
3288 fRGBInverted := tfR5G6B5us1;
3289 fPrecision := glBitmapRec4ub( 5, 6, 5, 0);
3290 fShift := glBitmapRec4ub( 0, 5, 11, 0);
3292 fOpenGLFormat := tfB5G6R5us1;
3293 fglFormat := GL_RGB;
3294 fglInternalFormat := GL_RGB565;
3295 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5_REV;
3297 fOpenGLFormat := tfR5G6B5us1;
3301 procedure TfdBGR5X1us1.SetValues;
3303 inherited SetValues;
3304 fBitsPerPixel := 16;
3305 fFormat := tfBGR5X1us1;
3306 fWithAlpha := tfBGR5A1us1;
3307 fWithoutAlpha := tfBGR5X1us1;
3308 fRGBInverted := tfRGB5X1us1;
3309 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
3310 fShift := glBitmapRec4ub( 1, 6, 11, 0);
3312 fOpenGLFormat := tfBGR5X1us1;
3313 fglFormat := GL_BGRA;
3314 fglInternalFormat := GL_RGB5;
3315 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3317 fOpenGLFormat := tfR5G6B5us1;
3321 procedure TfdX1BGR5us1.SetValues;
3323 inherited SetValues;
3324 fBitsPerPixel := 16;
3325 fFormat := tfX1BGR5us1;
3326 fWithAlpha := tfA1BGR5us1;
3327 fWithoutAlpha := tfX1BGR5us1;
3328 fRGBInverted := tfX1RGB5us1;
3329 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
3330 fShift := glBitmapRec4ub( 0, 5, 10, 0);
3332 fOpenGLFormat := tfX1BGR5us1;
3333 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3334 fglInternalFormat := GL_RGB5;
3335 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3337 fOpenGLFormat := tfR5G6B5us1;
3341 procedure TfdBGR8ub3.SetValues;
3343 inherited SetValues;
3344 fBitsPerPixel := 24;
3345 fFormat := tfBGR8ub3;
3346 fWithAlpha := tfBGRA8ub4;
3347 fWithoutAlpha := tfBGR8ub3;
3348 fRGBInverted := tfRGB8ub3;
3349 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3350 fShift := glBitmapRec4ub(16, 8, 0, 0);
3352 fOpenGLFormat := tfBGR8ub3;
3353 fglFormat := GL_BGR;
3354 fglInternalFormat := GL_RGB8;
3355 fglDataFormat := GL_UNSIGNED_BYTE;
3357 fOpenGLFormat := tfRGB8ub3;
3361 procedure TfdBGRX8ui1.SetValues;
3363 inherited SetValues;
3364 fBitsPerPixel := 32;
3365 fFormat := tfBGRX8ui1;
3366 fWithAlpha := tfBGRA8ui1;
3367 fWithoutAlpha := tfBGRX8ui1;
3368 fRGBInverted := tfRGBX8ui1;
3369 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3370 fShift := glBitmapRec4ub( 8, 16, 24, 0);
3372 fOpenGLFormat := tfBGRX8ui1;
3373 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3374 fglInternalFormat := GL_RGB8;
3375 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3377 fOpenGLFormat := tfRGB8ub3;
3381 procedure TfdXBGR8ui1.SetValues;
3383 inherited SetValues;
3384 fBitsPerPixel := 32;
3385 fFormat := tfXBGR8ui1;
3386 fWithAlpha := tfABGR8ui1;
3387 fWithoutAlpha := tfXBGR8ui1;
3388 fRGBInverted := tfXRGB8ui1;
3389 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3390 fShift := glBitmapRec4ub( 0, 8, 16, 0);
3392 fOpenGLFormat := tfXBGR8ui1;
3393 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3394 fglInternalFormat := GL_RGB8;
3395 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3397 fOpenGLFormat := tfRGB8ub3;
3401 procedure TfdBGR10X2ui1.SetValues;
3403 inherited SetValues;
3404 fBitsPerPixel := 32;
3405 fFormat := tfBGR10X2ui1;
3406 fWithAlpha := tfBGR10A2ui1;
3407 fWithoutAlpha := tfBGR10X2ui1;
3408 fRGBInverted := tfRGB10X2ui1;
3409 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3410 fShift := glBitmapRec4ub( 2, 12, 22, 0);
3412 fOpenGLFormat := tfBGR10X2ui1;
3413 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3414 fglInternalFormat := GL_RGB10;
3415 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3417 fOpenGLFormat := tfRGB16us3;
3421 procedure TfdX2BGR10ui1.SetValues;
3423 inherited SetValues;
3424 fBitsPerPixel := 32;
3425 fFormat := tfX2BGR10ui1;
3426 fWithAlpha := tfA2BGR10ui1;
3427 fWithoutAlpha := tfX2BGR10ui1;
3428 fRGBInverted := tfX2RGB10ui1;
3429 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3430 fShift := glBitmapRec4ub( 0, 10, 20, 0);
3432 fOpenGLFormat := tfX2BGR10ui1;
3433 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3434 fglInternalFormat := GL_RGB10;
3435 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3437 fOpenGLFormat := tfRGB16us3;
3441 procedure TfdBGR16us3.SetValues;
3443 inherited SetValues;
3444 fBitsPerPixel := 48;
3445 fFormat := tfBGR16us3;
3446 fWithAlpha := tfBGRA16us4;
3447 fWithoutAlpha := tfBGR16us3;
3448 fRGBInverted := tfRGB16us3;
3449 fPrecision := glBitmapRec4ub(16, 16, 16, 0);
3450 fShift := glBitmapRec4ub(32, 16, 0, 0);
3452 fOpenGLFormat := tfBGR16us3;
3453 fglFormat := GL_BGR;
3454 fglInternalFormat := GL_RGB16;
3455 fglDataFormat := GL_UNSIGNED_SHORT;
3457 fOpenGLFormat := tfRGB16us3;
3461 procedure TfdBGRA4us1.SetValues;
3463 inherited SetValues;
3464 fBitsPerPixel := 16;
3465 fFormat := tfBGRA4us1;
3466 fWithAlpha := tfBGRA4us1;
3467 fWithoutAlpha := tfBGRX4us1;
3468 fRGBInverted := tfRGBA4us1;
3469 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3470 fShift := glBitmapRec4ub( 4, 8, 12, 0);
3472 fOpenGLFormat := tfBGRA4us1;
3473 fglFormat := GL_BGRA;
3474 fglInternalFormat := GL_RGBA4;
3475 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3477 fOpenGLFormat := tfRGBA4us1;
3481 procedure TfdABGR4us1.SetValues;
3483 inherited SetValues;
3484 fBitsPerPixel := 16;
3485 fFormat := tfABGR4us1;
3486 fWithAlpha := tfABGR4us1;
3487 fWithoutAlpha := tfXBGR4us1;
3488 fRGBInverted := tfARGB4us1;
3489 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3490 fShift := glBitmapRec4ub( 0, 4, 8, 12);
3492 fOpenGLFormat := tfABGR4us1;
3493 fglFormat := GL_RGBA;
3494 fglInternalFormat := GL_RGBA4;
3495 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3497 fOpenGLFormat := tfRGBA4us1;
3501 procedure TfdBGR5A1us1.SetValues;
3503 inherited SetValues;
3504 fBitsPerPixel := 16;
3505 fFormat := tfBGR5A1us1;
3506 fWithAlpha := tfBGR5A1us1;
3507 fWithoutAlpha := tfBGR5X1us1;
3508 fRGBInverted := tfRGB5A1us1;
3509 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3510 fShift := glBitmapRec4ub( 1, 6, 11, 0);
3512 fOpenGLFormat := tfBGR5A1us1;
3513 fglFormat := GL_BGRA;
3514 fglInternalFormat := GL_RGB5_A1;
3515 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3517 fOpenGLFormat := tfRGB5A1us1;
3521 procedure TfdA1BGR5us1.SetValues;
3523 inherited SetValues;
3524 fBitsPerPixel := 16;
3525 fFormat := tfA1BGR5us1;
3526 fWithAlpha := tfA1BGR5us1;
3527 fWithoutAlpha := tfX1BGR5us1;
3528 fRGBInverted := tfA1RGB5us1;
3529 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3530 fShift := glBitmapRec4ub( 0, 5, 10, 15);
3532 fOpenGLFormat := tfA1BGR5us1;
3533 fglFormat := GL_RGBA;
3534 fglInternalFormat := GL_RGB5_A1;
3535 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3537 fOpenGLFormat := tfRGB5A1us1;
3541 procedure TfdBGRA8ui1.SetValues;
3543 inherited SetValues;
3544 fBitsPerPixel := 32;
3545 fFormat := tfBGRA8ui1;
3546 fWithAlpha := tfBGRA8ui1;
3547 fWithoutAlpha := tfBGRX8ui1;
3548 fRGBInverted := tfRGBA8ui1;
3549 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3550 fShift := glBitmapRec4ub( 8, 16, 24, 0);
3552 fOpenGLFormat := tfBGRA8ui1;
3553 fglFormat := GL_BGRA;
3554 fglInternalFormat := GL_RGBA8;
3555 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3557 fOpenGLFormat := tfRGBA8ub4;
3561 procedure TfdABGR8ui1.SetValues;
3563 inherited SetValues;
3564 fBitsPerPixel := 32;
3565 fFormat := tfABGR8ui1;
3566 fWithAlpha := tfABGR8ui1;
3567 fWithoutAlpha := tfXBGR8ui1;
3568 fRGBInverted := tfARGB8ui1;
3569 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3570 fShift := glBitmapRec4ub( 0, 8, 16, 24);
3572 fOpenGLFormat := tfABGR8ui1;
3573 fglFormat := GL_RGBA;
3574 fglInternalFormat := GL_RGBA8;
3575 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3577 fOpenGLFormat := tfRGBA8ub4
3581 procedure TfdBGRA8ub4.SetValues;
3583 inherited SetValues;
3584 fBitsPerPixel := 32;
3585 fFormat := tfBGRA8ub4;
3586 fWithAlpha := tfBGRA8ub4;
3587 fWithoutAlpha := tfBGR8ub3;
3588 fRGBInverted := tfRGBA8ub4;
3589 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3590 fShift := glBitmapRec4ub(16, 8, 0, 24);
3592 fOpenGLFormat := tfBGRA8ub4;
3593 fglFormat := GL_BGRA;
3594 fglInternalFormat := GL_RGBA8;
3595 fglDataFormat := GL_UNSIGNED_BYTE;
3597 fOpenGLFormat := tfRGBA8ub4;
3601 procedure TfdBGR10A2ui1.SetValues;
3603 inherited SetValues;
3604 fBitsPerPixel := 32;
3605 fFormat := tfBGR10A2ui1;
3606 fWithAlpha := tfBGR10A2ui1;
3607 fWithoutAlpha := tfBGR10X2ui1;
3608 fRGBInverted := tfRGB10A2ui1;
3609 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3610 fShift := glBitmapRec4ub( 2, 12, 22, 0);
3612 fOpenGLFormat := tfBGR10A2ui1;
3613 fglFormat := GL_BGRA;
3614 fglInternalFormat := GL_RGB10_A2;
3615 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3617 fOpenGLFormat := tfA2RGB10ui1;
3621 procedure TfdA2BGR10ui1.SetValues;
3623 inherited SetValues;
3624 fBitsPerPixel := 32;
3625 fFormat := tfA2BGR10ui1;
3626 fWithAlpha := tfA2BGR10ui1;
3627 fWithoutAlpha := tfX2BGR10ui1;
3628 fRGBInverted := tfA2RGB10ui1;
3629 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3630 fShift := glBitmapRec4ub( 0, 10, 20, 30);
3632 fOpenGLFormat := tfA2BGR10ui1;
3633 fglFormat := GL_RGBA;
3634 fglInternalFormat := GL_RGB10_A2;
3635 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3637 fOpenGLFormat := tfA2RGB10ui1;
3641 procedure TfdBGRA16us4.SetValues;
3643 inherited SetValues;
3644 fBitsPerPixel := 64;
3645 fFormat := tfBGRA16us4;
3646 fWithAlpha := tfBGRA16us4;
3647 fWithoutAlpha := tfBGR16us3;
3648 fRGBInverted := tfRGBA16us4;
3649 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3650 fShift := glBitmapRec4ub(32, 16, 0, 48);
3652 fOpenGLFormat := tfBGRA16us4;
3653 fglFormat := GL_BGRA;
3654 fglInternalFormat := GL_RGBA16;
3655 fglDataFormat := GL_UNSIGNED_SHORT;
3657 fOpenGLFormat := tfRGBA16us4;
3661 procedure TfdDepth16us1.SetValues;
3663 inherited SetValues;
3664 fBitsPerPixel := 16;
3665 fFormat := tfDepth16us1;
3666 fWithoutAlpha := tfDepth16us1;
3667 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3668 fShift := glBitmapRec4ub( 0, 0, 0, 0);
3669 {$IF NOT DEFINED (OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
3670 fOpenGLFormat := tfDepth16us1;
3671 fglFormat := GL_DEPTH_COMPONENT;
3672 fglInternalFormat := GL_DEPTH_COMPONENT16;
3673 fglDataFormat := GL_UNSIGNED_SHORT;
3677 procedure TfdDepth24ui1.SetValues;
3679 inherited SetValues;
3680 fBitsPerPixel := 32;
3681 fFormat := tfDepth24ui1;
3682 fWithoutAlpha := tfDepth24ui1;
3683 fOpenGLFormat := tfDepth24ui1;
3684 fPrecision := glBitmapRec4ub(32, 32, 32, 32);
3685 fShift := glBitmapRec4ub( 0, 0, 0, 0);
3686 {$IF NOT DEFINED (OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
3687 fOpenGLFormat := tfDepth24ui1;
3688 fglFormat := GL_DEPTH_COMPONENT;
3689 fglInternalFormat := GL_DEPTH_COMPONENT24;
3690 fglDataFormat := GL_UNSIGNED_INT;
3694 procedure TfdDepth32ui1.SetValues;
3696 inherited SetValues;
3697 fBitsPerPixel := 32;
3698 fFormat := tfDepth32ui1;
3699 fWithoutAlpha := tfDepth32ui1;
3700 fPrecision := glBitmapRec4ub(32, 32, 32, 32);
3701 fShift := glBitmapRec4ub( 0, 0, 0, 0);
3702 {$IF NOT DEFINED(OPENGL_ES)}
3703 fOpenGLFormat := tfDepth32ui1;
3704 fglFormat := GL_DEPTH_COMPONENT;
3705 fglInternalFormat := GL_DEPTH_COMPONENT32;
3706 fglDataFormat := GL_UNSIGNED_INT;
3707 {$ELSEIF DEFINED(OPENGL_ES_3_0)}
3708 fOpenGLFormat := tfDepth24ui1;
3709 {$ELSEIF DEFINED(OPENGL_ES_2_0)}
3710 fOpenGLFormat := tfDepth16us1;
3714 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3715 //TfdS3tcDtx1RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3716 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3717 procedure TfdS3tcDtx1RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3719 raise EglBitmap.Create('mapping for compressed formats is not supported');
3722 procedure TfdS3tcDtx1RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3724 raise EglBitmap.Create('mapping for compressed formats is not supported');
3727 procedure TfdS3tcDtx1RGBA.SetValues;
3729 inherited SetValues;
3730 fFormat := tfS3tcDtx1RGBA;
3731 fWithAlpha := tfS3tcDtx1RGBA;
3732 fUncompressed := tfRGB5A1us1;
3734 fIsCompressed := true;
3736 fOpenGLFormat := tfS3tcDtx1RGBA;
3737 fglFormat := GL_COMPRESSED_RGBA;
3738 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
3739 fglDataFormat := GL_UNSIGNED_BYTE;
3741 fOpenGLFormat := fUncompressed;
3745 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3746 //TfdS3tcDtx3RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3747 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3748 procedure TfdS3tcDtx3RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3750 raise EglBitmap.Create('mapping for compressed formats is not supported');
3753 procedure TfdS3tcDtx3RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3755 raise EglBitmap.Create('mapping for compressed formats is not supported');
3758 procedure TfdS3tcDtx3RGBA.SetValues;
3760 inherited SetValues;
3761 fFormat := tfS3tcDtx3RGBA;
3762 fWithAlpha := tfS3tcDtx3RGBA;
3763 fUncompressed := tfRGBA8ub4;
3765 fIsCompressed := true;
3767 fOpenGLFormat := tfS3tcDtx3RGBA;
3768 fglFormat := GL_COMPRESSED_RGBA;
3769 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
3770 fglDataFormat := GL_UNSIGNED_BYTE;
3772 fOpenGLFormat := fUncompressed;
3776 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3777 //TfdS3tcDtx5RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3778 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3779 procedure TfdS3tcDtx5RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3781 raise EglBitmap.Create('mapping for compressed formats is not supported');
3784 procedure TfdS3tcDtx5RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3786 raise EglBitmap.Create('mapping for compressed formats is not supported');
3789 procedure TfdS3tcDtx5RGBA.SetValues;
3791 inherited SetValues;
3792 fFormat := tfS3tcDtx3RGBA;
3793 fWithAlpha := tfS3tcDtx3RGBA;
3794 fUncompressed := tfRGBA8ub4;
3796 fIsCompressed := true;
3798 fOpenGLFormat := tfS3tcDtx3RGBA;
3799 fglFormat := GL_COMPRESSED_RGBA;
3800 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
3801 fglDataFormat := GL_UNSIGNED_BYTE;
3803 fOpenGLFormat := fUncompressed;
3807 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3808 //TglBitmapFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3809 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3810 function TglBitmapFormatDescriptor.GetHasRed: Boolean;
3812 result := (fPrecision.r > 0);
3815 function TglBitmapFormatDescriptor.GetHasGreen: Boolean;
3817 result := (fPrecision.g > 0);
3820 function TglBitmapFormatDescriptor.GetHasBlue: Boolean;
3822 result := (fPrecision.b > 0);
3825 function TglBitmapFormatDescriptor.GetHasAlpha: Boolean;
3827 result := (fPrecision.a > 0);
3830 function TglBitmapFormatDescriptor.GetHasColor: Boolean;
3832 result := HasRed or HasGreen or HasBlue;
3835 function TglBitmapFormatDescriptor.GetIsGrayscale: Boolean;
3837 result := (Mask.r = Mask.g) and (Mask.g = Mask.b) and (Mask.r > 0);
3840 procedure TglBitmapFormatDescriptor.SetValues;
3843 fWithAlpha := tfEmpty;
3844 fWithoutAlpha := tfEmpty;
3845 fOpenGLFormat := tfEmpty;
3846 fRGBInverted := tfEmpty;
3847 fUncompressed := tfEmpty;
3850 fIsCompressed := false;
3853 fglInternalFormat := 0;
3856 FillChar(fPrecision, 0, SizeOf(fPrecision));
3857 FillChar(fShift, 0, SizeOf(fShift));
3860 procedure TglBitmapFormatDescriptor.CalcValues;
3864 fBytesPerPixel := fBitsPerPixel / 8;
3866 for i := 0 to 3 do begin
3867 if (fPrecision.arr[i] > 0) then
3869 fRange.arr[i] := (1 shl fPrecision.arr[i]) - 1;
3870 fMask.arr[i] := fRange.arr[i] shl fShift.arr[i];
3874 function TglBitmapFormatDescriptor.GetSize(const aSize: TglBitmapSize): Integer;
3878 if (ffX in aSize.Fields) or (ffY in aSize.Fields) then begin
3879 w := Max(1, aSize.X);
3880 h := Max(1, aSize.Y);
3881 result := GetSize(w, h);
3886 function TglBitmapFormatDescriptor.GetSize(const aWidth, aHeight: Integer): Integer;
3889 if (aWidth <= 0) or (aHeight <= 0) then
3891 result := Ceil(aWidth * aHeight * BytesPerPixel);
3894 constructor TglBitmapFormatDescriptor.Create;
3901 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3902 class function TglBitmapFormatDescriptor.GetByFormat(const aInternalFormat: GLenum): TglBitmapFormatDescriptor;
3906 for f := Low(TglBitmapFormat) to High(TglBitmapFormat) do begin
3907 result := TFormatDescriptor.Get(f);
3908 if (result.glInternalFormat = aInternalFormat) then
3911 result := TFormatDescriptor.Get(tfEmpty);
3914 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3915 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3916 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3917 class procedure TFormatDescriptor.Init;
3919 if not Assigned(FormatDescriptorCS) then
3920 FormatDescriptorCS := TCriticalSection.Create;
3923 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3924 class function TFormatDescriptor.Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
3926 FormatDescriptorCS.Enter;
3928 result := FormatDescriptors[aFormat];
3929 if not Assigned(result) then begin
3930 result := FORMAT_DESCRIPTOR_CLASSES[aFormat].Create;
3931 FormatDescriptors[aFormat] := result;
3934 FormatDescriptorCS.Leave;
3938 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3939 class function TFormatDescriptor.GetAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
3941 result := Get(Get(aFormat).WithAlpha);
3944 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3945 class function TFormatDescriptor.GetFromMask(const aMask: TglBitmapRec4ul; const aBitCount: Integer): TFormatDescriptor;
3947 ft: TglBitmapFormat;
3949 // find matching format with OpenGL support
3950 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
3952 if (result.MaskMatch(aMask)) and
3953 (result.glFormat <> 0) and
3954 (result.glInternalFormat <> 0) and
3955 ((aBitCount = 0) or (aBitCount = result.BitsPerPixel))
3960 // find matching format without OpenGL Support
3961 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
3963 if result.MaskMatch(aMask) and ((aBitCount = 0) or (aBitCount = result.BitsPerPixel)) then
3967 result := TFormatDescriptor.Get(tfEmpty);
3970 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3971 class function TFormatDescriptor.GetFromPrecShift(const aPrec, aShift: TglBitmapRec4ub; const aBitCount: Integer): TFormatDescriptor;
3973 ft: TglBitmapFormat;
3975 // find matching format with OpenGL support
3976 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
3978 if glBitmapRec4ubCompare(result.Shift, aShift) and
3979 glBitmapRec4ubCompare(result.Precision, aPrec) and
3980 (result.glFormat <> 0) and
3981 (result.glInternalFormat <> 0) and
3982 ((aBitCount = 0) or (aBitCount = result.BitsPerPixel))
3987 // find matching format without OpenGL Support
3988 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
3990 if glBitmapRec4ubCompare(result.Shift, aShift) and
3991 glBitmapRec4ubCompare(result.Precision, aPrec) and
3992 ((aBitCount = 0) or (aBitCount = result.BitsPerPixel)) then
3996 result := TFormatDescriptor.Get(tfEmpty);
3999 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4000 class procedure TFormatDescriptor.Clear;
4004 FormatDescriptorCS.Enter;
4006 for f := low(FormatDescriptors) to high(FormatDescriptors) do
4007 FreeAndNil(FormatDescriptors[f]);
4009 FormatDescriptorCS.Leave;
4013 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4014 class procedure TFormatDescriptor.Finalize;
4017 FreeAndNil(FormatDescriptorCS);
4020 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4021 //TBitfieldFormat/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4022 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4023 procedure TbmpBitfieldFormat.SetCustomValues(const aBPP: Integer; aMask: TglBitmapRec4ul);
4027 for i := 0 to 3 do begin
4029 while (aMask.arr[i] > 0) and ((aMask.arr[i] and 1) = 0) do begin
4030 aMask.arr[i] := aMask.arr[i] shr 1;
4033 fPrecision.arr[i] := CountSetBits(aMask.arr[i]);
4035 fBitsPerPixel := aBPP;
4039 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4040 procedure TbmpBitfieldFormat.SetCustomValues(const aBBP: Integer; const aPrec, aShift: TglBitmapRec4ub);
4042 fBitsPerPixel := aBBP;
4043 fPrecision := aPrec;
4048 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4049 procedure TbmpBitfieldFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4054 ((aPixel.Data.r and Range.r) shl Shift.r) or
4055 ((aPixel.Data.g and Range.g) shl Shift.g) or
4056 ((aPixel.Data.b and Range.b) shl Shift.b) or
4057 ((aPixel.Data.a and Range.a) shl Shift.a);
4058 case BitsPerPixel of
4060 16: PWord(aData)^ := data;
4061 32: PCardinal(aData)^ := data;
4062 64: PQWord(aData)^ := data;
4064 raise EglBitmap.CreateFmt('invalid pixel size: %d', [BitsPerPixel]);
4066 inc(aData, Round(BytesPerPixel));
4069 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4070 procedure TbmpBitfieldFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4075 case BitsPerPixel of
4077 16: data := PWord(aData)^;
4078 32: data := PCardinal(aData)^;
4079 64: data := PQWord(aData)^;
4081 raise EglBitmap.CreateFmt('invalid pixel size: %d', [BitsPerPixel]);
4084 aPixel.Data.arr[i] := (data shr fShift.arr[i]) and Range.arr[i];
4085 inc(aData, Round(BytesPerPixel));
4088 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4089 //TColorTableFormat///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4090 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4091 procedure TbmpColorTableFormat.SetValues;
4093 inherited SetValues;
4094 fShift := glBitmapRec4ub(8, 8, 8, 0);
4097 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4098 procedure TbmpColorTableFormat.SetCustomValues(const aFormat: TglBitmapFormat; const aBPP: Integer; const aPrec, aShift: TglBitmapRec4ub);
4101 fBitsPerPixel := aBPP;
4102 fPrecision := aPrec;
4107 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4108 procedure TbmpColorTableFormat.CalcValues;
4110 inherited CalcValues;
4113 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4114 procedure TbmpColorTableFormat.CreateColorTable;
4118 SetLength(fColorTable, 256);
4119 if not HasColor then begin
4121 for i := 0 to High(fColorTable) do begin
4122 fColorTable[i].r := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
4123 fColorTable[i].g := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
4124 fColorTable[i].b := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
4125 fColorTable[i].a := 0;
4129 for i := 0 to High(fColorTable) do begin
4130 fColorTable[i].r := Round(((i shr Shift.r) and Range.r) / Range.r * 255);
4131 fColorTable[i].g := Round(((i shr Shift.g) and Range.g) / Range.g * 255);
4132 fColorTable[i].b := Round(((i shr Shift.b) and Range.b) / Range.b * 255);
4133 fColorTable[i].a := 0;
4138 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4139 function TbmpColorTableFormat.CreateMappingData: Pointer;
4141 result := Pointer(0);
4144 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4145 procedure TbmpColorTableFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4147 if (BitsPerPixel <> 8) then
4148 raise EglBitmapUnsupportedFormat.Create('color table are only supported for 8bit formats');
4149 if not HasColor then
4151 aData^ := aPixel.Data.a
4155 ((aPixel.Data.r shr Shift.r) and Range.r) * LUMINANCE_WEIGHT_R +
4156 ((aPixel.Data.g shr Shift.g) and Range.g) * LUMINANCE_WEIGHT_G +
4157 ((aPixel.Data.b shr Shift.b) and Range.b) * LUMINANCE_WEIGHT_B);
4161 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4162 procedure TbmpColorTableFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4164 function ReadValue: Byte;
4168 if (BitsPerPixel = 8) then begin
4172 i := {%H-}PtrUInt(aMapData);
4173 if (BitsPerPixel > 1) then
4174 result := (aData^ shr i) and ((1 shl BitsPerPixel) - 1)
4176 result := (aData^ shr (7-i)) and ((1 shl BitsPerPixel) - 1);
4177 inc(i, BitsPerPixel);
4178 while (i >= 8) do begin
4182 aMapData := {%H-}Pointer(i);
4187 if (BitsPerPixel > 8) then
4188 raise EglBitmapUnsupportedFormat.Create('color table are only supported for 8bit formats');
4189 with fColorTable[ReadValue] do begin
4197 destructor TbmpColorTableFormat.Destroy;
4199 SetLength(fColorTable, 0);
4203 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4204 //TglBitmap - Helper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4205 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4206 procedure glBitmapConvertPixel(var aPixel: TglBitmapPixelData; const aSourceFD, aDestFD: TFormatDescriptor);
4210 for i := 0 to 3 do begin
4211 if (aSourceFD.Range.arr[i] <> aDestFD.Range.arr[i]) then begin
4212 if (aSourceFD.Range.arr[i] > 0) then
4213 aPixel.Data.arr[i] := Round(aPixel.Data.arr[i] / aSourceFD.Range.arr[i] * aDestFD.Range.arr[i])
4215 aPixel.Data.arr[i] := 0;
4220 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4221 procedure glBitmapConvertCopyFunc(var aFuncRec: TglBitmapFunctionRec);
4223 with aFuncRec do begin
4224 if (Source.Range.r > 0) then
4225 Dest.Data.r := Source.Data.r;
4226 if (Source.Range.g > 0) then
4227 Dest.Data.g := Source.Data.g;
4228 if (Source.Range.b > 0) then
4229 Dest.Data.b := Source.Data.b;
4230 if (Source.Range.a > 0) then
4231 Dest.Data.a := Source.Data.a;
4235 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4236 procedure glBitmapConvertCalculateRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
4240 with aFuncRec do begin
4242 if (Source.Range.arr[i] > 0) then
4243 Dest.Data.arr[i] := Round(Dest.Range.arr[i] * Source.Data.arr[i] / Source.Range.arr[i]);
4248 TShiftData = packed record
4250 0: (r, g, b, a: SmallInt);
4251 1: (arr: array[0..3] of SmallInt);
4253 PShiftData = ^TShiftData;
4255 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4256 procedure glBitmapConvertShiftRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
4262 if (Source.Range.arr[i] > 0) then
4263 Dest.Data.arr[i] := Source.Data.arr[i] shr PShiftData(Args)^.arr[i];
4266 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4267 procedure glBitmapInvertFunc(var aFuncRec: TglBitmapFunctionRec);
4271 with aFuncRec do begin
4272 Dest.Data := Source.Data;
4274 if ({%H-}PtrUInt(Args) and (1 shl i) > 0) then
4275 Dest.Data.arr[i] := Dest.Data.arr[i] xor Dest.Range.arr[i];
4279 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4280 procedure glBitmapFillWithColorFunc(var aFuncRec: TglBitmapFunctionRec);
4284 with aFuncRec do begin
4286 Dest.Data.arr[i] := PglBitmapPixelData(Args)^.Data.arr[i];
4290 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4291 procedure glBitmapAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4295 with FuncRec do begin
4296 if (FuncRec.Args = nil) then begin //source has no alpha
4298 Source.Data.r / Source.Range.r * ALPHA_WEIGHT_R +
4299 Source.Data.g / Source.Range.g * ALPHA_WEIGHT_G +
4300 Source.Data.b / Source.Range.b * ALPHA_WEIGHT_B;
4301 Dest.Data.a := Round(Dest.Range.a * Temp);
4303 Dest.Data.a := Round(Source.Data.a / Source.Range.a * Dest.Range.a);
4307 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4308 procedure glBitmapColorKeyAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4310 PglBitmapPixelData = ^TglBitmapPixelData;
4312 with FuncRec do begin
4313 Dest.Data.r := Source.Data.r;
4314 Dest.Data.g := Source.Data.g;
4315 Dest.Data.b := Source.Data.b;
4317 with PglBitmapPixelData(Args)^ do
4318 if ((Dest.Data.r <= Data.r) and (Dest.Data.r >= Range.r) and
4319 (Dest.Data.g <= Data.g) and (Dest.Data.g >= Range.g) and
4320 (Dest.Data.b <= Data.b) and (Dest.Data.b >= Range.b)) then
4323 Dest.Data.a := Dest.Range.a;
4327 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4328 procedure glBitmapValueAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4330 with FuncRec do begin
4331 Dest.Data.r := Source.Data.r;
4332 Dest.Data.g := Source.Data.g;
4333 Dest.Data.b := Source.Data.b;
4334 Dest.Data.a := PCardinal(Args)^;
4338 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4339 procedure SwapRGB(aData: PByte; aWidth: Integer; const aHasAlpha: Boolean);
4342 TRGBPix = array [0..2] of byte;
4346 while aWidth > 0 do begin
4347 Temp := PRGBPix(aData)^[0];
4348 PRGBPix(aData)^[0] := PRGBPix(aData)^[2];
4349 PRGBPix(aData)^[2] := Temp;
4359 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4360 //TglBitmapData///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4361 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4362 function TglBitmapData.GetFormatDescriptor: TglBitmapFormatDescriptor;
4364 result := TFormatDescriptor.Get(fFormat);
4367 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4368 function TglBitmapData.GetWidth: Integer;
4370 if (ffX in fDimension.Fields) then
4371 result := fDimension.X
4376 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4377 function TglBitmapData.GetHeight: Integer;
4379 if (ffY in fDimension.Fields) then
4380 result := fDimension.Y
4385 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4386 function TglBitmapData.GetScanlines(const aIndex: Integer): PByte;
4388 if fHasScanlines and (aIndex >= Low(fScanlines)) and (aIndex <= High(fScanlines)) then
4389 result := fScanlines[aIndex]
4394 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4395 procedure TglBitmapData.SetFormat(const aValue: TglBitmapFormat);
4397 if fFormat = aValue then
4399 if TFormatDescriptor.Get(Format).BitsPerPixel <> TFormatDescriptor.Get(aValue).BitsPerPixel then
4400 raise EglBitmapUnsupportedFormat.Create(Format);
4401 SetData(fData, aValue, Width, Height);
4404 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4405 procedure TglBitmapData.PrepareResType(var aResource: String; var aResType: PChar);
4409 if not Assigned(aResType) then begin
4410 TempPos := Pos('.', aResource);
4411 aResType := PChar(UpperCase(Copy(aResource, TempPos + 1, Length(aResource) - TempPos)));
4412 aResource := UpperCase(Copy(aResource, 0, TempPos -1));
4416 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4417 procedure TglBitmapData.UpdateScanlines;
4419 w, h, i, LineWidth: Integer;
4423 fHasScanlines := Assigned(fData) and (w > 0) and (h > 0);
4424 if fHasScanlines then begin
4425 SetLength(fScanlines, h);
4426 LineWidth := Trunc(w * FormatDescriptor.BytesPerPixel);
4427 for i := 0 to h-1 do begin
4428 fScanlines[i] := fData;
4429 Inc(fScanlines[i], i * LineWidth);
4432 SetLength(fScanlines, 0);
4435 {$IFDEF GLB_SUPPORT_PNG_READ}
4436 {$IF DEFINED(GLB_LAZ_PNG)}
4437 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4438 //PNG/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4439 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4440 function TglBitmapData.LoadPNG(const aStream: TStream): Boolean;
4443 PNG_MAGIC: String[MAGIC_LEN] = #$89#$50#$4E#$47#$0D#$0A#$1A#$0A;
4445 reader: TLazReaderPNG;
4446 intf: TLazIntfImage;
4448 magic: String[MAGIC_LEN];
4451 StreamPos := aStream.Position;
4453 SetLength(magic, MAGIC_LEN);
4454 aStream.Read(magic[1], MAGIC_LEN);
4455 aStream.Position := StreamPos;
4456 if (magic <> PNG_MAGIC) then begin
4461 intf := TLazIntfImage.Create(0, 0);
4462 reader := TLazReaderPNG.Create;
4464 reader.UpdateDescription := true;
4465 reader.ImageRead(aStream, intf);
4466 AssignFromLazIntfImage(intf);
4469 aStream.Position := StreamPos;
4478 {$ELSEIF DEFINED(GLB_SDL_IMAGE)}
4479 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4480 function TglBitmapData.LoadPNG(const aStream: TStream): Boolean;
4482 Surface: PSDL_Surface;
4486 RWops := glBitmapCreateRWops(aStream);
4488 if IMG_isPNG(RWops) > 0 then begin
4489 Surface := IMG_LoadPNG_RW(RWops);
4491 AssignFromSurface(Surface);
4494 SDL_FreeSurface(Surface);
4502 {$ELSEIF DEFINED(GLB_LIB_PNG)}
4503 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4504 procedure glBitmap_libPNG_read_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
4506 TStream(png_get_io_ptr(png)).Read(buffer^, size);
4509 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4510 function TglBitmapData.LoadPNG(const aStream: TStream): Boolean;
4513 signature: array [0..7] of byte;
4515 png_info: png_infop;
4517 TempHeight, TempWidth: Integer;
4518 Format: TglBitmapFormat;
4521 png_rows: array of pByte;
4522 Row, LineSize: Integer;
4526 if not init_libPNG then
4527 raise Exception.Create('LoadPNG - unable to initialize libPNG.');
4531 StreamPos := aStream.Position;
4532 aStream.Read(signature{%H-}, 8);
4533 aStream.Position := StreamPos;
4535 if png_check_sig(@signature, 8) <> 0 then begin
4537 png := png_create_read_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
4539 raise EglBitmapException.Create('LoadPng - couldn''t create read struct.');
4542 png_info := png_create_info_struct(png);
4543 if png_info = nil then begin
4544 png_destroy_read_struct(@png, nil, nil);
4545 raise EglBitmapException.Create('LoadPng - couldn''t create info struct.');
4548 // set read callback
4549 png_set_read_fn(png, aStream, glBitmap_libPNG_read_func);
4551 // read informations
4552 png_read_info(png, png_info);
4555 TempHeight := png_get_image_height(png, png_info);
4556 TempWidth := png_get_image_width(png, png_info);
4559 case png_get_color_type(png, png_info) of
4560 PNG_COLOR_TYPE_GRAY:
4561 Format := tfLuminance8ub1;
4562 PNG_COLOR_TYPE_GRAY_ALPHA:
4563 Format := tfLuminance8Alpha8us1;
4565 Format := tfRGB8ub3;
4566 PNG_COLOR_TYPE_RGB_ALPHA:
4567 Format := tfRGBA8ub4;
4569 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
4572 // cut upper 8 bit from 16 bit formats
4573 if png_get_bit_depth(png, png_info) > 8 then
4574 png_set_strip_16(png);
4576 // expand bitdepth smaller than 8
4577 if png_get_bit_depth(png, png_info) < 8 then
4578 png_set_expand(png);
4580 // allocating mem for scanlines
4581 LineSize := png_get_rowbytes(png, png_info);
4582 GetMem(png_data, TempHeight * LineSize);
4584 SetLength(png_rows, TempHeight);
4585 for Row := Low(png_rows) to High(png_rows) do begin
4586 png_rows[Row] := png_data;
4587 Inc(png_rows[Row], Row * LineSize);
4590 // read complete image into scanlines
4591 png_read_image(png, @png_rows[0]);
4594 png_read_end(png, png_info);
4596 // destroy read struct
4597 png_destroy_read_struct(@png, @png_info, nil);
4599 SetLength(png_rows, 0);
4602 SetData(png_data, Format, TempWidth, TempHeight);
4606 if Assigned(png_data) then
4616 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
4617 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4618 function TglBitmapData.LoadPNG(const aStream: TStream): Boolean;
4623 Row, Col, PixSize, LineSize: Integer;
4624 NewImage, pSource, pDest, pAlpha: pByte;
4625 PngFormat: TglBitmapFormat;
4626 FormatDesc: TFormatDescriptor;
4629 PngHeader: String[8] = #137#80#78#71#13#10#26#10;
4634 StreamPos := aStream.Position;
4635 aStream.Read(Header[0], SizeOf(Header));
4636 aStream.Position := StreamPos;
4638 {Test if the header matches}
4639 if Header = PngHeader then begin
4640 Png := TPNGObject.Create;
4642 Png.LoadFromStream(aStream);
4644 case Png.Header.ColorType of
4646 PngFormat := tfLuminance8ub1;
4647 COLOR_GRAYSCALEALPHA:
4648 PngFormat := tfLuminance8Alpha8us1;
4650 PngFormat := tfBGR8ub3;
4652 PngFormat := tfBGRA8ub4;
4654 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
4657 FormatDesc := TFormatDescriptor.Get(PngFormat);
4658 PixSize := Round(FormatDesc.PixelSize);
4659 LineSize := FormatDesc.GetSize(Png.Header.Width, 1);
4661 GetMem(NewImage, LineSize * Integer(Png.Header.Height));
4665 case Png.Header.ColorType of
4666 COLOR_RGB, COLOR_GRAYSCALE:
4668 for Row := 0 to Png.Height -1 do begin
4669 Move (Png.Scanline[Row]^, pDest^, LineSize);
4670 Inc(pDest, LineSize);
4673 COLOR_RGBALPHA, COLOR_GRAYSCALEALPHA:
4675 PixSize := PixSize -1;
4677 for Row := 0 to Png.Height -1 do begin
4678 pSource := Png.Scanline[Row];
4679 pAlpha := pByte(Png.AlphaScanline[Row]);
4681 for Col := 0 to Png.Width -1 do begin
4682 Move (pSource^, pDest^, PixSize);
4683 Inc(pSource, PixSize);
4684 Inc(pDest, PixSize);
4693 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
4696 SetData(NewImage, PngFormat, Png.Header.Width, Png.Header.Height);
4700 if Assigned(NewImage) then
4712 {$IFDEF GLB_SUPPORT_PNG_WRITE}
4713 {$IFDEF GLB_LIB_PNG}
4714 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4715 procedure glBitmap_libPNG_write_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
4717 TStream(png_get_io_ptr(png)).Write(buffer^, size);
4721 {$IF DEFINED(GLB_LAZ_PNG)}
4722 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4723 procedure TglBitmapData.SavePNG(const aStream: TStream);
4725 png: TPortableNetworkGraphic;
4726 intf: TLazIntfImage;
4729 png := TPortableNetworkGraphic.Create;
4730 intf := TLazIntfImage.Create(0, 0);
4732 if not AssignToLazIntfImage(intf) then
4733 raise EglBitmap.Create('unable to create LazIntfImage from glBitmap');
4734 intf.GetRawImage(raw);
4735 png.LoadFromRawImage(raw, false);
4736 png.SaveToStream(aStream);
4743 {$ELSEIF DEFINED(GLB_LIB_PNG)}
4744 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4745 procedure TglBitmapData.SavePNG(const aStream: TStream);
4748 png_info: png_infop;
4749 png_rows: array of pByte;
4753 FormatDesc: TFormatDescriptor;
4755 if not (ftPNG in FormatGetSupportedFiles(Format)) then
4756 raise EglBitmapUnsupportedFormat.Create(Format);
4758 if not init_libPNG then
4759 raise Exception.Create('unable to initialize libPNG.');
4763 tfAlpha8ub1, tfLuminance8ub1:
4764 ColorType := PNG_COLOR_TYPE_GRAY;
4765 tfLuminance8Alpha8us1:
4766 ColorType := PNG_COLOR_TYPE_GRAY_ALPHA;
4767 tfBGR8ub3, tfRGB8ub3:
4768 ColorType := PNG_COLOR_TYPE_RGB;
4769 tfBGRA8ub4, tfRGBA8ub4:
4770 ColorType := PNG_COLOR_TYPE_RGBA;
4772 raise EglBitmapUnsupportedFormat.Create(Format);
4775 FormatDesc := TFormatDescriptor.Get(Format);
4776 LineSize := FormatDesc.GetSize(Width, 1);
4778 // creating array for scanline
4779 SetLength(png_rows, Height);
4781 for Row := 0 to Height - 1 do begin
4782 png_rows[Row] := Data;
4783 Inc(png_rows[Row], Row * LineSize)
4787 png := png_create_write_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
4789 raise EglBitmapException.Create('SavePng - couldn''t create write struct.');
4792 png_info := png_create_info_struct(png);
4793 if png_info = nil then begin
4794 png_destroy_write_struct(@png, nil);
4795 raise EglBitmapException.Create('SavePng - couldn''t create info struct.');
4798 // set read callback
4799 png_set_write_fn(png, aStream, glBitmap_libPNG_write_func, nil);
4802 png_set_compression_level(png, 6);
4804 if Format in [tfBGR8ub3, tfBGRA8ub4] then
4807 png_set_IHDR(png, png_info, Width, Height, 8, ColorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
4808 png_write_info(png, png_info);
4809 png_write_image(png, @png_rows[0]);
4810 png_write_end(png, png_info);
4811 png_destroy_write_struct(@png, @png_info);
4813 SetLength(png_rows, 0);
4820 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
4821 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4822 procedure TglBitmapData.SavePNG(const aStream: TStream);
4826 pSource, pDest: pByte;
4827 X, Y, PixSize: Integer;
4828 ColorType: Cardinal;
4834 if not (ftPNG in FormatGetSupportedFiles (Format)) then
4835 raise EglBitmapUnsupportedFormat.Create(Format);
4838 tfAlpha8ub1, tfLuminance8ub1: begin
4839 ColorType := COLOR_GRAYSCALE;
4843 tfLuminance8Alpha8us1: begin
4844 ColorType := COLOR_GRAYSCALEALPHA;
4848 tfBGR8ub3, tfRGB8ub3: begin
4849 ColorType := COLOR_RGB;
4853 tfBGRA8ub4, tfRGBA8ub4: begin
4854 ColorType := COLOR_RGBALPHA;
4859 raise EglBitmapUnsupportedFormat.Create(Format);
4862 Png := TPNGObject.CreateBlank(ColorType, 8, Width, Height);
4866 for Y := 0 to Height -1 do begin
4867 pDest := png.ScanLine[Y];
4868 for X := 0 to Width -1 do begin
4869 Move(pSource^, pDest^, PixSize);
4870 Inc(pDest, PixSize);
4871 Inc(pSource, PixSize);
4873 png.AlphaScanline[Y]^[X] := pSource^;
4878 // convert RGB line to BGR
4879 if Format in [tfRGB8ub3, tfRGBA8ub4] then begin
4880 pTemp := png.ScanLine[Y];
4881 for X := 0 to Width -1 do begin
4882 Temp := pByteArray(pTemp)^[0];
4883 pByteArray(pTemp)^[0] := pByteArray(pTemp)^[2];
4884 pByteArray(pTemp)^[2] := Temp;
4891 Png.CompressionLevel := 6;
4892 Png.SaveToStream(aStream);
4900 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4901 //JPEG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4902 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4903 {$IFDEF GLB_LIB_JPEG}
4905 glBitmap_libJPEG_source_mgr_ptr = ^glBitmap_libJPEG_source_mgr;
4906 glBitmap_libJPEG_source_mgr = record
4907 pub: jpeg_source_mgr;
4910 SrcBuffer: array [1..4096] of byte;
4913 glBitmap_libJPEG_dest_mgr_ptr = ^glBitmap_libJPEG_dest_mgr;
4914 glBitmap_libJPEG_dest_mgr = record
4915 pub: jpeg_destination_mgr;
4917 DestStream: TStream;
4918 DestBuffer: array [1..4096] of byte;
4921 procedure glBitmap_libJPEG_error_exit(cinfo: j_common_ptr); cdecl;
4927 procedure glBitmap_libJPEG_output_message(cinfo: j_common_ptr); cdecl;
4933 procedure glBitmap_libJPEG_init_source(cinfo: j_decompress_ptr); cdecl;
4938 procedure glBitmap_libJPEG_term_source(cinfo: j_decompress_ptr); cdecl;
4944 procedure glBitmap_libJPEG_init_destination(cinfo: j_compress_ptr); cdecl;
4950 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4951 function glBitmap_libJPEG_fill_input_buffer(cinfo: j_decompress_ptr): boolean; cdecl;
4953 src: glBitmap_libJPEG_source_mgr_ptr;
4956 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
4958 bytes := src^.SrcStream.Read(src^.SrcBuffer[1], 4096);
4959 if (bytes <= 0) then begin
4960 src^.SrcBuffer[1] := $FF;
4961 src^.SrcBuffer[2] := JPEG_EOI;
4965 src^.pub.next_input_byte := @(src^.SrcBuffer[1]);
4966 src^.pub.bytes_in_buffer := bytes;
4971 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4972 procedure glBitmap_libJPEG_skip_input_data(cinfo: j_decompress_ptr; num_bytes: Longint); cdecl;
4974 src: glBitmap_libJPEG_source_mgr_ptr;
4976 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
4978 if num_bytes > 0 then begin
4979 // wanted byte isn't in buffer so set stream position and read buffer
4980 if num_bytes > src^.pub.bytes_in_buffer then begin
4981 src^.SrcStream.Position := src^.SrcStream.Position + num_bytes - src^.pub.bytes_in_buffer;
4982 src^.pub.fill_input_buffer(cinfo);
4984 // wanted byte is in buffer so only skip
4985 inc(src^.pub.next_input_byte, num_bytes);
4986 dec(src^.pub.bytes_in_buffer, num_bytes);
4991 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4992 function glBitmap_libJPEG_empty_output_buffer(cinfo: j_compress_ptr): boolean; cdecl;
4994 dest: glBitmap_libJPEG_dest_mgr_ptr;
4996 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
4998 if dest^.pub.free_in_buffer < Cardinal(Length(dest^.DestBuffer)) then begin
4999 // write complete buffer
5000 dest^.DestStream.Write(dest^.DestBuffer[1], SizeOf(dest^.DestBuffer));
5003 dest^.pub.next_output_byte := @dest^.DestBuffer[1];
5004 dest^.pub.free_in_buffer := Length(dest^.DestBuffer);
5010 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5011 procedure glBitmap_libJPEG_term_destination(cinfo: j_compress_ptr); cdecl;
5014 dest: glBitmap_libJPEG_dest_mgr_ptr;
5016 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
5018 for Idx := Low(dest^.DestBuffer) to High(dest^.DestBuffer) do begin
5019 // check for endblock
5020 if (Idx < High(dest^.DestBuffer)) and (dest^.DestBuffer[Idx] = $FF) and (dest^.DestBuffer[Idx +1] = JPEG_EOI) then begin
5022 dest^.DestStream.Write(dest^.DestBuffer[Idx], 2);
5027 dest^.DestStream.Write(dest^.DestBuffer[Idx], 1);
5032 {$IFDEF GLB_SUPPORT_JPEG_READ}
5033 {$IF DEFINED(GLB_LAZ_JPEG)}
5034 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5035 function TglBitmapData.LoadJPEG(const aStream: TStream): Boolean;
5038 JPEG_MAGIC: String[MAGIC_LEN] = #$FF#$D8;
5040 intf: TLazIntfImage;
5041 reader: TFPReaderJPEG;
5043 magic: String[MAGIC_LEN];
5046 StreamPos := aStream.Position;
5048 SetLength(magic, MAGIC_LEN);
5049 aStream.Read(magic[1], MAGIC_LEN);
5050 aStream.Position := StreamPos;
5051 if (magic <> JPEG_MAGIC) then begin
5056 reader := TFPReaderJPEG.Create;
5057 intf := TLazIntfImage.Create(0, 0);
5059 intf.DataDescription := GetDescriptionFromDevice(0, 0, 0);
5060 reader.ImageRead(aStream, intf);
5061 AssignFromLazIntfImage(intf);
5064 aStream.Position := StreamPos;
5073 {$ELSEIF DEFINED(GLB_SDL_IMAGE)}
5074 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5075 function TglBitmapData.LoadJPEG(const aStream: TStream): Boolean;
5077 Surface: PSDL_Surface;
5082 RWops := glBitmapCreateRWops(aStream);
5084 if IMG_isJPG(RWops) > 0 then begin
5085 Surface := IMG_LoadJPG_RW(RWops);
5087 AssignFromSurface(Surface);
5090 SDL_FreeSurface(Surface);
5098 {$ELSEIF DEFINED(GLB_LIB_JPEG)}
5099 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5100 function TglBitmapData.LoadJPEG(const aStream: TStream): Boolean;
5103 Temp: array[0..1]of Byte;
5105 jpeg: jpeg_decompress_struct;
5106 jpeg_err: jpeg_error_mgr;
5108 IntFormat: TglBitmapFormat;
5110 TempHeight, TempWidth: Integer;
5115 FormatDesc: TFormatDescriptor;
5119 if not init_libJPEG then
5120 raise Exception.Create('LoadJPG - unable to initialize libJPEG.');
5123 // reading first two bytes to test file and set cursor back to begin
5124 StreamPos := aStream.Position;
5125 aStream.Read({%H-}Temp[0], 2);
5126 aStream.Position := StreamPos;
5128 // if Bitmap then read file.
5129 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
5130 FillChar(jpeg{%H-}, SizeOf(jpeg_decompress_struct), $00);
5131 FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
5134 jpeg.err := jpeg_std_error(@jpeg_err);
5135 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
5136 jpeg_err.output_message := glBitmap_libJPEG_output_message;
5138 // decompression struct
5139 jpeg_create_decompress(@jpeg);
5141 // allocation space for streaming methods
5142 jpeg.src := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_source_mgr));
5144 // seeting up custom functions
5145 with glBitmap_libJPEG_source_mgr_ptr(jpeg.src)^ do begin
5146 pub.init_source := glBitmap_libJPEG_init_source;
5147 pub.fill_input_buffer := glBitmap_libJPEG_fill_input_buffer;
5148 pub.skip_input_data := glBitmap_libJPEG_skip_input_data;
5149 pub.resync_to_restart := jpeg_resync_to_restart; // use default method
5150 pub.term_source := glBitmap_libJPEG_term_source;
5152 pub.bytes_in_buffer := 0; // forces fill_input_buffer on first read
5153 pub.next_input_byte := nil; // until buffer loaded
5155 SrcStream := aStream;
5158 // set global decoding state
5159 jpeg.global_state := DSTATE_START;
5161 // read header of jpeg
5162 jpeg_read_header(@jpeg, false);
5164 // setting output parameter
5165 case jpeg.jpeg_color_space of
5168 jpeg.out_color_space := JCS_GRAYSCALE;
5169 IntFormat := tfLuminance8ub1;
5172 jpeg.out_color_space := JCS_RGB;
5173 IntFormat := tfRGB8ub3;
5177 jpeg_start_decompress(@jpeg);
5179 TempHeight := jpeg.output_height;
5180 TempWidth := jpeg.output_width;
5182 FormatDesc := TFormatDescriptor.Get(IntFormat);
5184 // creating new image
5185 GetMem(pImage, FormatDesc.GetSize(TempWidth, TempHeight));
5189 for Row := 0 to TempHeight -1 do begin
5190 jpeg_read_scanlines(@jpeg, @pTemp, 1);
5191 Inc(pTemp, FormatDesc.GetSize(TempWidth, 1));
5194 // finish decompression
5195 jpeg_finish_decompress(@jpeg);
5197 // destroy decompression
5198 jpeg_destroy_decompress(@jpeg);
5200 SetData(pImage, IntFormat, TempWidth, TempHeight);
5204 if Assigned(pImage) then
5214 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
5215 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5216 function TglBitmapData.LoadJPEG(const aStream: TStream): Boolean;
5221 Temp: array[0..1]of Byte;
5225 // reading first two bytes to test file and set cursor back to begin
5226 StreamPos := aStream.Position;
5227 aStream.Read(Temp[0], 2);
5228 aStream.Position := StreamPos;
5230 // if Bitmap then read file.
5231 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
5232 bmp := TBitmap.Create;
5234 jpg := TJPEGImage.Create;
5236 jpg.LoadFromStream(aStream);
5238 result := AssignFromBitmap(bmp);
5250 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
5251 {$IF DEFINED(GLB_LAZ_JPEG)}
5252 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5253 procedure TglBitmapData.SaveJPEG(const aStream: TStream);
5256 intf: TLazIntfImage;
5259 jpeg := TJPEGImage.Create;
5260 intf := TLazIntfImage.Create(0, 0);
5262 if not AssignToLazIntfImage(intf) then
5263 raise EglBitmap.Create('unable to create LazIntfImage from glBitmap');
5264 intf.GetRawImage(raw);
5265 jpeg.LoadFromRawImage(raw, false);
5266 jpeg.SaveToStream(aStream);
5273 {$ELSEIF DEFINED(GLB_LIB_JPEG)}
5274 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5275 procedure TglBitmapData.SaveJPEG(const aStream: TStream);
5277 jpeg: jpeg_compress_struct;
5278 jpeg_err: jpeg_error_mgr;
5280 pTemp, pTemp2: pByte;
5282 procedure CopyRow(pDest, pSource: pByte);
5286 for X := 0 to Width - 1 do begin
5287 pByteArray(pDest)^[0] := pByteArray(pSource)^[2];
5288 pByteArray(pDest)^[1] := pByteArray(pSource)^[1];
5289 pByteArray(pDest)^[2] := pByteArray(pSource)^[0];
5296 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
5297 raise EglBitmapUnsupportedFormat.Create(Format);
5299 if not init_libJPEG then
5300 raise Exception.Create('SaveJPG - unable to initialize libJPEG.');
5303 FillChar(jpeg{%H-}, SizeOf(jpeg_compress_struct), $00);
5304 FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
5307 jpeg.err := jpeg_std_error(@jpeg_err);
5308 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
5309 jpeg_err.output_message := glBitmap_libJPEG_output_message;
5311 // compression struct
5312 jpeg_create_compress(@jpeg);
5314 // allocation space for streaming methods
5315 jpeg.dest := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_dest_mgr));
5317 // seeting up custom functions
5318 with glBitmap_libJPEG_dest_mgr_ptr(jpeg.dest)^ do begin
5319 pub.init_destination := glBitmap_libJPEG_init_destination;
5320 pub.empty_output_buffer := glBitmap_libJPEG_empty_output_buffer;
5321 pub.term_destination := glBitmap_libJPEG_term_destination;
5323 pub.next_output_byte := @DestBuffer[1];
5324 pub.free_in_buffer := Length(DestBuffer);
5326 DestStream := aStream;
5329 // very important state
5330 jpeg.global_state := CSTATE_START;
5331 jpeg.image_width := Width;
5332 jpeg.image_height := Height;
5334 tfAlpha8ub1, tfLuminance8ub1: begin
5335 jpeg.input_components := 1;
5336 jpeg.in_color_space := JCS_GRAYSCALE;
5338 tfRGB8ub3, tfBGR8ub3: begin
5339 jpeg.input_components := 3;
5340 jpeg.in_color_space := JCS_RGB;
5344 jpeg_set_defaults(@jpeg);
5345 jpeg_set_quality(@jpeg, 95, true);
5346 jpeg_start_compress(@jpeg, true);
5349 if Format = tfBGR8ub3 then
5350 GetMem(pTemp2, fRowSize)
5355 for Row := 0 to jpeg.image_height -1 do begin
5357 if Format = tfBGR8ub3 then
5358 CopyRow(pTemp2, pTemp)
5363 jpeg_write_scanlines(@jpeg, @pTemp2, 1);
5364 inc(pTemp, fRowSize);
5368 if Format = tfBGR8ub3 then
5371 jpeg_finish_compress(@jpeg);
5372 jpeg_destroy_compress(@jpeg);
5378 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
5379 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5380 procedure TglBitmapData.SaveJPEG(const aStream: TStream);
5385 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
5386 raise EglBitmapUnsupportedFormat.Create(Format);
5388 Bmp := TBitmap.Create;
5390 Jpg := TJPEGImage.Create;
5392 AssignToBitmap(Bmp);
5393 if (Format in [tfAlpha8ub1, tfLuminance8ub1]) then begin
5394 Jpg.Grayscale := true;
5395 Jpg.PixelFormat := jf8Bit;
5398 Jpg.SaveToStream(aStream);
5409 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5410 //RAW/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5411 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5413 RawHeader = packed record
5419 BitsPerPixel: Integer;
5420 Precision: TglBitmapRec4ub;
5421 Shift: TglBitmapRec4ub;
5424 function TglBitmapData.LoadRAW(const aStream: TStream): Boolean;
5428 fd: TFormatDescriptor;
5432 StartPos := aStream.Position;
5433 aStream.Read(header{%H-}, SizeOf(header));
5434 if (header.Magic <> 'glBMP') then begin
5435 aStream.Position := StartPos;
5439 fd := TFormatDescriptor.GetFromPrecShift(header.Precision, header.Shift, header.BitsPerPixel);
5440 if (fd.Format = tfEmpty) then
5441 raise EglBitmapUnsupportedFormat.Create('no supported format found');
5443 buf := GetMemory(header.DataSize);
5444 aStream.Read(buf^, header.DataSize);
5445 SetData(buf, fd.Format, header.Width, header.Height);
5450 procedure TglBitmapData.SaveRAW(const aStream: TStream);
5453 fd: TFormatDescriptor;
5455 fd := TFormatDescriptor.Get(Format);
5456 header.Magic := 'glBMP';
5457 header.Version := 1;
5458 header.Width := Width;
5459 header.Height := Height;
5460 header.DataSize := fd.GetSize(fDimension);
5461 header.BitsPerPixel := fd.BitsPerPixel;
5462 header.Precision := fd.Precision;
5463 header.Shift := fd.Shift;
5464 aStream.Write(header, SizeOf(header));
5465 aStream.Write(Data^, header.DataSize);
5468 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5469 //BMP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5470 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5477 BMP_COMP_BITFIELDS = 3;
5480 TBMPHeader = packed record
5485 bfOffBits: Cardinal;
5488 TBMPInfo = packed record
5494 biCompression: Cardinal;
5495 biSizeImage: Cardinal;
5496 biXPelsPerMeter: Longint;
5497 biYPelsPerMeter: Longint;
5498 biClrUsed: Cardinal;
5499 biClrImportant: Cardinal;
5502 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5503 function TglBitmapData.LoadBMP(const aStream: TStream): Boolean;
5505 //////////////////////////////////////////////////////////////////////////////////////////////////
5506 function ReadInfo(out aInfo: TBMPInfo; out aMask: TglBitmapRec4ul): TglBitmapFormat;
5511 aStream.Read(aInfo{%H-}, SizeOf(aInfo));
5512 FillChar(aMask{%H-}, SizeOf(aMask), 0);
5515 case aInfo.biCompression of
5517 BMP_COMP_RLE8: begin
5518 raise EglBitmap.Create('RLE compression is not supported');
5520 BMP_COMP_BITFIELDS: begin
5521 if (aInfo.biBitCount = 16) or (aInfo.biBitCount = 32) then begin
5522 for i := 0 to 2 do begin
5523 aStream.Read(tmp{%H-}, SizeOf(tmp));
5524 aMask.arr[i] := tmp;
5527 raise EglBitmap.Create('Bitfields are only supported for 16bit and 32bit formats');
5531 //get suitable format
5532 case aInfo.biBitCount of
5533 8: result := tfLuminance8ub1;
5534 16: result := tfX1RGB5us1;
5535 24: result := tfBGR8ub3;
5536 32: result := tfXRGB8ui1;
5540 function ReadColorTable(var aFormat: TglBitmapFormat; const aInfo: TBMPInfo): TbmpColorTableFormat;
5543 fd: TFormatDescriptor;
5544 ColorTable: TbmpColorTable;
5547 if (aInfo.biBitCount >= 16) then
5549 aFormat := tfLuminance8ub1;
5550 c := aInfo.biClrUsed;
5552 c := 1 shl aInfo.biBitCount;
5553 SetLength(ColorTable, c);
5554 for i := 0 to c-1 do begin
5555 aStream.Read(ColorTable[i], SizeOf(TbmpColorTableEnty));
5556 if (ColorTable[i].r <> ColorTable[i].g) or (ColorTable[i].g <> ColorTable[i].b) then
5557 aFormat := tfRGB8ub3;
5560 fd := TFormatDescriptor.Get(aFormat);
5561 result := TbmpColorTableFormat.Create;
5562 result.ColorTable := ColorTable;
5563 result.SetCustomValues(aFormat, aInfo.biBitCount, fd.Precision, fd.Shift);
5566 //////////////////////////////////////////////////////////////////////////////////////////////////
5567 function CheckBitfields(var aFormat: TglBitmapFormat; const aMask: TglBitmapRec4ul; const aInfo: TBMPInfo): TbmpBitfieldFormat;
5569 fd: TFormatDescriptor;
5572 if (aMask.r <> 0) or (aMask.g <> 0) or (aMask.b <> 0) or (aMask.a <> 0) then begin
5574 // find suitable format ...
5575 fd := TFormatDescriptor.GetFromMask(aMask);
5576 if (fd.Format <> tfEmpty) then begin
5577 aFormat := fd.Format;
5581 // or create custom bitfield format
5582 result := TbmpBitfieldFormat.Create;
5583 result.SetCustomValues(aInfo.biBitCount, aMask);
5590 ImageSize, rbLineSize, wbLineSize, Padding, i: Integer;
5591 PaddingBuff: Cardinal;
5592 LineBuf, ImageData, TmpData: PByte;
5593 SourceMD, DestMD: Pointer;
5594 BmpFormat: TglBitmapFormat;
5597 Mask: TglBitmapRec4ul;
5602 SpecialFormat: TFormatDescriptor;
5603 FormatDesc: TFormatDescriptor;
5605 //////////////////////////////////////////////////////////////////////////////////////////////////
5606 procedure SpecialFormatReadLine(aData: PByte; aLineBuf: PByte);
5609 Pixel: TglBitmapPixelData;
5611 aStream.Read(aLineBuf^, rbLineSize);
5612 SpecialFormat.PreparePixel(Pixel);
5613 for i := 0 to Info.biWidth-1 do begin
5614 SpecialFormat.Unmap(aLineBuf, Pixel, SourceMD);
5615 glBitmapConvertPixel(Pixel, SpecialFormat, FormatDesc);
5616 FormatDesc.Map(Pixel, aData, DestMD);
5622 BmpFormat := tfEmpty;
5623 SpecialFormat := nil;
5629 StartPos := aStream.Position;
5630 aStream.Read(Header{%H-}, SizeOf(Header));
5632 if Header.bfType = BMP_MAGIC then begin
5634 BmpFormat := ReadInfo(Info, Mask);
5635 SpecialFormat := ReadColorTable(BmpFormat, Info);
5636 if not Assigned(SpecialFormat) then
5637 SpecialFormat := CheckBitfields(BmpFormat, Mask, Info);
5638 aStream.Position := StartPos + Header.bfOffBits;
5640 if (BmpFormat <> tfEmpty) then begin
5641 FormatDesc := TFormatDescriptor.Get(BmpFormat);
5642 rbLineSize := Round(Info.biWidth * Info.biBitCount / 8); //ReadBuffer LineSize
5643 wbLineSize := Trunc(Info.biWidth * FormatDesc.BytesPerPixel);
5644 Padding := (((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3) - rbLineSize;
5647 DestMD := FormatDesc.CreateMappingData;
5648 ImageSize := FormatDesc.GetSize(Info.biWidth, abs(Info.biHeight));
5649 GetMem(ImageData, ImageSize);
5650 if Assigned(SpecialFormat) then begin
5651 GetMem(LineBuf, rbLineSize); //tmp Memory for converting Bitfields
5652 SourceMD := SpecialFormat.CreateMappingData;
5657 FillChar(ImageData^, ImageSize, $FF);
5658 TmpData := ImageData;
5659 if (Info.biHeight > 0) then
5660 Inc(TmpData, wbLineSize * (Info.biHeight-1));
5661 for i := 0 to Abs(Info.biHeight)-1 do begin
5662 if Assigned(SpecialFormat) then
5663 SpecialFormatReadLine(TmpData, LineBuf) //if is special format read and convert data
5665 aStream.Read(TmpData^, wbLineSize); //else only read data
5666 if (Info.biHeight > 0) then
5667 dec(TmpData, wbLineSize)
5669 inc(TmpData, wbLineSize);
5670 aStream.Read(PaddingBuff{%H-}, Padding);
5672 SetData(ImageData, BmpFormat, Info.biWidth, abs(Info.biHeight));
5675 if Assigned(LineBuf) then
5677 if Assigned(SourceMD) then
5678 SpecialFormat.FreeMappingData(SourceMD);
5679 FormatDesc.FreeMappingData(DestMD);
5682 if Assigned(ImageData) then
5687 raise EglBitmap.Create('LoadBMP - No suitable format found');
5689 aStream.Position := StartPos;
5693 FreeAndNil(SpecialFormat);
5696 else aStream.Position := StartPos;
5699 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5700 procedure TglBitmapData.SaveBMP(const aStream: TStream);
5704 Converter: TFormatDescriptor;
5705 FormatDesc: TFormatDescriptor;
5706 SourceFD, DestFD: Pointer;
5707 pData, srcData, dstData, ConvertBuffer: pByte;
5709 Pixel: TglBitmapPixelData;
5710 ImageSize, wbLineSize, rbLineSize, Padding, LineIdx, PixelIdx: Integer;
5711 RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
5713 PaddingBuff: Cardinal;
5715 function GetLineWidth : Integer;
5717 result := ((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3;
5721 if not (ftBMP in FormatGetSupportedFiles(Format)) then
5722 raise EglBitmapUnsupportedFormat.Create(Format);
5725 FormatDesc := TFormatDescriptor.Get(Format);
5726 ImageSize := FormatDesc.GetSize(Dimension);
5728 FillChar(Header{%H-}, SizeOf(Header), 0);
5729 Header.bfType := BMP_MAGIC;
5730 Header.bfSize := SizeOf(Header) + SizeOf(Info) + ImageSize;
5731 Header.bfReserved1 := 0;
5732 Header.bfReserved2 := 0;
5733 Header.bfOffBits := SizeOf(Header) + SizeOf(Info);
5735 FillChar(Info{%H-}, SizeOf(Info), 0);
5736 Info.biSize := SizeOf(Info);
5737 Info.biWidth := Width;
5738 Info.biHeight := Height;
5740 Info.biCompression := BMP_COMP_RGB;
5741 Info.biSizeImage := ImageSize;
5745 tfAlpha4ub1, tfAlpha8ub1, tfLuminance4ub1, tfLuminance8ub1, tfR3G3B2ub1:
5747 Info.biBitCount := 8;
5748 Header.bfSize := Header.bfSize + 256 * SizeOf(Cardinal);
5749 Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal); //256 ColorTable entries
5750 Converter := TbmpColorTableFormat.Create;
5751 with (Converter as TbmpColorTableFormat) do begin
5752 SetCustomValues(fFormat, 8, FormatDesc.Precision, FormatDesc.Shift);
5757 tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
5758 tfRGBX4us1, tfXRGB4us1, tfRGB5X1us1, tfX1RGB5us1, tfR5G6B5us1, tfRGB5A1us1, tfA1RGB5us1, tfRGBA4us1, tfARGB4us1,
5759 tfBGRX4us1, tfXBGR4us1, tfBGR5X1us1, tfX1BGR5us1, tfB5G6R5us1, tfBGR5A1us1, tfA1BGR5us1, tfBGRA4us1, tfABGR4us1:
5761 Info.biBitCount := 16;
5762 Info.biCompression := BMP_COMP_BITFIELDS;
5765 tfBGR8ub3, tfRGB8ub3:
5767 Info.biBitCount := 24;
5768 if (Format = tfRGB8ub3) then
5769 Converter := TfdBGR8ub3.Create; //use BGR8 Format Descriptor to Swap RGB Values
5772 tfRGBX8ui1, tfXRGB8ui1, tfRGB10X2ui1, tfX2RGB10ui1, tfRGBA8ui1, tfARGB8ui1, tfRGBA8ub4, tfRGB10A2ui1, tfA2RGB10ui1,
5773 tfBGRX8ui1, tfXBGR8ui1, tfBGR10X2ui1, tfX2BGR10ui1, tfBGRA8ui1, tfABGR8ui1, tfBGRA8ub4, tfBGR10A2ui1, tfA2BGR10ui1:
5775 Info.biBitCount := 32;
5776 Info.biCompression := BMP_COMP_BITFIELDS;
5779 raise EglBitmapUnsupportedFormat.Create(Format);
5781 Info.biXPelsPerMeter := 2835;
5782 Info.biYPelsPerMeter := 2835;
5785 if Info.biCompression = BMP_COMP_BITFIELDS then begin
5786 Header.bfSize := Header.bfSize + 4 * SizeOf(Cardinal);
5787 Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal);
5789 RedMask := FormatDesc.Mask.r;
5790 GreenMask := FormatDesc.Mask.g;
5791 BlueMask := FormatDesc.Mask.b;
5792 AlphaMask := FormatDesc.Mask.a;
5796 aStream.Write(Header, SizeOf(Header));
5797 aStream.Write(Info, SizeOf(Info));
5800 if Assigned(Converter) and (Converter is TbmpColorTableFormat) then
5801 with (Converter as TbmpColorTableFormat) do
5802 aStream.Write(ColorTable[0].b,
5803 SizeOf(TbmpColorTableEnty) * Length(ColorTable));
5806 if Info.biCompression = BMP_COMP_BITFIELDS then begin
5807 aStream.Write(RedMask, SizeOf(Cardinal));
5808 aStream.Write(GreenMask, SizeOf(Cardinal));
5809 aStream.Write(BlueMask, SizeOf(Cardinal));
5810 aStream.Write(AlphaMask, SizeOf(Cardinal));
5814 rbLineSize := Round(Info.biWidth * FormatDesc.BytesPerPixel);
5815 wbLineSize := Round(Info.biWidth * Info.biBitCount / 8);
5816 Padding := GetLineWidth - wbLineSize;
5820 inc(pData, (Height-1) * rbLineSize);
5822 // prepare row buffer. But only for RGB because RGBA supports color masks
5823 // so it's possible to change color within the image.
5824 if Assigned(Converter) then begin
5825 FormatDesc.PreparePixel(Pixel);
5826 GetMem(ConvertBuffer, wbLineSize);
5827 SourceFD := FormatDesc.CreateMappingData;
5828 DestFD := Converter.CreateMappingData;
5830 ConvertBuffer := nil;
5833 for LineIdx := 0 to Height - 1 do begin
5835 if Assigned(Converter) then begin
5837 dstData := ConvertBuffer;
5838 for PixelIdx := 0 to Info.biWidth-1 do begin
5839 FormatDesc.Unmap(srcData, Pixel, SourceFD);
5840 glBitmapConvertPixel(Pixel, FormatDesc, Converter);
5841 Converter.Map(Pixel, dstData, DestFD);
5843 aStream.Write(ConvertBuffer^, wbLineSize);
5845 aStream.Write(pData^, rbLineSize);
5847 dec(pData, rbLineSize);
5848 if (Padding > 0) then
5849 aStream.Write(PaddingBuff, Padding);
5852 // destroy row buffer
5853 if Assigned(ConvertBuffer) then begin
5854 FormatDesc.FreeMappingData(SourceFD);
5855 Converter.FreeMappingData(DestFD);
5856 FreeMem(ConvertBuffer);
5860 if Assigned(Converter) then
5865 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5866 //TGA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5867 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5869 TTGAHeader = packed record
5873 //ColorMapSpec: Array[0..4] of Byte;
5874 ColorMapStart: Word;
5875 ColorMapLength: Word;
5876 ColorMapEntrySize: Byte;
5886 TGA_UNCOMPRESSED_RGB = 2;
5887 TGA_UNCOMPRESSED_GRAY = 3;
5888 TGA_COMPRESSED_RGB = 10;
5889 TGA_COMPRESSED_GRAY = 11;
5891 TGA_NONE_COLOR_TABLE = 0;
5893 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5894 function TglBitmapData.LoadTGA(const aStream: TStream): Boolean;
5897 ImageData: System.PByte;
5898 StartPosition: Int64;
5899 PixelSize, LineSize: Integer;
5900 tgaFormat: TglBitmapFormat;
5901 FormatDesc: TFormatDescriptor;
5902 Counter: packed record
5904 low, high, dir: Integer;
5911 ////////////////////////////////////////////////////////////////////////////////////////
5912 procedure ReadUncompressed;
5915 buf, tmp1, tmp2: System.PByte;
5918 if (Counter.X.dir < 0) then
5919 GetMem(buf, LineSize);
5921 while (Counter.Y.low <> Counter.Y.high + counter.Y.dir) do begin
5923 inc(tmp1, (Counter.Y.low * LineSize)); //pointer to LineStart
5924 if (Counter.X.dir < 0) then begin //flip X
5925 aStream.Read(buf^, LineSize);
5927 inc(tmp2, LineSize - PixelSize); //pointer to last pixel in line
5928 for i := 0 to Header.Width-1 do begin //for all pixels in line
5929 for j := 0 to PixelSize-1 do begin //for all bytes in pixel
5934 dec(tmp2, 2*PixelSize); //move 2 backwards, because j-loop moved 1 forward
5937 aStream.Read(tmp1^, LineSize);
5938 inc(Counter.Y.low, Counter.Y.dir); //move to next line index
5941 if Assigned(buf) then
5946 ////////////////////////////////////////////////////////////////////////////////////////
5947 procedure ReadCompressed;
5949 /////////////////////////////////////////////////////////////////
5951 TmpData: System.PByte;
5952 LinePixelsRead: Integer;
5953 procedure CheckLine;
5955 if (LinePixelsRead >= Header.Width) then begin
5956 LinePixelsRead := 0;
5957 inc(Counter.Y.low, Counter.Y.dir); //next line index
5958 TmpData := ImageData;
5959 inc(TmpData, Counter.Y.low * LineSize); //set line
5960 if (Counter.X.dir < 0) then //if x flipped then
5961 inc(TmpData, LineSize - PixelSize); //set last pixel
5965 /////////////////////////////////////////////////////////////////
5968 CacheSize, CachePos: Integer;
5969 procedure CachedRead(out Buffer; Count: Integer);
5973 if (CachePos + Count > CacheSize) then begin
5974 //if buffer overflow save non read bytes
5976 if (CacheSize - CachePos > 0) then begin
5977 BytesRead := CacheSize - CachePos;
5978 Move(PByteArray(Cache)^[CachePos], Buffer{%H-}, BytesRead);
5979 inc(CachePos, BytesRead);
5982 //load cache from file
5983 CacheSize := Min(CACHE_SIZE, aStream.Size - aStream.Position);
5984 aStream.Read(Cache^, CacheSize);
5987 //read rest of requested bytes
5988 if (Count - BytesRead > 0) then begin
5989 Move(PByteArray(Cache)^[CachePos], TByteArray(Buffer)[BytesRead], Count - BytesRead);
5990 inc(CachePos, Count - BytesRead);
5993 //if no buffer overflow just read the data
5994 Move(PByteArray(Cache)^[CachePos], Buffer, Count);
5995 inc(CachePos, Count);
5999 procedure PixelToBuffer(const aData: PByte; var aBuffer: PByte);
6004 inc(aBuffer, Counter.X.dir);
6007 PWord(aBuffer)^ := PWord(aData)^;
6008 inc(aBuffer, 2 * Counter.X.dir);
6011 PByteArray(aBuffer)^[0] := PByteArray(aData)^[0];
6012 PByteArray(aBuffer)^[1] := PByteArray(aData)^[1];
6013 PByteArray(aBuffer)^[2] := PByteArray(aData)^[2];
6014 inc(aBuffer, 3 * Counter.X.dir);
6017 PCardinal(aBuffer)^ := PCardinal(aData)^;
6018 inc(aBuffer, 4 * Counter.X.dir);
6024 TotalPixelsToRead, TotalPixelsRead: Integer;
6026 buf: array [0..3] of Byte; //1 pixel is max 32bit long
6027 PixelRepeat: Boolean;
6028 PixelsToRead, PixelCount: Integer;
6033 TotalPixelsToRead := Header.Width * Header.Height;
6034 TotalPixelsRead := 0;
6035 LinePixelsRead := 0;
6037 GetMem(Cache, CACHE_SIZE);
6039 TmpData := ImageData;
6040 inc(TmpData, Counter.Y.low * LineSize); //set line
6041 if (Counter.X.dir < 0) then //if x flipped then
6042 inc(TmpData, LineSize - PixelSize); //set last pixel
6046 CachedRead(Temp, 1);
6047 PixelRepeat := (Temp and $80) > 0;
6048 PixelsToRead := (Temp and $7F) + 1;
6049 inc(TotalPixelsRead, PixelsToRead);
6052 CachedRead(buf[0], PixelSize);
6053 while (PixelsToRead > 0) do begin
6055 PixelCount := Min(Header.Width - LinePixelsRead, PixelsToRead); //max read to EOL or EOF
6056 while (PixelCount > 0) do begin
6057 if not PixelRepeat then
6058 CachedRead(buf[0], PixelSize);
6059 PixelToBuffer(@buf[0], TmpData);
6060 inc(LinePixelsRead);
6065 until (TotalPixelsRead >= TotalPixelsToRead);
6071 function IsGrayFormat: Boolean;
6073 result := Header.ImageType in [TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_GRAY];
6079 // reading header to test file and set cursor back to begin
6080 StartPosition := aStream.Position;
6081 aStream.Read(Header{%H-}, SizeOf(Header));
6083 // no colormapped files
6084 if (Header.ColorMapType = TGA_NONE_COLOR_TABLE) and (Header.ImageType in [
6085 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY]) then
6088 if Header.ImageID <> 0 then // skip image ID
6089 aStream.Position := aStream.Position + Header.ImageID;
6091 tgaFormat := tfEmpty;
6093 8: if IsGrayFormat then case (Header.ImageDesc and $F) of
6094 0: tgaFormat := tfLuminance8ub1;
6095 8: tgaFormat := tfAlpha8ub1;
6098 16: if IsGrayFormat then case (Header.ImageDesc and $F) of
6099 0: tgaFormat := tfLuminance16us1;
6100 8: tgaFormat := tfLuminance8Alpha8ub2;
6101 end else case (Header.ImageDesc and $F) of
6102 0: tgaFormat := tfX1RGB5us1;
6103 1: tgaFormat := tfA1RGB5us1;
6104 4: tgaFormat := tfARGB4us1;
6107 24: if not IsGrayFormat then case (Header.ImageDesc and $F) of
6108 0: tgaFormat := tfBGR8ub3;
6111 32: if IsGrayFormat then case (Header.ImageDesc and $F) of
6112 0: tgaFormat := tfDepth32ui1;
6113 end else case (Header.ImageDesc and $F) of
6114 0: tgaFormat := tfX2RGB10ui1;
6115 2: tgaFormat := tfA2RGB10ui1;
6116 8: tgaFormat := tfARGB8ui1;
6120 if (tgaFormat = tfEmpty) then
6121 raise EglBitmap.Create('LoadTga - unsupported format');
6123 FormatDesc := TFormatDescriptor.Get(tgaFormat);
6124 PixelSize := FormatDesc.GetSize(1, 1);
6125 LineSize := FormatDesc.GetSize(Header.Width, 1);
6127 GetMem(ImageData, LineSize * Header.Height);
6130 if ((Header.ImageDesc and (1 shl 4)) > 0) then begin
6131 Counter.X.low := Header.Height-1;;
6132 Counter.X.high := 0;
6133 Counter.X.dir := -1;
6136 Counter.X.high := Header.Height-1;
6141 if ((Header.ImageDesc and (1 shl 5)) > 0) then begin
6143 Counter.Y.high := Header.Height-1;
6146 Counter.Y.low := Header.Height-1;;
6147 Counter.Y.high := 0;
6148 Counter.Y.dir := -1;
6152 case Header.ImageType of
6153 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY:
6155 TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY:
6159 SetData(ImageData, tgaFormat, Header.Width, Header.Height);
6162 if Assigned(ImageData) then
6167 aStream.Position := StartPosition;
6170 else aStream.Position := StartPosition;
6173 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6174 procedure TglBitmapData.SaveTGA(const aStream: TStream);
6178 FormatDesc: TFormatDescriptor;
6180 if not (ftTGA in FormatGetSupportedFiles(Format)) then
6181 raise EglBitmapUnsupportedFormat.Create(Format);
6184 FormatDesc := TFormatDescriptor.Get(Format);
6185 FillChar(Header{%H-}, SizeOf(Header), 0);
6186 Header.ImageDesc := CountSetBits(FormatDesc.Range.a) and $F;
6187 Header.Bpp := FormatDesc.BitsPerPixel;
6188 Header.Width := Width;
6189 Header.Height := Height;
6190 Header.ImageDesc := Header.ImageDesc or $20; //flip y
6191 if FormatDesc.IsGrayscale or (not FormatDesc.IsGrayscale and not FormatDesc.HasRed and FormatDesc.HasAlpha) then
6192 Header.ImageType := TGA_UNCOMPRESSED_GRAY
6194 Header.ImageType := TGA_UNCOMPRESSED_RGB;
6195 aStream.Write(Header, SizeOf(Header));
6198 Size := FormatDesc.GetSize(Dimension);
6199 aStream.Write(Data^, Size);
6202 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6203 //DDS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6204 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6206 DDS_MAGIC: Cardinal = $20534444;
6208 // DDS_header.dwFlags
6209 DDSD_CAPS = $00000001;
6210 DDSD_HEIGHT = $00000002;
6211 DDSD_WIDTH = $00000004;
6212 DDSD_PIXELFORMAT = $00001000;
6214 // DDS_header.sPixelFormat.dwFlags
6215 DDPF_ALPHAPIXELS = $00000001;
6216 DDPF_ALPHA = $00000002;
6217 DDPF_FOURCC = $00000004;
6218 DDPF_RGB = $00000040;
6219 DDPF_LUMINANCE = $00020000;
6221 // DDS_header.sCaps.dwCaps1
6222 DDSCAPS_TEXTURE = $00001000;
6224 // DDS_header.sCaps.dwCaps2
6225 DDSCAPS2_CUBEMAP = $00000200;
6227 D3DFMT_DXT1 = $31545844;
6228 D3DFMT_DXT3 = $33545844;
6229 D3DFMT_DXT5 = $35545844;
6232 TDDSPixelFormat = packed record
6236 dwRGBBitCount: Cardinal;
6237 dwRBitMask: Cardinal;
6238 dwGBitMask: Cardinal;
6239 dwBBitMask: Cardinal;
6240 dwABitMask: Cardinal;
6243 TDDSCaps = packed record
6247 dwReserved: Cardinal;
6250 TDDSHeader = packed record
6255 dwPitchOrLinearSize: Cardinal;
6257 dwMipMapCount: Cardinal;
6258 dwReserved: array[0..10] of Cardinal;
6259 PixelFormat: TDDSPixelFormat;
6261 dwReserved2: Cardinal;
6264 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6265 function TglBitmapData.LoadDDS(const aStream: TStream): Boolean;
6268 Converter: TbmpBitfieldFormat;
6270 function GetDDSFormat: TglBitmapFormat;
6272 fd: TFormatDescriptor;
6274 Mask: TglBitmapRec4ul;
6275 Range: TglBitmapRec4ui;
6279 with Header.PixelFormat do begin
6281 if ((dwFlags and DDPF_FOURCC) > 0) then begin
6282 case Header.PixelFormat.dwFourCC of
6283 D3DFMT_DXT1: result := tfS3tcDtx1RGBA;
6284 D3DFMT_DXT3: result := tfS3tcDtx3RGBA;
6285 D3DFMT_DXT5: result := tfS3tcDtx5RGBA;
6287 end else if ((dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE or DDPF_ALPHA)) > 0) then begin
6289 if ((dwFlags and DDPF_LUMINANCE) = 0) then begin
6290 Mask.r := dwRBitMask;
6291 Mask.g := dwGBitMask;
6292 Mask.b := dwBBitMask;
6294 Mask.r := dwRBitMask;
6295 Mask.g := dwRBitMask;
6296 Mask.b := dwRBitMask;
6298 if (dwFlags and DDPF_ALPHAPIXELS > 0) then
6299 Mask.a := dwABitMask
6303 //find matching format
6304 fd := TFormatDescriptor.GetFromMask(Mask, dwRGBBitCount);
6305 result := fd.Format;
6306 if (result <> tfEmpty) then
6309 //find format with same Range
6311 Range.arr[i] := (2 shl CountSetBits(Mask.arr[i])) - 1;
6312 for result := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
6313 fd := TFormatDescriptor.Get(result);
6316 if (fd.Range.arr[i] <> Range.arr[i]) then begin
6324 //no format with same range found -> use default
6325 if (result = tfEmpty) then begin
6326 if (dwABitMask > 0) then
6327 result := tfRGBA8ui1
6329 result := tfRGB8ub3;
6332 Converter := TbmpBitfieldFormat.Create;
6333 Converter.SetCustomValues(dwRGBBitCount, glBitmapRec4ul(dwRBitMask, dwGBitMask, dwBBitMask, dwABitMask));
6340 x, y, LineSize, RowSize, Magic: Cardinal;
6341 NewImage, TmpData, RowData, SrcData: System.PByte;
6342 SourceMD, DestMD: Pointer;
6343 Pixel: TglBitmapPixelData;
6344 ddsFormat: TglBitmapFormat;
6345 FormatDesc: TFormatDescriptor;
6350 StreamPos := aStream.Position;
6353 aStream.Read(Magic{%H-}, sizeof(Magic));
6354 if (Magic <> DDS_MAGIC) then begin
6355 aStream.Position := StreamPos;
6360 aStream.Read(Header{%H-}, sizeof(Header));
6361 if (Header.dwSize <> SizeOf(Header)) or
6362 ((Header.dwFlags and (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) <>
6363 (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) then
6365 aStream.Position := StreamPos;
6369 if ((Header.Caps.dwCaps1 and DDSCAPS2_CUBEMAP) > 0) then
6370 raise EglBitmap.Create('LoadDDS - CubeMaps are not supported');
6372 ddsFormat := GetDDSFormat;
6374 if (ddsFormat = tfEmpty) then
6375 raise EglBitmap.Create('LoadDDS - unsupported Pixelformat found.');
6377 FormatDesc := TFormatDescriptor.Get(ddsFormat);
6378 LineSize := Trunc(Header.dwWidth * FormatDesc.BytesPerPixel);
6379 GetMem(NewImage, Header.dwHeight * LineSize);
6381 TmpData := NewImage;
6384 if Assigned(Converter) then begin
6385 RowSize := Round(Header.dwWidth * Header.PixelFormat.dwRGBBitCount / 8);
6386 GetMem(RowData, RowSize);
6387 SourceMD := Converter.CreateMappingData;
6388 DestMD := FormatDesc.CreateMappingData;
6390 for y := 0 to Header.dwHeight-1 do begin
6391 TmpData := NewImage;
6392 inc(TmpData, y * LineSize);
6394 aStream.Read(SrcData^, RowSize);
6395 for x := 0 to Header.dwWidth-1 do begin
6396 Converter.Unmap(SrcData, Pixel, SourceMD);
6397 glBitmapConvertPixel(Pixel, Converter, FormatDesc);
6398 FormatDesc.Map(Pixel, TmpData, DestMD);
6402 Converter.FreeMappingData(SourceMD);
6403 FormatDesc.FreeMappingData(DestMD);
6409 if ((Header.PixelFormat.dwFlags and DDPF_FOURCC) > 0) then begin
6410 RowSize := Header.dwPitchOrLinearSize div Header.dwWidth;
6411 for Y := 0 to Header.dwHeight-1 do begin
6412 aStream.Read(TmpData^, RowSize);
6413 Inc(TmpData, LineSize);
6418 if (Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE)) > 0 then begin
6419 RowSize := (Header.PixelFormat.dwRGBBitCount * Header.dwWidth) shr 3;
6420 for Y := 0 to Header.dwHeight-1 do begin
6421 aStream.Read(TmpData^, RowSize);
6422 Inc(TmpData, LineSize);
6425 raise EglBitmap.Create('LoadDDS - unsupported Pixelformat found.');
6427 SetData(NewImage, ddsFormat, Header.dwWidth, Header.dwHeight);
6430 if Assigned(NewImage) then
6435 FreeAndNil(Converter);
6439 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6440 procedure TglBitmapData.SaveDDS(const aStream: TStream);
6443 FormatDesc: TFormatDescriptor;
6445 if not (ftDDS in FormatGetSupportedFiles(Format)) then
6446 raise EglBitmapUnsupportedFormat.Create(Format);
6448 FormatDesc := TFormatDescriptor.Get(Format);
6451 FillChar(Header{%H-}, SizeOf(Header), 0);
6452 Header.dwSize := SizeOf(Header);
6453 Header.dwFlags := DDSD_WIDTH or DDSD_HEIGHT or DDSD_CAPS or DDSD_PIXELFORMAT;
6455 Header.dwWidth := Max(1, Width);
6456 Header.dwHeight := Max(1, Height);
6459 Header.Caps.dwCaps1 := DDSCAPS_TEXTURE;
6462 Header.PixelFormat.dwSize := sizeof(Header);
6463 if (FormatDesc.IsCompressed) then begin
6464 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_FOURCC;
6466 tfS3tcDtx1RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT1;
6467 tfS3tcDtx3RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT3;
6468 tfS3tcDtx5RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT5;
6470 end else if not FormatDesc.HasColor and FormatDesc.HasAlpha then begin
6471 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHA;
6472 Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
6473 Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
6474 end else if FormatDesc.IsGrayscale then begin
6475 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_LUMINANCE;
6476 Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
6477 Header.PixelFormat.dwRBitMask := FormatDesc.Mask.r;
6478 Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
6480 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_RGB;
6481 Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
6482 Header.PixelFormat.dwRBitMask := FormatDesc.Mask.r;
6483 Header.PixelFormat.dwGBitMask := FormatDesc.Mask.g;
6484 Header.PixelFormat.dwBBitMask := FormatDesc.Mask.b;
6485 Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
6488 if (FormatDesc.HasAlpha) then
6489 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHAPIXELS;
6491 aStream.Write(DDS_MAGIC, sizeof(DDS_MAGIC));
6492 aStream.Write(Header, SizeOf(Header));
6493 aStream.Write(Data^, FormatDesc.GetSize(Dimension));
6496 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6497 function TglBitmapData.FlipHorz: Boolean;
6499 fd: TglBitmapFormatDescriptor;
6500 Col, RowSize, PixelSize: Integer;
6501 pTempDest, pDest, pSource: PByte;
6504 fd := FormatDescriptor;
6505 PixelSize := Ceil(fd.BytesPerPixel);
6506 RowSize := fd.GetSize(Width, 1);
6507 if Assigned(Data) and not fd.IsCompressed then begin
6509 GetMem(pDest, RowSize);
6512 Inc(pTempDest, RowSize);
6513 for Col := 0 to Width-1 do begin
6514 dec(pTempDest, PixelSize); //dec before, because ptr is behind last byte of data
6515 Move(pSource^, pTempDest^, PixelSize);
6516 Inc(pSource, PixelSize);
6518 SetData(pDest, Format, Width);
6521 if Assigned(pDest) then
6528 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6529 function TglBitmapData.FlipVert: Boolean;
6531 fd: TglBitmapFormatDescriptor;
6532 Row, RowSize, PixelSize: Integer;
6533 TempDestData, DestData, SourceData: PByte;
6536 fd := FormatDescriptor;
6537 PixelSize := Ceil(fd.BytesPerPixel);
6538 RowSize := fd.GetSize(Width, 1);
6539 if Assigned(Data) then begin
6541 GetMem(DestData, Height * RowSize);
6543 TempDestData := DestData;
6544 Inc(TempDestData, Width * (Height -1) * PixelSize);
6545 for Row := 0 to Height -1 do begin
6546 Move(SourceData^, TempDestData^, RowSize);
6547 Dec(TempDestData, RowSize);
6548 Inc(SourceData, RowSize);
6550 SetData(DestData, Format, Width, Height);
6553 if Assigned(DestData) then
6560 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6561 procedure TglBitmapData.LoadFromFile(const aFilename: String);
6565 if not FileExists(aFilename) then
6566 raise EglBitmap.Create('file does not exist: ' + aFilename);
6567 fs := TFileStream.Create(aFilename, fmOpenRead);
6571 fFilename := aFilename;
6577 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6578 procedure TglBitmapData.LoadFromStream(const aStream: TStream);
6580 {$IFDEF GLB_SUPPORT_PNG_READ}
6581 if not LoadPNG(aStream) then
6583 {$IFDEF GLB_SUPPORT_JPEG_READ}
6584 if not LoadJPEG(aStream) then
6586 if not LoadDDS(aStream) then
6587 if not LoadTGA(aStream) then
6588 if not LoadBMP(aStream) then
6589 if not LoadRAW(aStream) then
6590 raise EglBitmap.Create('LoadFromStream - Couldn''t load Stream. It''s possible to be an unknow Streamtype.');
6593 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6594 procedure TglBitmapData.LoadFromFunc(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat;
6595 const aFunc: TglBitmapFunction; const aArgs: Pointer);
6600 size := TFormatDescriptor.Get(aFormat).GetSize(aSize);
6601 GetMem(tmpData, size);
6603 FillChar(tmpData^, size, #$FF);
6604 SetData(tmpData, aFormat, aSize.X, aSize.Y);
6606 if Assigned(tmpData) then
6610 Convert(Self, aFunc, false, aFormat, aArgs);
6613 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6614 procedure TglBitmapData.LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar);
6616 rs: TResourceStream;
6618 PrepareResType(aResource, aResType);
6619 rs := TResourceStream.Create(aInstance, aResource, aResType);
6627 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6628 procedure TglBitmapData.LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
6630 rs: TResourceStream;
6632 rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
6640 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6641 procedure TglBitmapData.SaveToFile(const aFilename: String; const aFileType: TglBitmapFileType);
6645 fs := TFileStream.Create(aFileName, fmCreate);
6648 SaveToStream(fs, aFileType);
6654 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6655 procedure TglBitmapData.SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType);
6658 {$IFDEF GLB_SUPPORT_PNG_WRITE}
6659 ftPNG: SavePNG(aStream);
6661 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
6662 ftJPEG: SaveJPEG(aStream);
6664 ftDDS: SaveDDS(aStream);
6665 ftTGA: SaveTGA(aStream);
6666 ftBMP: SaveBMP(aStream);
6667 ftRAW: SaveRAW(aStream);
6671 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6672 function TglBitmapData.Convert(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer): Boolean;
6674 result := Convert(Self, aFunc, aCreateTemp, Format, aArgs);
6677 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6678 function TglBitmapData.Convert(const aSource: TglBitmapData; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
6679 const aFormat: TglBitmapFormat; const aArgs: Pointer): Boolean;
6681 DestData, TmpData, SourceData: pByte;
6682 TempHeight, TempWidth: Integer;
6683 SourceFD, DestFD: TFormatDescriptor;
6684 SourceMD, DestMD: Pointer;
6686 FuncRec: TglBitmapFunctionRec;
6688 Assert(Assigned(Data));
6689 Assert(Assigned(aSource));
6690 Assert(Assigned(aSource.Data));
6693 if Assigned(aSource.Data) and ((aSource.Height > 0) or (aSource.Width > 0)) then begin
6694 SourceFD := TFormatDescriptor.Get(aSource.Format);
6695 DestFD := TFormatDescriptor.Get(aFormat);
6697 if (SourceFD.IsCompressed) then
6698 raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', SourceFD.Format);
6699 if (DestFD.IsCompressed) then
6700 raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', DestFD.Format);
6702 // inkompatible Formats so CreateTemp
6703 if (SourceFD.BitsPerPixel <> DestFD.BitsPerPixel) then
6704 aCreateTemp := true;
6707 TempHeight := Max(1, aSource.Height);
6708 TempWidth := Max(1, aSource.Width);
6710 FuncRec.Sender := Self;
6711 FuncRec.Args := aArgs;
6714 if aCreateTemp then begin
6715 GetMem(TmpData, DestFD.GetSize(TempWidth, TempHeight));
6716 DestData := TmpData;
6721 SourceFD.PreparePixel(FuncRec.Source);
6722 DestFD.PreparePixel (FuncRec.Dest);
6724 SourceMD := SourceFD.CreateMappingData;
6725 DestMD := DestFD.CreateMappingData;
6727 FuncRec.Size := aSource.Dimension;
6728 FuncRec.Position.Fields := FuncRec.Size.Fields;
6731 SourceData := aSource.Data;
6732 FuncRec.Position.Y := 0;
6733 while FuncRec.Position.Y < TempHeight do begin
6734 FuncRec.Position.X := 0;
6735 while FuncRec.Position.X < TempWidth do begin
6736 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
6738 DestFD.Map(FuncRec.Dest, DestData, DestMD);
6739 inc(FuncRec.Position.X);
6741 inc(FuncRec.Position.Y);
6744 // Updating Image or InternalFormat
6746 SetData(TmpData, aFormat, aSource.Width, aSource.Height)
6747 else if (aFormat <> fFormat) then
6752 SourceFD.FreeMappingData(SourceMD);
6753 DestFD.FreeMappingData(DestMD);
6756 if aCreateTemp and Assigned(TmpData) then
6763 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6764 function TglBitmapData.ConvertTo(const aFormat: TglBitmapFormat): Boolean;
6766 SourceFD, DestFD: TFormatDescriptor;
6767 SourcePD, DestPD: TglBitmapPixelData;
6768 ShiftData: TShiftData;
6770 function DataIsIdentical: Boolean;
6772 result := SourceFD.MaskMatch(DestFD.Mask);
6775 function CanCopyDirect: Boolean;
6778 ((SourcePD.Range.r = DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
6779 ((SourcePD.Range.g = DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
6780 ((SourcePD.Range.b = DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
6781 ((SourcePD.Range.a = DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
6784 function CanShift: Boolean;
6787 ((SourcePD.Range.r >= DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
6788 ((SourcePD.Range.g >= DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
6789 ((SourcePD.Range.b >= DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
6790 ((SourcePD.Range.a >= DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
6793 function GetShift(aSource, aDest: Cardinal) : ShortInt;
6796 while (aSource > aDest) and (aSource > 0) do begin
6798 aSource := aSource shr 1;
6803 if (aFormat <> fFormat) and (aFormat <> tfEmpty) then begin
6804 SourceFD := TFormatDescriptor.Get(Format);
6805 DestFD := TFormatDescriptor.Get(aFormat);
6807 if DataIsIdentical then begin
6813 SourceFD.PreparePixel(SourcePD);
6814 DestFD.PreparePixel (DestPD);
6816 if CanCopyDirect then
6817 result := Convert(Self, glBitmapConvertCopyFunc, false, aFormat)
6818 else if CanShift then begin
6819 ShiftData.r := GetShift(SourcePD.Range.r, DestPD.Range.r);
6820 ShiftData.g := GetShift(SourcePD.Range.g, DestPD.Range.g);
6821 ShiftData.b := GetShift(SourcePD.Range.b, DestPD.Range.b);
6822 ShiftData.a := GetShift(SourcePD.Range.a, DestPD.Range.a);
6823 result := Convert(Self, glBitmapConvertShiftRGBAFunc, false, aFormat, @ShiftData);
6825 result := Convert(Self, glBitmapConvertCalculateRGBAFunc, false, aFormat);
6831 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6832 function TglBitmapData.AssignToSurface(out aSurface: PSDL_Surface): Boolean;
6834 Row, RowSize: Integer;
6835 SourceData, TmpData: PByte;
6837 FormatDesc: TFormatDescriptor;
6839 function GetRowPointer(Row: Integer): pByte;
6841 result := aSurface.pixels;
6842 Inc(result, Row * RowSize);
6848 FormatDesc := TFormatDescriptor.Get(Format);
6849 if FormatDesc.IsCompressed then
6850 raise EglBitmapUnsupportedFormat.Create(Format);
6852 if Assigned(Data) then begin
6853 case Trunc(FormatDesc.PixelSize) of
6859 raise EglBitmapUnsupportedFormat.Create(Format);
6862 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, TempDepth,
6863 FormatDesc.RedMask, FormatDesc.GreenMask, FormatDesc.BlueMask, FormatDesc.AlphaMask);
6865 RowSize := FormatDesc.GetSize(FileWidth, 1);
6867 for Row := 0 to FileHeight-1 do begin
6868 TmpData := GetRowPointer(Row);
6869 if Assigned(TmpData) then begin
6870 Move(SourceData^, TmpData^, RowSize);
6871 inc(SourceData, RowSize);
6878 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6879 function TglBitmapData.AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
6881 pSource, pData, pTempData: PByte;
6882 Row, RowSize, TempWidth, TempHeight: Integer;
6883 IntFormat: TglBitmapFormat;
6884 fd: TFormatDescriptor;
6885 Mask: TglBitmapMask;
6887 function GetRowPointer(Row: Integer): pByte;
6889 result := aSurface^.pixels;
6890 Inc(result, Row * RowSize);
6895 if (Assigned(aSurface)) then begin
6896 with aSurface^.format^ do begin
6901 IntFormat := TFormatDescriptor.GetFromMask(Mask).Format;
6902 if (IntFormat = tfEmpty) then
6903 raise EglBitmap.Create('AssignFromSurface - Invalid Pixelformat.');
6906 fd := TFormatDescriptor.Get(IntFormat);
6907 TempWidth := aSurface^.w;
6908 TempHeight := aSurface^.h;
6909 RowSize := fd.GetSize(TempWidth, 1);
6910 GetMem(pData, TempHeight * RowSize);
6913 for Row := 0 to TempHeight -1 do begin
6914 pSource := GetRowPointer(Row);
6915 if (Assigned(pSource)) then begin
6916 Move(pSource^, pTempData^, RowSize);
6917 Inc(pTempData, RowSize);
6920 SetData(pData, IntFormat, TempWidth, TempHeight);
6923 if Assigned(pData) then
6930 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6931 function TglBitmapData.AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
6933 Row, Col, AlphaInterleave: Integer;
6934 pSource, pDest: PByte;
6936 function GetRowPointer(Row: Integer): pByte;
6938 result := aSurface.pixels;
6939 Inc(result, Row * Width);
6944 if Assigned(Data) then begin
6945 if Format in [tfAlpha8ub1, tfLuminance8Alpha8ub2, tfBGRA8ub4, tfRGBA8ub4] then begin
6946 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, 8, $FF, $FF, $FF, 0);
6948 AlphaInterleave := 0;
6950 tfLuminance8Alpha8ub2:
6951 AlphaInterleave := 1;
6952 tfBGRA8ub4, tfRGBA8ub4:
6953 AlphaInterleave := 3;
6957 for Row := 0 to Height -1 do begin
6958 pDest := GetRowPointer(Row);
6959 if Assigned(pDest) then begin
6960 for Col := 0 to Width -1 do begin
6961 Inc(pSource, AlphaInterleave);
6973 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6974 function TglBitmapData.AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
6978 bmp := TglBitmap2D.Create;
6980 bmp.AssignFromSurface(aSurface);
6981 result := AddAlphaFromGlBitmap(bmp, aFunc, aArgs);
6989 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6990 function CreateGrayPalette: HPALETTE;
6995 GetMem(Pal, SizeOf(TLogPalette) + (SizeOf(TPaletteEntry) * 256));
6997 Pal.palVersion := $300;
6998 Pal.palNumEntries := 256;
7000 for Idx := 0 to Pal.palNumEntries - 1 do begin
7001 Pal.palPalEntry[Idx].peRed := Idx;
7002 Pal.palPalEntry[Idx].peGreen := Idx;
7003 Pal.palPalEntry[Idx].peBlue := Idx;
7004 Pal.palPalEntry[Idx].peFlags := 0;
7006 Result := CreatePalette(Pal^);
7010 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7011 function TglBitmapData.AssignToBitmap(const aBitmap: TBitmap): Boolean;
7013 Row, RowSize: Integer;
7014 pSource, pData: PByte;
7017 if Assigned(Data) then begin
7018 if Assigned(aBitmap) then begin
7019 aBitmap.Width := Width;
7020 aBitmap.Height := Height;
7023 tfAlpha8ub1, tfLuminance8ub1: begin
7024 aBitmap.PixelFormat := pf8bit;
7025 aBitmap.Palette := CreateGrayPalette;
7028 aBitmap.PixelFormat := pf15bit;
7030 aBitmap.PixelFormat := pf16bit;
7031 tfRGB8ub3, tfBGR8ub3:
7032 aBitmap.PixelFormat := pf24bit;
7033 tfRGBA8ub4, tfBGRA8ub4:
7034 aBitmap.PixelFormat := pf32bit;
7036 raise EglBitmap.Create('AssignToBitmap - Invalid Pixelformat.');
7039 RowSize := FormatDescriptor.GetSize(Width, 1);
7041 for Row := 0 to Height-1 do begin
7042 pData := aBitmap.Scanline[Row];
7043 Move(pSource^, pData^, RowSize);
7044 Inc(pSource, RowSize);
7045 if (Format in [tfRGB8ub3, tfRGBA8ub4]) then // swap RGB(A) to BGR(A)
7046 SwapRGB(pData, Width, Format = tfRGBA8ub4);
7053 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7054 function TglBitmapData.AssignFromBitmap(const aBitmap: TBitmap): Boolean;
7056 pSource, pData, pTempData: PByte;
7057 Row, RowSize, TempWidth, TempHeight: Integer;
7058 IntFormat: TglBitmapFormat;
7062 if (Assigned(aBitmap)) then begin
7063 case aBitmap.PixelFormat of
7065 IntFormat := tfLuminance8ub1;
7067 IntFormat := tfRGB5A1us1;
7069 IntFormat := tfR5G6B5us1;
7071 IntFormat := tfBGR8ub3;
7073 IntFormat := tfBGRA8ub4;
7075 raise EglBitmap.Create('AssignFromBitmap - Invalid Pixelformat.');
7078 TempWidth := aBitmap.Width;
7079 TempHeight := aBitmap.Height;
7080 RowSize := TFormatDescriptor.Get(IntFormat).GetSize(TempWidth, 1);
7081 GetMem(pData, TempHeight * RowSize);
7084 for Row := 0 to TempHeight -1 do begin
7085 pSource := aBitmap.Scanline[Row];
7086 if (Assigned(pSource)) then begin
7087 Move(pSource^, pTempData^, RowSize);
7088 Inc(pTempData, RowSize);
7091 SetData(pData, IntFormat, TempWidth, TempHeight);
7094 if Assigned(pData) then
7101 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7102 function TglBitmapData.AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
7104 Row, Col, AlphaInterleave: Integer;
7105 pSource, pDest: PByte;
7109 if Assigned(Data) then begin
7110 if (Format in [tfAlpha8ub1, tfLuminance8Alpha8ub2, tfRGBA8ub4, tfBGRA8ub4]) then begin
7111 if Assigned(aBitmap) then begin
7112 aBitmap.PixelFormat := pf8bit;
7113 aBitmap.Palette := CreateGrayPalette;
7114 aBitmap.Width := Width;
7115 aBitmap.Height := Height;
7118 tfLuminance8Alpha8ub2:
7119 AlphaInterleave := 1;
7120 tfRGBA8ub4, tfBGRA8ub4:
7121 AlphaInterleave := 3;
7123 AlphaInterleave := 0;
7129 for Row := 0 to Height -1 do begin
7130 pDest := aBitmap.Scanline[Row];
7131 if Assigned(pDest) then begin
7132 for Col := 0 to Width -1 do begin
7133 Inc(pSource, AlphaInterleave);
7146 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7147 function TglBitmapData.AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
7149 data: TglBitmapData;
7151 data := TglBitmapData.Create;
7153 data.AssignFromBitmap(aBitmap);
7154 result := AddAlphaFromDataObj(data, aFunc, aArgs);
7161 {$IFDEF GLB_LAZARUS}
7162 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7163 function TglBitmapData.AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
7165 rid: TRawImageDescription;
7166 FormatDesc: TFormatDescriptor;
7168 if not Assigned(Data) then
7169 raise EglBitmap.Create('no pixel data assigned. load data before save');
7172 if not Assigned(aImage) or (Format = tfEmpty) then
7174 FormatDesc := TFormatDescriptor.Get(Format);
7175 if FormatDesc.IsCompressed then
7178 FillChar(rid{%H-}, SizeOf(rid), 0);
7179 if FormatDesc.IsGrayscale then
7180 rid.Format := ricfGray
7182 rid.Format := ricfRGBA;
7185 rid.Height := Height;
7186 rid.Depth := FormatDesc.BitsPerPixel;
7187 rid.BitOrder := riboBitsInOrder;
7188 rid.ByteOrder := riboLSBFirst;
7189 rid.LineOrder := riloTopToBottom;
7190 rid.LineEnd := rileTight;
7191 rid.BitsPerPixel := FormatDesc.BitsPerPixel;
7192 rid.RedPrec := CountSetBits(FormatDesc.Range.r);
7193 rid.GreenPrec := CountSetBits(FormatDesc.Range.g);
7194 rid.BluePrec := CountSetBits(FormatDesc.Range.b);
7195 rid.AlphaPrec := CountSetBits(FormatDesc.Range.a);
7196 rid.RedShift := FormatDesc.Shift.r;
7197 rid.GreenShift := FormatDesc.Shift.g;
7198 rid.BlueShift := FormatDesc.Shift.b;
7199 rid.AlphaShift := FormatDesc.Shift.a;
7201 rid.MaskBitsPerPixel := 0;
7202 rid.PaletteColorCount := 0;
7204 aImage.DataDescription := rid;
7207 if not Assigned(aImage.PixelData) then
7208 raise EglBitmap.Create('error while creating LazIntfImage');
7209 Move(Data^, aImage.PixelData^, FormatDesc.GetSize(Dimension));
7214 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7215 function TglBitmapData.AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
7218 FormatDesc: TFormatDescriptor;
7222 Mask: TglBitmapRec4ul;
7224 procedure CopyConvert;
7226 bfFormat: TbmpBitfieldFormat;
7227 pSourceLine, pDestLine: PByte;
7228 pSourceMD, pDestMD: Pointer;
7229 Shift, Prec: TglBitmapRec4ub;
7231 pixel: TglBitmapPixelData;
7233 bfFormat := TbmpBitfieldFormat.Create;
7234 with aImage.DataDescription do begin
7236 Prec.g := GreenPrec;
7238 Prec.a := AlphaPrec;
7239 Shift.r := RedShift;
7240 Shift.g := GreenShift;
7241 Shift.b := BlueShift;
7242 Shift.a := AlphaShift;
7243 bfFormat.SetCustomValues(BitsPerPixel, Prec, Shift);
7245 pSourceMD := bfFormat.CreateMappingData;
7246 pDestMD := FormatDesc.CreateMappingData;
7248 for y := 0 to aImage.Height-1 do begin
7249 pSourceLine := aImage.PixelData + y {%H-}* aImage.DataDescription.BytesPerLine;
7250 pDestLine := ImageData + y * Round(FormatDesc.BytesPerPixel * aImage.Width);
7251 for x := 0 to aImage.Width-1 do begin
7252 bfFormat.Unmap(pSourceLine, pixel, pSourceMD);
7253 FormatDesc.Map(pixel, pDestLine, pDestMD);
7257 FormatDesc.FreeMappingData(pDestMD);
7258 bfFormat.FreeMappingData(pSourceMD);
7265 if not Assigned(aImage) then
7268 with aImage.DataDescription do begin
7269 Mask.r := (QWord(1 shl RedPrec )-1) shl RedShift;
7270 Mask.g := (QWord(1 shl GreenPrec)-1) shl GreenShift;
7271 Mask.b := (QWord(1 shl BluePrec )-1) shl BlueShift;
7272 Mask.a := (QWord(1 shl AlphaPrec)-1) shl AlphaShift;
7274 FormatDesc := TFormatDescriptor.GetFromMask(Mask);
7275 f := FormatDesc.Format;
7276 if (f = tfEmpty) then
7280 (FormatDesc.BitsPerPixel = aImage.DataDescription.Depth) and
7281 (aImage.DataDescription.BitsPerPixel = aImage.DataDescription.Depth);
7283 ImageSize := FormatDesc.GetSize(aImage.Width, aImage.Height);
7284 ImageData := GetMem(ImageSize);
7287 Move(aImage.PixelData^, ImageData^, ImageSize)
7290 SetData(ImageData, f, aImage.Width, aImage.Height);
7292 if Assigned(ImageData) then
7300 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7301 function TglBitmapData.AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
7303 rid: TRawImageDescription;
7304 FormatDesc: TFormatDescriptor;
7305 Pixel: TglBitmapPixelData;
7311 if not Assigned(aImage) or (Format = tfEmpty) then
7313 FormatDesc := TFormatDescriptor.Get(Format);
7314 if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
7317 FillChar(rid{%H-}, SizeOf(rid), 0);
7318 rid.Format := ricfGray;
7320 rid.Height := Height;
7321 rid.Depth := CountSetBits(FormatDesc.Range.a);
7322 rid.BitOrder := riboBitsInOrder;
7323 rid.ByteOrder := riboLSBFirst;
7324 rid.LineOrder := riloTopToBottom;
7325 rid.LineEnd := rileTight;
7326 rid.BitsPerPixel := 8 * Ceil(rid.Depth / 8);
7327 rid.RedPrec := CountSetBits(FormatDesc.Range.a);
7332 rid.GreenShift := 0;
7334 rid.AlphaShift := 0;
7336 rid.MaskBitsPerPixel := 0;
7337 rid.PaletteColorCount := 0;
7339 aImage.DataDescription := rid;
7342 srcMD := FormatDesc.CreateMappingData;
7344 FormatDesc.PreparePixel(Pixel);
7346 dst := aImage.PixelData;
7347 for y := 0 to Height-1 do
7348 for x := 0 to Width-1 do begin
7349 FormatDesc.Unmap(src, Pixel, srcMD);
7350 case rid.BitsPerPixel of
7352 dst^ := Pixel.Data.a;
7356 PWord(dst)^ := Pixel.Data.a;
7360 PByteArray(dst)^[0] := PByteArray(@Pixel.Data.a)^[0];
7361 PByteArray(dst)^[1] := PByteArray(@Pixel.Data.a)^[1];
7362 PByteArray(dst)^[2] := PByteArray(@Pixel.Data.a)^[2];
7366 PCardinal(dst)^ := Pixel.Data.a;
7370 raise EglBitmapUnsupportedFormat.Create(Format);
7374 FormatDesc.FreeMappingData(srcMD);
7379 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7380 function TglBitmapData.AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
7382 data: TglBitmapData;
7384 data := TglBitmapData.Create;
7386 data.AssignFromLazIntfImage(aImage);
7387 result := AddAlphaFromDataObj(data, aFunc, aArgs);
7394 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7395 function TglBitmapData.AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar;
7396 const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
7398 rs: TResourceStream;
7400 PrepareResType(aResource, aResType);
7401 rs := TResourceStream.Create(aInstance, aResource, aResType);
7403 result := AddAlphaFromStream(rs, aFunc, aArgs);
7409 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7410 function TglBitmapData.AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
7411 const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
7413 rs: TResourceStream;
7415 rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
7417 result := AddAlphaFromStream(rs, aFunc, aArgs);
7423 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7424 function TglBitmapData.AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
7426 if TFormatDescriptor.Get(Format).IsCompressed then
7427 raise EglBitmapUnsupportedFormat.Create(Format);
7428 result := Convert(Self, aFunc, false, TFormatDescriptor.Get(Format).WithAlpha, aArgs);
7431 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7432 function TglBitmapData.AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
7436 FS := TFileStream.Create(aFileName, fmOpenRead);
7438 result := AddAlphaFromStream(FS, aFunc, aArgs);
7444 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7445 function TglBitmapData.AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
7447 data: TglBitmapData;
7449 data := TglBitmapData.Create(aStream);
7451 result := AddAlphaFromDataObj(data, aFunc, aArgs);
7457 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7458 function TglBitmapData.AddAlphaFromDataObj(const aDataObj: TglBitmapData; aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
7460 DestData, DestData2, SourceData: pByte;
7461 TempHeight, TempWidth: Integer;
7462 SourceFD, DestFD: TFormatDescriptor;
7463 SourceMD, DestMD, DestMD2: Pointer;
7465 FuncRec: TglBitmapFunctionRec;
7469 Assert(Assigned(Data));
7470 Assert(Assigned(aDataObj));
7471 Assert(Assigned(aDataObj.Data));
7473 if ((aDataObj.Width = Width) and (aDataObj.Height = Height)) then begin
7474 result := ConvertTo(TFormatDescriptor.Get(Format).WithAlpha);
7476 SourceFD := TFormatDescriptor.Get(aDataObj.Format);
7477 DestFD := TFormatDescriptor.Get(Format);
7479 if not Assigned(aFunc) then begin
7480 aFunc := glBitmapAlphaFunc;
7481 FuncRec.Args := {%H-}Pointer(SourceFD.HasAlpha);
7483 FuncRec.Args := aArgs;
7486 TempWidth := aDataObj.Width;
7487 TempHeight := aDataObj.Height;
7488 if (TempWidth <= 0) or (TempHeight <= 0) then
7491 FuncRec.Sender := Self;
7492 FuncRec.Size := Dimension;
7493 FuncRec.Position.Fields := FuncRec.Size.Fields;
7497 SourceData := aDataObj.Data;
7500 SourceFD.PreparePixel(FuncRec.Source);
7501 DestFD.PreparePixel (FuncRec.Dest);
7503 SourceMD := SourceFD.CreateMappingData;
7504 DestMD := DestFD.CreateMappingData;
7505 DestMD2 := DestFD.CreateMappingData;
7507 FuncRec.Position.Y := 0;
7508 while FuncRec.Position.Y < TempHeight do begin
7509 FuncRec.Position.X := 0;
7510 while FuncRec.Position.X < TempWidth do begin
7511 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
7512 DestFD.Unmap (DestData, FuncRec.Dest, DestMD);
7514 DestFD.Map(FuncRec.Dest, DestData2, DestMD2);
7515 inc(FuncRec.Position.X);
7517 inc(FuncRec.Position.Y);
7520 SourceFD.FreeMappingData(SourceMD);
7521 DestFD.FreeMappingData(DestMD);
7522 DestFD.FreeMappingData(DestMD2);
7527 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7528 function TglBitmapData.AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte): Boolean;
7530 result := AddAlphaFromColorKeyFloat(aRed / $FF, aGreen / $FF, aBlue / $FF, aDeviation / $FF);
7533 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7534 function TglBitmapData.AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal): Boolean;
7536 PixelData: TglBitmapPixelData;
7538 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
7539 result := AddAlphaFromColorKeyFloat(
7540 aRed / PixelData.Range.r,
7541 aGreen / PixelData.Range.g,
7542 aBlue / PixelData.Range.b,
7543 aDeviation / Max(PixelData.Range.r, Max(PixelData.Range.g, PixelData.Range.b)));
7546 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7547 function TglBitmapData.AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single): Boolean;
7549 values: array[0..2] of Single;
7552 PixelData: TglBitmapPixelData;
7554 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
7555 with PixelData do begin
7557 values[1] := aGreen;
7560 for i := 0 to 2 do begin
7561 tmp := Trunc(Range.arr[i] * aDeviation);
7562 Data.arr[i] := Min(Range.arr[i], Trunc(Range.arr[i] * values[i] + tmp));
7563 Range.arr[i] := Max(0, Trunc(Range.arr[i] * values[i] - tmp));
7568 result := AddAlphaFromFunc(glBitmapColorKeyAlphaFunc, @PixelData);
7571 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7572 function TglBitmapData.AddAlphaFromValue(const aAlpha: Byte): Boolean;
7574 result := AddAlphaFromValueFloat(aAlpha / $FF);
7577 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7578 function TglBitmapData.AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
7580 PixelData: TglBitmapPixelData;
7582 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
7583 result := AddAlphaFromValueFloat(aAlpha / PixelData.Range.a);
7586 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7587 function TglBitmapData.AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
7589 PixelData: TglBitmapPixelData;
7591 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
7593 Data.a := Min(Range.a, Max(0, Round(Range.a * aAlpha)));
7594 result := AddAlphaFromFunc(glBitmapValueAlphaFunc, @PixelData.Data.a);
7597 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7598 function TglBitmapData.RemoveAlpha: Boolean;
7600 FormatDesc: TFormatDescriptor;
7603 FormatDesc := TFormatDescriptor.Get(Format);
7604 if Assigned(Data) then begin
7605 if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
7606 raise EglBitmapUnsupportedFormat.Create(Format);
7607 result := ConvertTo(FormatDesc.WithoutAlpha);
7611 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7612 procedure TglBitmapData.FillWithColor(const aRed, aGreen, aBlue: Byte;
7613 const aAlpha: Byte);
7615 FillWithColorFloat(aRed/$FF, aGreen/$FF, aBlue/$FF, aAlpha/$FF);
7618 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7619 procedure TglBitmapData.FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal);
7621 PixelData: TglBitmapPixelData;
7623 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
7625 aRed / PixelData.Range.r,
7626 aGreen / PixelData.Range.g,
7627 aBlue / PixelData.Range.b,
7628 aAlpha / PixelData.Range.a);
7631 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7632 procedure TglBitmapData.FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single);
7634 PixelData: TglBitmapPixelData;
7636 TFormatDescriptor.Get(Format).PreparePixel(PixelData);
7637 with PixelData do begin
7638 Data.r := Max(0, Min(Range.r, Trunc(Range.r * aRed)));
7639 Data.g := Max(0, Min(Range.g, Trunc(Range.g * aGreen)));
7640 Data.b := Max(0, Min(Range.b, Trunc(Range.b * aBlue)));
7641 Data.a := Max(0, Min(Range.a, Trunc(Range.a * aAlpha)));
7643 Convert(glBitmapFillWithColorFunc, false, @PixelData);
7646 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7647 procedure TglBitmapData.SetData(const aData: PByte; const aFormat: TglBitmapFormat; const aWidth: Integer; const aHeight: Integer);
7649 if (Data <> aData) then begin
7650 if (Assigned(Data)) then
7655 if Assigned(fData) then begin
7656 FillChar(fDimension, SizeOf(fDimension), 0);
7657 if aWidth <> -1 then begin
7658 fDimension.Fields := fDimension.Fields + [ffX];
7659 fDimension.X := aWidth;
7662 if aHeight <> -1 then begin
7663 fDimension.Fields := fDimension.Fields + [ffY];
7664 fDimension.Y := aHeight;
7674 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7675 function TglBitmapData.Clone: TglBitmapData;
7677 Temp: TglBitmapData;
7682 Temp := (ClassType.Create as TglBitmapData);
7684 // copy texture data if assigned
7685 if Assigned(Data) then begin
7686 Size := TFormatDescriptor.Get(Format).GetSize(fDimension);
7687 GetMem(TempPtr, Size);
7689 Move(Data^, TempPtr^, Size);
7690 Temp.SetData(TempPtr, Format, Width, Height);
7692 if Assigned(TempPtr) then
7698 Temp.SetData(TempPtr, Format, Width, Height);
7702 Temp.fFormat := Format;
7710 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7711 procedure TglBitmapData.Invert(const aRed, aGreen, aBlue, aAlpha: Boolean);
7716 (Byte(aRed) and 1) or
7717 ((Byte(aGreen) and 1) shl 1) or
7718 ((Byte(aBlue) and 1) shl 2) or
7719 ((Byte(aAlpha) and 1) shl 3);
7721 Convert(glBitmapInvertFunc, false, {%H-}Pointer(mask));
7724 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7726 TMatrixItem = record
7731 PglBitmapToNormalMapRec = ^TglBitmapToNormalMapRec;
7732 TglBitmapToNormalMapRec = Record
7734 Heights: array of Single;
7735 MatrixU : array of TMatrixItem;
7736 MatrixV : array of TMatrixItem;
7740 ONE_OVER_255 = 1 / 255;
7742 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7743 procedure glBitmapToNormalMapPrepareFunc(var FuncRec: TglBitmapFunctionRec);
7747 with FuncRec do begin
7749 Source.Data.r * LUMINANCE_WEIGHT_R +
7750 Source.Data.g * LUMINANCE_WEIGHT_G +
7751 Source.Data.b * LUMINANCE_WEIGHT_B;
7752 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Val * ONE_OVER_255;
7756 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7757 procedure glBitmapToNormalMapPrepareAlphaFunc(var FuncRec: TglBitmapFunctionRec);
7760 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Source.Data.a * ONE_OVER_255;
7763 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7764 procedure glBitmapToNormalMapFunc (var FuncRec: TglBitmapFunctionRec);
7766 TVec = Array[0..2] of Single;
7773 function GetHeight(X, Y: Integer): Single;
7775 with FuncRec do begin
7776 X := Max(0, Min(Size.X -1, X));
7777 Y := Max(0, Min(Size.Y -1, Y));
7778 result := PglBitmapToNormalMapRec(Args)^.Heights[Y * Size.X + X];
7783 with FuncRec do begin
7784 with PglBitmapToNormalMapRec(Args)^ do begin
7786 for Idx := Low(MatrixU) to High(MatrixU) do
7787 du := du + GetHeight(Position.X + MatrixU[Idx].X, Position.Y + MatrixU[Idx].Y) * MatrixU[Idx].W;
7790 for Idx := Low(MatrixU) to High(MatrixU) do
7791 dv := dv + GetHeight(Position.X + MatrixV[Idx].X, Position.Y + MatrixV[Idx].Y) * MatrixV[Idx].W;
7793 Vec[0] := -du * Scale;
7794 Vec[1] := -dv * Scale;
7799 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
7800 if Len <> 0 then begin
7801 Vec[0] := Vec[0] * Len;
7802 Vec[1] := Vec[1] * Len;
7803 Vec[2] := Vec[2] * Len;
7807 Dest.Data.r := Trunc((Vec[0] + 1) * 127.5);
7808 Dest.Data.g := Trunc((Vec[1] + 1) * 127.5);
7809 Dest.Data.b := Trunc((Vec[2] + 1) * 127.5);
7813 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7814 procedure TglBitmapData.GenerateNormalMap(const aFunc: TglBitmapNormalMapFunc; const aScale: Single; const aUseAlpha: Boolean);
7816 Rec: TglBitmapToNormalMapRec;
7818 procedure SetEntry (var Matrix: array of TMatrixItem; Index, X, Y: Integer; W: Single);
7820 if (Index >= Low(Matrix)) and (Index <= High(Matrix)) then begin
7821 Matrix[Index].X := X;
7822 Matrix[Index].Y := Y;
7823 Matrix[Index].W := W;
7828 if TFormatDescriptor.Get(Format).IsCompressed then
7829 raise EglBitmapUnsupportedFormat.Create(Format);
7831 if aScale > 100 then
7833 else if aScale < -100 then
7836 Rec.Scale := aScale;
7838 SetLength(Rec.Heights, Width * Height);
7842 SetLength(Rec.MatrixU, 2);
7843 SetEntry(Rec.MatrixU, 0, -1, 0, -0.5);
7844 SetEntry(Rec.MatrixU, 1, 1, 0, 0.5);
7846 SetLength(Rec.MatrixV, 2);
7847 SetEntry(Rec.MatrixV, 0, 0, 1, 0.5);
7848 SetEntry(Rec.MatrixV, 1, 0, -1, -0.5);
7852 SetLength(Rec.MatrixU, 6);
7853 SetEntry(Rec.MatrixU, 0, -1, 1, -1.0);
7854 SetEntry(Rec.MatrixU, 1, -1, 0, -2.0);
7855 SetEntry(Rec.MatrixU, 2, -1, -1, -1.0);
7856 SetEntry(Rec.MatrixU, 3, 1, 1, 1.0);
7857 SetEntry(Rec.MatrixU, 4, 1, 0, 2.0);
7858 SetEntry(Rec.MatrixU, 5, 1, -1, 1.0);
7860 SetLength(Rec.MatrixV, 6);
7861 SetEntry(Rec.MatrixV, 0, -1, 1, 1.0);
7862 SetEntry(Rec.MatrixV, 1, 0, 1, 2.0);
7863 SetEntry(Rec.MatrixV, 2, 1, 1, 1.0);
7864 SetEntry(Rec.MatrixV, 3, -1, -1, -1.0);
7865 SetEntry(Rec.MatrixV, 4, 0, -1, -2.0);
7866 SetEntry(Rec.MatrixV, 5, 1, -1, -1.0);
7870 SetLength(Rec.MatrixU, 6);
7871 SetEntry(Rec.MatrixU, 0, -1, 1, -1/6);
7872 SetEntry(Rec.MatrixU, 1, -1, 0, -1/6);
7873 SetEntry(Rec.MatrixU, 2, -1, -1, -1/6);
7874 SetEntry(Rec.MatrixU, 3, 1, 1, 1/6);
7875 SetEntry(Rec.MatrixU, 4, 1, 0, 1/6);
7876 SetEntry(Rec.MatrixU, 5, 1, -1, 1/6);
7878 SetLength(Rec.MatrixV, 6);
7879 SetEntry(Rec.MatrixV, 0, -1, 1, 1/6);
7880 SetEntry(Rec.MatrixV, 1, 0, 1, 1/6);
7881 SetEntry(Rec.MatrixV, 2, 1, 1, 1/6);
7882 SetEntry(Rec.MatrixV, 3, -1, -1, -1/6);
7883 SetEntry(Rec.MatrixV, 4, 0, -1, -1/6);
7884 SetEntry(Rec.MatrixV, 5, 1, -1, -1/6);
7888 SetLength(Rec.MatrixU, 20);
7889 SetEntry(Rec.MatrixU, 0, -2, 2, -1 / 16);
7890 SetEntry(Rec.MatrixU, 1, -1, 2, -1 / 10);
7891 SetEntry(Rec.MatrixU, 2, 1, 2, 1 / 10);
7892 SetEntry(Rec.MatrixU, 3, 2, 2, 1 / 16);
7893 SetEntry(Rec.MatrixU, 4, -2, 1, -1 / 10);
7894 SetEntry(Rec.MatrixU, 5, -1, 1, -1 / 8);
7895 SetEntry(Rec.MatrixU, 6, 1, 1, 1 / 8);
7896 SetEntry(Rec.MatrixU, 7, 2, 1, 1 / 10);
7897 SetEntry(Rec.MatrixU, 8, -2, 0, -1 / 2.8);
7898 SetEntry(Rec.MatrixU, 9, -1, 0, -0.5);
7899 SetEntry(Rec.MatrixU, 10, 1, 0, 0.5);
7900 SetEntry(Rec.MatrixU, 11, 2, 0, 1 / 2.8);
7901 SetEntry(Rec.MatrixU, 12, -2, -1, -1 / 10);
7902 SetEntry(Rec.MatrixU, 13, -1, -1, -1 / 8);
7903 SetEntry(Rec.MatrixU, 14, 1, -1, 1 / 8);
7904 SetEntry(Rec.MatrixU, 15, 2, -1, 1 / 10);
7905 SetEntry(Rec.MatrixU, 16, -2, -2, -1 / 16);
7906 SetEntry(Rec.MatrixU, 17, -1, -2, -1 / 10);
7907 SetEntry(Rec.MatrixU, 18, 1, -2, 1 / 10);
7908 SetEntry(Rec.MatrixU, 19, 2, -2, 1 / 16);
7910 SetLength(Rec.MatrixV, 20);
7911 SetEntry(Rec.MatrixV, 0, -2, 2, 1 / 16);
7912 SetEntry(Rec.MatrixV, 1, -1, 2, 1 / 10);
7913 SetEntry(Rec.MatrixV, 2, 0, 2, 0.25);
7914 SetEntry(Rec.MatrixV, 3, 1, 2, 1 / 10);
7915 SetEntry(Rec.MatrixV, 4, 2, 2, 1 / 16);
7916 SetEntry(Rec.MatrixV, 5, -2, 1, 1 / 10);
7917 SetEntry(Rec.MatrixV, 6, -1, 1, 1 / 8);
7918 SetEntry(Rec.MatrixV, 7, 0, 1, 0.5);
7919 SetEntry(Rec.MatrixV, 8, 1, 1, 1 / 8);
7920 SetEntry(Rec.MatrixV, 9, 2, 1, 1 / 16);
7921 SetEntry(Rec.MatrixV, 10, -2, -1, -1 / 16);
7922 SetEntry(Rec.MatrixV, 11, -1, -1, -1 / 8);
7923 SetEntry(Rec.MatrixV, 12, 0, -1, -0.5);
7924 SetEntry(Rec.MatrixV, 13, 1, -1, -1 / 8);
7925 SetEntry(Rec.MatrixV, 14, 2, -1, -1 / 10);
7926 SetEntry(Rec.MatrixV, 15, -2, -2, -1 / 16);
7927 SetEntry(Rec.MatrixV, 16, -1, -2, -1 / 10);
7928 SetEntry(Rec.MatrixV, 17, 0, -2, -0.25);
7929 SetEntry(Rec.MatrixV, 18, 1, -2, -1 / 10);
7930 SetEntry(Rec.MatrixV, 19, 2, -2, -1 / 16);
7935 if aUseAlpha and TFormatDescriptor.Get(Format).HasAlpha then
7936 Convert(glBitmapToNormalMapPrepareAlphaFunc, false, @Rec)
7938 Convert(glBitmapToNormalMapPrepareFunc, false, @Rec);
7939 Convert(glBitmapToNormalMapFunc, false, @Rec);
7941 SetLength(Rec.Heights, 0);
7945 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7946 constructor TglBitmapData.Create;
7949 fFormat := glBitmapDefaultFormat;
7952 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7953 constructor TglBitmapData.Create(const aFileName: String);
7956 LoadFromFile(aFileName);
7959 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7960 constructor TglBitmapData.Create(const aStream: TStream);
7963 LoadFromStream(aStream);
7966 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7967 constructor TglBitmapData.Create(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat; aData: PByte);
7972 if not Assigned(aData) then begin
7973 ImageSize := TFormatDescriptor.Get(aFormat).GetSize(aSize);
7974 GetMem(aData, ImageSize);
7976 FillChar(aData^, ImageSize, #$FF);
7977 SetData(aData, aFormat, aSize.X, aSize.Y);
7979 if Assigned(aData) then
7984 SetData(aData, aFormat, aSize.X, aSize.Y);
7988 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7989 constructor TglBitmapData.Create(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer);
7992 LoadFromFunc(aSize, aFormat, aFunc, aArgs);
7995 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7996 constructor TglBitmapData.Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar);
7999 LoadFromResource(aInstance, aResource, aResType);
8002 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8003 constructor TglBitmapData.Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
8006 LoadFromResourceID(aInstance, aResourceID, aResType);
8009 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8010 destructor TglBitmapData.Destroy;
8012 SetData(nil, tfEmpty);
8016 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8017 //TglBitmap - PROTECTED///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8018 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8019 function TglBitmap.GetWidth: Integer;
8021 if (ffX in fDimension.Fields) then
8022 result := fDimension.X
8027 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8028 function TglBitmap.GetHeight: Integer;
8030 if (ffY in fDimension.Fields) then
8031 result := fDimension.Y
8036 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8037 procedure TglBitmap.SetCustomData(const aValue: Pointer);
8039 if fCustomData = aValue then
8041 fCustomData := aValue;
8044 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8045 procedure TglBitmap.SetCustomName(const aValue: String);
8047 if fCustomName = aValue then
8049 fCustomName := aValue;
8052 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8053 procedure TglBitmap.SetCustomNameW(const aValue: WideString);
8055 if fCustomNameW = aValue then
8057 fCustomNameW := aValue;
8060 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8061 procedure TglBitmap.SetDeleteTextureOnFree(const aValue: Boolean);
8063 if fDeleteTextureOnFree = aValue then
8065 fDeleteTextureOnFree := aValue;
8068 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8069 procedure TglBitmap.SetID(const aValue: Cardinal);
8071 if fID = aValue then
8076 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8077 procedure TglBitmap.SetMipMap(const aValue: TglBitmapMipMap);
8079 if fMipMap = aValue then
8084 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8085 procedure TglBitmap.SetTarget(const aValue: Cardinal);
8087 if fTarget = aValue then
8092 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8093 procedure TglBitmap.SetAnisotropic(const aValue: Integer);
8094 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_EXT)}
8096 MaxAnisotropic: Integer;
8099 fAnisotropic := aValue;
8100 if (ID > 0) then begin
8101 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_EXT)}
8102 if GL_EXT_texture_filter_anisotropic then begin
8103 if fAnisotropic > 0 then begin
8105 glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @MaxAnisotropic);
8106 if aValue > MaxAnisotropic then
8107 fAnisotropic := MaxAnisotropic;
8108 glTexParameteri(Target, GL_TEXTURE_MAX_ANISOTROPY_EXT, fAnisotropic);
8119 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8120 procedure TglBitmap.CreateID;
8123 glDeleteTextures(1, @fID);
8124 glGenTextures(1, @fID);
8128 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8129 procedure TglBitmap.SetupParameters({$IFNDEF OPENGL_ES}out aBuildWithGlu: Boolean{$ENDIF});
8131 // Set Up Parameters
8132 SetWrap(fWrapS, fWrapT, fWrapR);
8133 SetFilter(fFilterMin, fFilterMag);
8134 SetAnisotropic(fAnisotropic);
8137 SetBorderColor(fBorderColor[0], fBorderColor[1], fBorderColor[2], fBorderColor[3]);
8138 if (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
8139 SetSwizzle(fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
8143 // Mip Maps Generation Mode
8144 aBuildWithGlu := false;
8145 if (MipMap = mmMipmap) then begin
8146 if (GL_VERSION_1_4 or GL_SGIS_generate_mipmap) then
8147 glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE)
8149 aBuildWithGlu := true;
8150 end else if (MipMap = mmMipmapGlu) then
8151 aBuildWithGlu := true;
8153 if (MipMap = mmMipmap) then
8154 glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE);
8158 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8159 //TglBitmap - PUBLIC//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8160 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8161 procedure TglBitmap.AfterConstruction;
8163 inherited AfterConstruction;
8168 fIsResident := false;
8171 fMipMap := glBitmapDefaultMipmap;
8172 fDeleteTextureOnFree := glBitmapGetDefaultDeleteTextureOnFree;
8174 glBitmapGetDefaultFilter (fFilterMin, fFilterMag);
8175 glBitmapGetDefaultTextureWrap(fWrapS, fWrapT, fWrapR);
8177 glBitmapGetDefaultSwizzle (fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
8181 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8182 procedure TglBitmap.BeforeDestruction;
8184 if (fID > 0) and fDeleteTextureOnFree then
8185 glDeleteTextures(1, @fID);
8186 inherited BeforeDestruction;
8190 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8191 procedure TglBitmap.SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
8193 fBorderColor[0] := aRed;
8194 fBorderColor[1] := aGreen;
8195 fBorderColor[2] := aBlue;
8196 fBorderColor[3] := aAlpha;
8197 if (ID > 0) then begin
8199 glTexParameterfv(Target, GL_TEXTURE_BORDER_COLOR, @fBorderColor[0]);
8204 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8205 procedure TglBitmap.SetFilter(const aMin, aMag: GLenum);
8210 fFilterMin := GL_NEAREST;
8212 fFilterMin := GL_LINEAR;
8213 GL_NEAREST_MIPMAP_NEAREST:
8214 fFilterMin := GL_NEAREST_MIPMAP_NEAREST;
8215 GL_LINEAR_MIPMAP_NEAREST:
8216 fFilterMin := GL_LINEAR_MIPMAP_NEAREST;
8217 GL_NEAREST_MIPMAP_LINEAR:
8218 fFilterMin := GL_NEAREST_MIPMAP_LINEAR;
8219 GL_LINEAR_MIPMAP_LINEAR:
8220 fFilterMin := GL_LINEAR_MIPMAP_LINEAR;
8222 raise EglBitmap.Create('SetFilter - Unknow MIN filter.');
8228 fFilterMag := GL_NEAREST;
8230 fFilterMag := GL_LINEAR;
8232 raise EglBitmap.Create('SetFilter - Unknow MAG filter.');
8236 if (ID > 0) then begin
8238 glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, fFilterMag);
8240 if (MipMap = mmNone) {$IFNDEF OPENGL_ES}or (Target = GL_TEXTURE_RECTANGLE){$ENDIF} then begin
8242 GL_NEAREST, GL_LINEAR:
8243 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
8244 GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR:
8245 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8246 GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR:
8247 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
8250 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
8254 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8255 procedure TglBitmap.SetWrap(const S: GLenum; const T: GLenum; const R: GLenum);
8257 procedure CheckAndSetWrap(const aValue: Cardinal; var aTarget: Cardinal);
8262 aTarget := GL_CLAMP;
8266 aTarget := GL_REPEAT;
8268 GL_CLAMP_TO_EDGE: begin
8270 if not GL_VERSION_1_2 and not GL_EXT_texture_edge_clamp then
8274 aTarget := GL_CLAMP_TO_EDGE;
8278 GL_CLAMP_TO_BORDER: begin
8279 if GL_VERSION_1_3 or GL_ARB_texture_border_clamp then
8280 aTarget := GL_CLAMP_TO_BORDER
8282 aTarget := GL_CLAMP;
8286 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
8287 GL_MIRRORED_REPEAT: begin
8289 if GL_VERSION_1_4 or GL_ARB_texture_mirrored_repeat or GL_IBM_texture_mirrored_repeat then
8291 if GL_VERSION_2_0 then
8293 aTarget := GL_MIRRORED_REPEAT
8295 raise EglBitmap.Create('SetWrap - Unsupported Texturewrap GL_MIRRORED_REPEAT (S).');
8299 raise EglBitmap.Create('SetWrap - Unknow Texturewrap');
8304 CheckAndSetWrap(S, fWrapS);
8305 CheckAndSetWrap(T, fWrapT);
8306 CheckAndSetWrap(R, fWrapR);
8308 if (ID > 0) then begin
8310 glTexParameteri(Target, GL_TEXTURE_WRAP_S, fWrapS);
8311 glTexParameteri(Target, GL_TEXTURE_WRAP_T, fWrapT);
8312 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
8313 {$IFDEF OPENGL_ES} if GL_VERSION_3_0 then{$ENDIF}
8314 glTexParameteri(Target, GL_TEXTURE_WRAP_R, fWrapR);
8319 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
8320 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8321 procedure TglBitmap.SetSwizzle(const r, g, b, a: GLenum);
8323 procedure CheckAndSetValue(const aValue: GLenum; const aIndex: Integer);
8325 if (aValue = GL_ZERO) or (aValue = GL_ONE) or (aValue = GL_ALPHA) or
8326 (aValue = GL_RED) or (aValue = GL_GREEN) or (aValue = GL_BLUE) then
8327 fSwizzle[aIndex] := aValue
8329 raise EglBitmap.Create('SetSwizzle - Unknow Swizle Value');
8334 if not (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
8335 raise EglBitmapNotSupported.Create('texture swizzle is not supported');
8337 if not GL_VERSION_3_0 then
8338 raise EglBitmapNotSupported.Create('texture swizzle is not supported');
8340 CheckAndSetValue(r, 0);
8341 CheckAndSetValue(g, 1);
8342 CheckAndSetValue(b, 2);
8343 CheckAndSetValue(a, 3);
8345 if (ID > 0) then begin
8348 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_RGBA, PGLint(@fSwizzle[0]));
8350 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_R, PGLint(@fSwizzle[0]));
8351 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_G, PGLint(@fSwizzle[1]));
8352 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_B, PGLint(@fSwizzle[2]));
8353 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_A, PGLint(@fSwizzle[3]));
8359 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8360 procedure TglBitmap.Bind(const aEnableTextureUnit: Boolean);
8362 if aEnableTextureUnit then
8365 glBindTexture(Target, ID);
8368 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8369 procedure TglBitmap.Unbind(const aDisableTextureUnit: Boolean);
8371 if aDisableTextureUnit then
8373 glBindTexture(Target, 0);
8376 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8377 procedure TglBitmap.UploadData(const aDataObj: TglBitmapData; const aCheckSize: Boolean);
8381 w := aDataObj.Width;
8382 h := aDataObj.Height;
8383 fDimension.Fields := [];
8385 fDimension.Fields := fDimension.Fields + [ffX];
8387 fDimension.Fields := fDimension.Fields + [ffY];
8393 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8394 function TglBitmap.DownloadData(const aDataObj: TglBitmapData): Boolean;
8397 TempWidth, TempHeight: Integer;
8398 TempIntFormat: GLint;
8399 IntFormat: TglBitmapFormat;
8400 FormatDesc: TFormatDescriptor;
8406 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_WIDTH, @TempWidth);
8407 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT, @TempHeight);
8408 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat);
8410 FormatDesc := (TglBitmapFormatDescriptor.GetByFormat(TempIntFormat) as TFormatDescriptor);
8411 IntFormat := FormatDesc.Format;
8413 // Getting data from OpenGL
8414 FormatDesc := TFormatDescriptor.Get(IntFormat);
8415 GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight));
8417 if FormatDesc.IsCompressed then begin
8418 if not Assigned(glGetCompressedTexImage) then
8419 raise EglBitmap.Create('compressed formats not supported by video adapter');
8420 glGetCompressedTexImage(Target, 0, Temp)
8422 glGetTexImage(Target, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
8423 aDataObj.SetData(Temp, IntFormat, TempWidth, TempHeight);
8426 if Assigned(Temp) then
8433 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8434 constructor TglBitmap.Create;
8436 if (ClassType = TglBitmap) then
8437 raise EglBitmap.Create('Don''t create TglBitmap directly. Use one of the deviated classes (TglBitmap2D) instead.');
8441 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8442 constructor TglBitmap.Create(const aData: TglBitmapData);
8449 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8450 //TglBitmap1D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8451 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8452 procedure TglBitmap1D.UploadDataIntern(const aDataObj: TglBitmapData; const aBuildWithGlu: Boolean);
8454 fd: TglBitmapFormatDescriptor;
8457 fd := aDataObj.FormatDescriptor;
8458 if (fd.glFormat = 0) or (fd.glInternalFormat = 0) or (fd.glDataFormat = 0) then
8459 raise EglBitmap.Create('format is not supported by video adapter, please convert before uploading data');
8461 if fd.IsCompressed then begin
8462 if not Assigned(glCompressedTexImage1D) then
8463 raise EglBitmap.Create('compressed formats not supported by video adapter');
8464 glCompressedTexImage1D(Target, 0, fd.glInternalFormat, aDataObj.Width, 0, fd.GetSize(aDataObj.Width, 1), aDataObj.Data)
8465 end else if aBuildWithGlu then
8466 gluBuild1DMipmaps(Target, fd.glInternalFormat, aDataObj.Width, fd.glFormat, fd.glDataFormat, aDataObj.Data)
8468 glTexImage1D(Target, 0, fd.glInternalFormat, aDataObj.Width, 0, fd.glFormat, fd.glDataFormat, aDataObj.Data);
8471 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8472 procedure TglBitmap1D.AfterConstruction;
8475 Target := GL_TEXTURE_1D;
8478 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8479 procedure TglBitmap1D.UploadData(const aDataObj: TglBitmapData; const aCheckSize: Boolean);
8481 BuildWithGlu, TexRec: Boolean;
8484 if not Assigned(aDataObj) then
8487 // Check Texture Size
8488 if (aCheckSize) then begin
8489 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
8491 if (aDataObj.Width > TexSize) then
8492 raise EglBitmapSizeToLarge.Create('TglBitmap1D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
8494 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and
8495 (Target = GL_TEXTURE_RECTANGLE);
8496 if not (IsPowerOfTwo(aDataObj.Width) or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
8497 raise EglBitmapNonPowerOfTwo.Create('TglBitmap1D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8502 SetupParameters(BuildWithGlu);
8503 UploadDataIntern(aDataObj, BuildWithGlu);
8504 glAreTexturesResident(1, @fID, @fIsResident);
8506 inherited UploadData(aDataObj, aCheckSize);
8510 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8511 //TglBitmap2D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8512 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8513 procedure TglBitmap2D.UploadDataIntern(const aDataObj: TglBitmapData; const aTarget: GLenum; const aBuildWithGlu: Boolean);
8515 fd: TglBitmapFormatDescriptor;
8517 fd := aDataObj.FormatDescriptor;
8518 if (fd.glFormat = 0) or (fd.glInternalFormat = 0) or (fd.glDataFormat = 0) then
8519 raise EglBitmap.Create('format is not supported by video adapter, please convert before uploading data');
8521 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
8523 if fd.IsCompressed then begin
8524 if not Assigned(glCompressedTexImage2D) then
8525 raise EglBitmap.Create('compressed formats not supported by video adapter');
8526 glCompressedTexImage2D(aTarget, 0, fd.glInternalFormat, aDataObj.Width, aDataObj.Height, 0, fd.GetSize(fDimension), aDataObj.Data)
8528 end else if aBuildWithGlu then begin
8529 gluBuild2DMipmaps(aTarget, fd.ChannelCount, aDataObj.Width, aDataObj.Height, fd.glFormat, fd.glDataFormat, aDataObj.Data)
8532 glTexImage2D(aTarget, 0, fd.glInternalFormat, aDataObj.Width, aDataObj.Height, 0, fd.glFormat, fd.glDataFormat, aDataObj.Data);
8536 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8537 procedure TglBitmap2D.AfterConstruction;
8540 Target := GL_TEXTURE_2D;
8543 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8544 procedure TglBitmap2D.UploadData(const aDataObj: TglBitmapData; const aCheckSize: Boolean);
8547 BuildWithGlu, TexRec: Boolean;
8552 if not Assigned(aDataObj) then
8555 // Check Texture Size
8556 if (aCheckSize) then begin
8557 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
8559 if ((aDataObj.Width > TexSize) or (aDataObj.Height > TexSize)) then
8560 raise EglBitmapSizeToLarge.Create('TglBitmap2D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
8562 PotTex := IsPowerOfTwo(aDataObj.Width) and IsPowerOfTwo(aDataObj.Height);
8563 {$IF NOT DEFINED(OPENGL_ES)}
8564 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and (Target = GL_TEXTURE_RECTANGLE);
8565 if not (PotTex or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
8566 raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8567 {$ELSEIF DEFINED(OPENGL_ES_EXT)}
8568 if not PotTex and not GL_OES_texture_npot then
8569 raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8572 raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8578 SetupParameters({$IFNDEF OPENGL_ES}BuildWithGlu{$ENDIF});
8579 UploadDataIntern(aDataObj, Target{$IFNDEF OPENGL_ES}, BuildWithGlu{$ENDIF});
8581 glAreTexturesResident(1, @fID, @fIsResident);
8584 inherited UploadData(aDataObj, aCheckSize);
8587 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8588 class procedure TglBitmap2D.GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat; const aDataObj: TglBitmapData);
8591 Size, w, h: Integer;
8592 FormatDesc: TFormatDescriptor;
8594 FormatDesc := TFormatDescriptor.Get(aFormat);
8595 if FormatDesc.IsCompressed then
8596 raise EglBitmapUnsupportedFormat.Create(aFormat);
8598 w := aRight - aLeft;
8599 h := aBottom - aTop;
8600 Size := FormatDesc.GetSize(w, h);
8603 glPixelStorei(GL_PACK_ALIGNMENT, 1);
8604 glReadPixels(aLeft, aTop, w, h, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
8605 aDataObj.SetData(Temp, aFormat, w, h);
8608 if Assigned(Temp) then
8614 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
8615 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8616 //TglBitmapCubeMap////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8617 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8618 procedure TglBitmapCubeMap.AfterConstruction;
8623 if not (GL_VERSION_1_3 or GL_ARB_texture_cube_map or GL_EXT_texture_cube_map) then
8624 raise EglBitmap.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
8626 if not (GL_VERSION_2_0) then
8627 raise EglBitmap.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
8631 Target := GL_TEXTURE_CUBE_MAP;
8633 fGenMode := GL_REFLECTION_MAP;
8637 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8638 procedure TglBitmapCubeMap.UploadData(const aDataObj: TglBitmapData; const aCheckSize: Boolean);
8640 Assert(false, 'TglBitmapCubeMap.UploadData - Don''t call UploadData directly, use UploadCubeMap instead');
8643 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8644 procedure TglBitmapCubeMap.UploadCubeMap(const aDataObj: TglBitmapData; const aCubeTarget: Cardinal; const aCheckSize: Boolean);
8647 BuildWithGlu: Boolean;
8651 if (aCheckSize) then begin
8652 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, @TexSize);
8654 if (aDataObj.Width > TexSize) or (aDataObj.Height > TexSize) then
8655 raise EglBitmapSizeToLarge.Create('TglBitmapCubeMap.GenerateCubeMap - The size for the Cubemap is to large. It''s may be not conform with the Hardware.');
8657 {$IF NOT DEFINED(OPENGL_ES)}
8658 if not ((IsPowerOfTwo(aDataObj.Width) and IsPowerOfTwo(aDataObj.Height)) or GL_VERSION_2_0 or GL_ARB_texture_non_power_of_two) then
8659 raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenerateCubeMap - Cubemaps dosn''t support non power of two texture.');
8660 {$ELSEIF DEFINED(OPENGL_ES_EXT)}
8661 if not (IsPowerOfTwo(aDataObj.Width) and IsPowerOfTwo(aDataObj.Height)) and not GL_OES_texture_npot then
8662 raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenerateCubeMap - Cubemaps dosn''t support non power of two texture.');
8664 if not (IsPowerOfTwo(aDataObj.Width) and IsPowerOfTwo(aDataObj.Height)) then
8665 raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenerateCubeMap - Cubemaps dosn''t support non power of two texture.');
8671 SetupParameters({$IFNDEF OPENGL_ES}BuildWithGlu{$ENDIF});
8672 UploadDataIntern(aDataObj, aCubeTarget{$IFNDEF OPENGL_ES}, BuildWithGlu{$ENDIF});
8674 inherited UploadData(aDataObj, aCheckSize);
8677 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8678 procedure TglBitmapCubeMap.Bind({$IFNDEF OPENGL_ES}const aEnableTexCoordsGen: Boolean;{$ENDIF} const aEnableTextureUnit: Boolean);
8680 inherited Bind (aEnableTextureUnit);
8682 if aEnableTexCoordsGen then begin
8683 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, fGenMode);
8684 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, fGenMode);
8685 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, fGenMode);
8686 glEnable(GL_TEXTURE_GEN_S);
8687 glEnable(GL_TEXTURE_GEN_T);
8688 glEnable(GL_TEXTURE_GEN_R);
8693 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8694 procedure TglBitmapCubeMap.Unbind({$IFNDEF OPENGL_ES}const aDisableTexCoordsGen: Boolean;{$ENDIF} const aDisableTextureUnit: Boolean);
8696 inherited Unbind(aDisableTextureUnit);
8698 if aDisableTexCoordsGen then begin
8699 glDisable(GL_TEXTURE_GEN_S);
8700 glDisable(GL_TEXTURE_GEN_T);
8701 glDisable(GL_TEXTURE_GEN_R);
8707 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
8708 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8709 //TglBitmapNormalMap//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8710 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8712 TVec = Array[0..2] of Single;
8713 TglBitmapNormalMapGetVectorFunc = procedure (out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8715 PglBitmapNormalMapRec = ^TglBitmapNormalMapRec;
8716 TglBitmapNormalMapRec = record
8718 Func: TglBitmapNormalMapGetVectorFunc;
8721 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8722 procedure glBitmapNormalMapPosX(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8724 aVec[0] := aHalfSize;
8725 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8726 aVec[2] := - (aPosition.X + 0.5 - aHalfSize);
8729 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8730 procedure glBitmapNormalMapNegX(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8732 aVec[0] := - aHalfSize;
8733 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8734 aVec[2] := aPosition.X + 0.5 - aHalfSize;
8737 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8738 procedure glBitmapNormalMapPosY(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8740 aVec[0] := aPosition.X + 0.5 - aHalfSize;
8741 aVec[1] := aHalfSize;
8742 aVec[2] := aPosition.Y + 0.5 - aHalfSize;
8745 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8746 procedure glBitmapNormalMapNegY(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8748 aVec[0] := aPosition.X + 0.5 - aHalfSize;
8749 aVec[1] := - aHalfSize;
8750 aVec[2] := - (aPosition.Y + 0.5 - aHalfSize);
8753 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8754 procedure glBitmapNormalMapPosZ(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8756 aVec[0] := aPosition.X + 0.5 - aHalfSize;
8757 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8758 aVec[2] := aHalfSize;
8761 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8762 procedure glBitmapNormalMapNegZ(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8764 aVec[0] := - (aPosition.X + 0.5 - aHalfSize);
8765 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8766 aVec[2] := - aHalfSize;
8769 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8770 procedure glBitmapNormalMapFunc(var FuncRec: TglBitmapFunctionRec);
8776 with FuncRec do begin
8777 with PglBitmapNormalMapRec(Args)^ do begin
8778 Func(Vec, Position, HalfSize);
8781 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
8782 if Len <> 0 then begin
8783 Vec[0] := Vec[0] * Len;
8784 Vec[1] := Vec[1] * Len;
8785 Vec[2] := Vec[2] * Len;
8788 // Scale Vector and AddVectro
8789 Vec[0] := Vec[0] * 0.5 + 0.5;
8790 Vec[1] := Vec[1] * 0.5 + 0.5;
8791 Vec[2] := Vec[2] * 0.5 + 0.5;
8796 Dest.Data.arr[i] := Round(Vec[i] * 255);
8800 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8801 procedure TglBitmapNormalMap.AfterConstruction;
8805 fGenMode := GL_NORMAL_MAP;
8809 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8810 procedure TglBitmapNormalMap.GenerateNormalMap(const aSize: Integer; const aCheckSize: Boolean);
8812 Rec: TglBitmapNormalMapRec;
8813 SizeRec: TglBitmapSize;
8814 DataObj: TglBitmapData;
8816 Rec.HalfSize := aSize div 2;
8818 SizeRec.Fields := [ffX, ffY];
8822 DataObj := TglBitmapData.Create;
8825 Rec.Func := glBitmapNormalMapPosX;
8826 DataObj.LoadFromFunc(SizeRec, tfBGR8ub3, glBitmapNormalMapFunc, @Rec);
8827 UploadCubeMap(DataObj, GL_TEXTURE_CUBE_MAP_POSITIVE_X, aCheckSize);
8830 Rec.Func := glBitmapNormalMapNegX;
8831 DataObj.LoadFromFunc(SizeRec, tfBGR8ub3, glBitmapNormalMapFunc, @Rec);
8832 UploadCubeMap(DataObj, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, aCheckSize);
8835 Rec.Func := glBitmapNormalMapPosY;
8836 DataObj.LoadFromFunc(SizeRec, tfBGR8ub3, glBitmapNormalMapFunc, @Rec);
8837 UploadCubeMap(DataObj, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, aCheckSize);
8840 Rec.Func := glBitmapNormalMapNegY;
8841 DataObj.LoadFromFunc(SizeRec, tfBGR8ub3, glBitmapNormalMapFunc, @Rec);
8842 UploadCubeMap(DataObj, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, aCheckSize);
8845 Rec.Func := glBitmapNormalMapPosZ;
8846 DataObj.LoadFromFunc(SizeRec, tfBGR8ub3, glBitmapNormalMapFunc, @Rec);
8847 UploadCubeMap(DataObj, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, aCheckSize);
8850 Rec.Func := glBitmapNormalMapNegZ;
8851 DataObj.LoadFromFunc(SizeRec, tfBGR8ub3, glBitmapNormalMapFunc, @Rec);
8852 UploadCubeMap(DataObj, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, aCheckSize);
8854 FreeAndNil(DataObj);
8860 glBitmapSetDefaultFormat (tfEmpty);
8861 glBitmapSetDefaultMipmap (mmMipmap);
8862 glBitmapSetDefaultFilter (GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
8863 glBitmapSetDefaultWrap (GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
8864 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
8865 glBitmapSetDefaultSwizzle(GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA);
8868 glBitmapSetDefaultFreeDataAfterGenTexture(true);
8869 glBitmapSetDefaultDeleteTextureOnFree (true);
8871 TFormatDescriptor.Init;
8874 TFormatDescriptor.Finalize;