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}
185 {$IFDEF OPENGL_ES} dglOpenGLES,
186 {$ELSE} dglOpenGL, {$ENDIF}
188 {$IF DEFINED(GLB_WIN) AND
189 DEFINED(GLB_DELPHI)} windows, {$IFEND}
191 {$IFDEF GLB_SDL} SDL, {$ENDIF}
192 {$IFDEF GLB_LAZARUS} IntfGraphics, GraphType, Graphics, {$ENDIF}
193 {$IFDEF GLB_DELPHI} Dialogs, Graphics, Types, {$ENDIF}
195 {$IFDEF GLB_SDL_IMAGE} SDL_image, {$ENDIF}
196 {$IFDEF GLB_PNGIMAGE} pngimage, {$ENDIF}
197 {$IFDEF GLB_LIB_PNG} libPNG, {$ENDIF}
198 {$IFDEF GLB_DELPHI_JPEG} JPEG, {$ENDIF}
199 {$IFDEF GLB_LIB_JPEG} libJPEG, {$ENDIF}
205 QWord = System.UInt64;
213 { type that describes the format of the data stored in a texture.
214 the name of formats is composed of the following constituents:
216 - channel (e.g. R, G, B, A or Alpha, Luminance or X (reserved))
217 - width of the chanel in bit (4, 8, 16, ...)
218 - data type (e.g. ub, us, ui)
219 - number of elements of data types }
223 tfAlpha4ub1, //< 1 x unsigned byte
224 tfAlpha8ub1, //< 1 x unsigned byte
225 tfAlpha16us1, //< 1 x unsigned short
227 tfLuminance4ub1, //< 1 x unsigned byte
228 tfLuminance8ub1, //< 1 x unsigned byte
229 tfLuminance16us1, //< 1 x unsigned short
231 tfLuminance4Alpha4ub2, //< 1 x unsigned byte (lum), 1 x unsigned byte (alpha)
232 tfLuminance6Alpha2ub2, //< 1 x unsigned byte (lum), 1 x unsigned byte (alpha)
233 tfLuminance8Alpha8ub2, //< 1 x unsigned byte (lum), 1 x unsigned byte (alpha)
234 tfLuminance12Alpha4us2, //< 1 x unsigned short (lum), 1 x unsigned short (alpha)
235 tfLuminance16Alpha16us2, //< 1 x unsigned short (lum), 1 x unsigned short (alpha)
237 tfR3G3B2ub1, //< 1 x unsigned byte (3bit red, 3bit green, 2bit blue)
238 tfRGBX4us1, //< 1 x unsigned short (4bit red, 4bit green, 4bit blue, 4bit reserverd)
239 tfXRGB4us1, //< 1 x unsigned short (4bit reserved, 4bit red, 4bit green, 4bit blue)
240 tfR5G6B5us1, //< 1 x unsigned short (5bit red, 6bit green, 5bit blue)
241 tfRGB5X1us1, //< 1 x unsigned short (5bit red, 5bit green, 5bit blue, 1bit reserved)
242 tfX1RGB5us1, //< 1 x unsigned short (1bit reserved, 5bit red, 5bit green, 5bit blue)
243 tfRGB8ub3, //< 1 x unsigned byte (red), 1 x unsigned byte (green), 1 x unsigned byte (blue)
244 tfRGBX8ui1, //< 1 x unsigned int (8bit red, 8bit green, 8bit blue, 8bit reserved)
245 tfXRGB8ui1, //< 1 x unsigned int (8bit reserved, 8bit red, 8bit green, 8bit blue)
246 tfRGB10X2ui1, //< 1 x unsigned int (10bit red, 10bit green, 10bit blue, 2bit reserved)
247 tfX2RGB10ui1, //< 1 x unsigned int (2bit reserved, 10bit red, 10bit green, 10bit blue)
248 tfRGB16us3, //< 1 x unsigned short (red), 1 x unsigned short (green), 1 x unsigned short (blue)
250 tfRGBA4us1, //< 1 x unsigned short (4bit red, 4bit green, 4bit blue, 4bit alpha)
251 tfARGB4us1, //< 1 x unsigned short (4bit alpha, 4bit red, 4bit green, 4bit blue)
252 tfRGB5A1us1, //< 1 x unsigned short (5bit red, 5bit green, 5bit blue, 1bit alpha)
253 tfA1RGB5us1, //< 1 x unsigned short (1bit alpha, 5bit red, 5bit green, 5bit blue)
254 tfRGBA8ui1, //< 1 x unsigned int (8bit red, 8bit green, 8bit blue, 8 bit alpha)
255 tfARGB8ui1, //< 1 x unsigned int (8 bit alpha, 8bit red, 8bit green, 8bit blue)
256 tfRGBA8ub4, //< 1 x unsigned byte (red), 1 x unsigned byte (green), 1 x unsigned byte (blue), 1 x unsigned byte (alpha)
257 tfRGB10A2ui1, //< 1 x unsigned int (10bit red, 10bit green, 10bit blue, 2bit alpha)
258 tfA2RGB10ui1, //< 1 x unsigned int (2bit alpha, 10bit red, 10bit green, 10bit blue)
259 tfRGBA16us4, //< 1 x unsigned short (red), 1 x unsigned short (green), 1 x unsigned short (blue), 1 x unsigned short (alpha)
261 tfBGRX4us1, //< 1 x unsigned short (4bit blue, 4bit green, 4bit red, 4bit reserved)
262 tfXBGR4us1, //< 1 x unsigned short (4bit reserved, 4bit blue, 4bit green, 4bit red)
263 tfB5G6R5us1, //< 1 x unsigned short (5bit blue, 6bit green, 5bit red)
264 tfBGR5X1us1, //< 1 x unsigned short (5bit blue, 5bit green, 5bit red, 1bit reserved)
265 tfX1BGR5us1, //< 1 x unsigned short (1bit reserved, 5bit blue, 5bit green, 5bit red)
266 tfBGR8ub3, //< 1 x unsigned byte (blue), 1 x unsigned byte (green), 1 x unsigned byte (red)
267 tfBGRX8ui1, //< 1 x unsigned int (8bit blue, 8bit green, 8bit red, 8bit reserved)
268 tfXBGR8ui1, //< 1 x unsigned int (8bit reserved, 8bit blue, 8bit green, 8bit red)
269 tfBGR10X2ui1, //< 1 x unsigned int (10bit blue, 10bit green, 10bit red, 2bit reserved)
270 tfX2BGR10ui1, //< 1 x unsigned int (2bit reserved, 10bit blue, 10bit green, 10bit red)
271 tfBGR16us3, //< 1 x unsigned short (blue), 1 x unsigned short (green), 1 x unsigned short (red)
273 tfBGRA4us1, //< 1 x unsigned short (4bit blue, 4bit green, 4bit red, 4bit alpha)
274 tfABGR4us1, //< 1 x unsigned short (4bit alpha, 4bit blue, 4bit green, 4bit red)
275 tfBGR5A1us1, //< 1 x unsigned short (5bit blue, 5bit green, 5bit red, 1bit alpha)
276 tfA1BGR5us1, //< 1 x unsigned short (1bit alpha, 5bit blue, 5bit green, 5bit red)
277 tfBGRA8ui1, //< 1 x unsigned int (8bit blue, 8bit green, 8bit red, 8bit alpha)
278 tfABGR8ui1, //< 1 x unsigned int (8bit alpha, 8bit blue, 8bit green, 8bit red)
279 tfBGRA8ub4, //< 1 x unsigned byte (blue), 1 x unsigned byte (green), 1 x unsigned byte (red), 1 x unsigned byte (alpha)
280 tfBGR10A2ui1, //< 1 x unsigned int (10bit blue, 10bit green, 10bit red, 2bit alpha)
281 tfA2BGR10ui1, //< 1 x unsigned int (2bit alpha, 10bit blue, 10bit green, 10bit red)
282 tfBGRA16us4, //< 1 x unsigned short (blue), 1 x unsigned short (green), 1 x unsigned short (red), 1 x unsigned short (alpha)
284 tfDepth16us1, //< 1 x unsigned short (depth)
285 tfDepth24ui1, //< 1 x unsigned int (depth)
286 tfDepth32ui1, //< 1 x unsigned int (depth)
293 { type to define suitable file formats }
294 TglBitmapFileType = (
295 {$IFDEF GLB_SUPPORT_PNG_WRITE} ftPNG, {$ENDIF} //< Portable Network Graphic file (PNG)
296 {$IFDEF GLB_SUPPORT_JPEG_WRITE}ftJPEG, {$ENDIF} //< JPEG file
297 ftDDS, //< Direct Draw Surface file (DDS)
298 ftTGA, //< Targa Image File (TGA)
299 ftBMP, //< Windows Bitmap File (BMP)
300 ftRAW); //< glBitmap RAW file format
301 TglBitmapFileTypes = set of TglBitmapFileType;
303 { possible mipmap types }
305 mmNone, //< no mipmaps
306 mmMipmap, //< normal mipmaps
307 mmMipmapGlu); //< mipmaps generated with glu functions
309 { possible normal map functions }
310 TglBitmapNormalMapFunc = (
316 ////////////////////////////////////////////////////////////////////////////////////////////////////
317 EglBitmap = class(Exception); //< glBitmap exception
318 EglBitmapNotSupported = class(Exception); //< exception for not supported functions
319 EglBitmapSizeToLarge = class(EglBitmap); //< exception for to large textures
320 EglBitmapNonPowerOfTwo = class(EglBitmap); //< exception for non power of two textures
321 EglBitmapUnsupportedFormat = class(EglBitmap) //< exception for unsupporetd formats
323 constructor Create(const aFormat: TglBitmapFormat); overload;
324 constructor Create(const aMsg: String; const aFormat: TglBitmapFormat); overload;
327 ////////////////////////////////////////////////////////////////////////////////////////////////////
328 { record that stores 4 unsigned integer values }
329 TglBitmapRec4ui = packed record
331 0: (r, g, b, a: Cardinal);
332 1: (arr: array[0..3] of Cardinal);
335 { record that stores 4 unsigned byte values }
336 TglBitmapRec4ub = packed record
338 0: (r, g, b, a: Byte);
339 1: (arr: array[0..3] of Byte);
342 { record that stores 4 unsigned long integer values }
343 TglBitmapRec4ul = packed record
345 0: (r, g, b, a: QWord);
346 1: (arr: array[0..3] of QWord);
349 { structure to store pixel data in }
350 TglBitmapPixelData = packed record
351 Data: TglBitmapRec4ui; //< color data for each color channel
352 Range: TglBitmapRec4ui; //< maximal color value for each channel
353 Format: TglBitmapFormat; //< format of the pixel
355 PglBitmapPixelData = ^TglBitmapPixelData;
357 TglBitmapSizeFields = set of (ffX, ffY);
358 TglBitmapSize = packed record
359 Fields: TglBitmapSizeFields;
363 TglBitmapPixelPosition = TglBitmapSize;
365 { describes the properties of a given texture data format }
366 TglBitmapFormatDescriptor = class(TObject)
369 fBytesPerPixel: Single; //< number of bytes for each pixel
370 fChannelCount: Integer; //< number of color channels
371 fMask: TglBitmapRec4ul; //< bitmask for each color channel
372 fRange: TglBitmapRec4ui; //< maximal value of each color channel
374 { @return @true if the format has a red color channel, @false otherwise }
375 function GetHasRed: Boolean;
377 { @return @true if the format has a green color channel, @false otherwise }
378 function GetHasGreen: Boolean;
380 { @return @true if the format has a blue color channel, @false otherwise }
381 function GetHasBlue: Boolean;
383 { @return @true if the format has a alpha color channel, @false otherwise }
384 function GetHasAlpha: Boolean;
386 { @return @true if the format has any color color channel, @false otherwise }
387 function GetHasColor: Boolean;
389 { @return @true if the format is a grayscale format, @false otherwise }
390 function GetIsGrayscale: Boolean;
392 { @return @true if the format is supported by OpenGL, @false otherwise }
393 function GetHasOpenGLSupport: Boolean;
396 fFormat: TglBitmapFormat; //< format this descriptor belongs to
397 fWithAlpha: TglBitmapFormat; //< suitable format with alpha channel
398 fWithoutAlpha: TglBitmapFormat; //< suitable format without alpha channel
399 fOpenGLFormat: TglBitmapFormat; //< suitable format that is supported by OpenGL
400 fRGBInverted: TglBitmapFormat; //< suitable format with inverted RGB channels
401 fUncompressed: TglBitmapFormat; //< suitable format with uncompressed data
403 fBitsPerPixel: Integer; //< number of bits per pixel
404 fIsCompressed: Boolean; //< @true if the format is compressed, @false otherwise
406 fPrecision: TglBitmapRec4ub; //< number of bits for each color channel
407 fShift: TglBitmapRec4ub; //< bit offset for each color channel
409 fglFormat: GLenum; //< OpenGL format enum (e.g. GL_RGB)
410 fglInternalFormat: GLenum; //< OpenGL internal format enum (e.g. GL_RGB8)
411 fglDataFormat: GLenum; //< OpenGL data format enum (e.g. GL_UNSIGNED_BYTE)
413 { set values for this format descriptor }
414 procedure SetValues; virtual;
416 { calculate cached values }
417 procedure CalcValues;
419 property Format: TglBitmapFormat read fFormat; //< format this descriptor belongs to
420 property ChannelCount: Integer read fChannelCount; //< number of color channels
421 property IsCompressed: Boolean read fIsCompressed; //< @true if the format is compressed, @false otherwise
422 property BitsPerPixel: Integer read fBitsPerPixel; //< number of bytes per pixel
423 property BytesPerPixel: Single read fBytesPerPixel; //< number of bits per pixel
425 property Precision: TglBitmapRec4ub read fPrecision; //< number of bits for each color channel
426 property Shift: TglBitmapRec4ub read fShift; //< bit offset for each color channel
427 property Range: TglBitmapRec4ui read fRange; //< maximal value of each color channel
428 property Mask: TglBitmapRec4ul read fMask; //< bitmask for each color channel
430 property RGBInverted: TglBitmapFormat read fRGBInverted; //< suitable format with inverted RGB channels
431 property WithAlpha: TglBitmapFormat read fWithAlpha; //< suitable format with alpha channel
432 property WithoutAlpha: TglBitmapFormat read fWithAlpha; //< suitable format without alpha channel
433 property OpenGLFormat: TglBitmapFormat read fOpenGLFormat; //< suitable format that is supported by OpenGL
434 property Uncompressed: TglBitmapFormat read fUncompressed; //< suitable format with uncompressed data
436 property glFormat: GLenum read fglFormat; //< OpenGL format enum (e.g. GL_RGB)
437 property glInternalFormat: GLenum read fglInternalFormat; //< OpenGL internal format enum (e.g. GL_RGB8)
438 property glDataFormat: GLenum read fglDataFormat; //< OpenGL data format enum (e.g. GL_UNSIGNED_BYTE)
440 property HasRed: Boolean read GetHasRed; //< @true if the format has a red color channel, @false otherwise
441 property HasGreen: Boolean read GetHasGreen; //< @true if the format has a green color channel, @false otherwise
442 property HasBlue: Boolean read GetHasBlue; //< @true if the format has a blue color channel, @false otherwise
443 property HasAlpha: Boolean read GetHasAlpha; //< @true if the format has a alpha color channel, @false otherwise
444 property HasColor: Boolean read GetHasColor; //< @true if the format has any color color channel, @false otherwise
445 property IsGrayscale: Boolean read GetIsGrayscale; //< @true if the format is a grayscale format, @false otherwise
447 property HasOpenGLSupport: Boolean read GetHasOpenGLSupport; //< @true if the format is supported by OpenGL, @false otherwise
449 function GetSize(const aSize: TglBitmapSize): Integer; overload; virtual;
450 function GetSize(const aWidth, aHeight: Integer): Integer; overload; virtual;
455 { get the format descriptor by a given OpenGL internal format
456 @param aInternalFormat OpenGL internal format to get format descriptor for
457 @returns suitable format descriptor or tfEmpty-Descriptor }
458 class function GetByFormat(const aInternalFormat: GLenum): TglBitmapFormatDescriptor;
461 ////////////////////////////////////////////////////////////////////////////////////////////////////
462 TglBitmapData = class;
464 { structure to store data for converting in }
465 TglBitmapFunctionRec = record
466 Sender: TglBitmapData; //< texture object that stores the data to convert
467 Size: TglBitmapSize; //< size of the texture
468 Position: TglBitmapPixelPosition; //< position of the currently pixel
469 Source: TglBitmapPixelData; //< pixel data of the current pixel
470 Dest: TglBitmapPixelData; //< new data of the pixel (must be filled in)
471 Args: Pointer; //< user defined args that was passed to the convert function
474 { callback to use for converting texture data }
475 TglBitmapFunction = procedure(var FuncRec: TglBitmapFunctionRec);
477 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
478 { class to store texture data in. used to load, save and
479 manipulate data before assigned to texture object
480 all operations on a data object can be done from a background thread }
481 TglBitmapData = class
484 fData: PByte; //< texture data
485 fDimension: TglBitmapSize; //< pixel size of the data
486 fFormat: TglBitmapFormat; //< format the texture data is stored in
487 fFilename: String; //< file the data was load from
489 fScanlines: array of PByte; //< pointer to begin of each line
490 fHasScanlines: Boolean; //< @true if scanlines are initialized, @false otherwise
492 private { getter / setter }
494 { @returns the format descriptor suitable to the texture data format }
495 function GetFormatDescriptor: TglBitmapFormatDescriptor;
497 { @returns the width of the texture data (in pixel) or -1 if no data is set }
498 function GetWidth: Integer;
500 { @returns the height of the texture data (in pixel) or -1 if no data is set }
501 function GetHeight: Integer;
503 { get scanline at index aIndex
504 @returns Pointer to start of line or @nil }
505 function GetScanlines(const aIndex: Integer): PByte;
507 { set new value for the data format. only possible if new format has the same pixel size.
508 if you want to convert the texture data, see ConvertTo function }
509 procedure SetFormat(const aValue: TglBitmapFormat);
511 private { internal misc }
513 { splits a resource identifier into the resource and it's type
514 @param aResource resource identifier to split and store name in
515 @param aResType type of the resource }
516 procedure PrepareResType(var aResource: String; var aResType: PChar);
518 { updates scanlines array }
519 procedure UpdateScanlines;
521 private { internal load and save }
522 {$IFDEF GLB_SUPPORT_PNG_READ}
523 { try to load a PNG from a stream
524 @param aStream stream to load PNG from
525 @returns @true on success, @false otherwise }
526 function LoadPNG(const aStream: TStream): Boolean; virtual;
529 {$ifdef GLB_SUPPORT_PNG_WRITE}
530 { save texture data as PNG to stream
531 @param aStream stream to save data to}
532 procedure SavePNG(const aStream: TStream); virtual;
535 {$IFDEF GLB_SUPPORT_JPEG_READ}
536 { try to load a JPEG from a stream
537 @param aStream stream to load JPEG from
538 @returns @true on success, @false otherwise }
539 function LoadJPEG(const aStream: TStream): Boolean; virtual;
542 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
543 { save texture data as JPEG to stream
544 @param aStream stream to save data to}
545 procedure SaveJPEG(const aStream: TStream); virtual;
548 { try to load a RAW image from a stream
549 @param aStream stream to load RAW image from
550 @returns @true on success, @false otherwise }
551 function LoadRAW(const aStream: TStream): Boolean;
553 { save texture data as RAW image to stream
554 @param aStream stream to save data to}
555 procedure SaveRAW(const aStream: TStream);
557 { try to load a BMP from a stream
558 @param aStream stream to load BMP from
559 @returns @true on success, @false otherwise }
560 function LoadBMP(const aStream: TStream): Boolean;
562 { save texture data as BMP to stream
563 @param aStream stream to save data to}
564 procedure SaveBMP(const aStream: TStream);
566 { try to load a TGA from a stream
567 @param aStream stream to load TGA from
568 @returns @true on success, @false otherwise }
569 function LoadTGA(const aStream: TStream): Boolean;
571 { save texture data as TGA to stream
572 @param aStream stream to save data to}
573 procedure SaveTGA(const aStream: TStream);
575 { try to load a DDS from a stream
576 @param aStream stream to load DDS from
577 @returns @true on success, @false otherwise }
578 function LoadDDS(const aStream: TStream): Boolean;
580 { save texture data as DDS to stream
581 @param aStream stream to save data to}
582 procedure SaveDDS(const aStream: TStream);
584 public { properties }
585 property Data: PByte read fData; //< texture data (be carefull with this!)
586 property Dimension: TglBitmapSize read fDimension; //< size of the texture data (in pixel)
587 property Filename: String read fFilename; //< file the data was loaded from
588 property Width: Integer read GetWidth; //< width of the texture data (in pixel)
589 property Height: Integer read GetHeight; //< height of the texture data (in pixel)
590 property Format: TglBitmapFormat read fFormat write SetFormat; //< format the texture data is stored in
591 property Scanlines[const aIndex: Integer]: PByte read GetScanlines; //< pointer to begin of line at given index or @nil
593 property FormatDescriptor: TglBitmapFormatDescriptor read GetFormatDescriptor; //< descriptor object that describes the format of the stored data
597 { flip texture horizontal
598 @returns @true in success, @false otherwise }
599 function FlipHorz: Boolean; virtual;
601 { flip texture vertical
602 @returns @true in success, @false otherwise }
603 function FlipVert: Boolean; virtual;
607 { load a texture from a file
608 @param aFilename file to load texuture from }
609 procedure LoadFromFile(const aFilename: String);
611 { load a texture from a stream
612 @param aStream stream to load texture from }
613 procedure LoadFromStream(const aStream: TStream); virtual;
615 { use a function to generate texture data
616 @param aSize size of the texture
617 @param aFormat format of the texture data
618 @param aFunc callback to use for generation
619 @param aArgs user defined paramaters (use at will) }
620 procedure LoadFromFunc(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer = nil);
622 { load a texture from a resource
623 @param aInstance resource handle
624 @param aResource resource indentifier
625 @param aResType resource type (if known) }
626 procedure LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil);
628 { load a texture from a resource id
629 @param aInstance resource handle
630 @param aResource resource ID
631 @param aResType resource type }
632 procedure LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
636 { save texture data to a file
637 @param aFilename filename to store texture in
638 @param aFileType file type to store data into }
639 procedure SaveToFile(const aFilename: String; const aFileType: TglBitmapFileType);
641 { save texture data to a stream
642 @param aFilename filename to store texture in
643 @param aFileType file type to store data into }
644 procedure SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType); virtual;
648 { convert texture data using a user defined callback
649 @param aFunc callback to use for converting
650 @param aCreateTemp create a temporary buffer to use for converting
651 @param aArgs user defined paramters (use at will)
652 @returns @true if converting was successful, @false otherwise }
653 function Convert(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer = nil): Boolean; overload;
655 { convert texture data using a user defined callback
656 @param aSource glBitmap to read data from
657 @param aFunc callback to use for converting
658 @param aCreateTemp create a temporary buffer to use for converting
659 @param aFormat format of the new data
660 @param aArgs user defined paramters (use at will)
661 @returns @true if converting was successful, @false otherwise }
662 function Convert(const aSource: TglBitmapData; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
663 const aFormat: TglBitmapFormat; const aArgs: Pointer = nil): Boolean; overload;
665 { convert texture data using a specific format
666 @param aFormat new format of texture data
667 @returns @true if converting was successful, @false otherwise }
668 function ConvertTo(const aFormat: TglBitmapFormat): Boolean; virtual;
673 { assign texture data to SDL surface
674 @param aSurface SDL surface to write data to
675 @returns @true on success, @false otherwise }
676 function AssignToSurface(out aSurface: PSDL_Surface): Boolean;
678 { assign texture data from SDL surface
679 @param aSurface SDL surface to read data from
680 @returns @true on success, @false otherwise }
681 function AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
683 { assign alpha channel data to SDL surface
684 @param aSurface SDL surface to write alpha channel data to
685 @returns @true on success, @false otherwise }
686 function AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
688 { assign alpha channel data from SDL surface
689 @param aSurface SDL surface to read data from
690 @param aFunc callback to use for converting
691 @param aArgs user defined parameters (use at will)
692 @returns @true on success, @false otherwise }
693 function AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
699 { assign texture data to TBitmap object
700 @param aBitmap TBitmap to write data to
701 @returns @true on success, @false otherwise }
702 function AssignToBitmap(const aBitmap: TBitmap): Boolean;
704 { assign texture data from TBitmap object
705 @param aBitmap TBitmap to read data from
706 @returns @true on success, @false otherwise }
707 function AssignFromBitmap(const aBitmap: TBitmap): Boolean;
709 { assign alpha channel data to TBitmap object
710 @param aBitmap TBitmap to write data to
711 @returns @true on success, @false otherwise }
712 function AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
714 { assign alpha channel data from TBitmap object
715 @param aBitmap TBitmap to read data from
716 @param aFunc callback to use for converting
717 @param aArgs user defined parameters (use at will)
718 @returns @true on success, @false otherwise }
719 function AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
725 { assign texture data to TLazIntfImage object
726 @param aImage TLazIntfImage to write data to
727 @returns @true on success, @false otherwise }
728 function AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
730 { assign texture data from TLazIntfImage object
731 @param aImage TLazIntfImage to read data from
732 @returns @true on success, @false otherwise }
733 function AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
735 { assign alpha channel data to TLazIntfImage object
736 @param aImage TLazIntfImage to write data to
737 @returns @true on success, @false otherwise }
738 function AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
740 { assign alpha channel data from TLazIntfImage object
741 @param aImage TLazIntfImage to read data from
742 @param aFunc callback to use for converting
743 @param aArgs user defined parameters (use at will)
744 @returns @true on success, @false otherwise }
745 function AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
749 { load alpha channel data from resource
750 @param aInstance resource handle
751 @param aResource resource ID
752 @param aResType resource type
753 @param aFunc callback to use for converting
754 @param aArgs user defined parameters (use at will)
755 @returns @true on success, @false otherwise }
756 function AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
758 { load alpha channel data from resource ID
759 @param aInstance resource handle
760 @param aResourceID resource ID
761 @param aResType resource type
762 @param aFunc callback to use for converting
763 @param aArgs user defined parameters (use at will)
764 @returns @true on success, @false otherwise }
765 function AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
767 { add alpha channel data from function
768 @param aFunc callback to get data from
769 @param aArgs user defined parameters (use at will)
770 @returns @true on success, @false otherwise }
771 function AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer = nil): Boolean; virtual;
773 { add alpha channel data from file (macro for: new glBitmap, LoadFromFile, AddAlphaFromGlBitmap)
774 @param aFilename file to load alpha channel data from
775 @param aFunc callback to use for converting
776 @param aArgs SetFormat user defined parameters (use at will)
777 @returns @true on success, @false otherwise }
778 function AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
780 { add alpha channel data from stream (macro for: new glBitmap, LoadFromStream, AddAlphaFromGlBitmap)
781 @param aStream stream to load alpha channel data from
782 @param aFunc callback to use for converting
783 @param aArgs user defined parameters (use at will)
784 @returns @true on success, @false otherwise }
785 function AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
787 { add alpha channel data from existing glBitmap object
788 @param aBitmap TglBitmap to copy alpha channel data from
789 @param aFunc callback to use for converting
790 @param aArgs user defined parameters (use at will)
791 @returns @true on success, @false otherwise }
792 function AddAlphaFromDataObj(const aDataObj: TglBitmapData; aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
794 { add alpha to pixel if the pixels color is greter than the given color value
795 @param aRed red threshold (0-255)
796 @param aGreen green threshold (0-255)
797 @param aBlue blue threshold (0-255)
798 @param aDeviatation accepted deviatation (0-255)
799 @returns @true on success, @false otherwise }
800 function AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte = 0): Boolean;
802 { add alpha to pixel if the pixels color is greter than the given color value
803 @param aRed red threshold (0-Range.r)
804 @param aGreen green threshold (0-Range.g)
805 @param aBlue blue threshold (0-Range.b)
806 @param aDeviatation accepted deviatation (0-max(Range.rgb))
807 @returns @true on success, @false otherwise }
808 function AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal = 0): Boolean;
810 { add alpha to pixel if the pixels color is greter than the given color value
811 @param aRed red threshold (0.0-1.0)
812 @param aGreen green threshold (0.0-1.0)
813 @param aBlue blue threshold (0.0-1.0)
814 @param aDeviatation accepted deviatation (0.0-1.0)
815 @returns @true on success, @false otherwise }
816 function AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single = 0): Boolean;
818 { add a constand alpha value to all pixels
819 @param aAlpha alpha value to add (0-255)
820 @returns @true on success, @false otherwise }
821 function AddAlphaFromValue(const aAlpha: Byte): Boolean;
823 { add a constand alpha value to all pixels
824 @param aAlpha alpha value to add (0-max(Range.rgb))
825 @returns @true on success, @false otherwise }
826 function AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
828 { add a constand alpha value to all pixels
829 @param aAlpha alpha value to add (0.0-1.0)
830 @returns @true on success, @false otherwise }
831 function AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
833 { remove alpha channel
834 @returns @true on success, @false otherwise }
835 function RemoveAlpha: Boolean; virtual;
838 { fill complete texture with one color
839 @param aRed red color for border (0-255)
840 @param aGreen green color for border (0-255)
841 @param aBlue blue color for border (0-255)
842 @param aAlpha alpha color for border (0-255) }
843 procedure FillWithColor(const aRed, aGreen, aBlue: Byte; const aAlpha: Byte = 255);
845 { fill complete texture with one color
846 @param aRed red color for border (0-Range.r)
847 @param aGreen green color for border (0-Range.g)
848 @param aBlue blue color for border (0-Range.b)
849 @param aAlpha alpha color for border (0-Range.a) }
850 procedure FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal = $FFFFFFFF);
852 { fill complete texture with one color
853 @param aRed red color for border (0.0-1.0)
854 @param aGreen green color for border (0.0-1.0)
855 @param aBlue blue color for border (0.0-1.0)
856 @param aAlpha alpha color for border (0.0-1.0) }
857 procedure FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single = 1.0);
861 { set data pointer of texture data
862 @param aData pointer to new texture data
863 @param aFormat format of the data stored at aData
864 @param aWidth width of the texture data
865 @param aHeight height of the texture data }
866 procedure SetData(const aData: PByte; const aFormat: TglBitmapFormat;
867 const aWidth: Integer = -1; const aHeight: Integer = -1); virtual;
869 { create a clone of the current object
870 @returns clone of this object}
871 function Clone: TglBitmapData;
873 { invert color data (bitwise not)
874 @param aRed invert red channel
875 @param aGreen invert green channel
876 @param aBlue invert blue channel
877 @param aAlpha invert alpha channel }
878 procedure Invert(const aRed, aGreen, aBlue, aAlpha: Boolean);
880 { create normal map from texture data
881 @param aFunc normal map function to generate normalmap with
882 @param aScale scale of the normale stored in the normal map
883 @param aUseAlpha generate normalmap from alpha channel data (if present) }
884 procedure GenerateNormalMap(const aFunc: TglBitmapNormalMapFunc = nm3x3;
885 const aScale: Single = 2; const aUseAlpha: Boolean = false);
887 public { constructor }
889 { constructor - creates a texutre data object }
890 constructor Create; overload;
892 { constructor - creates a texture data object and loads it from a file
893 @param aFilename file to load texture from }
894 constructor Create(const aFileName: String); overload;
896 { constructor - creates a texture data object and loads it from a stream
897 @param aStream stream to load texture from }
898 constructor Create(const aStream: TStream); overload;
900 { constructor - creates a texture data object with the given size, format and data
901 @param aSize size of the texture
902 @param aFormat format of the given data
903 @param aData texture data - be carefull: the data will now be managed by the texture data object }
904 constructor Create(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat; aData: PByte = nil); overload;
906 { constructor - creates a texture data object with the given size and format and uses the given callback to create the data
907 @param aSize size of the texture
908 @param aFormat format of the given data
909 @param aFunc callback to use for generating the data
910 @param aArgs user defined parameters (use at will) }
911 constructor Create(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer = nil); overload;
913 { constructor - creates a texture data object and loads it from a resource
914 @param aInstance resource handle
915 @param aResource resource indentifier
916 @param aResType resource type (if known) }
917 constructor Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil); overload;
919 { constructor - creates a texture data object and loads it from a resource
920 @param aInstance resource handle
921 @param aResourceID resource ID
922 @param aResType resource type (if known) }
923 constructor Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar); overload;
926 destructor Destroy; override;
930 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
931 { base class for all glBitmap classes. used to manage OpenGL texture objects
932 all operations on a bitmap object must be done from the render thread }
935 fID: GLuint; //< name of the OpenGL texture object
936 fTarget: GLuint; //< texture target (e.g. GL_TEXTURE_2D)
937 fDeleteTextureOnFree: Boolean; //< delete OpenGL texture object when this object is destroyed
939 // texture properties
940 fFilterMin: GLenum; //< min filter to apply to the texture
941 fFilterMag: GLenum; //< mag filter to apply to the texture
942 fWrapS: GLenum; //< texture wrapping for x axis
943 fWrapT: GLenum; //< texture wrapping for y axis
944 fWrapR: GLenum; //< texture wrapping for z axis
945 fAnisotropic: Integer; //< anisotropic level
946 fBorderColor: array[0..3] of Single; //< color of the texture border
948 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
950 fSwizzle: array[0..3] of GLenum; //< color channel swizzle
953 fIsResident: GLboolean; //< @true if OpenGL texture object has data, @false otherwise
956 fDimension: TglBitmapSize; //< size of this texture
957 fMipMap: TglBitmapMipMap; //< mipmap type
960 fCustomData: Pointer; //< user defined data
961 fCustomName: String; //< user defined name
962 fCustomNameW: WideString; //< user defined name
964 { @returns the actual width of the texture }
965 function GetWidth: Integer; virtual;
967 { @returns the actual height of the texture }
968 function GetHeight: Integer; virtual;
971 { set a new value for fCustomData }
972 procedure SetCustomData(const aValue: Pointer);
974 { set a new value for fCustomName }
975 procedure SetCustomName(const aValue: String);
977 { set a new value for fCustomNameW }
978 procedure SetCustomNameW(const aValue: WideString);
980 { set new value for fDeleteTextureOnFree }
981 procedure SetDeleteTextureOnFree(const aValue: Boolean);
983 { set name of OpenGL texture object }
984 procedure SetID(const aValue: Cardinal);
986 { set new value for fMipMap }
987 procedure SetMipMap(const aValue: TglBitmapMipMap);
989 { set new value for target }
990 procedure SetTarget(const aValue: Cardinal);
992 { set new value for fAnisotrophic }
993 procedure SetAnisotropic(const aValue: Integer);
996 { create OpenGL texture object (delete exisiting object if exists) }
999 { setup texture parameters }
1000 procedure SetupParameters({$IFNDEF OPENGL_ES}out aBuildWithGlu: Boolean{$ENDIF});
1003 property Width: Integer read GetWidth; //< the actual width of the texture
1004 property Height: Integer read GetHeight; //< the actual height of the texture
1007 property ID: Cardinal read fID write SetID; //< name of the OpenGL texture object
1008 property Target: Cardinal read fTarget write SetTarget; //< texture target (e.g. GL_TEXTURE_2D)
1009 property DeleteTextureOnFree: Boolean read fDeleteTextureOnFree write SetDeleteTextureOnFree; //< delete texture object when this object is destroyed
1011 property MipMap: TglBitmapMipMap read fMipMap write SetMipMap; //< mipmap type
1012 property Anisotropic: Integer read fAnisotropic write SetAnisotropic; //< anisotropic level
1014 property CustomData: Pointer read fCustomData write SetCustomData; //< user defined data (use at will)
1015 property CustomName: String read fCustomName write SetCustomName; //< user defined name (use at will)
1016 property CustomNameW: WideString read fCustomNameW write SetCustomNameW; //< user defined name (as WideString; use at will)
1018 property Dimension: TglBitmapSize read fDimension; //< size of the texture
1020 property IsResident: GLboolean read fIsResident; //< @true if OpenGL texture object has data, @false otherwise
1023 { this method is called after the constructor and sets the default values of this object }
1024 procedure AfterConstruction; override;
1026 { this method is called before the destructor and does some cleanup }
1027 procedure BeforeDestruction; override;
1031 { set the new value for texture border color
1032 @param aRed red color for border (0.0-1.0)
1033 @param aGreen green color for border (0.0-1.0)
1034 @param aBlue blue color for border (0.0-1.0)
1035 @param aAlpha alpha color for border (0.0-1.0) }
1036 procedure SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
1040 { set new texture filer
1041 @param aMin min filter
1042 @param aMag mag filter }
1043 procedure SetFilter(const aMin, aMag: GLenum);
1045 { set new texture wrapping
1046 @param S texture wrapping for x axis
1047 @param T texture wrapping for y axis
1048 @param R texture wrapping for z axis }
1050 const S: GLenum = GL_CLAMP_TO_EDGE;
1051 const T: GLenum = GL_CLAMP_TO_EDGE;
1052 const R: GLenum = GL_CLAMP_TO_EDGE);
1054 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
1056 @param r swizzle for red channel
1057 @param g swizzle for green channel
1058 @param b swizzle for blue channel
1059 @param a swizzle for alpha channel }
1060 procedure SetSwizzle(const r, g, b, a: GLenum);
1065 @param aEnableTextureUnit enable texture unit for this texture (e.g. glEnable(GL_TEXTURE_2D)) }
1066 procedure Bind({$IFNDEF OPENGL_ES}const aEnableTextureUnit: Boolean = true{$ENDIF}); virtual;
1069 @param aDisableTextureUnit disable texture unit for this texture (e.g. glEnable(GL_TEXTURE_2D)) }
1070 procedure Unbind({$IFNDEF OPENGL_ES}const aDisableTextureUnit: Boolean = true{$ENDIF}); virtual;
1072 { upload texture data from given data object to video card
1073 @param aData texture data object that contains the actual data
1074 @param aCheckSize check size before upload and throw exception if something is wrong }
1075 procedure UploadData(const aDataObj: TglBitmapData; const aCheckSize: Boolean = true); virtual;
1078 { download texture data from video card and store it into given data object
1079 @returns @true when download was successfull, @false otherwise }
1080 function DownloadData(const aDataObj: TglBitmapData): Boolean; virtual;
1083 { constructor - creates an empty texture }
1084 constructor Create; overload;
1086 { constructor - creates an texture object and uploads the given data }
1087 constructor Create(const aData: TglBitmapData); overload;
1091 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1092 {$IF NOT DEFINED(OPENGL_ES)}
1093 { wrapper class for 1-dimensional textures (OpenGL target = GL_TEXTURE_1D
1094 all operations on a bitmap object must be done from the render thread }
1095 TglBitmap1D = class(TglBitmap)
1098 { upload the texture data to video card
1099 @param aDataObj texture data object that contains the actual data
1100 @param aBuildWithGlu use glu functions to build mipmaps }
1101 procedure UploadDataIntern(const aDataObj: TglBitmapData; const aBuildWithGlu: Boolean);
1104 property Width; //< actual with of the texture
1106 { this method is called after constructor and initializes the object }
1107 procedure AfterConstruction; override;
1109 { upload texture data from given data object to video card
1110 @param aData texture data object that contains the actual data
1111 @param aCheckSize check size before upload and throw exception if something is wrong }
1112 procedure UploadData(const aDataObj: TglBitmapData; const aCheckSize: Boolean = true); override;
1117 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1118 { wrapper class for 2-dimensional textures (OpenGL target = GL_TEXTURE_2D)
1119 all operations on a bitmap object must be done from the render thread }
1120 TglBitmap2D = class(TglBitmap)
1123 { upload the texture data to video card
1124 @param aDataObj texture data object that contains the actual data
1125 @param aTarget target o upload data to (e.g. GL_TEXTURE_2D)
1126 @param aBuildWithGlu use glu functions to build mipmaps }
1127 procedure UploadDataIntern(const aDataObj: TglBitmapData; const aTarget: GLenum
1128 {$IFNDEF OPENGL_ES}; const aBuildWithGlu: Boolean{$ENDIF});
1131 property Width; //< actual width of the texture
1132 property Height; //< actual height of the texture
1134 { this method is called after constructor and initializes the object }
1135 procedure AfterConstruction; override;
1137 { upload texture data from given data object to video card
1138 @param aData texture data object that contains the actual data
1139 @param aCheckSize check size before upload and throw exception if something is wrong }
1140 procedure UploadData(const aDataObj: TglBitmapData; const aCheckSize: Boolean = true); override;
1144 { copy a part of the frame buffer to the texture
1145 @param aTop topmost pixel to copy
1146 @param aLeft leftmost pixel to copy
1147 @param aRight rightmost pixel to copy
1148 @param aBottom bottommost pixel to copy
1149 @param aFormat format to store data in
1150 @param aDataObj texture data object to store the data in }
1151 class procedure GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat; const aDataObj: TglBitmapData);
1155 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1156 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
1157 { wrapper class for cube maps (OpenGL target = GL_TEXTURE_CUBE_MAP)
1158 all operations on a bitmap object must be done from the render thread }
1159 TglBitmapCubeMap = class(TglBitmap2D)
1162 fGenMode: Integer; //< generation mode for the cube map (e.g. GL_REFLECTION_MAP)
1166 { this method is called after constructor and initializes the object }
1167 procedure AfterConstruction; override;
1169 { upload texture data from given data object to video card
1170 @param aData texture data object that contains the actual data
1171 @param aCheckSize check size before upload and throw exception if something is wrong }
1172 procedure UploadData(const aDataObj: TglBitmapData; const aCheckSize: Boolean = true); override;
1174 { upload texture data from given data object to video card
1175 @param aData texture data object that contains the actual data
1176 @param aCubeTarget cube map target to upload data to (e.g. GL_TEXTURE_CUBE_MAP_POSITIVE_X)
1177 @param aCheckSize check size before upload and throw exception if something is wrong }
1178 procedure UploadCubeMap(const aDataObj: TglBitmapData; const aCubeTarget: Cardinal; const aCheckSize: Boolean);
1181 @param aEnableTexCoordsGen enable cube map generator
1182 @param aEnableTextureUnit enable texture unit }
1183 procedure Bind({$IFNDEF OPENGL_ES}const aEnableTexCoordsGen: Boolean = true; const aEnableTextureUnit: Boolean = true{$ENDIF}); reintroduce; virtual;
1186 @param aDisableTexCoordsGen disable cube map generator
1187 @param aDisableTextureUnit disable texture unit }
1188 procedure Unbind({$IFNDEF OPENGL_ES}const aDisableTexCoordsGen: Boolean = true; const aDisableTextureUnit: Boolean = true{$ENDIF}); reintroduce; virtual;
1192 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
1193 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1194 { wrapper class for cube normal maps
1195 all operations on a bitmap object must be done from the render thread }
1196 TglBitmapNormalMap = class(TglBitmapCubeMap)
1198 { this method is called after constructor and initializes the object }
1199 procedure AfterConstruction; override;
1201 { create cube normal map from texture data and upload it to video card
1202 @param aSize size of each cube map texture
1203 @param aCheckSize check size before upload and throw exception if something is wrong }
1204 procedure GenerateNormalMap(const aSize: Integer = 32; const aCheckSize: Boolean = true);
1208 TglcBitmapFormat = TglBitmapFormat;
1209 TglcBitmap2D = TglBitmap2D;
1210 TglcBitmapData = TglBitmapData;
1211 {$IF NOT DEFINED(OPENGL_ES)}
1212 TglcBitmap1D = TglBitmap1D;
1213 TglcBitmapCubeMap = TglBitmapCubeMap;
1214 TglcBitmapNormalMap = TglBitmapNormalMap;
1215 {$ELSEIF DEFINED(OPENGL_ES_2_0)}
1216 TglcBitmapCubeMap = TglBitmapCubeMap;
1217 TglcBitmapNormalMap = TglBitmapNormalMap;
1221 NULL_SIZE: TglBitmapSize = (Fields: []; X: 0; Y: 0);
1223 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
1224 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
1225 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
1226 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
1227 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
1228 procedure glBitmapSetDefaultWrap(
1229 const S: Cardinal = GL_CLAMP_TO_EDGE;
1230 const T: Cardinal = GL_CLAMP_TO_EDGE;
1231 const R: Cardinal = GL_CLAMP_TO_EDGE);
1233 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
1234 procedure glBitmapSetDefaultSwizzle(const r: GLenum = GL_RED; g: GLenum = GL_GREEN; b: GLenum = GL_BLUE; a: GLenum = GL_ALPHA);
1237 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
1238 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
1239 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
1240 function glBitmapGetDefaultFormat: TglBitmapFormat;
1241 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
1242 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
1243 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
1244 procedure glBitmapGetDefaultSwizzle(var r, g, b, a: GLenum);
1247 function glBitmapSize(X: Integer = -1; Y: Integer = -1): TglBitmapSize;
1248 function glBitmapPosition(X: Integer = -1; Y: Integer = -1): TglBitmapPixelPosition;
1249 function glBitmapRec4ub(const r, g, b, a: Byte): TglBitmapRec4ub;
1250 function glBitmapRec4ui(const r, g, b, a: Cardinal): TglBitmapRec4ui;
1251 function glBitmapRec4ul(const r, g, b, a: QWord): TglBitmapRec4ul;
1252 function glBitmapRec4ubCompare(const r1, r2: TglBitmapRec4ub): Boolean;
1253 function glBitmapRec4uiCompare(const r1, r2: TglBitmapRec4ui): Boolean;
1255 function glBitmapCreateTestData(const aFormat: TglBitmapFormat): TglBitmapData;
1258 function CreateGrayPalette: HPALETTE;
1264 Math, syncobjs, typinfo
1265 {$IF DEFINED(GLB_SUPPORT_JPEG_READ) AND DEFINED(GLB_LAZ_JPEG)}, FPReadJPEG{$IFEND};
1269 glBitmapDefaultDeleteTextureOnFree: Boolean;
1270 glBitmapDefaultFreeDataAfterGenTextures: Boolean;
1271 glBitmapDefaultFormat: TglBitmapFormat;
1272 glBitmapDefaultMipmap: TglBitmapMipMap;
1273 glBitmapDefaultFilterMin: Cardinal;
1274 glBitmapDefaultFilterMag: Cardinal;
1275 glBitmapDefaultWrapS: Cardinal;
1276 glBitmapDefaultWrapT: Cardinal;
1277 glBitmapDefaultWrapR: Cardinal;
1278 glDefaultSwizzle: array[0..3] of GLenum;
1280 ////////////////////////////////////////////////////////////////////////////////////////////////////
1282 TFormatDescriptor = class(TglBitmapFormatDescriptor)
1284 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); virtual; abstract;
1285 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); virtual; abstract;
1287 function CreateMappingData: Pointer; virtual;
1288 procedure FreeMappingData(var aMappingData: Pointer); virtual;
1290 function IsEmpty: Boolean; virtual;
1291 function MaskMatch(const aMask: TglBitmapRec4ul): Boolean; virtual;
1293 procedure PreparePixel(out aPixel: TglBitmapPixelData); virtual;
1295 constructor Create; virtual;
1297 class procedure Init;
1298 class function Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
1299 class function GetAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
1300 class function GetFromMask(const aMask: TglBitmapRec4ul; const aBitCount: Integer = 0): TFormatDescriptor;
1301 class function GetFromPrecShift(const aPrec, aShift: TglBitmapRec4ub; const aBitCount: Integer): TFormatDescriptor;
1302 class procedure Clear;
1303 class procedure Finalize;
1305 TFormatDescriptorClass = class of TFormatDescriptor;
1307 TfdEmpty = class(TFormatDescriptor);
1309 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1310 TfdAlphaUB1 = class(TFormatDescriptor) //1* unsigned byte
1311 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1312 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1315 TfdLuminanceUB1 = class(TFormatDescriptor) //1* unsigned byte
1316 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1317 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1320 TfdUniversalUB1 = class(TFormatDescriptor) //1* unsigned byte
1321 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1322 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1325 TfdLuminanceAlphaUB2 = class(TfdLuminanceUB1) //2* unsigned byte
1326 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1327 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1330 TfdRGBub3 = class(TFormatDescriptor) //3* unsigned byte
1331 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1332 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1335 TfdBGRub3 = class(TFormatDescriptor) //3* unsigned byte (inverse)
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 TfdRGBAub4 = class(TfdRGBub3) //3* unsigned byte
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 TfdBGRAub4 = class(TfdBGRub3) //3* unsigned byte (inverse)
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 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1351 TfdAlphaUS1 = class(TFormatDescriptor) //1* unsigned short
1352 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1353 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1356 TfdLuminanceUS1 = class(TFormatDescriptor) //1* unsigned short
1357 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1358 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1361 TfdUniversalUS1 = class(TFormatDescriptor) //1* unsigned short
1362 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1363 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1366 TfdDepthUS1 = class(TFormatDescriptor) //1* unsigned short
1367 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1368 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1371 TfdLuminanceAlphaUS2 = class(TfdLuminanceUS1) //2* unsigned short
1372 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1373 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1376 TfdRGBus3 = class(TFormatDescriptor) //3* unsigned short
1377 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1378 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1381 TfdBGRus3 = class(TFormatDescriptor) //3* unsigned short (inverse)
1382 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1383 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1386 TfdRGBAus4 = class(TfdRGBus3) //4* unsigned short
1387 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1388 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1391 TfdARGBus4 = class(TfdRGBus3) //4* unsigned short
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 TfdBGRAus4 = class(TfdBGRus3) //4* unsigned short (inverse)
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 TfdABGRus4 = class(TfdBGRus3) //4* unsigned short (inverse)
1402 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1403 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1406 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1407 TfdUniversalUI1 = class(TFormatDescriptor) //1* unsigned int
1408 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1409 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1412 TfdDepthUI1 = class(TFormatDescriptor) //1* unsigned int
1413 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1414 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1417 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1418 TfdAlpha4ub1 = class(TfdAlphaUB1)
1419 procedure SetValues; override;
1422 TfdAlpha8ub1 = class(TfdAlphaUB1)
1423 procedure SetValues; override;
1426 TfdAlpha16us1 = class(TfdAlphaUS1)
1427 procedure SetValues; override;
1430 TfdLuminance4ub1 = class(TfdLuminanceUB1)
1431 procedure SetValues; override;
1434 TfdLuminance8ub1 = class(TfdLuminanceUB1)
1435 procedure SetValues; override;
1438 TfdLuminance16us1 = class(TfdLuminanceUS1)
1439 procedure SetValues; override;
1442 TfdLuminance4Alpha4ub2 = class(TfdLuminanceAlphaUB2)
1443 procedure SetValues; override;
1446 TfdLuminance6Alpha2ub2 = class(TfdLuminanceAlphaUB2)
1447 procedure SetValues; override;
1450 TfdLuminance8Alpha8ub2 = class(TfdLuminanceAlphaUB2)
1451 procedure SetValues; override;
1454 TfdLuminance12Alpha4us2 = class(TfdLuminanceAlphaUS2)
1455 procedure SetValues; override;
1458 TfdLuminance16Alpha16us2 = class(TfdLuminanceAlphaUS2)
1459 procedure SetValues; override;
1462 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1463 TfdR3G3B2ub1 = class(TfdUniversalUB1)
1464 procedure SetValues; override;
1467 TfdRGBX4us1 = class(TfdUniversalUS1)
1468 procedure SetValues; override;
1471 TfdXRGB4us1 = class(TfdUniversalUS1)
1472 procedure SetValues; override;
1475 TfdR5G6B5us1 = class(TfdUniversalUS1)
1476 procedure SetValues; override;
1479 TfdRGB5X1us1 = class(TfdUniversalUS1)
1480 procedure SetValues; override;
1483 TfdX1RGB5us1 = class(TfdUniversalUS1)
1484 procedure SetValues; override;
1487 TfdRGB8ub3 = class(TfdRGBub3)
1488 procedure SetValues; override;
1491 TfdRGBX8ui1 = class(TfdUniversalUI1)
1492 procedure SetValues; override;
1495 TfdXRGB8ui1 = class(TfdUniversalUI1)
1496 procedure SetValues; override;
1499 TfdRGB10X2ui1 = class(TfdUniversalUI1)
1500 procedure SetValues; override;
1503 TfdX2RGB10ui1 = class(TfdUniversalUI1)
1504 procedure SetValues; override;
1507 TfdRGB16us3 = class(TfdRGBus3)
1508 procedure SetValues; override;
1511 TfdRGBA4us1 = class(TfdUniversalUS1)
1512 procedure SetValues; override;
1515 TfdARGB4us1 = class(TfdUniversalUS1)
1516 procedure SetValues; override;
1519 TfdRGB5A1us1 = class(TfdUniversalUS1)
1520 procedure SetValues; override;
1523 TfdA1RGB5us1 = class(TfdUniversalUS1)
1524 procedure SetValues; override;
1527 TfdRGBA8ui1 = class(TfdUniversalUI1)
1528 procedure SetValues; override;
1531 TfdARGB8ui1 = class(TfdUniversalUI1)
1532 procedure SetValues; override;
1535 TfdRGBA8ub4 = class(TfdRGBAub4)
1536 procedure SetValues; override;
1539 TfdRGB10A2ui1 = class(TfdUniversalUI1)
1540 procedure SetValues; override;
1543 TfdA2RGB10ui1 = class(TfdUniversalUI1)
1544 procedure SetValues; override;
1547 TfdRGBA16us4 = class(TfdRGBAus4)
1548 procedure SetValues; override;
1551 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1552 TfdBGRX4us1 = class(TfdUniversalUS1)
1553 procedure SetValues; override;
1556 TfdXBGR4us1 = class(TfdUniversalUS1)
1557 procedure SetValues; override;
1560 TfdB5G6R5us1 = class(TfdUniversalUS1)
1561 procedure SetValues; override;
1564 TfdBGR5X1us1 = class(TfdUniversalUS1)
1565 procedure SetValues; override;
1568 TfdX1BGR5us1 = class(TfdUniversalUS1)
1569 procedure SetValues; override;
1572 TfdBGR8ub3 = class(TfdBGRub3)
1573 procedure SetValues; override;
1576 TfdBGRX8ui1 = class(TfdUniversalUI1)
1577 procedure SetValues; override;
1580 TfdXBGR8ui1 = class(TfdUniversalUI1)
1581 procedure SetValues; override;
1584 TfdBGR10X2ui1 = class(TfdUniversalUI1)
1585 procedure SetValues; override;
1588 TfdX2BGR10ui1 = class(TfdUniversalUI1)
1589 procedure SetValues; override;
1592 TfdBGR16us3 = class(TfdBGRus3)
1593 procedure SetValues; override;
1596 TfdBGRA4us1 = class(TfdUniversalUS1)
1597 procedure SetValues; override;
1600 TfdABGR4us1 = class(TfdUniversalUS1)
1601 procedure SetValues; override;
1604 TfdBGR5A1us1 = class(TfdUniversalUS1)
1605 procedure SetValues; override;
1608 TfdA1BGR5us1 = class(TfdUniversalUS1)
1609 procedure SetValues; override;
1612 TfdBGRA8ui1 = class(TfdUniversalUI1)
1613 procedure SetValues; override;
1616 TfdABGR8ui1 = class(TfdUniversalUI1)
1617 procedure SetValues; override;
1620 TfdBGRA8ub4 = class(TfdBGRAub4)
1621 procedure SetValues; override;
1624 TfdBGR10A2ui1 = class(TfdUniversalUI1)
1625 procedure SetValues; override;
1628 TfdA2BGR10ui1 = class(TfdUniversalUI1)
1629 procedure SetValues; override;
1632 TfdBGRA16us4 = class(TfdBGRAus4)
1633 procedure SetValues; override;
1636 TfdDepth16us1 = class(TfdDepthUS1)
1637 procedure SetValues; override;
1640 TfdDepth24ui1 = class(TfdDepthUI1)
1641 procedure SetValues; override;
1644 TfdDepth32ui1 = class(TfdDepthUI1)
1645 procedure SetValues; override;
1648 TfdS3tcDtx1RGBA = class(TFormatDescriptor)
1649 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1650 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1651 procedure SetValues; override;
1654 TfdS3tcDtx3RGBA = class(TFormatDescriptor)
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;
1657 procedure SetValues; override;
1660 TfdS3tcDtx5RGBA = class(TFormatDescriptor)
1661 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1662 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1663 procedure SetValues; override;
1666 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1667 TbmpBitfieldFormat = class(TFormatDescriptor)
1669 procedure SetCustomValues(const aBPP: Integer; aMask: TglBitmapRec4ul); overload;
1670 procedure SetCustomValues(const aBBP: Integer; const aPrec, aShift: TglBitmapRec4ub); overload;
1671 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1672 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1675 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1676 TbmpColorTableEnty = packed record
1679 TbmpColorTable = array of TbmpColorTableEnty;
1680 TbmpColorTableFormat = class(TFormatDescriptor)
1682 fColorTable: TbmpColorTable;
1684 procedure SetValues; override;
1686 property ColorTable: TbmpColorTable read fColorTable write fColorTable;
1688 procedure SetCustomValues(const aFormat: TglBitmapFormat; const aBPP: Integer; const aPrec, aShift: TglBitmapRec4ub); overload;
1689 procedure CalcValues;
1690 procedure CreateColorTable;
1692 function CreateMappingData: Pointer; override;
1693 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1694 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1695 destructor Destroy; override;
1699 LUMINANCE_WEIGHT_R = 0.30;
1700 LUMINANCE_WEIGHT_G = 0.59;
1701 LUMINANCE_WEIGHT_B = 0.11;
1703 ALPHA_WEIGHT_R = 0.30;
1704 ALPHA_WEIGHT_G = 0.59;
1705 ALPHA_WEIGHT_B = 0.11;
1707 DEPTH_WEIGHT_R = 0.333333333;
1708 DEPTH_WEIGHT_G = 0.333333333;
1709 DEPTH_WEIGHT_B = 0.333333333;
1711 FORMAT_DESCRIPTOR_CLASSES: array[TglBitmapFormat] of TFormatDescriptorClass = (
1722 TfdLuminance4Alpha4ub2,
1723 TfdLuminance6Alpha2ub2,
1724 TfdLuminance8Alpha8ub2,
1725 TfdLuminance12Alpha4us2,
1726 TfdLuminance16Alpha16us2,
1785 FormatDescriptorCS: TCriticalSection;
1786 FormatDescriptors: array[TglBitmapFormat] of TFormatDescriptor;
1788 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1789 constructor EglBitmapUnsupportedFormat.Create(const aFormat: TglBitmapFormat);
1791 inherited Create('unsupported format: ' + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
1794 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1795 constructor EglBitmapUnsupportedFormat.Create(const aMsg: String; const aFormat: TglBitmapFormat);
1797 inherited Create(aMsg + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
1800 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1801 function glBitmapSize(X: Integer; Y: Integer): TglBitmapSize;
1803 result.Fields := [];
1805 result.Fields := result.Fields + [ffX];
1807 result.Fields := result.Fields + [ffY];
1808 result.X := Max(0, X);
1809 result.Y := Max(0, Y);
1812 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1813 function glBitmapPosition(X: Integer; Y: Integer): TglBitmapPixelPosition;
1815 result := glBitmapSize(X, Y);
1818 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1819 function glBitmapRec4ub(const r, g, b, a: Byte): TglBitmapRec4ub;
1827 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1828 function glBitmapRec4ui(const r, g, b, a: Cardinal): TglBitmapRec4ui;
1836 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1837 function glBitmapRec4ul(const r, g, b, a: QWord): TglBitmapRec4ul;
1845 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1846 function glBitmapRec4ubCompare(const r1, r2: TglBitmapRec4ub): Boolean;
1851 for i := 0 to high(r1.arr) do
1852 if (r1.arr[i] <> r2.arr[i]) then
1857 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1858 function glBitmapRec4uiCompare(const r1, r2: TglBitmapRec4ui): Boolean;
1863 for i := 0 to high(r1.arr) do
1864 if (r1.arr[i] <> r2.arr[i]) then
1869 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1870 function glBitmapCreateTestData(const aFormat: TglBitmapFormat): TglBitmapData;
1872 desc: TFormatDescriptor;
1876 px: TglBitmapPixelData;
1879 desc := TFormatDescriptor.Get(aFormat);
1880 if (desc.IsCompressed) or (desc.glFormat = 0) then
1883 p := GetMemory(ceil(25 * desc.BytesPerPixel)); // 5 x 5 pixel
1884 md := desc.CreateMappingData;
1887 desc.PreparePixel(px);
1889 for x := 0 to 4 do begin
1890 px.Data := glBitmapRec4ui(0, 0, 0, 0);
1891 for i := 0 to 3 do begin
1892 if ((y < 3) and (y = i)) or
1893 ((y = 3) and (i < 3)) or
1894 ((y = 4) and (i = 3))
1896 px.Data.arr[i] := Trunc(px.Range.arr[i] / 4 * x)
1897 else if ((y < 4) and (i = 3)) or
1898 ((y = 4) and (i < 3))
1900 px.Data.arr[i] := px.Range.arr[i]
1902 px.Data.arr[i] := 0; //px.Range.arr[i];
1904 desc.Map(px, tmp, md);
1907 desc.FreeMappingData(md);
1910 result := TglBitmapData.Create(glBitmapPosition(5, 5), aFormat, p);
1913 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1914 function glBitmapShiftRec(const r, g, b, a: Byte): TglBitmapRec4ub;
1922 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1923 function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes;
1929 tfAlpha4ub1, tfAlpha8ub1,
1930 tfLuminance4ub1, tfLuminance8ub1, tfR3G3B2ub1,
1933 tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
1934 tfRGBX4us1, tfXRGB4us1, tfRGB5X1us1, tfX1RGB5us1, tfR5G6B5us1, tfRGB5A1us1, tfA1RGB5us1, tfRGBA4us1, tfARGB4us1,
1935 tfBGRX4us1, tfXBGR4us1, tfBGR5X1us1, tfX1BGR5us1, tfB5G6R5us1, tfBGR5A1us1, tfA1BGR5us1, tfBGRA4us1, tfABGR4us1,
1938 tfBGR8ub3, tfRGB8ub3,
1941 tfRGBX8ui1, tfXRGB8ui1, tfRGB10X2ui1, tfX2RGB10ui1, tfRGBA8ui1, tfARGB8ui1, tfRGBA8ub4, tfRGB10A2ui1, tfA2RGB10ui1,
1942 tfBGRX8ui1, tfXBGR8ui1, tfBGR10X2ui1, tfX2BGR10ui1, tfBGRA8ui1, tfABGR8ui1, tfBGRA8ub4, tfBGR10A2ui1, tfA2BGR10ui1])
1944 result := result + [ ftBMP ];
1948 tfAlpha4ub1, tfAlpha8ub1, tfLuminance4ub1, tfLuminance8ub1,
1951 tfAlpha16us1, tfLuminance16us1,
1952 tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
1953 tfX1RGB5us1, tfARGB4us1, tfA1RGB5us1, tfDepth16us1,
1959 tfX2RGB10ui1, tfARGB8ui1, tfBGRA8ub4, tfA2RGB10ui1,
1960 tfDepth24ui1, tfDepth32ui1])
1962 result := result + [ftTGA];
1964 if not (aFormat in [tfEmpty, tfRGB16us3, tfBGR16us3]) then
1965 result := result + [ftDDS];
1967 {$IFDEF GLB_SUPPORT_PNG_WRITE}
1969 tfAlpha8ub1, tfLuminance8ub1, tfLuminance8Alpha8ub2,
1970 tfRGB8ub3, tfRGBA8ui1,
1971 tfBGR8ub3, tfBGRA8ui1] then
1972 result := result + [ftPNG];
1975 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
1976 if aFormat in [tfAlpha8ub1, tfLuminance8ub1, tfRGB8ub3, tfBGR8ub3] then
1977 result := result + [ftJPEG];
1981 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1982 function IsPowerOfTwo(aNumber: Integer): Boolean;
1984 while (aNumber and 1) = 0 do
1985 aNumber := aNumber shr 1;
1986 result := aNumber = 1;
1989 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1990 function GetTopMostBit(aBitSet: QWord): Integer;
1993 while aBitSet > 0 do begin
1995 aBitSet := aBitSet shr 1;
1999 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2000 function CountSetBits(aBitSet: QWord): Integer;
2003 while aBitSet > 0 do begin
2004 if (aBitSet and 1) = 1 then
2006 aBitSet := aBitSet shr 1;
2010 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2011 function LuminanceWeight(const aPixel: TglBitmapPixelData): Cardinal;
2014 LUMINANCE_WEIGHT_R * aPixel.Data.r +
2015 LUMINANCE_WEIGHT_G * aPixel.Data.g +
2016 LUMINANCE_WEIGHT_B * aPixel.Data.b);
2019 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2020 function DepthWeight(const aPixel: TglBitmapPixelData): Cardinal;
2023 DEPTH_WEIGHT_R * aPixel.Data.r +
2024 DEPTH_WEIGHT_G * aPixel.Data.g +
2025 DEPTH_WEIGHT_B * aPixel.Data.b);
2028 {$IFDEF GLB_SDL_IMAGE}
2029 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2030 // SDL Image Helper /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2031 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2032 function glBitmapRWseek(context: PSDL_RWops; offset: Integer; whence: Integer): Integer; cdecl;
2034 result := TStream(context^.unknown.data1).Seek(offset, whence);
2037 function glBitmapRWread(context: PSDL_RWops; Ptr: Pointer; size: Integer; maxnum : Integer): Integer; cdecl;
2039 result := TStream(context^.unknown.data1).Read(Ptr^, size * maxnum);
2042 function glBitmapRWwrite(context: PSDL_RWops; Ptr: Pointer; size: Integer; num: Integer): Integer; cdecl;
2044 result := TStream(context^.unknown.data1).Write(Ptr^, size * num);
2047 function glBitmapRWclose(context: PSDL_RWops): Integer; cdecl;
2052 function glBitmapCreateRWops(Stream: TStream): PSDL_RWops;
2054 result := SDL_AllocRW;
2056 if result = nil then
2057 raise EglBitmap.Create('glBitmapCreateRWops - SDL_AllocRW failed.');
2059 result^.seek := glBitmapRWseek;
2060 result^.read := glBitmapRWread;
2061 result^.write := glBitmapRWwrite;
2062 result^.close := glBitmapRWclose;
2063 result^.unknown.data1 := Stream;
2067 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2068 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
2070 glBitmapDefaultDeleteTextureOnFree := aDeleteTextureOnFree;
2073 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2074 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
2076 glBitmapDefaultFreeDataAfterGenTextures := aFreeData;
2079 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2080 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
2082 glBitmapDefaultMipmap := aValue;
2085 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2086 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
2088 glBitmapDefaultFormat := aFormat;
2091 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2092 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
2094 glBitmapDefaultFilterMin := aMin;
2095 glBitmapDefaultFilterMag := aMag;
2098 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2099 procedure glBitmapSetDefaultWrap(const S: Cardinal = GL_CLAMP_TO_EDGE; const T: Cardinal = GL_CLAMP_TO_EDGE; const R: Cardinal = GL_CLAMP_TO_EDGE);
2101 glBitmapDefaultWrapS := S;
2102 glBitmapDefaultWrapT := T;
2103 glBitmapDefaultWrapR := R;
2106 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2107 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
2108 procedure glBitmapSetDefaultSwizzle(const r: GLenum = GL_RED; g: GLenum = GL_GREEN; b: GLenum = GL_BLUE; a: GLenum = GL_ALPHA);
2110 glDefaultSwizzle[0] := r;
2111 glDefaultSwizzle[1] := g;
2112 glDefaultSwizzle[2] := b;
2113 glDefaultSwizzle[3] := a;
2117 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2118 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
2120 result := glBitmapDefaultDeleteTextureOnFree;
2123 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2124 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
2126 result := glBitmapDefaultFreeDataAfterGenTextures;
2129 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2130 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
2132 result := glBitmapDefaultMipmap;
2135 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2136 function glBitmapGetDefaultFormat: TglBitmapFormat;
2138 result := glBitmapDefaultFormat;
2141 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2142 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
2144 aMin := glBitmapDefaultFilterMin;
2145 aMag := glBitmapDefaultFilterMag;
2148 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2149 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
2151 S := glBitmapDefaultWrapS;
2152 T := glBitmapDefaultWrapT;
2153 R := glBitmapDefaultWrapR;
2156 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
2157 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2158 procedure glBitmapGetDefaultSwizzle(var r, g, b, a: GLenum);
2160 r := glDefaultSwizzle[0];
2161 g := glDefaultSwizzle[1];
2162 b := glDefaultSwizzle[2];
2163 a := glDefaultSwizzle[3];
2167 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2168 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2169 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2170 function TFormatDescriptor.CreateMappingData: Pointer;
2175 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2176 procedure TFormatDescriptor.FreeMappingData(var aMappingData: Pointer);
2181 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2182 function TFormatDescriptor.IsEmpty: Boolean;
2184 result := (fFormat = tfEmpty);
2187 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2188 function TFormatDescriptor.MaskMatch(const aMask: TglBitmapRec4ul): Boolean;
2194 if (aMask.r = 0) and (aMask.g = 0) and (aMask.b = 0) and (aMask.a = 0) then
2195 raise EglBitmap.Create('FormatCheckFormat - All Masks are 0');
2198 if (aMask.arr[i] <> m.arr[i]) then
2203 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2204 procedure TFormatDescriptor.PreparePixel(out aPixel: TglBitmapPixelData);
2206 FillChar(aPixel{%H-}, SizeOf(aPixel), 0);
2207 aPixel.Data := Range;
2208 aPixel.Format := fFormat;
2209 aPixel.Range := Range;
2212 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2213 constructor TFormatDescriptor.Create;
2218 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2219 //TfdAlpha_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2220 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2221 procedure TfdAlphaUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2223 aData^ := aPixel.Data.a;
2227 procedure TfdAlphaUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2232 aPixel.Data.a := aData^;
2236 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2237 //TfdLuminance_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2238 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2239 procedure TfdLuminanceUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2241 aData^ := LuminanceWeight(aPixel);
2245 procedure TfdLuminanceUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2247 aPixel.Data.r := aData^;
2248 aPixel.Data.g := aData^;
2249 aPixel.Data.b := aData^;
2254 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2255 //TfdUniversal_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2256 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2257 procedure TfdUniversalUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2263 if (Range.arr[i] > 0) then
2264 aData^ := aData^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
2268 procedure TfdUniversalUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2273 aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and Range.arr[i];
2277 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2278 //TfdLuminanceAlpha_UB2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2279 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2280 procedure TfdLuminanceAlphaUB2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2282 inherited Map(aPixel, aData, aMapData);
2283 aData^ := aPixel.Data.a;
2287 procedure TfdLuminanceAlphaUB2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2289 inherited Unmap(aData, aPixel, aMapData);
2290 aPixel.Data.a := aData^;
2294 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2295 //TfdRGB_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2296 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2297 procedure TfdRGBub3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2299 aData^ := aPixel.Data.r;
2301 aData^ := aPixel.Data.g;
2303 aData^ := aPixel.Data.b;
2307 procedure TfdRGBub3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2309 aPixel.Data.r := aData^;
2311 aPixel.Data.g := aData^;
2313 aPixel.Data.b := aData^;
2318 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2319 //TfdBGR_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2320 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2321 procedure TfdBGRub3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2323 aData^ := aPixel.Data.b;
2325 aData^ := aPixel.Data.g;
2327 aData^ := aPixel.Data.r;
2331 procedure TfdBGRub3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2333 aPixel.Data.b := aData^;
2335 aPixel.Data.g := aData^;
2337 aPixel.Data.r := aData^;
2342 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2343 //TfdRGBA_UB4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2344 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2345 procedure TfdRGBAub4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2347 inherited Map(aPixel, aData, aMapData);
2348 aData^ := aPixel.Data.a;
2352 procedure TfdRGBAub4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2354 inherited Unmap(aData, aPixel, aMapData);
2355 aPixel.Data.a := aData^;
2359 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2360 //TfdBGRA_UB4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2361 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2362 procedure TfdBGRAub4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2364 inherited Map(aPixel, aData, aMapData);
2365 aData^ := aPixel.Data.a;
2369 procedure TfdBGRAub4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2371 inherited Unmap(aData, aPixel, aMapData);
2372 aPixel.Data.a := aData^;
2376 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2377 //TfdAlpha_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2378 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2379 procedure TfdAlphaUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2381 PWord(aData)^ := aPixel.Data.a;
2385 procedure TfdAlphaUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2390 aPixel.Data.a := PWord(aData)^;
2394 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2395 //TfdLuminance_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2396 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2397 procedure TfdLuminanceUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2399 PWord(aData)^ := LuminanceWeight(aPixel);
2403 procedure TfdLuminanceUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2405 aPixel.Data.r := PWord(aData)^;
2406 aPixel.Data.g := PWord(aData)^;
2407 aPixel.Data.b := PWord(aData)^;
2412 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2413 //TfdUniversal_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2414 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2415 procedure TfdUniversalUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2421 if (Range.arr[i] > 0) then
2422 PWord(aData)^ := PWord(aData)^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
2426 procedure TfdUniversalUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2431 aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and Range.arr[i];
2435 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2436 //TfdDepth_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2437 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2438 procedure TfdDepthUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2440 PWord(aData)^ := DepthWeight(aPixel);
2444 procedure TfdDepthUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2446 aPixel.Data.r := PWord(aData)^;
2447 aPixel.Data.g := PWord(aData)^;
2448 aPixel.Data.b := PWord(aData)^;
2449 aPixel.Data.a := PWord(aData)^;;
2453 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2454 //TfdLuminanceAlpha_US2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2455 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2456 procedure TfdLuminanceAlphaUS2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2458 inherited Map(aPixel, aData, aMapData);
2459 PWord(aData)^ := aPixel.Data.a;
2463 procedure TfdLuminanceAlphaUS2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2465 inherited Unmap(aData, aPixel, aMapData);
2466 aPixel.Data.a := PWord(aData)^;
2470 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2471 //TfdRGB_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2472 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2473 procedure TfdRGBus3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2475 PWord(aData)^ := aPixel.Data.r;
2477 PWord(aData)^ := aPixel.Data.g;
2479 PWord(aData)^ := aPixel.Data.b;
2483 procedure TfdRGBus3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2485 aPixel.Data.r := PWord(aData)^;
2487 aPixel.Data.g := PWord(aData)^;
2489 aPixel.Data.b := PWord(aData)^;
2494 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2495 //TfdBGR_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2496 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2497 procedure TfdBGRus3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2499 PWord(aData)^ := aPixel.Data.b;
2501 PWord(aData)^ := aPixel.Data.g;
2503 PWord(aData)^ := aPixel.Data.r;
2507 procedure TfdBGRus3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2509 aPixel.Data.b := PWord(aData)^;
2511 aPixel.Data.g := PWord(aData)^;
2513 aPixel.Data.r := PWord(aData)^;
2518 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2519 //TfdRGBA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2520 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2521 procedure TfdRGBAus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2523 inherited Map(aPixel, aData, aMapData);
2524 PWord(aData)^ := aPixel.Data.a;
2528 procedure TfdRGBAus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2530 inherited Unmap(aData, aPixel, aMapData);
2531 aPixel.Data.a := PWord(aData)^;
2535 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2536 //TfdARGB_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2537 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2538 procedure TfdARGBus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2540 PWord(aData)^ := aPixel.Data.a;
2542 inherited Map(aPixel, aData, aMapData);
2545 procedure TfdARGBus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2547 aPixel.Data.a := PWord(aData)^;
2549 inherited Unmap(aData, aPixel, aMapData);
2552 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2553 //TfdBGRA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2554 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2555 procedure TfdBGRAus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2557 inherited Map(aPixel, aData, aMapData);
2558 PWord(aData)^ := aPixel.Data.a;
2562 procedure TfdBGRAus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2564 inherited Unmap(aData, aPixel, aMapData);
2565 aPixel.Data.a := PWord(aData)^;
2569 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2570 //TfdABGR_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2571 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2572 procedure TfdABGRus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2574 PWord(aData)^ := aPixel.Data.a;
2576 inherited Map(aPixel, aData, aMapData);
2579 procedure TfdABGRus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2581 aPixel.Data.a := PWord(aData)^;
2583 inherited Unmap(aData, aPixel, aMapData);
2586 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2587 //TfdUniversal_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2588 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2589 procedure TfdUniversalUI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2593 PCardinal(aData)^ := 0;
2595 if (Range.arr[i] > 0) then
2596 PCardinal(aData)^ := PCardinal(aData)^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
2600 procedure TfdUniversalUI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2605 aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and Range.arr[i];
2609 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2610 //TfdDepth_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2611 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2612 procedure TfdDepthUI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2614 PCardinal(aData)^ := DepthWeight(aPixel);
2618 procedure TfdDepthUI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2620 aPixel.Data.r := PCardinal(aData)^;
2621 aPixel.Data.g := PCardinal(aData)^;
2622 aPixel.Data.b := PCardinal(aData)^;
2623 aPixel.Data.a := PCardinal(aData)^;
2627 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2628 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2629 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2630 procedure TfdAlpha4ub1.SetValues;
2632 inherited SetValues;
2634 fFormat := tfAlpha4ub1;
2635 fWithAlpha := tfAlpha4ub1;
2636 fPrecision := glBitmapRec4ub(0, 0, 0, 8);
2637 fShift := glBitmapRec4ub(0, 0, 0, 0);
2639 fOpenGLFormat := tfAlpha4ub1;
2640 fglFormat := GL_ALPHA;
2641 fglInternalFormat := GL_ALPHA4;
2642 fglDataFormat := GL_UNSIGNED_BYTE;
2644 fOpenGLFormat := tfAlpha8ub1;
2648 procedure TfdAlpha8ub1.SetValues;
2650 inherited SetValues;
2652 fFormat := tfAlpha8ub1;
2653 fWithAlpha := tfAlpha8ub1;
2654 fPrecision := glBitmapRec4ub(0, 0, 0, 8);
2655 fShift := glBitmapRec4ub(0, 0, 0, 0);
2656 fOpenGLFormat := tfAlpha8ub1;
2657 fglFormat := GL_ALPHA;
2658 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_ALPHA8{$ELSE}GL_ALPHA{$ENDIF};
2659 fglDataFormat := GL_UNSIGNED_BYTE;
2662 procedure TfdAlpha16us1.SetValues;
2664 inherited SetValues;
2665 fBitsPerPixel := 16;
2666 fFormat := tfAlpha16us1;
2667 fWithAlpha := tfAlpha16us1;
2668 fPrecision := glBitmapRec4ub(0, 0, 0, 16);
2669 fShift := glBitmapRec4ub(0, 0, 0, 0);
2671 fOpenGLFormat := tfAlpha16us1;
2672 fglFormat := GL_ALPHA;
2673 fglInternalFormat := GL_ALPHA16;
2674 fglDataFormat := GL_UNSIGNED_SHORT;
2676 fOpenGLFormat := tfAlpha8ub1;
2680 procedure TfdLuminance4ub1.SetValues;
2682 inherited SetValues;
2684 fFormat := tfLuminance4ub1;
2685 fWithAlpha := tfLuminance4Alpha4ub2;
2686 fWithoutAlpha := tfLuminance4ub1;
2687 fPrecision := glBitmapRec4ub(8, 8, 8, 0);
2688 fShift := glBitmapRec4ub(0, 0, 0, 0);
2690 fOpenGLFormat := tfLuminance4ub1;
2691 fglFormat := GL_LUMINANCE;
2692 fglInternalFormat := GL_LUMINANCE4;
2693 fglDataFormat := GL_UNSIGNED_BYTE;
2695 fOpenGLFormat := tfLuminance8ub1;
2699 procedure TfdLuminance8ub1.SetValues;
2701 inherited SetValues;
2703 fFormat := tfLuminance8ub1;
2704 fWithAlpha := tfLuminance8Alpha8ub2;
2705 fWithoutAlpha := tfLuminance8ub1;
2706 fOpenGLFormat := tfLuminance8ub1;
2707 fPrecision := glBitmapRec4ub(8, 8, 8, 0);
2708 fShift := glBitmapRec4ub(0, 0, 0, 0);
2709 fglFormat := GL_LUMINANCE;
2710 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_LUMINANCE8{$ELSE}GL_LUMINANCE{$ENDIF};
2711 fglDataFormat := GL_UNSIGNED_BYTE;
2714 procedure TfdLuminance16us1.SetValues;
2716 inherited SetValues;
2717 fBitsPerPixel := 16;
2718 fFormat := tfLuminance16us1;
2719 fWithAlpha := tfLuminance16Alpha16us2;
2720 fWithoutAlpha := tfLuminance16us1;
2721 fPrecision := glBitmapRec4ub(16, 16, 16, 0);
2722 fShift := glBitmapRec4ub( 0, 0, 0, 0);
2724 fOpenGLFormat := tfLuminance16us1;
2725 fglFormat := GL_LUMINANCE;
2726 fglInternalFormat := GL_LUMINANCE16;
2727 fglDataFormat := GL_UNSIGNED_SHORT;
2729 fOpenGLFormat := tfLuminance8ub1;
2733 procedure TfdLuminance4Alpha4ub2.SetValues;
2735 inherited SetValues;
2736 fBitsPerPixel := 16;
2737 fFormat := tfLuminance4Alpha4ub2;
2738 fWithAlpha := tfLuminance4Alpha4ub2;
2739 fWithoutAlpha := tfLuminance4ub1;
2740 fPrecision := glBitmapRec4ub(8, 8, 8, 8);
2741 fShift := glBitmapRec4ub(0, 0, 0, 8);
2743 fOpenGLFormat := tfLuminance4Alpha4ub2;
2744 fglFormat := GL_LUMINANCE_ALPHA;
2745 fglInternalFormat := GL_LUMINANCE4_ALPHA4;
2746 fglDataFormat := GL_UNSIGNED_BYTE;
2748 fOpenGLFormat := tfLuminance8Alpha8ub2;
2752 procedure TfdLuminance6Alpha2ub2.SetValues;
2754 inherited SetValues;
2755 fBitsPerPixel := 16;
2756 fFormat := tfLuminance6Alpha2ub2;
2757 fWithAlpha := tfLuminance6Alpha2ub2;
2758 fWithoutAlpha := tfLuminance8ub1;
2759 fPrecision := glBitmapRec4ub(8, 8, 8, 8);
2760 fShift := glBitmapRec4ub(0, 0, 0, 8);
2762 fOpenGLFormat := tfLuminance6Alpha2ub2;
2763 fglFormat := GL_LUMINANCE_ALPHA;
2764 fglInternalFormat := GL_LUMINANCE6_ALPHA2;
2765 fglDataFormat := GL_UNSIGNED_BYTE;
2767 fOpenGLFormat := tfLuminance8Alpha8ub2;
2771 procedure TfdLuminance8Alpha8ub2.SetValues;
2773 inherited SetValues;
2774 fBitsPerPixel := 16;
2775 fFormat := tfLuminance8Alpha8ub2;
2776 fWithAlpha := tfLuminance8Alpha8ub2;
2777 fWithoutAlpha := tfLuminance8ub1;
2778 fOpenGLFormat := tfLuminance8Alpha8ub2;
2779 fPrecision := glBitmapRec4ub(8, 8, 8, 8);
2780 fShift := glBitmapRec4ub(0, 0, 0, 8);
2781 fglFormat := GL_LUMINANCE_ALPHA;
2782 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_LUMINANCE8_ALPHA8{$ELSE}GL_LUMINANCE_ALPHA{$ENDIF};
2783 fglDataFormat := GL_UNSIGNED_BYTE;
2786 procedure TfdLuminance12Alpha4us2.SetValues;
2788 inherited SetValues;
2789 fBitsPerPixel := 32;
2790 fFormat := tfLuminance12Alpha4us2;
2791 fWithAlpha := tfLuminance12Alpha4us2;
2792 fWithoutAlpha := tfLuminance16us1;
2793 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
2794 fShift := glBitmapRec4ub( 0, 0, 0, 16);
2796 fOpenGLFormat := tfLuminance12Alpha4us2;
2797 fglFormat := GL_LUMINANCE_ALPHA;
2798 fglInternalFormat := GL_LUMINANCE12_ALPHA4;
2799 fglDataFormat := GL_UNSIGNED_SHORT;
2801 fOpenGLFormat := tfLuminance8Alpha8ub2;
2805 procedure TfdLuminance16Alpha16us2.SetValues;
2807 inherited SetValues;
2808 fBitsPerPixel := 32;
2809 fFormat := tfLuminance16Alpha16us2;
2810 fWithAlpha := tfLuminance16Alpha16us2;
2811 fWithoutAlpha := tfLuminance16us1;
2812 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
2813 fShift := glBitmapRec4ub( 0, 0, 0, 16);
2815 fOpenGLFormat := tfLuminance16Alpha16us2;
2816 fglFormat := GL_LUMINANCE_ALPHA;
2817 fglInternalFormat := GL_LUMINANCE16_ALPHA16;
2818 fglDataFormat := GL_UNSIGNED_SHORT;
2820 fOpenGLFormat := tfLuminance8Alpha8ub2;
2824 procedure TfdR3G3B2ub1.SetValues;
2826 inherited SetValues;
2828 fFormat := tfR3G3B2ub1;
2829 fWithAlpha := tfRGBA4us1;
2830 fWithoutAlpha := tfR3G3B2ub1;
2831 fRGBInverted := tfEmpty;
2832 fPrecision := glBitmapRec4ub(3, 3, 2, 0);
2833 fShift := glBitmapRec4ub(5, 2, 0, 0);
2835 fOpenGLFormat := tfR3G3B2ub1;
2836 fglFormat := GL_RGB;
2837 fglInternalFormat := GL_R3_G3_B2;
2838 fglDataFormat := GL_UNSIGNED_BYTE_3_3_2;
2840 fOpenGLFormat := tfR5G6B5us1;
2844 procedure TfdRGBX4us1.SetValues;
2846 inherited SetValues;
2847 fBitsPerPixel := 16;
2848 fFormat := tfRGBX4us1;
2849 fWithAlpha := tfRGBA4us1;
2850 fWithoutAlpha := tfRGBX4us1;
2851 fRGBInverted := tfBGRX4us1;
2852 fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
2853 fShift := glBitmapRec4ub(12, 8, 4, 0);
2855 fOpenGLFormat := tfRGBX4us1;
2856 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
2857 fglInternalFormat := GL_RGB4;
2858 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
2860 fOpenGLFormat := tfR5G6B5us1;
2864 procedure TfdXRGB4us1.SetValues;
2866 inherited SetValues;
2867 fBitsPerPixel := 16;
2868 fFormat := tfXRGB4us1;
2869 fWithAlpha := tfARGB4us1;
2870 fWithoutAlpha := tfXRGB4us1;
2871 fRGBInverted := tfXBGR4us1;
2872 fPrecision := glBitmapRec4ub(4, 4, 4, 0);
2873 fShift := glBitmapRec4ub(8, 4, 0, 0);
2875 fOpenGLFormat := tfXRGB4us1;
2876 fglFormat := GL_BGRA;
2877 fglInternalFormat := GL_RGB4;
2878 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
2880 fOpenGLFormat := tfR5G6B5us1;
2884 procedure TfdR5G6B5us1.SetValues;
2886 inherited SetValues;
2887 fBitsPerPixel := 16;
2888 fFormat := tfR5G6B5us1;
2889 fWithAlpha := tfRGB5A1us1;
2890 fWithoutAlpha := tfR5G6B5us1;
2891 fRGBInverted := tfB5G6R5us1;
2892 fPrecision := glBitmapRec4ub( 5, 6, 5, 0);
2893 fShift := glBitmapRec4ub(11, 5, 0, 0);
2894 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
2895 fOpenGLFormat := tfR5G6B5us1;
2896 fglFormat := GL_RGB;
2897 fglInternalFormat := GL_RGB565;
2898 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5;
2900 fOpenGLFormat := tfRGB8ub3;
2904 procedure TfdRGB5X1us1.SetValues;
2906 inherited SetValues;
2907 fBitsPerPixel := 16;
2908 fFormat := tfRGB5X1us1;
2909 fWithAlpha := tfRGB5A1us1;
2910 fWithoutAlpha := tfRGB5X1us1;
2911 fRGBInverted := tfBGR5X1us1;
2912 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
2913 fShift := glBitmapRec4ub(11, 6, 1, 0);
2915 fOpenGLFormat := tfRGB5X1us1;
2916 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
2917 fglInternalFormat := GL_RGB5;
2918 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
2920 fOpenGLFormat := tfR5G6B5us1;
2924 procedure TfdX1RGB5us1.SetValues;
2926 inherited SetValues;
2927 fBitsPerPixel := 16;
2928 fFormat := tfX1RGB5us1;
2929 fWithAlpha := tfA1RGB5us1;
2930 fWithoutAlpha := tfX1RGB5us1;
2931 fRGBInverted := tfX1BGR5us1;
2932 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
2933 fShift := glBitmapRec4ub(10, 5, 0, 0);
2935 fOpenGLFormat := tfX1RGB5us1;
2936 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
2937 fglInternalFormat := GL_RGB5;
2938 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
2940 fOpenGLFormat := tfR5G6B5us1;
2944 procedure TfdRGB8ub3.SetValues;
2946 inherited SetValues;
2947 fBitsPerPixel := 24;
2948 fFormat := tfRGB8ub3;
2949 fWithAlpha := tfRGBA8ub4;
2950 fWithoutAlpha := tfRGB8ub3;
2951 fRGBInverted := tfBGR8ub3;
2952 fPrecision := glBitmapRec4ub(8, 8, 8, 0);
2953 fShift := glBitmapRec4ub(0, 8, 16, 0);
2954 fOpenGLFormat := tfRGB8ub3;
2955 fglFormat := GL_RGB;
2956 fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}GL_RGB8{$ELSE}GL_RGB{$IFEND};
2957 fglDataFormat := GL_UNSIGNED_BYTE;
2960 procedure TfdRGBX8ui1.SetValues;
2962 inherited SetValues;
2963 fBitsPerPixel := 32;
2964 fFormat := tfRGBX8ui1;
2965 fWithAlpha := tfRGBA8ui1;
2966 fWithoutAlpha := tfRGBX8ui1;
2967 fRGBInverted := tfBGRX8ui1;
2968 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
2969 fShift := glBitmapRec4ub(24, 16, 8, 0);
2971 fOpenGLFormat := tfRGBX8ui1;
2972 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
2973 fglInternalFormat := GL_RGB8;
2974 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
2976 fOpenGLFormat := tfRGB8ub3;
2980 procedure TfdXRGB8ui1.SetValues;
2982 inherited SetValues;
2983 fBitsPerPixel := 32;
2984 fFormat := tfXRGB8ui1;
2985 fWithAlpha := tfXRGB8ui1;
2986 fWithoutAlpha := tfXRGB8ui1;
2987 fOpenGLFormat := tfXRGB8ui1;
2988 fRGBInverted := tfXBGR8ui1;
2989 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
2990 fShift := glBitmapRec4ub(16, 8, 0, 0);
2992 fOpenGLFormat := tfXRGB8ui1;
2993 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
2994 fglInternalFormat := GL_RGB8;
2995 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
2997 fOpenGLFormat := tfRGB8ub3;
3001 procedure TfdRGB10X2ui1.SetValues;
3003 inherited SetValues;
3004 fBitsPerPixel := 32;
3005 fFormat := tfRGB10X2ui1;
3006 fWithAlpha := tfRGB10A2ui1;
3007 fWithoutAlpha := tfRGB10X2ui1;
3008 fRGBInverted := tfBGR10X2ui1;
3009 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3010 fShift := glBitmapRec4ub(22, 12, 2, 0);
3012 fOpenGLFormat := tfRGB10X2ui1;
3013 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3014 fglInternalFormat := GL_RGB10;
3015 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3017 fOpenGLFormat := tfRGB16us3;
3021 procedure TfdX2RGB10ui1.SetValues;
3023 inherited SetValues;
3024 fBitsPerPixel := 32;
3025 fFormat := tfX2RGB10ui1;
3026 fWithAlpha := tfA2RGB10ui1;
3027 fWithoutAlpha := tfX2RGB10ui1;
3028 fRGBInverted := tfX2BGR10ui1;
3029 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3030 fShift := glBitmapRec4ub(20, 10, 0, 0);
3032 fOpenGLFormat := tfX2RGB10ui1;
3033 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3034 fglInternalFormat := GL_RGB10;
3035 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3037 fOpenGLFormat := tfRGB16us3;
3041 procedure TfdRGB16us3.SetValues;
3043 inherited SetValues;
3044 fBitsPerPixel := 48;
3045 fFormat := tfRGB16us3;
3046 fWithAlpha := tfRGBA16us4;
3047 fWithoutAlpha := tfRGB16us3;
3048 fRGBInverted := tfBGR16us3;
3049 fPrecision := glBitmapRec4ub(16, 16, 16, 0);
3050 fShift := glBitmapRec4ub( 0, 16, 32, 0);
3051 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
3052 fOpenGLFormat := tfRGB16us3;
3053 fglFormat := GL_RGB;
3054 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_RGB16{$ELSE}GL_RGB16UI{$ENDIF};
3055 fglDataFormat := GL_UNSIGNED_SHORT;
3057 fOpenGLFormat := tfRGB8ub3;
3061 procedure TfdRGBA4us1.SetValues;
3063 inherited SetValues;
3064 fBitsPerPixel := 16;
3065 fFormat := tfRGBA4us1;
3066 fWithAlpha := tfRGBA4us1;
3067 fWithoutAlpha := tfRGBX4us1;
3068 fOpenGLFormat := tfRGBA4us1;
3069 fRGBInverted := tfBGRA4us1;
3070 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3071 fShift := glBitmapRec4ub(12, 8, 4, 0);
3072 fglFormat := GL_RGBA;
3073 fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}GL_RGBA8{$ELSE}GL_RGBA{$IFEND};
3074 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3077 procedure TfdARGB4us1.SetValues;
3079 inherited SetValues;
3080 fBitsPerPixel := 16;
3081 fFormat := tfARGB4us1;
3082 fWithAlpha := tfARGB4us1;
3083 fWithoutAlpha := tfXRGB4us1;
3084 fRGBInverted := tfABGR4us1;
3085 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3086 fShift := glBitmapRec4ub( 8, 4, 0, 12);
3088 fOpenGLFormat := tfARGB4us1;
3089 fglFormat := GL_BGRA;
3090 fglInternalFormat := GL_RGBA4;
3091 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3093 fOpenGLFormat := tfRGBA4us1;
3097 procedure TfdRGB5A1us1.SetValues;
3099 inherited SetValues;
3100 fBitsPerPixel := 16;
3101 fFormat := tfRGB5A1us1;
3102 fWithAlpha := tfRGB5A1us1;
3103 fWithoutAlpha := tfRGB5X1us1;
3104 fOpenGLFormat := tfRGB5A1us1;
3105 fRGBInverted := tfBGR5A1us1;
3106 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3107 fShift := glBitmapRec4ub(11, 6, 1, 0);
3108 fglFormat := GL_RGBA;
3109 fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}GL_RGB5_A1{$ELSE}GL_RGBA{$IFEND};
3110 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3113 procedure TfdA1RGB5us1.SetValues;
3115 inherited SetValues;
3116 fBitsPerPixel := 16;
3117 fFormat := tfA1RGB5us1;
3118 fWithAlpha := tfA1RGB5us1;
3119 fWithoutAlpha := tfX1RGB5us1;
3120 fRGBInverted := tfA1BGR5us1;
3121 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3122 fShift := glBitmapRec4ub(10, 5, 0, 15);
3124 fOpenGLFormat := tfA1RGB5us1;
3125 fglFormat := GL_BGRA;
3126 fglInternalFormat := GL_RGB5_A1;
3127 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3129 fOpenGLFormat := tfRGB5A1us1;
3133 procedure TfdRGBA8ui1.SetValues;
3135 inherited SetValues;
3136 fBitsPerPixel := 32;
3137 fFormat := tfRGBA8ui1;
3138 fWithAlpha := tfRGBA8ui1;
3139 fWithoutAlpha := tfRGBX8ui1;
3140 fRGBInverted := tfBGRA8ui1;
3141 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3142 fShift := glBitmapRec4ub(24, 16, 8, 0);
3144 fOpenGLFormat := tfRGBA8ui1;
3145 fglFormat := GL_RGBA;
3146 fglInternalFormat := GL_RGBA8;
3147 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3149 fOpenGLFormat := tfRGBA8ub4;
3153 procedure TfdARGB8ui1.SetValues;
3155 inherited SetValues;
3156 fBitsPerPixel := 32;
3157 fFormat := tfARGB8ui1;
3158 fWithAlpha := tfARGB8ui1;
3159 fWithoutAlpha := tfXRGB8ui1;
3160 fRGBInverted := tfABGR8ui1;
3161 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3162 fShift := glBitmapRec4ub(16, 8, 0, 24);
3164 fOpenGLFormat := tfARGB8ui1;
3165 fglFormat := GL_BGRA;
3166 fglInternalFormat := GL_RGBA8;
3167 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3169 fOpenGLFormat := tfRGBA8ub4;
3173 procedure TfdRGBA8ub4.SetValues;
3175 inherited SetValues;
3176 fBitsPerPixel := 32;
3177 fFormat := tfRGBA8ub4;
3178 fWithAlpha := tfRGBA8ub4;
3179 fWithoutAlpha := tfRGB8ub3;
3180 fOpenGLFormat := tfRGBA8ub4;
3181 fRGBInverted := tfBGRA8ub4;
3182 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3183 fShift := glBitmapRec4ub( 0, 8, 16, 24);
3184 fglFormat := GL_RGBA;
3185 fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}GL_RGBA8{$ELSE}GL_RGBA{$IFEND};
3186 fglDataFormat := GL_UNSIGNED_BYTE;
3189 procedure TfdRGB10A2ui1.SetValues;
3191 inherited SetValues;
3192 fBitsPerPixel := 32;
3193 fFormat := tfRGB10A2ui1;
3194 fWithAlpha := tfRGB10A2ui1;
3195 fWithoutAlpha := tfRGB10X2ui1;
3196 fRGBInverted := tfBGR10A2ui1;
3197 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3198 fShift := glBitmapRec4ub(22, 12, 2, 0);
3200 fOpenGLFormat := tfRGB10A2ui1;
3201 fglFormat := GL_RGBA;
3202 fglInternalFormat := GL_RGB10_A2;
3203 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3205 fOpenGLFormat := tfA2RGB10ui1;
3209 procedure TfdA2RGB10ui1.SetValues;
3211 inherited SetValues;
3212 fBitsPerPixel := 32;
3213 fFormat := tfA2RGB10ui1;
3214 fWithAlpha := tfA2RGB10ui1;
3215 fWithoutAlpha := tfX2RGB10ui1;
3216 fRGBInverted := tfA2BGR10ui1;
3217 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3218 fShift := glBitmapRec4ub(20, 10, 0, 30);
3219 {$IF NOT DEFINED(OPENGL_ES)}
3220 fOpenGLFormat := tfA2RGB10ui1;
3221 fglFormat := GL_BGRA;
3222 fglInternalFormat := GL_RGB10_A2;
3223 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3224 {$ELSEIF DEFINED(OPENGL_ES_3_0)}
3225 fOpenGLFormat := tfA2RGB10ui1;
3226 fglFormat := GL_RGBA;
3227 fglInternalFormat := GL_RGB10_A2;
3228 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3230 fOpenGLFormat := tfRGBA8ui1;
3234 procedure TfdRGBA16us4.SetValues;
3236 inherited SetValues;
3237 fBitsPerPixel := 64;
3238 fFormat := tfRGBA16us4;
3239 fWithAlpha := tfRGBA16us4;
3240 fWithoutAlpha := tfRGB16us3;
3241 fRGBInverted := tfBGRA16us4;
3242 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3243 fShift := glBitmapRec4ub( 0, 16, 32, 48);
3244 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
3245 fOpenGLFormat := tfRGBA16us4;
3246 fglFormat := GL_RGBA;
3247 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_RGBA16{$ELSE}GL_RGBA16UI{$ENDIF};
3248 fglDataFormat := GL_UNSIGNED_SHORT;
3250 fOpenGLFormat := tfRGBA8ub4;
3254 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3255 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3256 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3257 procedure TfdBGRX4us1.SetValues;
3259 inherited SetValues;
3260 fBitsPerPixel := 16;
3261 fFormat := tfBGRX4us1;
3262 fWithAlpha := tfBGRA4us1;
3263 fWithoutAlpha := tfBGRX4us1;
3264 fRGBInverted := tfRGBX4us1;
3265 fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
3266 fShift := glBitmapRec4ub( 4, 8, 12, 0);
3268 fOpenGLFormat := tfBGRX4us1;
3269 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3270 fglInternalFormat := GL_RGB4;
3271 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3273 fOpenGLFormat := tfR5G6B5us1;
3277 procedure TfdXBGR4us1.SetValues;
3279 inherited SetValues;
3280 fBitsPerPixel := 16;
3281 fFormat := tfXBGR4us1;
3282 fWithAlpha := tfABGR4us1;
3283 fWithoutAlpha := tfXBGR4us1;
3284 fRGBInverted := tfXRGB4us1;
3285 fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
3286 fShift := glBitmapRec4ub( 0, 4, 8, 0);
3288 fOpenGLFormat := tfXBGR4us1;
3289 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3290 fglInternalFormat := GL_RGB4;
3291 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3293 fOpenGLFormat := tfR5G6B5us1;
3297 procedure TfdB5G6R5us1.SetValues;
3299 inherited SetValues;
3300 fBitsPerPixel := 16;
3301 fFormat := tfB5G6R5us1;
3302 fWithAlpha := tfBGR5A1us1;
3303 fWithoutAlpha := tfB5G6R5us1;
3304 fRGBInverted := tfR5G6B5us1;
3305 fPrecision := glBitmapRec4ub( 5, 6, 5, 0);
3306 fShift := glBitmapRec4ub( 0, 5, 11, 0);
3308 fOpenGLFormat := tfB5G6R5us1;
3309 fglFormat := GL_RGB;
3310 fglInternalFormat := GL_RGB565;
3311 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5_REV;
3313 fOpenGLFormat := tfR5G6B5us1;
3317 procedure TfdBGR5X1us1.SetValues;
3319 inherited SetValues;
3320 fBitsPerPixel := 16;
3321 fFormat := tfBGR5X1us1;
3322 fWithAlpha := tfBGR5A1us1;
3323 fWithoutAlpha := tfBGR5X1us1;
3324 fRGBInverted := tfRGB5X1us1;
3325 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
3326 fShift := glBitmapRec4ub( 1, 6, 11, 0);
3328 fOpenGLFormat := tfBGR5X1us1;
3329 fglFormat := GL_BGRA;
3330 fglInternalFormat := GL_RGB5;
3331 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3333 fOpenGLFormat := tfR5G6B5us1;
3337 procedure TfdX1BGR5us1.SetValues;
3339 inherited SetValues;
3340 fBitsPerPixel := 16;
3341 fFormat := tfX1BGR5us1;
3342 fWithAlpha := tfA1BGR5us1;
3343 fWithoutAlpha := tfX1BGR5us1;
3344 fRGBInverted := tfX1RGB5us1;
3345 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
3346 fShift := glBitmapRec4ub( 0, 5, 10, 0);
3348 fOpenGLFormat := tfX1BGR5us1;
3349 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3350 fglInternalFormat := GL_RGB5;
3351 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3353 fOpenGLFormat := tfR5G6B5us1;
3357 procedure TfdBGR8ub3.SetValues;
3359 inherited SetValues;
3360 fBitsPerPixel := 24;
3361 fFormat := tfBGR8ub3;
3362 fWithAlpha := tfBGRA8ub4;
3363 fWithoutAlpha := tfBGR8ub3;
3364 fRGBInverted := tfRGB8ub3;
3365 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3366 fShift := glBitmapRec4ub(16, 8, 0, 0);
3368 fOpenGLFormat := tfBGR8ub3;
3369 fglFormat := GL_BGR;
3370 fglInternalFormat := GL_RGB8;
3371 fglDataFormat := GL_UNSIGNED_BYTE;
3373 fOpenGLFormat := tfRGB8ub3;
3377 procedure TfdBGRX8ui1.SetValues;
3379 inherited SetValues;
3380 fBitsPerPixel := 32;
3381 fFormat := tfBGRX8ui1;
3382 fWithAlpha := tfBGRA8ui1;
3383 fWithoutAlpha := tfBGRX8ui1;
3384 fRGBInverted := tfRGBX8ui1;
3385 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3386 fShift := glBitmapRec4ub( 8, 16, 24, 0);
3388 fOpenGLFormat := tfBGRX8ui1;
3389 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3390 fglInternalFormat := GL_RGB8;
3391 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3393 fOpenGLFormat := tfRGB8ub3;
3397 procedure TfdXBGR8ui1.SetValues;
3399 inherited SetValues;
3400 fBitsPerPixel := 32;
3401 fFormat := tfXBGR8ui1;
3402 fWithAlpha := tfABGR8ui1;
3403 fWithoutAlpha := tfXBGR8ui1;
3404 fRGBInverted := tfXRGB8ui1;
3405 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3406 fShift := glBitmapRec4ub( 0, 8, 16, 0);
3408 fOpenGLFormat := tfXBGR8ui1;
3409 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3410 fglInternalFormat := GL_RGB8;
3411 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3413 fOpenGLFormat := tfRGB8ub3;
3417 procedure TfdBGR10X2ui1.SetValues;
3419 inherited SetValues;
3420 fBitsPerPixel := 32;
3421 fFormat := tfBGR10X2ui1;
3422 fWithAlpha := tfBGR10A2ui1;
3423 fWithoutAlpha := tfBGR10X2ui1;
3424 fRGBInverted := tfRGB10X2ui1;
3425 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3426 fShift := glBitmapRec4ub( 2, 12, 22, 0);
3428 fOpenGLFormat := tfBGR10X2ui1;
3429 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3430 fglInternalFormat := GL_RGB10;
3431 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3433 fOpenGLFormat := tfRGB16us3;
3437 procedure TfdX2BGR10ui1.SetValues;
3439 inherited SetValues;
3440 fBitsPerPixel := 32;
3441 fFormat := tfX2BGR10ui1;
3442 fWithAlpha := tfA2BGR10ui1;
3443 fWithoutAlpha := tfX2BGR10ui1;
3444 fRGBInverted := tfX2RGB10ui1;
3445 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3446 fShift := glBitmapRec4ub( 0, 10, 20, 0);
3448 fOpenGLFormat := tfX2BGR10ui1;
3449 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3450 fglInternalFormat := GL_RGB10;
3451 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3453 fOpenGLFormat := tfRGB16us3;
3457 procedure TfdBGR16us3.SetValues;
3459 inherited SetValues;
3460 fBitsPerPixel := 48;
3461 fFormat := tfBGR16us3;
3462 fWithAlpha := tfBGRA16us4;
3463 fWithoutAlpha := tfBGR16us3;
3464 fRGBInverted := tfRGB16us3;
3465 fPrecision := glBitmapRec4ub(16, 16, 16, 0);
3466 fShift := glBitmapRec4ub(32, 16, 0, 0);
3468 fOpenGLFormat := tfBGR16us3;
3469 fglFormat := GL_BGR;
3470 fglInternalFormat := GL_RGB16;
3471 fglDataFormat := GL_UNSIGNED_SHORT;
3473 fOpenGLFormat := tfRGB16us3;
3477 procedure TfdBGRA4us1.SetValues;
3479 inherited SetValues;
3480 fBitsPerPixel := 16;
3481 fFormat := tfBGRA4us1;
3482 fWithAlpha := tfBGRA4us1;
3483 fWithoutAlpha := tfBGRX4us1;
3484 fRGBInverted := tfRGBA4us1;
3485 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3486 fShift := glBitmapRec4ub( 4, 8, 12, 0);
3488 fOpenGLFormat := tfBGRA4us1;
3489 fglFormat := GL_BGRA;
3490 fglInternalFormat := GL_RGBA4;
3491 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3493 fOpenGLFormat := tfRGBA4us1;
3497 procedure TfdABGR4us1.SetValues;
3499 inherited SetValues;
3500 fBitsPerPixel := 16;
3501 fFormat := tfABGR4us1;
3502 fWithAlpha := tfABGR4us1;
3503 fWithoutAlpha := tfXBGR4us1;
3504 fRGBInverted := tfARGB4us1;
3505 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3506 fShift := glBitmapRec4ub( 0, 4, 8, 12);
3508 fOpenGLFormat := tfABGR4us1;
3509 fglFormat := GL_RGBA;
3510 fglInternalFormat := GL_RGBA4;
3511 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3513 fOpenGLFormat := tfRGBA4us1;
3517 procedure TfdBGR5A1us1.SetValues;
3519 inherited SetValues;
3520 fBitsPerPixel := 16;
3521 fFormat := tfBGR5A1us1;
3522 fWithAlpha := tfBGR5A1us1;
3523 fWithoutAlpha := tfBGR5X1us1;
3524 fRGBInverted := tfRGB5A1us1;
3525 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3526 fShift := glBitmapRec4ub( 1, 6, 11, 0);
3528 fOpenGLFormat := tfBGR5A1us1;
3529 fglFormat := GL_BGRA;
3530 fglInternalFormat := GL_RGB5_A1;
3531 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3533 fOpenGLFormat := tfRGB5A1us1;
3537 procedure TfdA1BGR5us1.SetValues;
3539 inherited SetValues;
3540 fBitsPerPixel := 16;
3541 fFormat := tfA1BGR5us1;
3542 fWithAlpha := tfA1BGR5us1;
3543 fWithoutAlpha := tfX1BGR5us1;
3544 fRGBInverted := tfA1RGB5us1;
3545 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3546 fShift := glBitmapRec4ub( 0, 5, 10, 15);
3548 fOpenGLFormat := tfA1BGR5us1;
3549 fglFormat := GL_RGBA;
3550 fglInternalFormat := GL_RGB5_A1;
3551 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3553 fOpenGLFormat := tfRGB5A1us1;
3557 procedure TfdBGRA8ui1.SetValues;
3559 inherited SetValues;
3560 fBitsPerPixel := 32;
3561 fFormat := tfBGRA8ui1;
3562 fWithAlpha := tfBGRA8ui1;
3563 fWithoutAlpha := tfBGRX8ui1;
3564 fRGBInverted := tfRGBA8ui1;
3565 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3566 fShift := glBitmapRec4ub( 8, 16, 24, 0);
3568 fOpenGLFormat := tfBGRA8ui1;
3569 fglFormat := GL_BGRA;
3570 fglInternalFormat := GL_RGBA8;
3571 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3573 fOpenGLFormat := tfRGBA8ub4;
3577 procedure TfdABGR8ui1.SetValues;
3579 inherited SetValues;
3580 fBitsPerPixel := 32;
3581 fFormat := tfABGR8ui1;
3582 fWithAlpha := tfABGR8ui1;
3583 fWithoutAlpha := tfXBGR8ui1;
3584 fRGBInverted := tfARGB8ui1;
3585 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3586 fShift := glBitmapRec4ub( 0, 8, 16, 24);
3588 fOpenGLFormat := tfABGR8ui1;
3589 fglFormat := GL_RGBA;
3590 fglInternalFormat := GL_RGBA8;
3591 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3593 fOpenGLFormat := tfRGBA8ub4
3597 procedure TfdBGRA8ub4.SetValues;
3599 inherited SetValues;
3600 fBitsPerPixel := 32;
3601 fFormat := tfBGRA8ub4;
3602 fWithAlpha := tfBGRA8ub4;
3603 fWithoutAlpha := tfBGR8ub3;
3604 fRGBInverted := tfRGBA8ub4;
3605 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3606 fShift := glBitmapRec4ub(16, 8, 0, 24);
3608 fOpenGLFormat := tfBGRA8ub4;
3609 fglFormat := GL_BGRA;
3610 fglInternalFormat := GL_RGBA8;
3611 fglDataFormat := GL_UNSIGNED_BYTE;
3613 fOpenGLFormat := tfRGBA8ub4;
3617 procedure TfdBGR10A2ui1.SetValues;
3619 inherited SetValues;
3620 fBitsPerPixel := 32;
3621 fFormat := tfBGR10A2ui1;
3622 fWithAlpha := tfBGR10A2ui1;
3623 fWithoutAlpha := tfBGR10X2ui1;
3624 fRGBInverted := tfRGB10A2ui1;
3625 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3626 fShift := glBitmapRec4ub( 2, 12, 22, 0);
3628 fOpenGLFormat := tfBGR10A2ui1;
3629 fglFormat := GL_BGRA;
3630 fglInternalFormat := GL_RGB10_A2;
3631 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3633 fOpenGLFormat := tfA2RGB10ui1;
3637 procedure TfdA2BGR10ui1.SetValues;
3639 inherited SetValues;
3640 fBitsPerPixel := 32;
3641 fFormat := tfA2BGR10ui1;
3642 fWithAlpha := tfA2BGR10ui1;
3643 fWithoutAlpha := tfX2BGR10ui1;
3644 fRGBInverted := tfA2RGB10ui1;
3645 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3646 fShift := glBitmapRec4ub( 0, 10, 20, 30);
3648 fOpenGLFormat := tfA2BGR10ui1;
3649 fglFormat := GL_RGBA;
3650 fglInternalFormat := GL_RGB10_A2;
3651 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3653 fOpenGLFormat := tfA2RGB10ui1;
3657 procedure TfdBGRA16us4.SetValues;
3659 inherited SetValues;
3660 fBitsPerPixel := 64;
3661 fFormat := tfBGRA16us4;
3662 fWithAlpha := tfBGRA16us4;
3663 fWithoutAlpha := tfBGR16us3;
3664 fRGBInverted := tfRGBA16us4;
3665 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3666 fShift := glBitmapRec4ub(32, 16, 0, 48);
3668 fOpenGLFormat := tfBGRA16us4;
3669 fglFormat := GL_BGRA;
3670 fglInternalFormat := GL_RGBA16;
3671 fglDataFormat := GL_UNSIGNED_SHORT;
3673 fOpenGLFormat := tfRGBA16us4;
3677 procedure TfdDepth16us1.SetValues;
3679 inherited SetValues;
3680 fBitsPerPixel := 16;
3681 fFormat := tfDepth16us1;
3682 fWithoutAlpha := tfDepth16us1;
3683 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3684 fShift := glBitmapRec4ub( 0, 0, 0, 0);
3685 {$IF NOT DEFINED (OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
3686 fOpenGLFormat := tfDepth16us1;
3687 fglFormat := GL_DEPTH_COMPONENT;
3688 fglInternalFormat := GL_DEPTH_COMPONENT16;
3689 fglDataFormat := GL_UNSIGNED_SHORT;
3693 procedure TfdDepth24ui1.SetValues;
3695 inherited SetValues;
3696 fBitsPerPixel := 32;
3697 fFormat := tfDepth24ui1;
3698 fWithoutAlpha := tfDepth24ui1;
3699 fOpenGLFormat := tfDepth24ui1;
3700 fPrecision := glBitmapRec4ub(32, 32, 32, 32);
3701 fShift := glBitmapRec4ub( 0, 0, 0, 0);
3702 {$IF NOT DEFINED (OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
3703 fOpenGLFormat := tfDepth24ui1;
3704 fglFormat := GL_DEPTH_COMPONENT;
3705 fglInternalFormat := GL_DEPTH_COMPONENT24;
3706 fglDataFormat := GL_UNSIGNED_INT;
3710 procedure TfdDepth32ui1.SetValues;
3712 inherited SetValues;
3713 fBitsPerPixel := 32;
3714 fFormat := tfDepth32ui1;
3715 fWithoutAlpha := tfDepth32ui1;
3716 fPrecision := glBitmapRec4ub(32, 32, 32, 32);
3717 fShift := glBitmapRec4ub( 0, 0, 0, 0);
3718 {$IF NOT DEFINED(OPENGL_ES)}
3719 fOpenGLFormat := tfDepth32ui1;
3720 fglFormat := GL_DEPTH_COMPONENT;
3721 fglInternalFormat := GL_DEPTH_COMPONENT32;
3722 fglDataFormat := GL_UNSIGNED_INT;
3723 {$ELSEIF DEFINED(OPENGL_ES_3_0)}
3724 fOpenGLFormat := tfDepth24ui1;
3725 {$ELSEIF DEFINED(OPENGL_ES_2_0)}
3726 fOpenGLFormat := tfDepth16us1;
3730 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3731 //TfdS3tcDtx1RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3732 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3733 procedure TfdS3tcDtx1RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3735 raise EglBitmap.Create('mapping for compressed formats is not supported');
3738 procedure TfdS3tcDtx1RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3740 raise EglBitmap.Create('mapping for compressed formats is not supported');
3743 procedure TfdS3tcDtx1RGBA.SetValues;
3745 inherited SetValues;
3746 fFormat := tfS3tcDtx1RGBA;
3747 fWithAlpha := tfS3tcDtx1RGBA;
3748 fUncompressed := tfRGB5A1us1;
3750 fIsCompressed := true;
3752 fOpenGLFormat := tfS3tcDtx1RGBA;
3753 fglFormat := GL_COMPRESSED_RGBA;
3754 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
3755 fglDataFormat := GL_UNSIGNED_BYTE;
3757 fOpenGLFormat := fUncompressed;
3761 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3762 //TfdS3tcDtx3RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3763 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3764 procedure TfdS3tcDtx3RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3766 raise EglBitmap.Create('mapping for compressed formats is not supported');
3769 procedure TfdS3tcDtx3RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3771 raise EglBitmap.Create('mapping for compressed formats is not supported');
3774 procedure TfdS3tcDtx3RGBA.SetValues;
3776 inherited SetValues;
3777 fFormat := tfS3tcDtx3RGBA;
3778 fWithAlpha := tfS3tcDtx3RGBA;
3779 fUncompressed := tfRGBA8ub4;
3781 fIsCompressed := true;
3783 fOpenGLFormat := tfS3tcDtx3RGBA;
3784 fglFormat := GL_COMPRESSED_RGBA;
3785 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
3786 fglDataFormat := GL_UNSIGNED_BYTE;
3788 fOpenGLFormat := fUncompressed;
3792 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3793 //TfdS3tcDtx5RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3794 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3795 procedure TfdS3tcDtx5RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3797 raise EglBitmap.Create('mapping for compressed formats is not supported');
3800 procedure TfdS3tcDtx5RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3802 raise EglBitmap.Create('mapping for compressed formats is not supported');
3805 procedure TfdS3tcDtx5RGBA.SetValues;
3807 inherited SetValues;
3808 fFormat := tfS3tcDtx3RGBA;
3809 fWithAlpha := tfS3tcDtx3RGBA;
3810 fUncompressed := tfRGBA8ub4;
3812 fIsCompressed := true;
3814 fOpenGLFormat := tfS3tcDtx3RGBA;
3815 fglFormat := GL_COMPRESSED_RGBA;
3816 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
3817 fglDataFormat := GL_UNSIGNED_BYTE;
3819 fOpenGLFormat := fUncompressed;
3823 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3824 //TglBitmapFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3825 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3826 function TglBitmapFormatDescriptor.GetHasRed: Boolean;
3828 result := (fPrecision.r > 0);
3831 function TglBitmapFormatDescriptor.GetHasGreen: Boolean;
3833 result := (fPrecision.g > 0);
3836 function TglBitmapFormatDescriptor.GetHasBlue: Boolean;
3838 result := (fPrecision.b > 0);
3841 function TglBitmapFormatDescriptor.GetHasAlpha: Boolean;
3843 result := (fPrecision.a > 0);
3846 function TglBitmapFormatDescriptor.GetHasColor: Boolean;
3848 result := HasRed or HasGreen or HasBlue;
3851 function TglBitmapFormatDescriptor.GetIsGrayscale: Boolean;
3853 result := (Mask.r = Mask.g) and (Mask.g = Mask.b) and (Mask.r > 0);
3856 function TglBitmapFormatDescriptor.GetHasOpenGLSupport: Boolean;
3858 result := (OpenGLFormat = Format);
3861 procedure TglBitmapFormatDescriptor.SetValues;
3864 fWithAlpha := tfEmpty;
3865 fWithoutAlpha := tfEmpty;
3866 fOpenGLFormat := tfEmpty;
3867 fRGBInverted := tfEmpty;
3868 fUncompressed := tfEmpty;
3871 fIsCompressed := false;
3874 fglInternalFormat := 0;
3877 FillChar(fPrecision, 0, SizeOf(fPrecision));
3878 FillChar(fShift, 0, SizeOf(fShift));
3881 procedure TglBitmapFormatDescriptor.CalcValues;
3885 fBytesPerPixel := fBitsPerPixel / 8;
3887 for i := 0 to 3 do begin
3888 if (fPrecision.arr[i] > 0) then
3890 fRange.arr[i] := (1 shl fPrecision.arr[i]) - 1;
3891 fMask.arr[i] := fRange.arr[i] shl fShift.arr[i];
3895 function TglBitmapFormatDescriptor.GetSize(const aSize: TglBitmapSize): Integer;
3899 if (ffX in aSize.Fields) or (ffY in aSize.Fields) then begin
3900 w := Max(1, aSize.X);
3901 h := Max(1, aSize.Y);
3902 result := GetSize(w, h);
3907 function TglBitmapFormatDescriptor.GetSize(const aWidth, aHeight: Integer): Integer;
3910 if (aWidth <= 0) or (aHeight <= 0) then
3912 result := Ceil(aWidth * aHeight * BytesPerPixel);
3915 constructor TglBitmapFormatDescriptor.Create;
3922 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3923 class function TglBitmapFormatDescriptor.GetByFormat(const aInternalFormat: GLenum): TglBitmapFormatDescriptor;
3927 for f := Low(TglBitmapFormat) to High(TglBitmapFormat) do begin
3928 result := TFormatDescriptor.Get(f);
3929 if (result.glInternalFormat = aInternalFormat) then
3932 result := TFormatDescriptor.Get(tfEmpty);
3935 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3936 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3937 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3938 class procedure TFormatDescriptor.Init;
3940 if not Assigned(FormatDescriptorCS) then
3941 FormatDescriptorCS := TCriticalSection.Create;
3944 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3945 class function TFormatDescriptor.Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
3947 FormatDescriptorCS.Enter;
3949 result := FormatDescriptors[aFormat];
3950 if not Assigned(result) then begin
3951 result := FORMAT_DESCRIPTOR_CLASSES[aFormat].Create;
3952 FormatDescriptors[aFormat] := result;
3955 FormatDescriptorCS.Leave;
3959 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3960 class function TFormatDescriptor.GetAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
3962 result := Get(Get(aFormat).WithAlpha);
3965 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3966 class function TFormatDescriptor.GetFromMask(const aMask: TglBitmapRec4ul; const aBitCount: Integer): TFormatDescriptor;
3968 ft: TglBitmapFormat;
3970 // find matching format with OpenGL support
3971 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
3973 if (result.MaskMatch(aMask)) and
3974 (result.glFormat <> 0) and
3975 (result.glInternalFormat <> 0) and
3976 ((aBitCount = 0) or (aBitCount = result.BitsPerPixel))
3981 // find matching format without OpenGL Support
3982 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
3984 if result.MaskMatch(aMask) and ((aBitCount = 0) or (aBitCount = result.BitsPerPixel)) then
3988 result := TFormatDescriptor.Get(tfEmpty);
3991 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3992 class function TFormatDescriptor.GetFromPrecShift(const aPrec, aShift: TglBitmapRec4ub; const aBitCount: Integer): TFormatDescriptor;
3994 ft: TglBitmapFormat;
3996 // find matching format with OpenGL support
3997 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
3999 if glBitmapRec4ubCompare(result.Shift, aShift) and
4000 glBitmapRec4ubCompare(result.Precision, aPrec) and
4001 (result.glFormat <> 0) and
4002 (result.glInternalFormat <> 0) and
4003 ((aBitCount = 0) or (aBitCount = result.BitsPerPixel))
4008 // find matching format without OpenGL Support
4009 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
4011 if glBitmapRec4ubCompare(result.Shift, aShift) and
4012 glBitmapRec4ubCompare(result.Precision, aPrec) and
4013 ((aBitCount = 0) or (aBitCount = result.BitsPerPixel)) then
4017 result := TFormatDescriptor.Get(tfEmpty);
4020 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4021 class procedure TFormatDescriptor.Clear;
4025 FormatDescriptorCS.Enter;
4027 for f := low(FormatDescriptors) to high(FormatDescriptors) do
4028 FreeAndNil(FormatDescriptors[f]);
4030 FormatDescriptorCS.Leave;
4034 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4035 class procedure TFormatDescriptor.Finalize;
4038 FreeAndNil(FormatDescriptorCS);
4041 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4042 //TBitfieldFormat/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4043 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4044 procedure TbmpBitfieldFormat.SetCustomValues(const aBPP: Integer; aMask: TglBitmapRec4ul);
4048 for i := 0 to 3 do begin
4050 while (aMask.arr[i] > 0) and ((aMask.arr[i] and 1) = 0) do begin
4051 aMask.arr[i] := aMask.arr[i] shr 1;
4054 fPrecision.arr[i] := CountSetBits(aMask.arr[i]);
4056 fBitsPerPixel := aBPP;
4060 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4061 procedure TbmpBitfieldFormat.SetCustomValues(const aBBP: Integer; const aPrec, aShift: TglBitmapRec4ub);
4063 fBitsPerPixel := aBBP;
4064 fPrecision := aPrec;
4069 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4070 procedure TbmpBitfieldFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4075 ((aPixel.Data.r and Range.r) shl Shift.r) or
4076 ((aPixel.Data.g and Range.g) shl Shift.g) or
4077 ((aPixel.Data.b and Range.b) shl Shift.b) or
4078 ((aPixel.Data.a and Range.a) shl Shift.a);
4079 case BitsPerPixel of
4081 16: PWord(aData)^ := data;
4082 32: PCardinal(aData)^ := data;
4083 64: PQWord(aData)^ := data;
4085 raise EglBitmap.CreateFmt('invalid pixel size: %d', [BitsPerPixel]);
4087 inc(aData, Round(BytesPerPixel));
4090 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4091 procedure TbmpBitfieldFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4096 case BitsPerPixel of
4098 16: data := PWord(aData)^;
4099 32: data := PCardinal(aData)^;
4100 64: data := PQWord(aData)^;
4102 raise EglBitmap.CreateFmt('invalid pixel size: %d', [BitsPerPixel]);
4105 aPixel.Data.arr[i] := (data shr fShift.arr[i]) and Range.arr[i];
4106 inc(aData, Round(BytesPerPixel));
4109 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4110 //TColorTableFormat///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4111 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4112 procedure TbmpColorTableFormat.SetValues;
4114 inherited SetValues;
4115 fShift := glBitmapRec4ub(8, 8, 8, 0);
4118 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4119 procedure TbmpColorTableFormat.SetCustomValues(const aFormat: TglBitmapFormat; const aBPP: Integer; const aPrec, aShift: TglBitmapRec4ub);
4122 fBitsPerPixel := aBPP;
4123 fPrecision := aPrec;
4128 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4129 procedure TbmpColorTableFormat.CalcValues;
4131 inherited CalcValues;
4134 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4135 procedure TbmpColorTableFormat.CreateColorTable;
4139 SetLength(fColorTable, 256);
4140 if not HasColor then begin
4142 for i := 0 to High(fColorTable) do begin
4143 fColorTable[i].r := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
4144 fColorTable[i].g := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
4145 fColorTable[i].b := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
4146 fColorTable[i].a := 0;
4150 for i := 0 to High(fColorTable) do begin
4151 fColorTable[i].r := Round(((i shr Shift.r) and Range.r) / Range.r * 255);
4152 fColorTable[i].g := Round(((i shr Shift.g) and Range.g) / Range.g * 255);
4153 fColorTable[i].b := Round(((i shr Shift.b) and Range.b) / Range.b * 255);
4154 fColorTable[i].a := 0;
4159 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4160 function TbmpColorTableFormat.CreateMappingData: Pointer;
4162 result := Pointer(0);
4165 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4166 procedure TbmpColorTableFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4168 if (BitsPerPixel <> 8) then
4169 raise EglBitmapUnsupportedFormat.Create('color table are only supported for 8bit formats');
4170 if not HasColor then
4172 aData^ := aPixel.Data.a
4176 ((aPixel.Data.r shr Shift.r) and Range.r) * LUMINANCE_WEIGHT_R +
4177 ((aPixel.Data.g shr Shift.g) and Range.g) * LUMINANCE_WEIGHT_G +
4178 ((aPixel.Data.b shr Shift.b) and Range.b) * LUMINANCE_WEIGHT_B);
4182 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4183 procedure TbmpColorTableFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4185 function ReadValue: Byte;
4189 if (BitsPerPixel = 8) then begin
4193 i := {%H-}PtrUInt(aMapData);
4194 if (BitsPerPixel > 1) then
4195 result := (aData^ shr i) and ((1 shl BitsPerPixel) - 1)
4197 result := (aData^ shr (7-i)) and ((1 shl BitsPerPixel) - 1);
4198 inc(i, BitsPerPixel);
4199 while (i >= 8) do begin
4203 aMapData := {%H-}Pointer(i);
4208 if (BitsPerPixel > 8) then
4209 raise EglBitmapUnsupportedFormat.Create('color table are only supported for 8bit formats');
4210 with fColorTable[ReadValue] do begin
4218 destructor TbmpColorTableFormat.Destroy;
4220 SetLength(fColorTable, 0);
4224 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4225 //TglBitmap - Helper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4226 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4227 procedure glBitmapConvertPixel(var aPixel: TglBitmapPixelData; const aSourceFD, aDestFD: TFormatDescriptor);
4231 for i := 0 to 3 do begin
4232 if (aSourceFD.Range.arr[i] <> aDestFD.Range.arr[i]) then begin
4233 if (aSourceFD.Range.arr[i] > 0) then
4234 aPixel.Data.arr[i] := Round(aPixel.Data.arr[i] / aSourceFD.Range.arr[i] * aDestFD.Range.arr[i])
4236 aPixel.Data.arr[i] := 0;
4241 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4242 procedure glBitmapConvertCopyFunc(var aFuncRec: TglBitmapFunctionRec);
4244 with aFuncRec do begin
4245 if (Source.Range.r > 0) then
4246 Dest.Data.r := Source.Data.r;
4247 if (Source.Range.g > 0) then
4248 Dest.Data.g := Source.Data.g;
4249 if (Source.Range.b > 0) then
4250 Dest.Data.b := Source.Data.b;
4251 if (Source.Range.a > 0) then
4252 Dest.Data.a := Source.Data.a;
4256 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4257 procedure glBitmapConvertCalculateRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
4261 with aFuncRec do begin
4263 if (Source.Range.arr[i] > 0) then
4264 Dest.Data.arr[i] := Round(Dest.Range.arr[i] * Source.Data.arr[i] / Source.Range.arr[i]);
4269 TShiftData = packed record
4271 0: (r, g, b, a: SmallInt);
4272 1: (arr: array[0..3] of SmallInt);
4274 PShiftData = ^TShiftData;
4276 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4277 procedure glBitmapConvertShiftRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
4283 if (Source.Range.arr[i] > 0) then
4284 Dest.Data.arr[i] := Source.Data.arr[i] shr PShiftData(Args)^.arr[i];
4287 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4288 procedure glBitmapInvertFunc(var aFuncRec: TglBitmapFunctionRec);
4292 with aFuncRec do begin
4293 Dest.Data := Source.Data;
4295 if ({%H-}PtrUInt(Args) and (1 shl i) > 0) then
4296 Dest.Data.arr[i] := Dest.Data.arr[i] xor Dest.Range.arr[i];
4300 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4301 procedure glBitmapFillWithColorFunc(var aFuncRec: TglBitmapFunctionRec);
4305 with aFuncRec do begin
4307 Dest.Data.arr[i] := PglBitmapPixelData(Args)^.Data.arr[i];
4311 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4312 procedure glBitmapAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4316 with FuncRec do begin
4317 if (FuncRec.Args = nil) then begin //source has no alpha
4319 Source.Data.r / Source.Range.r * ALPHA_WEIGHT_R +
4320 Source.Data.g / Source.Range.g * ALPHA_WEIGHT_G +
4321 Source.Data.b / Source.Range.b * ALPHA_WEIGHT_B;
4322 Dest.Data.a := Round(Dest.Range.a * Temp);
4324 Dest.Data.a := Round(Source.Data.a / Source.Range.a * Dest.Range.a);
4328 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4329 procedure glBitmapColorKeyAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4331 PglBitmapPixelData = ^TglBitmapPixelData;
4333 with FuncRec do begin
4334 Dest.Data.r := Source.Data.r;
4335 Dest.Data.g := Source.Data.g;
4336 Dest.Data.b := Source.Data.b;
4338 with PglBitmapPixelData(Args)^ do
4339 if ((Dest.Data.r <= Data.r) and (Dest.Data.r >= Range.r) and
4340 (Dest.Data.g <= Data.g) and (Dest.Data.g >= Range.g) and
4341 (Dest.Data.b <= Data.b) and (Dest.Data.b >= Range.b)) then
4344 Dest.Data.a := Dest.Range.a;
4348 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4349 procedure glBitmapValueAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4351 with FuncRec do begin
4352 Dest.Data.r := Source.Data.r;
4353 Dest.Data.g := Source.Data.g;
4354 Dest.Data.b := Source.Data.b;
4355 Dest.Data.a := PCardinal(Args)^;
4359 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4360 procedure SwapRGB(aData: PByte; aWidth: Integer; const aHasAlpha: Boolean);
4363 TRGBPix = array [0..2] of byte;
4367 while aWidth > 0 do begin
4368 Temp := PRGBPix(aData)^[0];
4369 PRGBPix(aData)^[0] := PRGBPix(aData)^[2];
4370 PRGBPix(aData)^[2] := Temp;
4380 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4381 //TglBitmapData///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4382 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4383 function TglBitmapData.GetFormatDescriptor: TglBitmapFormatDescriptor;
4385 result := TFormatDescriptor.Get(fFormat);
4388 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4389 function TglBitmapData.GetWidth: Integer;
4391 if (ffX in fDimension.Fields) then
4392 result := fDimension.X
4397 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4398 function TglBitmapData.GetHeight: Integer;
4400 if (ffY in fDimension.Fields) then
4401 result := fDimension.Y
4406 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4407 function TglBitmapData.GetScanlines(const aIndex: Integer): PByte;
4409 if fHasScanlines and (aIndex >= Low(fScanlines)) and (aIndex <= High(fScanlines)) then
4410 result := fScanlines[aIndex]
4415 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4416 procedure TglBitmapData.SetFormat(const aValue: TglBitmapFormat);
4418 if fFormat = aValue then
4420 if TFormatDescriptor.Get(Format).BitsPerPixel <> TFormatDescriptor.Get(aValue).BitsPerPixel then
4421 raise EglBitmapUnsupportedFormat.Create(Format);
4422 SetData(fData, aValue, Width, Height);
4425 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4426 procedure TglBitmapData.PrepareResType(var aResource: String; var aResType: PChar);
4430 if not Assigned(aResType) then begin
4431 TempPos := Pos('.', aResource);
4432 aResType := PChar(UpperCase(Copy(aResource, TempPos + 1, Length(aResource) - TempPos)));
4433 aResource := UpperCase(Copy(aResource, 0, TempPos -1));
4437 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4438 procedure TglBitmapData.UpdateScanlines;
4440 w, h, i, LineWidth: Integer;
4444 fHasScanlines := Assigned(fData) and (w > 0) and (h > 0);
4445 if fHasScanlines then begin
4446 SetLength(fScanlines, h);
4447 LineWidth := Trunc(w * FormatDescriptor.BytesPerPixel);
4448 for i := 0 to h-1 do begin
4449 fScanlines[i] := fData;
4450 Inc(fScanlines[i], i * LineWidth);
4453 SetLength(fScanlines, 0);
4456 {$IFDEF GLB_SUPPORT_PNG_READ}
4457 {$IF DEFINED(GLB_LAZ_PNG)}
4458 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4459 //PNG/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4460 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4461 function TglBitmapData.LoadPNG(const aStream: TStream): Boolean;
4464 PNG_MAGIC: String[MAGIC_LEN] = #$89#$50#$4E#$47#$0D#$0A#$1A#$0A;
4466 reader: TLazReaderPNG;
4467 intf: TLazIntfImage;
4469 magic: String[MAGIC_LEN];
4472 StreamPos := aStream.Position;
4474 SetLength(magic, MAGIC_LEN);
4475 aStream.Read(magic[1], MAGIC_LEN);
4476 aStream.Position := StreamPos;
4477 if (magic <> PNG_MAGIC) then begin
4482 intf := TLazIntfImage.Create(0, 0);
4483 reader := TLazReaderPNG.Create;
4485 reader.UpdateDescription := true;
4486 reader.ImageRead(aStream, intf);
4487 AssignFromLazIntfImage(intf);
4490 aStream.Position := StreamPos;
4499 {$ELSEIF DEFINED(GLB_SDL_IMAGE)}
4500 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4501 function TglBitmapData.LoadPNG(const aStream: TStream): Boolean;
4503 Surface: PSDL_Surface;
4507 RWops := glBitmapCreateRWops(aStream);
4509 if IMG_isPNG(RWops) > 0 then begin
4510 Surface := IMG_LoadPNG_RW(RWops);
4512 AssignFromSurface(Surface);
4515 SDL_FreeSurface(Surface);
4523 {$ELSEIF DEFINED(GLB_LIB_PNG)}
4524 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4525 procedure glBitmap_libPNG_read_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
4527 TStream(png_get_io_ptr(png)).Read(buffer^, size);
4530 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4531 function TglBitmapData.LoadPNG(const aStream: TStream): Boolean;
4534 signature: array [0..7] of byte;
4536 png_info: png_infop;
4538 TempHeight, TempWidth: Integer;
4539 Format: TglBitmapFormat;
4542 png_rows: array of pByte;
4543 Row, LineSize: Integer;
4547 if not init_libPNG then
4548 raise Exception.Create('LoadPNG - unable to initialize libPNG.');
4552 StreamPos := aStream.Position;
4553 aStream.Read(signature{%H-}, 8);
4554 aStream.Position := StreamPos;
4556 if png_check_sig(@signature, 8) <> 0 then begin
4558 png := png_create_read_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
4560 raise EglBitmapException.Create('LoadPng - couldn''t create read struct.');
4563 png_info := png_create_info_struct(png);
4564 if png_info = nil then begin
4565 png_destroy_read_struct(@png, nil, nil);
4566 raise EglBitmapException.Create('LoadPng - couldn''t create info struct.');
4569 // set read callback
4570 png_set_read_fn(png, aStream, glBitmap_libPNG_read_func);
4572 // read informations
4573 png_read_info(png, png_info);
4576 TempHeight := png_get_image_height(png, png_info);
4577 TempWidth := png_get_image_width(png, png_info);
4580 case png_get_color_type(png, png_info) of
4581 PNG_COLOR_TYPE_GRAY:
4582 Format := tfLuminance8ub1;
4583 PNG_COLOR_TYPE_GRAY_ALPHA:
4584 Format := tfLuminance8Alpha8us1;
4586 Format := tfRGB8ub3;
4587 PNG_COLOR_TYPE_RGB_ALPHA:
4588 Format := tfRGBA8ub4;
4590 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
4593 // cut upper 8 bit from 16 bit formats
4594 if png_get_bit_depth(png, png_info) > 8 then
4595 png_set_strip_16(png);
4597 // expand bitdepth smaller than 8
4598 if png_get_bit_depth(png, png_info) < 8 then
4599 png_set_expand(png);
4601 // allocating mem for scanlines
4602 LineSize := png_get_rowbytes(png, png_info);
4603 GetMem(png_data, TempHeight * LineSize);
4605 SetLength(png_rows, TempHeight);
4606 for Row := Low(png_rows) to High(png_rows) do begin
4607 png_rows[Row] := png_data;
4608 Inc(png_rows[Row], Row * LineSize);
4611 // read complete image into scanlines
4612 png_read_image(png, @png_rows[0]);
4615 png_read_end(png, png_info);
4617 // destroy read struct
4618 png_destroy_read_struct(@png, @png_info, nil);
4620 SetLength(png_rows, 0);
4623 SetData(png_data, Format, TempWidth, TempHeight);
4627 if Assigned(png_data) then
4637 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
4638 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4639 function TglBitmapData.LoadPNG(const aStream: TStream): Boolean;
4644 Row, Col, PixSize, LineSize: Integer;
4645 NewImage, pSource, pDest, pAlpha: pByte;
4646 PngFormat: TglBitmapFormat;
4647 FormatDesc: TFormatDescriptor;
4650 PngHeader: String[8] = #137#80#78#71#13#10#26#10;
4655 StreamPos := aStream.Position;
4656 aStream.Read(Header[0], SizeOf(Header));
4657 aStream.Position := StreamPos;
4659 {Test if the header matches}
4660 if Header = PngHeader then begin
4661 Png := TPNGObject.Create;
4663 Png.LoadFromStream(aStream);
4665 case Png.Header.ColorType of
4667 PngFormat := tfLuminance8ub1;
4668 COLOR_GRAYSCALEALPHA:
4669 PngFormat := tfLuminance8Alpha8us1;
4671 PngFormat := tfBGR8ub3;
4673 PngFormat := tfBGRA8ub4;
4675 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
4678 FormatDesc := TFormatDescriptor.Get(PngFormat);
4679 PixSize := Round(FormatDesc.PixelSize);
4680 LineSize := FormatDesc.GetSize(Png.Header.Width, 1);
4682 GetMem(NewImage, LineSize * Integer(Png.Header.Height));
4686 case Png.Header.ColorType of
4687 COLOR_RGB, COLOR_GRAYSCALE:
4689 for Row := 0 to Png.Height -1 do begin
4690 Move (Png.Scanline[Row]^, pDest^, LineSize);
4691 Inc(pDest, LineSize);
4694 COLOR_RGBALPHA, COLOR_GRAYSCALEALPHA:
4696 PixSize := PixSize -1;
4698 for Row := 0 to Png.Height -1 do begin
4699 pSource := Png.Scanline[Row];
4700 pAlpha := pByte(Png.AlphaScanline[Row]);
4702 for Col := 0 to Png.Width -1 do begin
4703 Move (pSource^, pDest^, PixSize);
4704 Inc(pSource, PixSize);
4705 Inc(pDest, PixSize);
4714 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
4717 SetData(NewImage, PngFormat, Png.Header.Width, Png.Header.Height);
4721 if Assigned(NewImage) then
4733 {$IFDEF GLB_SUPPORT_PNG_WRITE}
4734 {$IFDEF GLB_LIB_PNG}
4735 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4736 procedure glBitmap_libPNG_write_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
4738 TStream(png_get_io_ptr(png)).Write(buffer^, size);
4742 {$IF DEFINED(GLB_LAZ_PNG)}
4743 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4744 procedure TglBitmapData.SavePNG(const aStream: TStream);
4746 png: TPortableNetworkGraphic;
4747 intf: TLazIntfImage;
4750 png := TPortableNetworkGraphic.Create;
4751 intf := TLazIntfImage.Create(0, 0);
4753 if not AssignToLazIntfImage(intf) then
4754 raise EglBitmap.Create('unable to create LazIntfImage from glBitmap');
4755 intf.GetRawImage(raw);
4756 png.LoadFromRawImage(raw, false);
4757 png.SaveToStream(aStream);
4764 {$ELSEIF DEFINED(GLB_LIB_PNG)}
4765 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4766 procedure TglBitmapData.SavePNG(const aStream: TStream);
4769 png_info: png_infop;
4770 png_rows: array of pByte;
4774 FormatDesc: TFormatDescriptor;
4776 if not (ftPNG in FormatGetSupportedFiles(Format)) then
4777 raise EglBitmapUnsupportedFormat.Create(Format);
4779 if not init_libPNG then
4780 raise Exception.Create('unable to initialize libPNG.');
4784 tfAlpha8ub1, tfLuminance8ub1:
4785 ColorType := PNG_COLOR_TYPE_GRAY;
4786 tfLuminance8Alpha8us1:
4787 ColorType := PNG_COLOR_TYPE_GRAY_ALPHA;
4788 tfBGR8ub3, tfRGB8ub3:
4789 ColorType := PNG_COLOR_TYPE_RGB;
4790 tfBGRA8ub4, tfRGBA8ub4:
4791 ColorType := PNG_COLOR_TYPE_RGBA;
4793 raise EglBitmapUnsupportedFormat.Create(Format);
4796 FormatDesc := TFormatDescriptor.Get(Format);
4797 LineSize := FormatDesc.GetSize(Width, 1);
4799 // creating array for scanline
4800 SetLength(png_rows, Height);
4802 for Row := 0 to Height - 1 do begin
4803 png_rows[Row] := Data;
4804 Inc(png_rows[Row], Row * LineSize)
4808 png := png_create_write_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
4810 raise EglBitmapException.Create('SavePng - couldn''t create write struct.');
4813 png_info := png_create_info_struct(png);
4814 if png_info = nil then begin
4815 png_destroy_write_struct(@png, nil);
4816 raise EglBitmapException.Create('SavePng - couldn''t create info struct.');
4819 // set read callback
4820 png_set_write_fn(png, aStream, glBitmap_libPNG_write_func, nil);
4823 png_set_compression_level(png, 6);
4825 if Format in [tfBGR8ub3, tfBGRA8ub4] then
4828 png_set_IHDR(png, png_info, Width, Height, 8, ColorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
4829 png_write_info(png, png_info);
4830 png_write_image(png, @png_rows[0]);
4831 png_write_end(png, png_info);
4832 png_destroy_write_struct(@png, @png_info);
4834 SetLength(png_rows, 0);
4841 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
4842 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4843 procedure TglBitmapData.SavePNG(const aStream: TStream);
4847 pSource, pDest: pByte;
4848 X, Y, PixSize: Integer;
4849 ColorType: Cardinal;
4855 if not (ftPNG in FormatGetSupportedFiles (Format)) then
4856 raise EglBitmapUnsupportedFormat.Create(Format);
4859 tfAlpha8ub1, tfLuminance8ub1: begin
4860 ColorType := COLOR_GRAYSCALE;
4864 tfLuminance8Alpha8us1: begin
4865 ColorType := COLOR_GRAYSCALEALPHA;
4869 tfBGR8ub3, tfRGB8ub3: begin
4870 ColorType := COLOR_RGB;
4874 tfBGRA8ub4, tfRGBA8ub4: begin
4875 ColorType := COLOR_RGBALPHA;
4880 raise EglBitmapUnsupportedFormat.Create(Format);
4883 Png := TPNGObject.CreateBlank(ColorType, 8, Width, Height);
4887 for Y := 0 to Height -1 do begin
4888 pDest := png.ScanLine[Y];
4889 for X := 0 to Width -1 do begin
4890 Move(pSource^, pDest^, PixSize);
4891 Inc(pDest, PixSize);
4892 Inc(pSource, PixSize);
4894 png.AlphaScanline[Y]^[X] := pSource^;
4899 // convert RGB line to BGR
4900 if Format in [tfRGB8ub3, tfRGBA8ub4] then begin
4901 pTemp := png.ScanLine[Y];
4902 for X := 0 to Width -1 do begin
4903 Temp := pByteArray(pTemp)^[0];
4904 pByteArray(pTemp)^[0] := pByteArray(pTemp)^[2];
4905 pByteArray(pTemp)^[2] := Temp;
4912 Png.CompressionLevel := 6;
4913 Png.SaveToStream(aStream);
4921 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4922 //JPEG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4923 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4924 {$IFDEF GLB_LIB_JPEG}
4926 glBitmap_libJPEG_source_mgr_ptr = ^glBitmap_libJPEG_source_mgr;
4927 glBitmap_libJPEG_source_mgr = record
4928 pub: jpeg_source_mgr;
4931 SrcBuffer: array [1..4096] of byte;
4934 glBitmap_libJPEG_dest_mgr_ptr = ^glBitmap_libJPEG_dest_mgr;
4935 glBitmap_libJPEG_dest_mgr = record
4936 pub: jpeg_destination_mgr;
4938 DestStream: TStream;
4939 DestBuffer: array [1..4096] of byte;
4942 procedure glBitmap_libJPEG_error_exit(cinfo: j_common_ptr); cdecl;
4948 procedure glBitmap_libJPEG_output_message(cinfo: j_common_ptr); cdecl;
4954 procedure glBitmap_libJPEG_init_source(cinfo: j_decompress_ptr); cdecl;
4959 procedure glBitmap_libJPEG_term_source(cinfo: j_decompress_ptr); cdecl;
4965 procedure glBitmap_libJPEG_init_destination(cinfo: j_compress_ptr); cdecl;
4971 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4972 function glBitmap_libJPEG_fill_input_buffer(cinfo: j_decompress_ptr): boolean; cdecl;
4974 src: glBitmap_libJPEG_source_mgr_ptr;
4977 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
4979 bytes := src^.SrcStream.Read(src^.SrcBuffer[1], 4096);
4980 if (bytes <= 0) then begin
4981 src^.SrcBuffer[1] := $FF;
4982 src^.SrcBuffer[2] := JPEG_EOI;
4986 src^.pub.next_input_byte := @(src^.SrcBuffer[1]);
4987 src^.pub.bytes_in_buffer := bytes;
4992 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4993 procedure glBitmap_libJPEG_skip_input_data(cinfo: j_decompress_ptr; num_bytes: Longint); cdecl;
4995 src: glBitmap_libJPEG_source_mgr_ptr;
4997 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
4999 if num_bytes > 0 then begin
5000 // wanted byte isn't in buffer so set stream position and read buffer
5001 if num_bytes > src^.pub.bytes_in_buffer then begin
5002 src^.SrcStream.Position := src^.SrcStream.Position + num_bytes - src^.pub.bytes_in_buffer;
5003 src^.pub.fill_input_buffer(cinfo);
5005 // wanted byte is in buffer so only skip
5006 inc(src^.pub.next_input_byte, num_bytes);
5007 dec(src^.pub.bytes_in_buffer, num_bytes);
5012 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5013 function glBitmap_libJPEG_empty_output_buffer(cinfo: j_compress_ptr): boolean; cdecl;
5015 dest: glBitmap_libJPEG_dest_mgr_ptr;
5017 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
5019 if dest^.pub.free_in_buffer < Cardinal(Length(dest^.DestBuffer)) then begin
5020 // write complete buffer
5021 dest^.DestStream.Write(dest^.DestBuffer[1], SizeOf(dest^.DestBuffer));
5024 dest^.pub.next_output_byte := @dest^.DestBuffer[1];
5025 dest^.pub.free_in_buffer := Length(dest^.DestBuffer);
5031 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5032 procedure glBitmap_libJPEG_term_destination(cinfo: j_compress_ptr); cdecl;
5035 dest: glBitmap_libJPEG_dest_mgr_ptr;
5037 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
5039 for Idx := Low(dest^.DestBuffer) to High(dest^.DestBuffer) do begin
5040 // check for endblock
5041 if (Idx < High(dest^.DestBuffer)) and (dest^.DestBuffer[Idx] = $FF) and (dest^.DestBuffer[Idx +1] = JPEG_EOI) then begin
5043 dest^.DestStream.Write(dest^.DestBuffer[Idx], 2);
5048 dest^.DestStream.Write(dest^.DestBuffer[Idx], 1);
5053 {$IFDEF GLB_SUPPORT_JPEG_READ}
5054 {$IF DEFINED(GLB_LAZ_JPEG)}
5055 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5056 function TglBitmapData.LoadJPEG(const aStream: TStream): Boolean;
5059 JPEG_MAGIC: String[MAGIC_LEN] = #$FF#$D8;
5061 intf: TLazIntfImage;
5062 reader: TFPReaderJPEG;
5064 magic: String[MAGIC_LEN];
5067 StreamPos := aStream.Position;
5069 SetLength(magic, MAGIC_LEN);
5070 aStream.Read(magic[1], MAGIC_LEN);
5071 aStream.Position := StreamPos;
5072 if (magic <> JPEG_MAGIC) then begin
5077 reader := TFPReaderJPEG.Create;
5078 intf := TLazIntfImage.Create(0, 0);
5080 intf.DataDescription := GetDescriptionFromDevice(0, 0, 0);
5081 reader.ImageRead(aStream, intf);
5082 AssignFromLazIntfImage(intf);
5085 aStream.Position := StreamPos;
5094 {$ELSEIF DEFINED(GLB_SDL_IMAGE)}
5095 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5096 function TglBitmapData.LoadJPEG(const aStream: TStream): Boolean;
5098 Surface: PSDL_Surface;
5103 RWops := glBitmapCreateRWops(aStream);
5105 if IMG_isJPG(RWops) > 0 then begin
5106 Surface := IMG_LoadJPG_RW(RWops);
5108 AssignFromSurface(Surface);
5111 SDL_FreeSurface(Surface);
5119 {$ELSEIF DEFINED(GLB_LIB_JPEG)}
5120 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5121 function TglBitmapData.LoadJPEG(const aStream: TStream): Boolean;
5124 Temp: array[0..1]of Byte;
5126 jpeg: jpeg_decompress_struct;
5127 jpeg_err: jpeg_error_mgr;
5129 IntFormat: TglBitmapFormat;
5131 TempHeight, TempWidth: Integer;
5136 FormatDesc: TFormatDescriptor;
5140 if not init_libJPEG then
5141 raise Exception.Create('LoadJPG - unable to initialize libJPEG.');
5144 // reading first two bytes to test file and set cursor back to begin
5145 StreamPos := aStream.Position;
5146 aStream.Read({%H-}Temp[0], 2);
5147 aStream.Position := StreamPos;
5149 // if Bitmap then read file.
5150 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
5151 FillChar(jpeg{%H-}, SizeOf(jpeg_decompress_struct), $00);
5152 FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
5155 jpeg.err := jpeg_std_error(@jpeg_err);
5156 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
5157 jpeg_err.output_message := glBitmap_libJPEG_output_message;
5159 // decompression struct
5160 jpeg_create_decompress(@jpeg);
5162 // allocation space for streaming methods
5163 jpeg.src := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_source_mgr));
5165 // seeting up custom functions
5166 with glBitmap_libJPEG_source_mgr_ptr(jpeg.src)^ do begin
5167 pub.init_source := glBitmap_libJPEG_init_source;
5168 pub.fill_input_buffer := glBitmap_libJPEG_fill_input_buffer;
5169 pub.skip_input_data := glBitmap_libJPEG_skip_input_data;
5170 pub.resync_to_restart := jpeg_resync_to_restart; // use default method
5171 pub.term_source := glBitmap_libJPEG_term_source;
5173 pub.bytes_in_buffer := 0; // forces fill_input_buffer on first read
5174 pub.next_input_byte := nil; // until buffer loaded
5176 SrcStream := aStream;
5179 // set global decoding state
5180 jpeg.global_state := DSTATE_START;
5182 // read header of jpeg
5183 jpeg_read_header(@jpeg, false);
5185 // setting output parameter
5186 case jpeg.jpeg_color_space of
5189 jpeg.out_color_space := JCS_GRAYSCALE;
5190 IntFormat := tfLuminance8ub1;
5193 jpeg.out_color_space := JCS_RGB;
5194 IntFormat := tfRGB8ub3;
5198 jpeg_start_decompress(@jpeg);
5200 TempHeight := jpeg.output_height;
5201 TempWidth := jpeg.output_width;
5203 FormatDesc := TFormatDescriptor.Get(IntFormat);
5205 // creating new image
5206 GetMem(pImage, FormatDesc.GetSize(TempWidth, TempHeight));
5210 for Row := 0 to TempHeight -1 do begin
5211 jpeg_read_scanlines(@jpeg, @pTemp, 1);
5212 Inc(pTemp, FormatDesc.GetSize(TempWidth, 1));
5215 // finish decompression
5216 jpeg_finish_decompress(@jpeg);
5218 // destroy decompression
5219 jpeg_destroy_decompress(@jpeg);
5221 SetData(pImage, IntFormat, TempWidth, TempHeight);
5225 if Assigned(pImage) then
5235 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
5236 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5237 function TglBitmapData.LoadJPEG(const aStream: TStream): Boolean;
5242 Temp: array[0..1]of Byte;
5246 // reading first two bytes to test file and set cursor back to begin
5247 StreamPos := aStream.Position;
5248 aStream.Read(Temp[0], 2);
5249 aStream.Position := StreamPos;
5251 // if Bitmap then read file.
5252 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
5253 bmp := TBitmap.Create;
5255 jpg := TJPEGImage.Create;
5257 jpg.LoadFromStream(aStream);
5259 result := AssignFromBitmap(bmp);
5271 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
5272 {$IF DEFINED(GLB_LAZ_JPEG)}
5273 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5274 procedure TglBitmapData.SaveJPEG(const aStream: TStream);
5277 intf: TLazIntfImage;
5280 jpeg := TJPEGImage.Create;
5281 intf := TLazIntfImage.Create(0, 0);
5283 if not AssignToLazIntfImage(intf) then
5284 raise EglBitmap.Create('unable to create LazIntfImage from glBitmap');
5285 intf.GetRawImage(raw);
5286 jpeg.LoadFromRawImage(raw, false);
5287 jpeg.SaveToStream(aStream);
5294 {$ELSEIF DEFINED(GLB_LIB_JPEG)}
5295 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5296 procedure TglBitmapData.SaveJPEG(const aStream: TStream);
5298 jpeg: jpeg_compress_struct;
5299 jpeg_err: jpeg_error_mgr;
5301 pTemp, pTemp2: pByte;
5303 procedure CopyRow(pDest, pSource: pByte);
5307 for X := 0 to Width - 1 do begin
5308 pByteArray(pDest)^[0] := pByteArray(pSource)^[2];
5309 pByteArray(pDest)^[1] := pByteArray(pSource)^[1];
5310 pByteArray(pDest)^[2] := pByteArray(pSource)^[0];
5317 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
5318 raise EglBitmapUnsupportedFormat.Create(Format);
5320 if not init_libJPEG then
5321 raise Exception.Create('SaveJPG - unable to initialize libJPEG.');
5324 FillChar(jpeg{%H-}, SizeOf(jpeg_compress_struct), $00);
5325 FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
5328 jpeg.err := jpeg_std_error(@jpeg_err);
5329 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
5330 jpeg_err.output_message := glBitmap_libJPEG_output_message;
5332 // compression struct
5333 jpeg_create_compress(@jpeg);
5335 // allocation space for streaming methods
5336 jpeg.dest := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_dest_mgr));
5338 // seeting up custom functions
5339 with glBitmap_libJPEG_dest_mgr_ptr(jpeg.dest)^ do begin
5340 pub.init_destination := glBitmap_libJPEG_init_destination;
5341 pub.empty_output_buffer := glBitmap_libJPEG_empty_output_buffer;
5342 pub.term_destination := glBitmap_libJPEG_term_destination;
5344 pub.next_output_byte := @DestBuffer[1];
5345 pub.free_in_buffer := Length(DestBuffer);
5347 DestStream := aStream;
5350 // very important state
5351 jpeg.global_state := CSTATE_START;
5352 jpeg.image_width := Width;
5353 jpeg.image_height := Height;
5355 tfAlpha8ub1, tfLuminance8ub1: begin
5356 jpeg.input_components := 1;
5357 jpeg.in_color_space := JCS_GRAYSCALE;
5359 tfRGB8ub3, tfBGR8ub3: begin
5360 jpeg.input_components := 3;
5361 jpeg.in_color_space := JCS_RGB;
5365 jpeg_set_defaults(@jpeg);
5366 jpeg_set_quality(@jpeg, 95, true);
5367 jpeg_start_compress(@jpeg, true);
5370 if Format = tfBGR8ub3 then
5371 GetMem(pTemp2, fRowSize)
5376 for Row := 0 to jpeg.image_height -1 do begin
5378 if Format = tfBGR8ub3 then
5379 CopyRow(pTemp2, pTemp)
5384 jpeg_write_scanlines(@jpeg, @pTemp2, 1);
5385 inc(pTemp, fRowSize);
5389 if Format = tfBGR8ub3 then
5392 jpeg_finish_compress(@jpeg);
5393 jpeg_destroy_compress(@jpeg);
5399 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
5400 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5401 procedure TglBitmapData.SaveJPEG(const aStream: TStream);
5406 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
5407 raise EglBitmapUnsupportedFormat.Create(Format);
5409 Bmp := TBitmap.Create;
5411 Jpg := TJPEGImage.Create;
5413 AssignToBitmap(Bmp);
5414 if (Format in [tfAlpha8ub1, tfLuminance8ub1]) then begin
5415 Jpg.Grayscale := true;
5416 Jpg.PixelFormat := jf8Bit;
5419 Jpg.SaveToStream(aStream);
5430 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5431 //RAW/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5432 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5434 RawHeader = packed record
5440 BitsPerPixel: Integer;
5441 Precision: TglBitmapRec4ub;
5442 Shift: TglBitmapRec4ub;
5445 function TglBitmapData.LoadRAW(const aStream: TStream): Boolean;
5449 fd: TFormatDescriptor;
5453 StartPos := aStream.Position;
5454 aStream.Read(header{%H-}, SizeOf(header));
5455 if (header.Magic <> 'glBMP') then begin
5456 aStream.Position := StartPos;
5460 fd := TFormatDescriptor.GetFromPrecShift(header.Precision, header.Shift, header.BitsPerPixel);
5461 if (fd.Format = tfEmpty) then
5462 raise EglBitmapUnsupportedFormat.Create('no supported format found');
5464 buf := GetMemory(header.DataSize);
5465 aStream.Read(buf^, header.DataSize);
5466 SetData(buf, fd.Format, header.Width, header.Height);
5471 procedure TglBitmapData.SaveRAW(const aStream: TStream);
5474 fd: TFormatDescriptor;
5476 fd := TFormatDescriptor.Get(Format);
5477 header.Magic := 'glBMP';
5478 header.Version := 1;
5479 header.Width := Width;
5480 header.Height := Height;
5481 header.DataSize := fd.GetSize(fDimension);
5482 header.BitsPerPixel := fd.BitsPerPixel;
5483 header.Precision := fd.Precision;
5484 header.Shift := fd.Shift;
5485 aStream.Write(header, SizeOf(header));
5486 aStream.Write(Data^, header.DataSize);
5489 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5490 //BMP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5491 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5498 BMP_COMP_BITFIELDS = 3;
5501 TBMPHeader = packed record
5506 bfOffBits: Cardinal;
5509 TBMPInfo = packed record
5515 biCompression: Cardinal;
5516 biSizeImage: Cardinal;
5517 biXPelsPerMeter: Longint;
5518 biYPelsPerMeter: Longint;
5519 biClrUsed: Cardinal;
5520 biClrImportant: Cardinal;
5523 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5524 function TglBitmapData.LoadBMP(const aStream: TStream): Boolean;
5526 //////////////////////////////////////////////////////////////////////////////////////////////////
5527 function ReadInfo(out aInfo: TBMPInfo; out aMask: TglBitmapRec4ul): TglBitmapFormat;
5532 aStream.Read(aInfo{%H-}, SizeOf(aInfo));
5533 FillChar(aMask{%H-}, SizeOf(aMask), 0);
5536 case aInfo.biCompression of
5538 BMP_COMP_RLE8: begin
5539 raise EglBitmap.Create('RLE compression is not supported');
5541 BMP_COMP_BITFIELDS: begin
5542 if (aInfo.biBitCount = 16) or (aInfo.biBitCount = 32) then begin
5543 for i := 0 to 2 do begin
5544 aStream.Read(tmp{%H-}, SizeOf(tmp));
5545 aMask.arr[i] := tmp;
5548 raise EglBitmap.Create('Bitfields are only supported for 16bit and 32bit formats');
5552 //get suitable format
5553 case aInfo.biBitCount of
5554 8: result := tfLuminance8ub1;
5555 16: result := tfX1RGB5us1;
5556 24: result := tfBGR8ub3;
5557 32: result := tfXRGB8ui1;
5561 function ReadColorTable(var aFormat: TglBitmapFormat; const aInfo: TBMPInfo): TbmpColorTableFormat;
5564 fd: TFormatDescriptor;
5565 ColorTable: TbmpColorTable;
5568 if (aInfo.biBitCount >= 16) then
5570 aFormat := tfLuminance8ub1;
5571 c := aInfo.biClrUsed;
5573 c := 1 shl aInfo.biBitCount;
5574 SetLength(ColorTable, c);
5575 for i := 0 to c-1 do begin
5576 aStream.Read(ColorTable[i], SizeOf(TbmpColorTableEnty));
5577 if (ColorTable[i].r <> ColorTable[i].g) or (ColorTable[i].g <> ColorTable[i].b) then
5578 aFormat := tfRGB8ub3;
5581 fd := TFormatDescriptor.Get(aFormat);
5582 result := TbmpColorTableFormat.Create;
5583 result.ColorTable := ColorTable;
5584 result.SetCustomValues(aFormat, aInfo.biBitCount, fd.Precision, fd.Shift);
5587 //////////////////////////////////////////////////////////////////////////////////////////////////
5588 function CheckBitfields(var aFormat: TglBitmapFormat; const aMask: TglBitmapRec4ul; const aInfo: TBMPInfo): TbmpBitfieldFormat;
5590 fd: TFormatDescriptor;
5593 if (aMask.r <> 0) or (aMask.g <> 0) or (aMask.b <> 0) or (aMask.a <> 0) then begin
5595 // find suitable format ...
5596 fd := TFormatDescriptor.GetFromMask(aMask);
5597 if (fd.Format <> tfEmpty) then begin
5598 aFormat := fd.Format;
5602 // or create custom bitfield format
5603 result := TbmpBitfieldFormat.Create;
5604 result.SetCustomValues(aInfo.biBitCount, aMask);
5611 ImageSize, rbLineSize, wbLineSize, Padding, i: Integer;
5612 PaddingBuff: Cardinal;
5613 LineBuf, ImageData, TmpData: PByte;
5614 SourceMD, DestMD: Pointer;
5615 BmpFormat: TglBitmapFormat;
5618 Mask: TglBitmapRec4ul;
5623 SpecialFormat: TFormatDescriptor;
5624 FormatDesc: TFormatDescriptor;
5626 //////////////////////////////////////////////////////////////////////////////////////////////////
5627 procedure SpecialFormatReadLine(aData: PByte; aLineBuf: PByte);
5630 Pixel: TglBitmapPixelData;
5632 aStream.Read(aLineBuf^, rbLineSize);
5633 SpecialFormat.PreparePixel(Pixel);
5634 for i := 0 to Info.biWidth-1 do begin
5635 SpecialFormat.Unmap(aLineBuf, Pixel, SourceMD);
5636 glBitmapConvertPixel(Pixel, SpecialFormat, FormatDesc);
5637 FormatDesc.Map(Pixel, aData, DestMD);
5643 BmpFormat := tfEmpty;
5644 SpecialFormat := nil;
5650 StartPos := aStream.Position;
5651 aStream.Read(Header{%H-}, SizeOf(Header));
5653 if Header.bfType = BMP_MAGIC then begin
5655 BmpFormat := ReadInfo(Info, Mask);
5656 SpecialFormat := ReadColorTable(BmpFormat, Info);
5657 if not Assigned(SpecialFormat) then
5658 SpecialFormat := CheckBitfields(BmpFormat, Mask, Info);
5659 aStream.Position := StartPos + Header.bfOffBits;
5661 if (BmpFormat <> tfEmpty) then begin
5662 FormatDesc := TFormatDescriptor.Get(BmpFormat);
5663 rbLineSize := Round(Info.biWidth * Info.biBitCount / 8); //ReadBuffer LineSize
5664 wbLineSize := Trunc(Info.biWidth * FormatDesc.BytesPerPixel);
5665 Padding := (((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3) - rbLineSize;
5668 DestMD := FormatDesc.CreateMappingData;
5669 ImageSize := FormatDesc.GetSize(Info.biWidth, abs(Info.biHeight));
5670 GetMem(ImageData, ImageSize);
5671 if Assigned(SpecialFormat) then begin
5672 GetMem(LineBuf, rbLineSize); //tmp Memory for converting Bitfields
5673 SourceMD := SpecialFormat.CreateMappingData;
5678 FillChar(ImageData^, ImageSize, $FF);
5679 TmpData := ImageData;
5680 if (Info.biHeight > 0) then
5681 Inc(TmpData, wbLineSize * (Info.biHeight-1));
5682 for i := 0 to Abs(Info.biHeight)-1 do begin
5683 if Assigned(SpecialFormat) then
5684 SpecialFormatReadLine(TmpData, LineBuf) //if is special format read and convert data
5686 aStream.Read(TmpData^, wbLineSize); //else only read data
5687 if (Info.biHeight > 0) then
5688 dec(TmpData, wbLineSize)
5690 inc(TmpData, wbLineSize);
5691 aStream.Read(PaddingBuff{%H-}, Padding);
5693 SetData(ImageData, BmpFormat, Info.biWidth, abs(Info.biHeight));
5696 if Assigned(LineBuf) then
5698 if Assigned(SourceMD) then
5699 SpecialFormat.FreeMappingData(SourceMD);
5700 FormatDesc.FreeMappingData(DestMD);
5703 if Assigned(ImageData) then
5708 raise EglBitmap.Create('LoadBMP - No suitable format found');
5710 aStream.Position := StartPos;
5714 FreeAndNil(SpecialFormat);
5717 else aStream.Position := StartPos;
5720 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5721 procedure TglBitmapData.SaveBMP(const aStream: TStream);
5725 Converter: TFormatDescriptor;
5726 FormatDesc: TFormatDescriptor;
5727 SourceFD, DestFD: Pointer;
5728 pData, srcData, dstData, ConvertBuffer: pByte;
5730 Pixel: TglBitmapPixelData;
5731 ImageSize, wbLineSize, rbLineSize, Padding, LineIdx, PixelIdx: Integer;
5732 RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
5734 PaddingBuff: Cardinal;
5736 function GetLineWidth : Integer;
5738 result := ((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3;
5742 if not (ftBMP in FormatGetSupportedFiles(Format)) then
5743 raise EglBitmapUnsupportedFormat.Create(Format);
5746 FormatDesc := TFormatDescriptor.Get(Format);
5747 ImageSize := FormatDesc.GetSize(Dimension);
5749 FillChar(Header{%H-}, SizeOf(Header), 0);
5750 Header.bfType := BMP_MAGIC;
5751 Header.bfSize := SizeOf(Header) + SizeOf(Info) + ImageSize;
5752 Header.bfReserved1 := 0;
5753 Header.bfReserved2 := 0;
5754 Header.bfOffBits := SizeOf(Header) + SizeOf(Info);
5756 FillChar(Info{%H-}, SizeOf(Info), 0);
5757 Info.biSize := SizeOf(Info);
5758 Info.biWidth := Width;
5759 Info.biHeight := Height;
5761 Info.biCompression := BMP_COMP_RGB;
5762 Info.biSizeImage := ImageSize;
5766 tfAlpha4ub1, tfAlpha8ub1, tfLuminance4ub1, tfLuminance8ub1, tfR3G3B2ub1:
5768 Info.biBitCount := 8;
5769 Header.bfSize := Header.bfSize + 256 * SizeOf(Cardinal);
5770 Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal); //256 ColorTable entries
5771 Converter := TbmpColorTableFormat.Create;
5772 with (Converter as TbmpColorTableFormat) do begin
5773 SetCustomValues(fFormat, 8, FormatDesc.Precision, FormatDesc.Shift);
5778 tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
5779 tfRGBX4us1, tfXRGB4us1, tfRGB5X1us1, tfX1RGB5us1, tfR5G6B5us1, tfRGB5A1us1, tfA1RGB5us1, tfRGBA4us1, tfARGB4us1,
5780 tfBGRX4us1, tfXBGR4us1, tfBGR5X1us1, tfX1BGR5us1, tfB5G6R5us1, tfBGR5A1us1, tfA1BGR5us1, tfBGRA4us1, tfABGR4us1:
5782 Info.biBitCount := 16;
5783 Info.biCompression := BMP_COMP_BITFIELDS;
5786 tfBGR8ub3, tfRGB8ub3:
5788 Info.biBitCount := 24;
5789 if (Format = tfRGB8ub3) then
5790 Converter := TfdBGR8ub3.Create; //use BGR8 Format Descriptor to Swap RGB Values
5793 tfRGBX8ui1, tfXRGB8ui1, tfRGB10X2ui1, tfX2RGB10ui1, tfRGBA8ui1, tfARGB8ui1, tfRGBA8ub4, tfRGB10A2ui1, tfA2RGB10ui1,
5794 tfBGRX8ui1, tfXBGR8ui1, tfBGR10X2ui1, tfX2BGR10ui1, tfBGRA8ui1, tfABGR8ui1, tfBGRA8ub4, tfBGR10A2ui1, tfA2BGR10ui1:
5796 Info.biBitCount := 32;
5797 Info.biCompression := BMP_COMP_BITFIELDS;
5800 raise EglBitmapUnsupportedFormat.Create(Format);
5802 Info.biXPelsPerMeter := 2835;
5803 Info.biYPelsPerMeter := 2835;
5806 if Info.biCompression = BMP_COMP_BITFIELDS then begin
5807 Header.bfSize := Header.bfSize + 4 * SizeOf(Cardinal);
5808 Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal);
5810 RedMask := FormatDesc.Mask.r;
5811 GreenMask := FormatDesc.Mask.g;
5812 BlueMask := FormatDesc.Mask.b;
5813 AlphaMask := FormatDesc.Mask.a;
5817 aStream.Write(Header, SizeOf(Header));
5818 aStream.Write(Info, SizeOf(Info));
5821 if Assigned(Converter) and (Converter is TbmpColorTableFormat) then
5822 with (Converter as TbmpColorTableFormat) do
5823 aStream.Write(ColorTable[0].b,
5824 SizeOf(TbmpColorTableEnty) * Length(ColorTable));
5827 if Info.biCompression = BMP_COMP_BITFIELDS then begin
5828 aStream.Write(RedMask, SizeOf(Cardinal));
5829 aStream.Write(GreenMask, SizeOf(Cardinal));
5830 aStream.Write(BlueMask, SizeOf(Cardinal));
5831 aStream.Write(AlphaMask, SizeOf(Cardinal));
5835 rbLineSize := Round(Info.biWidth * FormatDesc.BytesPerPixel);
5836 wbLineSize := Round(Info.biWidth * Info.biBitCount / 8);
5837 Padding := GetLineWidth - wbLineSize;
5841 inc(pData, (Height-1) * rbLineSize);
5843 // prepare row buffer. But only for RGB because RGBA supports color masks
5844 // so it's possible to change color within the image.
5845 if Assigned(Converter) then begin
5846 FormatDesc.PreparePixel(Pixel);
5847 GetMem(ConvertBuffer, wbLineSize);
5848 SourceFD := FormatDesc.CreateMappingData;
5849 DestFD := Converter.CreateMappingData;
5851 ConvertBuffer := nil;
5854 for LineIdx := 0 to Height - 1 do begin
5856 if Assigned(Converter) then begin
5858 dstData := ConvertBuffer;
5859 for PixelIdx := 0 to Info.biWidth-1 do begin
5860 FormatDesc.Unmap(srcData, Pixel, SourceFD);
5861 glBitmapConvertPixel(Pixel, FormatDesc, Converter);
5862 Converter.Map(Pixel, dstData, DestFD);
5864 aStream.Write(ConvertBuffer^, wbLineSize);
5866 aStream.Write(pData^, rbLineSize);
5868 dec(pData, rbLineSize);
5869 if (Padding > 0) then
5870 aStream.Write(PaddingBuff, Padding);
5873 // destroy row buffer
5874 if Assigned(ConvertBuffer) then begin
5875 FormatDesc.FreeMappingData(SourceFD);
5876 Converter.FreeMappingData(DestFD);
5877 FreeMem(ConvertBuffer);
5881 if Assigned(Converter) then
5886 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5887 //TGA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5888 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5890 TTGAHeader = packed record
5894 //ColorMapSpec: Array[0..4] of Byte;
5895 ColorMapStart: Word;
5896 ColorMapLength: Word;
5897 ColorMapEntrySize: Byte;
5907 TGA_UNCOMPRESSED_RGB = 2;
5908 TGA_UNCOMPRESSED_GRAY = 3;
5909 TGA_COMPRESSED_RGB = 10;
5910 TGA_COMPRESSED_GRAY = 11;
5912 TGA_NONE_COLOR_TABLE = 0;
5914 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5915 function TglBitmapData.LoadTGA(const aStream: TStream): Boolean;
5918 ImageData: System.PByte;
5919 StartPosition: Int64;
5920 PixelSize, LineSize: Integer;
5921 tgaFormat: TglBitmapFormat;
5922 FormatDesc: TFormatDescriptor;
5923 Counter: packed record
5925 low, high, dir: Integer;
5932 ////////////////////////////////////////////////////////////////////////////////////////
5933 procedure ReadUncompressed;
5936 buf, tmp1, tmp2: System.PByte;
5939 if (Counter.X.dir < 0) then
5940 GetMem(buf, LineSize);
5942 while (Counter.Y.low <> Counter.Y.high + counter.Y.dir) do begin
5944 inc(tmp1, (Counter.Y.low * LineSize)); //pointer to LineStart
5945 if (Counter.X.dir < 0) then begin //flip X
5946 aStream.Read(buf^, LineSize);
5948 inc(tmp2, LineSize - PixelSize); //pointer to last pixel in line
5949 for i := 0 to Header.Width-1 do begin //for all pixels in line
5950 for j := 0 to PixelSize-1 do begin //for all bytes in pixel
5955 dec(tmp2, 2*PixelSize); //move 2 backwards, because j-loop moved 1 forward
5958 aStream.Read(tmp1^, LineSize);
5959 inc(Counter.Y.low, Counter.Y.dir); //move to next line index
5962 if Assigned(buf) then
5967 ////////////////////////////////////////////////////////////////////////////////////////
5968 procedure ReadCompressed;
5970 /////////////////////////////////////////////////////////////////
5972 TmpData: System.PByte;
5973 LinePixelsRead: Integer;
5974 procedure CheckLine;
5976 if (LinePixelsRead >= Header.Width) then begin
5977 LinePixelsRead := 0;
5978 inc(Counter.Y.low, Counter.Y.dir); //next line index
5979 TmpData := ImageData;
5980 inc(TmpData, Counter.Y.low * LineSize); //set line
5981 if (Counter.X.dir < 0) then //if x flipped then
5982 inc(TmpData, LineSize - PixelSize); //set last pixel
5986 /////////////////////////////////////////////////////////////////
5989 CacheSize, CachePos: Integer;
5990 procedure CachedRead(out Buffer; Count: Integer);
5994 if (CachePos + Count > CacheSize) then begin
5995 //if buffer overflow save non read bytes
5997 if (CacheSize - CachePos > 0) then begin
5998 BytesRead := CacheSize - CachePos;
5999 Move(PByteArray(Cache)^[CachePos], Buffer{%H-}, BytesRead);
6000 inc(CachePos, BytesRead);
6003 //load cache from file
6004 CacheSize := Min(CACHE_SIZE, aStream.Size - aStream.Position);
6005 aStream.Read(Cache^, CacheSize);
6008 //read rest of requested bytes
6009 if (Count - BytesRead > 0) then begin
6010 Move(PByteArray(Cache)^[CachePos], TByteArray(Buffer)[BytesRead], Count - BytesRead);
6011 inc(CachePos, Count - BytesRead);
6014 //if no buffer overflow just read the data
6015 Move(PByteArray(Cache)^[CachePos], Buffer, Count);
6016 inc(CachePos, Count);
6020 procedure PixelToBuffer(const aData: PByte; var aBuffer: PByte);
6025 inc(aBuffer, Counter.X.dir);
6028 PWord(aBuffer)^ := PWord(aData)^;
6029 inc(aBuffer, 2 * Counter.X.dir);
6032 PByteArray(aBuffer)^[0] := PByteArray(aData)^[0];
6033 PByteArray(aBuffer)^[1] := PByteArray(aData)^[1];
6034 PByteArray(aBuffer)^[2] := PByteArray(aData)^[2];
6035 inc(aBuffer, 3 * Counter.X.dir);
6038 PCardinal(aBuffer)^ := PCardinal(aData)^;
6039 inc(aBuffer, 4 * Counter.X.dir);
6045 TotalPixelsToRead, TotalPixelsRead: Integer;
6047 buf: array [0..3] of Byte; //1 pixel is max 32bit long
6048 PixelRepeat: Boolean;
6049 PixelsToRead, PixelCount: Integer;
6054 TotalPixelsToRead := Header.Width * Header.Height;
6055 TotalPixelsRead := 0;
6056 LinePixelsRead := 0;
6058 GetMem(Cache, CACHE_SIZE);
6060 TmpData := ImageData;
6061 inc(TmpData, Counter.Y.low * LineSize); //set line
6062 if (Counter.X.dir < 0) then //if x flipped then
6063 inc(TmpData, LineSize - PixelSize); //set last pixel
6067 CachedRead(Temp, 1);
6068 PixelRepeat := (Temp and $80) > 0;
6069 PixelsToRead := (Temp and $7F) + 1;
6070 inc(TotalPixelsRead, PixelsToRead);
6073 CachedRead(buf[0], PixelSize);
6074 while (PixelsToRead > 0) do begin
6076 PixelCount := Min(Header.Width - LinePixelsRead, PixelsToRead); //max read to EOL or EOF
6077 while (PixelCount > 0) do begin
6078 if not PixelRepeat then
6079 CachedRead(buf[0], PixelSize);
6080 PixelToBuffer(@buf[0], TmpData);
6081 inc(LinePixelsRead);
6086 until (TotalPixelsRead >= TotalPixelsToRead);
6092 function IsGrayFormat: Boolean;
6094 result := Header.ImageType in [TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_GRAY];
6100 // reading header to test file and set cursor back to begin
6101 StartPosition := aStream.Position;
6102 aStream.Read(Header{%H-}, SizeOf(Header));
6104 // no colormapped files
6105 if (Header.ColorMapType = TGA_NONE_COLOR_TABLE) and (Header.ImageType in [
6106 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY]) then
6109 if Header.ImageID <> 0 then // skip image ID
6110 aStream.Position := aStream.Position + Header.ImageID;
6112 tgaFormat := tfEmpty;
6114 8: if IsGrayFormat then case (Header.ImageDesc and $F) of
6115 0: tgaFormat := tfLuminance8ub1;
6116 8: tgaFormat := tfAlpha8ub1;
6119 16: if IsGrayFormat then case (Header.ImageDesc and $F) of
6120 0: tgaFormat := tfLuminance16us1;
6121 8: tgaFormat := tfLuminance8Alpha8ub2;
6122 end else case (Header.ImageDesc and $F) of
6123 0: tgaFormat := tfX1RGB5us1;
6124 1: tgaFormat := tfA1RGB5us1;
6125 4: tgaFormat := tfARGB4us1;
6128 24: if not IsGrayFormat then case (Header.ImageDesc and $F) of
6129 0: tgaFormat := tfBGR8ub3;
6132 32: if IsGrayFormat then case (Header.ImageDesc and $F) of
6133 0: tgaFormat := tfDepth32ui1;
6134 end else case (Header.ImageDesc and $F) of
6135 0: tgaFormat := tfX2RGB10ui1;
6136 2: tgaFormat := tfA2RGB10ui1;
6137 8: tgaFormat := tfARGB8ui1;
6141 if (tgaFormat = tfEmpty) then
6142 raise EglBitmap.Create('LoadTga - unsupported format');
6144 FormatDesc := TFormatDescriptor.Get(tgaFormat);
6145 PixelSize := FormatDesc.GetSize(1, 1);
6146 LineSize := FormatDesc.GetSize(Header.Width, 1);
6148 GetMem(ImageData, LineSize * Header.Height);
6151 if ((Header.ImageDesc and (1 shl 4)) > 0) then begin
6152 Counter.X.low := Header.Height-1;;
6153 Counter.X.high := 0;
6154 Counter.X.dir := -1;
6157 Counter.X.high := Header.Height-1;
6162 if ((Header.ImageDesc and (1 shl 5)) > 0) then begin
6164 Counter.Y.high := Header.Height-1;
6167 Counter.Y.low := Header.Height-1;;
6168 Counter.Y.high := 0;
6169 Counter.Y.dir := -1;
6173 case Header.ImageType of
6174 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY:
6176 TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY:
6180 SetData(ImageData, tgaFormat, Header.Width, Header.Height);
6183 if Assigned(ImageData) then
6188 aStream.Position := StartPosition;
6191 else aStream.Position := StartPosition;
6194 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6195 procedure TglBitmapData.SaveTGA(const aStream: TStream);
6199 FormatDesc: TFormatDescriptor;
6201 if not (ftTGA in FormatGetSupportedFiles(Format)) then
6202 raise EglBitmapUnsupportedFormat.Create(Format);
6205 FormatDesc := TFormatDescriptor.Get(Format);
6206 FillChar(Header{%H-}, SizeOf(Header), 0);
6207 Header.ImageDesc := CountSetBits(FormatDesc.Range.a) and $F;
6208 Header.Bpp := FormatDesc.BitsPerPixel;
6209 Header.Width := Width;
6210 Header.Height := Height;
6211 Header.ImageDesc := Header.ImageDesc or $20; //flip y
6212 if FormatDesc.IsGrayscale or (not FormatDesc.IsGrayscale and not FormatDesc.HasRed and FormatDesc.HasAlpha) then
6213 Header.ImageType := TGA_UNCOMPRESSED_GRAY
6215 Header.ImageType := TGA_UNCOMPRESSED_RGB;
6216 aStream.Write(Header, SizeOf(Header));
6219 Size := FormatDesc.GetSize(Dimension);
6220 aStream.Write(Data^, Size);
6223 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6224 //DDS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6225 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6227 DDS_MAGIC: Cardinal = $20534444;
6229 // DDS_header.dwFlags
6230 DDSD_CAPS = $00000001;
6231 DDSD_HEIGHT = $00000002;
6232 DDSD_WIDTH = $00000004;
6233 DDSD_PIXELFORMAT = $00001000;
6235 // DDS_header.sPixelFormat.dwFlags
6236 DDPF_ALPHAPIXELS = $00000001;
6237 DDPF_ALPHA = $00000002;
6238 DDPF_FOURCC = $00000004;
6239 DDPF_RGB = $00000040;
6240 DDPF_LUMINANCE = $00020000;
6242 // DDS_header.sCaps.dwCaps1
6243 DDSCAPS_TEXTURE = $00001000;
6245 // DDS_header.sCaps.dwCaps2
6246 DDSCAPS2_CUBEMAP = $00000200;
6248 D3DFMT_DXT1 = $31545844;
6249 D3DFMT_DXT3 = $33545844;
6250 D3DFMT_DXT5 = $35545844;
6253 TDDSPixelFormat = packed record
6257 dwRGBBitCount: Cardinal;
6258 dwRBitMask: Cardinal;
6259 dwGBitMask: Cardinal;
6260 dwBBitMask: Cardinal;
6261 dwABitMask: Cardinal;
6264 TDDSCaps = packed record
6268 dwReserved: Cardinal;
6271 TDDSHeader = packed record
6276 dwPitchOrLinearSize: Cardinal;
6278 dwMipMapCount: Cardinal;
6279 dwReserved: array[0..10] of Cardinal;
6280 PixelFormat: TDDSPixelFormat;
6282 dwReserved2: Cardinal;
6285 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6286 function TglBitmapData.LoadDDS(const aStream: TStream): Boolean;
6289 Converter: TbmpBitfieldFormat;
6291 function GetDDSFormat: TglBitmapFormat;
6293 fd: TFormatDescriptor;
6295 Mask: TglBitmapRec4ul;
6296 Range: TglBitmapRec4ui;
6300 with Header.PixelFormat do begin
6302 if ((dwFlags and DDPF_FOURCC) > 0) then begin
6303 case Header.PixelFormat.dwFourCC of
6304 D3DFMT_DXT1: result := tfS3tcDtx1RGBA;
6305 D3DFMT_DXT3: result := tfS3tcDtx3RGBA;
6306 D3DFMT_DXT5: result := tfS3tcDtx5RGBA;
6308 end else if ((dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE or DDPF_ALPHA)) > 0) then begin
6310 if ((dwFlags and DDPF_LUMINANCE) = 0) then begin
6311 Mask.r := dwRBitMask;
6312 Mask.g := dwGBitMask;
6313 Mask.b := dwBBitMask;
6315 Mask.r := dwRBitMask;
6316 Mask.g := dwRBitMask;
6317 Mask.b := dwRBitMask;
6319 if (dwFlags and DDPF_ALPHAPIXELS > 0) then
6320 Mask.a := dwABitMask
6324 //find matching format
6325 fd := TFormatDescriptor.GetFromMask(Mask, dwRGBBitCount);
6326 result := fd.Format;
6327 if (result <> tfEmpty) then
6330 //find format with same Range
6332 Range.arr[i] := (2 shl CountSetBits(Mask.arr[i])) - 1;
6333 for result := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
6334 fd := TFormatDescriptor.Get(result);
6337 if (fd.Range.arr[i] <> Range.arr[i]) then begin
6345 //no format with same range found -> use default
6346 if (result = tfEmpty) then begin
6347 if (dwABitMask > 0) then
6348 result := tfRGBA8ui1
6350 result := tfRGB8ub3;
6353 Converter := TbmpBitfieldFormat.Create;
6354 Converter.SetCustomValues(dwRGBBitCount, glBitmapRec4ul(dwRBitMask, dwGBitMask, dwBBitMask, dwABitMask));
6361 x, y, LineSize, RowSize, Magic: Cardinal;
6362 NewImage, TmpData, RowData, SrcData: System.PByte;
6363 SourceMD, DestMD: Pointer;
6364 Pixel: TglBitmapPixelData;
6365 ddsFormat: TglBitmapFormat;
6366 FormatDesc: TFormatDescriptor;
6371 StreamPos := aStream.Position;
6374 aStream.Read(Magic{%H-}, sizeof(Magic));
6375 if (Magic <> DDS_MAGIC) then begin
6376 aStream.Position := StreamPos;
6381 aStream.Read(Header{%H-}, sizeof(Header));
6382 if (Header.dwSize <> SizeOf(Header)) or
6383 ((Header.dwFlags and (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) <>
6384 (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) then
6386 aStream.Position := StreamPos;
6390 if ((Header.Caps.dwCaps1 and DDSCAPS2_CUBEMAP) > 0) then
6391 raise EglBitmap.Create('LoadDDS - CubeMaps are not supported');
6393 ddsFormat := GetDDSFormat;
6395 if (ddsFormat = tfEmpty) then
6396 raise EglBitmap.Create('LoadDDS - unsupported Pixelformat found.');
6398 FormatDesc := TFormatDescriptor.Get(ddsFormat);
6399 LineSize := Trunc(Header.dwWidth * FormatDesc.BytesPerPixel);
6400 GetMem(NewImage, Header.dwHeight * LineSize);
6402 TmpData := NewImage;
6405 if Assigned(Converter) then begin
6406 RowSize := Round(Header.dwWidth * Header.PixelFormat.dwRGBBitCount / 8);
6407 GetMem(RowData, RowSize);
6408 SourceMD := Converter.CreateMappingData;
6409 DestMD := FormatDesc.CreateMappingData;
6411 for y := 0 to Header.dwHeight-1 do begin
6412 TmpData := NewImage;
6413 inc(TmpData, y * LineSize);
6415 aStream.Read(SrcData^, RowSize);
6416 for x := 0 to Header.dwWidth-1 do begin
6417 Converter.Unmap(SrcData, Pixel, SourceMD);
6418 glBitmapConvertPixel(Pixel, Converter, FormatDesc);
6419 FormatDesc.Map(Pixel, TmpData, DestMD);
6423 Converter.FreeMappingData(SourceMD);
6424 FormatDesc.FreeMappingData(DestMD);
6430 if ((Header.PixelFormat.dwFlags and DDPF_FOURCC) > 0) then begin
6431 RowSize := Header.dwPitchOrLinearSize div Header.dwWidth;
6432 for Y := 0 to Header.dwHeight-1 do begin
6433 aStream.Read(TmpData^, RowSize);
6434 Inc(TmpData, LineSize);
6439 if (Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE)) > 0 then begin
6440 RowSize := (Header.PixelFormat.dwRGBBitCount * Header.dwWidth) shr 3;
6441 for Y := 0 to Header.dwHeight-1 do begin
6442 aStream.Read(TmpData^, RowSize);
6443 Inc(TmpData, LineSize);
6446 raise EglBitmap.Create('LoadDDS - unsupported Pixelformat found.');
6448 SetData(NewImage, ddsFormat, Header.dwWidth, Header.dwHeight);
6451 if Assigned(NewImage) then
6456 FreeAndNil(Converter);
6460 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6461 procedure TglBitmapData.SaveDDS(const aStream: TStream);
6464 FormatDesc: TFormatDescriptor;
6466 if not (ftDDS in FormatGetSupportedFiles(Format)) then
6467 raise EglBitmapUnsupportedFormat.Create(Format);
6469 FormatDesc := TFormatDescriptor.Get(Format);
6472 FillChar(Header{%H-}, SizeOf(Header), 0);
6473 Header.dwSize := SizeOf(Header);
6474 Header.dwFlags := DDSD_WIDTH or DDSD_HEIGHT or DDSD_CAPS or DDSD_PIXELFORMAT;
6476 Header.dwWidth := Max(1, Width);
6477 Header.dwHeight := Max(1, Height);
6480 Header.Caps.dwCaps1 := DDSCAPS_TEXTURE;
6483 Header.PixelFormat.dwSize := sizeof(Header);
6484 if (FormatDesc.IsCompressed) then begin
6485 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_FOURCC;
6487 tfS3tcDtx1RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT1;
6488 tfS3tcDtx3RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT3;
6489 tfS3tcDtx5RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT5;
6491 end else if not FormatDesc.HasColor and FormatDesc.HasAlpha then begin
6492 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHA;
6493 Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
6494 Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
6495 end else if FormatDesc.IsGrayscale then begin
6496 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_LUMINANCE;
6497 Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
6498 Header.PixelFormat.dwRBitMask := FormatDesc.Mask.r;
6499 Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
6501 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_RGB;
6502 Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
6503 Header.PixelFormat.dwRBitMask := FormatDesc.Mask.r;
6504 Header.PixelFormat.dwGBitMask := FormatDesc.Mask.g;
6505 Header.PixelFormat.dwBBitMask := FormatDesc.Mask.b;
6506 Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
6509 if (FormatDesc.HasAlpha) then
6510 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHAPIXELS;
6512 aStream.Write(DDS_MAGIC, sizeof(DDS_MAGIC));
6513 aStream.Write(Header, SizeOf(Header));
6514 aStream.Write(Data^, FormatDesc.GetSize(Dimension));
6517 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6518 function TglBitmapData.FlipHorz: Boolean;
6520 fd: TglBitmapFormatDescriptor;
6521 Col, RowSize, PixelSize: Integer;
6522 pTempDest, pDest, pSource: PByte;
6525 fd := FormatDescriptor;
6526 PixelSize := Ceil(fd.BytesPerPixel);
6527 RowSize := fd.GetSize(Width, 1);
6528 if Assigned(Data) and not fd.IsCompressed then begin
6530 GetMem(pDest, RowSize);
6533 Inc(pTempDest, RowSize);
6534 for Col := 0 to Width-1 do begin
6535 dec(pTempDest, PixelSize); //dec before, because ptr is behind last byte of data
6536 Move(pSource^, pTempDest^, PixelSize);
6537 Inc(pSource, PixelSize);
6539 SetData(pDest, Format, Width);
6542 if Assigned(pDest) then
6549 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6550 function TglBitmapData.FlipVert: Boolean;
6552 fd: TglBitmapFormatDescriptor;
6553 Row, RowSize, PixelSize: Integer;
6554 TempDestData, DestData, SourceData: PByte;
6557 fd := FormatDescriptor;
6558 PixelSize := Ceil(fd.BytesPerPixel);
6559 RowSize := fd.GetSize(Width, 1);
6560 if Assigned(Data) then begin
6562 GetMem(DestData, Height * RowSize);
6564 TempDestData := DestData;
6565 Inc(TempDestData, Width * (Height -1) * PixelSize);
6566 for Row := 0 to Height -1 do begin
6567 Move(SourceData^, TempDestData^, RowSize);
6568 Dec(TempDestData, RowSize);
6569 Inc(SourceData, RowSize);
6571 SetData(DestData, Format, Width, Height);
6574 if Assigned(DestData) then
6581 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6582 procedure TglBitmapData.LoadFromFile(const aFilename: String);
6586 if not FileExists(aFilename) then
6587 raise EglBitmap.Create('file does not exist: ' + aFilename);
6588 fs := TFileStream.Create(aFilename, fmOpenRead);
6592 fFilename := aFilename;
6598 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6599 procedure TglBitmapData.LoadFromStream(const aStream: TStream);
6601 {$IFDEF GLB_SUPPORT_PNG_READ}
6602 if not LoadPNG(aStream) then
6604 {$IFDEF GLB_SUPPORT_JPEG_READ}
6605 if not LoadJPEG(aStream) then
6607 if not LoadDDS(aStream) then
6608 if not LoadTGA(aStream) then
6609 if not LoadBMP(aStream) then
6610 if not LoadRAW(aStream) then
6611 raise EglBitmap.Create('LoadFromStream - Couldn''t load Stream. It''s possible to be an unknow Streamtype.');
6614 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6615 procedure TglBitmapData.LoadFromFunc(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat;
6616 const aFunc: TglBitmapFunction; const aArgs: Pointer);
6621 size := TFormatDescriptor.Get(aFormat).GetSize(aSize);
6622 GetMem(tmpData, size);
6624 FillChar(tmpData^, size, #$FF);
6625 SetData(tmpData, aFormat, aSize.X, aSize.Y);
6627 if Assigned(tmpData) then
6631 Convert(Self, aFunc, false, aFormat, aArgs);
6634 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6635 procedure TglBitmapData.LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar);
6637 rs: TResourceStream;
6639 PrepareResType(aResource, aResType);
6640 rs := TResourceStream.Create(aInstance, aResource, aResType);
6648 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6649 procedure TglBitmapData.LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
6651 rs: TResourceStream;
6653 rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
6661 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6662 procedure TglBitmapData.SaveToFile(const aFilename: String; const aFileType: TglBitmapFileType);
6666 fs := TFileStream.Create(aFileName, fmCreate);
6669 SaveToStream(fs, aFileType);
6675 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6676 procedure TglBitmapData.SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType);
6679 {$IFDEF GLB_SUPPORT_PNG_WRITE}
6680 ftPNG: SavePNG(aStream);
6682 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
6683 ftJPEG: SaveJPEG(aStream);
6685 ftDDS: SaveDDS(aStream);
6686 ftTGA: SaveTGA(aStream);
6687 ftBMP: SaveBMP(aStream);
6688 ftRAW: SaveRAW(aStream);
6692 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6693 function TglBitmapData.Convert(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer): Boolean;
6695 result := Convert(Self, aFunc, aCreateTemp, Format, aArgs);
6698 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6699 function TglBitmapData.Convert(const aSource: TglBitmapData; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
6700 const aFormat: TglBitmapFormat; const aArgs: Pointer): Boolean;
6702 DestData, TmpData, SourceData: pByte;
6703 TempHeight, TempWidth: Integer;
6704 SourceFD, DestFD: TFormatDescriptor;
6705 SourceMD, DestMD: Pointer;
6707 FuncRec: TglBitmapFunctionRec;
6709 Assert(Assigned(Data));
6710 Assert(Assigned(aSource));
6711 Assert(Assigned(aSource.Data));
6714 if Assigned(aSource.Data) and ((aSource.Height > 0) or (aSource.Width > 0)) then begin
6715 SourceFD := TFormatDescriptor.Get(aSource.Format);
6716 DestFD := TFormatDescriptor.Get(aFormat);
6718 if (SourceFD.IsCompressed) then
6719 raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', SourceFD.Format);
6720 if (DestFD.IsCompressed) then
6721 raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', DestFD.Format);
6723 // inkompatible Formats so CreateTemp
6724 if (SourceFD.BitsPerPixel <> DestFD.BitsPerPixel) then
6725 aCreateTemp := true;
6728 TempHeight := Max(1, aSource.Height);
6729 TempWidth := Max(1, aSource.Width);
6731 FuncRec.Sender := Self;
6732 FuncRec.Args := aArgs;
6735 if aCreateTemp then begin
6736 GetMem(TmpData, DestFD.GetSize(TempWidth, TempHeight));
6737 DestData := TmpData;
6742 SourceFD.PreparePixel(FuncRec.Source);
6743 DestFD.PreparePixel (FuncRec.Dest);
6745 SourceMD := SourceFD.CreateMappingData;
6746 DestMD := DestFD.CreateMappingData;
6748 FuncRec.Size := aSource.Dimension;
6749 FuncRec.Position.Fields := FuncRec.Size.Fields;
6752 SourceData := aSource.Data;
6753 FuncRec.Position.Y := 0;
6754 while FuncRec.Position.Y < TempHeight do begin
6755 FuncRec.Position.X := 0;
6756 while FuncRec.Position.X < TempWidth do begin
6757 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
6759 DestFD.Map(FuncRec.Dest, DestData, DestMD);
6760 inc(FuncRec.Position.X);
6762 inc(FuncRec.Position.Y);
6765 // Updating Image or InternalFormat
6767 SetData(TmpData, aFormat, aSource.Width, aSource.Height)
6768 else if (aFormat <> fFormat) then
6773 SourceFD.FreeMappingData(SourceMD);
6774 DestFD.FreeMappingData(DestMD);
6777 if aCreateTemp and Assigned(TmpData) then
6784 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6785 function TglBitmapData.ConvertTo(const aFormat: TglBitmapFormat): Boolean;
6787 SourceFD, DestFD: TFormatDescriptor;
6788 SourcePD, DestPD: TglBitmapPixelData;
6789 ShiftData: TShiftData;
6791 function DataIsIdentical: Boolean;
6793 result := SourceFD.MaskMatch(DestFD.Mask);
6796 function CanCopyDirect: Boolean;
6799 ((SourcePD.Range.r = DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
6800 ((SourcePD.Range.g = DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
6801 ((SourcePD.Range.b = DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
6802 ((SourcePD.Range.a = DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
6805 function CanShift: Boolean;
6808 ((SourcePD.Range.r >= DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
6809 ((SourcePD.Range.g >= DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
6810 ((SourcePD.Range.b >= DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
6811 ((SourcePD.Range.a >= DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
6814 function GetShift(aSource, aDest: Cardinal) : ShortInt;
6817 while (aSource > aDest) and (aSource > 0) do begin
6819 aSource := aSource shr 1;
6824 if (aFormat <> fFormat) and (aFormat <> tfEmpty) then begin
6825 SourceFD := TFormatDescriptor.Get(Format);
6826 DestFD := TFormatDescriptor.Get(aFormat);
6828 if DataIsIdentical then begin
6834 SourceFD.PreparePixel(SourcePD);
6835 DestFD.PreparePixel (DestPD);
6837 if CanCopyDirect then
6838 result := Convert(Self, glBitmapConvertCopyFunc, false, aFormat)
6839 else if CanShift then begin
6840 ShiftData.r := GetShift(SourcePD.Range.r, DestPD.Range.r);
6841 ShiftData.g := GetShift(SourcePD.Range.g, DestPD.Range.g);
6842 ShiftData.b := GetShift(SourcePD.Range.b, DestPD.Range.b);
6843 ShiftData.a := GetShift(SourcePD.Range.a, DestPD.Range.a);
6844 result := Convert(Self, glBitmapConvertShiftRGBAFunc, false, aFormat, @ShiftData);
6846 result := Convert(Self, glBitmapConvertCalculateRGBAFunc, false, aFormat);
6852 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6853 function TglBitmapData.AssignToSurface(out aSurface: PSDL_Surface): Boolean;
6855 Row, RowSize: Integer;
6856 SourceData, TmpData: PByte;
6858 FormatDesc: TFormatDescriptor;
6860 function GetRowPointer(Row: Integer): pByte;
6862 result := aSurface.pixels;
6863 Inc(result, Row * RowSize);
6869 FormatDesc := TFormatDescriptor.Get(Format);
6870 if FormatDesc.IsCompressed then
6871 raise EglBitmapUnsupportedFormat.Create(Format);
6873 if Assigned(Data) then begin
6874 case Trunc(FormatDesc.PixelSize) of
6880 raise EglBitmapUnsupportedFormat.Create(Format);
6883 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, TempDepth,
6884 FormatDesc.RedMask, FormatDesc.GreenMask, FormatDesc.BlueMask, FormatDesc.AlphaMask);
6886 RowSize := FormatDesc.GetSize(FileWidth, 1);
6888 for Row := 0 to FileHeight-1 do begin
6889 TmpData := GetRowPointer(Row);
6890 if Assigned(TmpData) then begin
6891 Move(SourceData^, TmpData^, RowSize);
6892 inc(SourceData, RowSize);
6899 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6900 function TglBitmapData.AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
6902 pSource, pData, pTempData: PByte;
6903 Row, RowSize, TempWidth, TempHeight: Integer;
6904 IntFormat: TglBitmapFormat;
6905 fd: TFormatDescriptor;
6906 Mask: TglBitmapMask;
6908 function GetRowPointer(Row: Integer): pByte;
6910 result := aSurface^.pixels;
6911 Inc(result, Row * RowSize);
6916 if (Assigned(aSurface)) then begin
6917 with aSurface^.format^ do begin
6922 IntFormat := TFormatDescriptor.GetFromMask(Mask).Format;
6923 if (IntFormat = tfEmpty) then
6924 raise EglBitmap.Create('AssignFromSurface - Invalid Pixelformat.');
6927 fd := TFormatDescriptor.Get(IntFormat);
6928 TempWidth := aSurface^.w;
6929 TempHeight := aSurface^.h;
6930 RowSize := fd.GetSize(TempWidth, 1);
6931 GetMem(pData, TempHeight * RowSize);
6934 for Row := 0 to TempHeight -1 do begin
6935 pSource := GetRowPointer(Row);
6936 if (Assigned(pSource)) then begin
6937 Move(pSource^, pTempData^, RowSize);
6938 Inc(pTempData, RowSize);
6941 SetData(pData, IntFormat, TempWidth, TempHeight);
6944 if Assigned(pData) then
6951 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6952 function TglBitmapData.AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
6954 Row, Col, AlphaInterleave: Integer;
6955 pSource, pDest: PByte;
6957 function GetRowPointer(Row: Integer): pByte;
6959 result := aSurface.pixels;
6960 Inc(result, Row * Width);
6965 if Assigned(Data) then begin
6966 if Format in [tfAlpha8ub1, tfLuminance8Alpha8ub2, tfBGRA8ub4, tfRGBA8ub4] then begin
6967 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, 8, $FF, $FF, $FF, 0);
6969 AlphaInterleave := 0;
6971 tfLuminance8Alpha8ub2:
6972 AlphaInterleave := 1;
6973 tfBGRA8ub4, tfRGBA8ub4:
6974 AlphaInterleave := 3;
6978 for Row := 0 to Height -1 do begin
6979 pDest := GetRowPointer(Row);
6980 if Assigned(pDest) then begin
6981 for Col := 0 to Width -1 do begin
6982 Inc(pSource, AlphaInterleave);
6994 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6995 function TglBitmapData.AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
6999 bmp := TglBitmap2D.Create;
7001 bmp.AssignFromSurface(aSurface);
7002 result := AddAlphaFromGlBitmap(bmp, aFunc, aArgs);
7010 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7011 function CreateGrayPalette: HPALETTE;
7016 GetMem(Pal, SizeOf(TLogPalette) + (SizeOf(TPaletteEntry) * 256));
7018 Pal.palVersion := $300;
7019 Pal.palNumEntries := 256;
7021 for Idx := 0 to Pal.palNumEntries - 1 do begin
7022 Pal.palPalEntry[Idx].peRed := Idx;
7023 Pal.palPalEntry[Idx].peGreen := Idx;
7024 Pal.palPalEntry[Idx].peBlue := Idx;
7025 Pal.palPalEntry[Idx].peFlags := 0;
7027 Result := CreatePalette(Pal^);
7031 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7032 function TglBitmapData.AssignToBitmap(const aBitmap: TBitmap): Boolean;
7034 Row, RowSize: Integer;
7035 pSource, pData: PByte;
7038 if Assigned(Data) then begin
7039 if Assigned(aBitmap) then begin
7040 aBitmap.Width := Width;
7041 aBitmap.Height := Height;
7044 tfAlpha8ub1, tfLuminance8ub1: begin
7045 aBitmap.PixelFormat := pf8bit;
7046 aBitmap.Palette := CreateGrayPalette;
7049 aBitmap.PixelFormat := pf15bit;
7051 aBitmap.PixelFormat := pf16bit;
7052 tfRGB8ub3, tfBGR8ub3:
7053 aBitmap.PixelFormat := pf24bit;
7054 tfRGBA8ub4, tfBGRA8ub4:
7055 aBitmap.PixelFormat := pf32bit;
7057 raise EglBitmap.Create('AssignToBitmap - Invalid Pixelformat.');
7060 RowSize := FormatDescriptor.GetSize(Width, 1);
7062 for Row := 0 to Height-1 do begin
7063 pData := aBitmap.Scanline[Row];
7064 Move(pSource^, pData^, RowSize);
7065 Inc(pSource, RowSize);
7066 if (Format in [tfRGB8ub3, tfRGBA8ub4]) then // swap RGB(A) to BGR(A)
7067 SwapRGB(pData, Width, Format = tfRGBA8ub4);
7074 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7075 function TglBitmapData.AssignFromBitmap(const aBitmap: TBitmap): Boolean;
7077 pSource, pData, pTempData: PByte;
7078 Row, RowSize, TempWidth, TempHeight: Integer;
7079 IntFormat: TglBitmapFormat;
7083 if (Assigned(aBitmap)) then begin
7084 case aBitmap.PixelFormat of
7086 IntFormat := tfLuminance8ub1;
7088 IntFormat := tfRGB5A1us1;
7090 IntFormat := tfR5G6B5us1;
7092 IntFormat := tfBGR8ub3;
7094 IntFormat := tfBGRA8ub4;
7096 raise EglBitmap.Create('AssignFromBitmap - Invalid Pixelformat.');
7099 TempWidth := aBitmap.Width;
7100 TempHeight := aBitmap.Height;
7101 RowSize := TFormatDescriptor.Get(IntFormat).GetSize(TempWidth, 1);
7102 GetMem(pData, TempHeight * RowSize);
7105 for Row := 0 to TempHeight -1 do begin
7106 pSource := aBitmap.Scanline[Row];
7107 if (Assigned(pSource)) then begin
7108 Move(pSource^, pTempData^, RowSize);
7109 Inc(pTempData, RowSize);
7112 SetData(pData, IntFormat, TempWidth, TempHeight);
7115 if Assigned(pData) then
7122 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7123 function TglBitmapData.AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
7125 Row, Col, AlphaInterleave: Integer;
7126 pSource, pDest: PByte;
7130 if Assigned(Data) then begin
7131 if (Format in [tfAlpha8ub1, tfLuminance8Alpha8ub2, tfRGBA8ub4, tfBGRA8ub4]) then begin
7132 if Assigned(aBitmap) then begin
7133 aBitmap.PixelFormat := pf8bit;
7134 aBitmap.Palette := CreateGrayPalette;
7135 aBitmap.Width := Width;
7136 aBitmap.Height := Height;
7139 tfLuminance8Alpha8ub2:
7140 AlphaInterleave := 1;
7141 tfRGBA8ub4, tfBGRA8ub4:
7142 AlphaInterleave := 3;
7144 AlphaInterleave := 0;
7150 for Row := 0 to Height -1 do begin
7151 pDest := aBitmap.Scanline[Row];
7152 if Assigned(pDest) then begin
7153 for Col := 0 to Width -1 do begin
7154 Inc(pSource, AlphaInterleave);
7167 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7168 function TglBitmapData.AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
7170 data: TglBitmapData;
7172 data := TglBitmapData.Create;
7174 data.AssignFromBitmap(aBitmap);
7175 result := AddAlphaFromDataObj(data, aFunc, aArgs);
7182 {$IFDEF GLB_LAZARUS}
7183 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7184 function TglBitmapData.AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
7186 rid: TRawImageDescription;
7187 FormatDesc: TFormatDescriptor;
7189 if not Assigned(Data) then
7190 raise EglBitmap.Create('no pixel data assigned. load data before save');
7193 if not Assigned(aImage) or (Format = tfEmpty) then
7195 FormatDesc := TFormatDescriptor.Get(Format);
7196 if FormatDesc.IsCompressed then
7199 FillChar(rid{%H-}, SizeOf(rid), 0);
7200 if FormatDesc.IsGrayscale then
7201 rid.Format := ricfGray
7203 rid.Format := ricfRGBA;
7206 rid.Height := Height;
7207 rid.Depth := FormatDesc.BitsPerPixel;
7208 rid.BitOrder := riboBitsInOrder;
7209 rid.ByteOrder := riboLSBFirst;
7210 rid.LineOrder := riloTopToBottom;
7211 rid.LineEnd := rileTight;
7212 rid.BitsPerPixel := FormatDesc.BitsPerPixel;
7213 rid.RedPrec := CountSetBits(FormatDesc.Range.r);
7214 rid.GreenPrec := CountSetBits(FormatDesc.Range.g);
7215 rid.BluePrec := CountSetBits(FormatDesc.Range.b);
7216 rid.AlphaPrec := CountSetBits(FormatDesc.Range.a);
7217 rid.RedShift := FormatDesc.Shift.r;
7218 rid.GreenShift := FormatDesc.Shift.g;
7219 rid.BlueShift := FormatDesc.Shift.b;
7220 rid.AlphaShift := FormatDesc.Shift.a;
7222 rid.MaskBitsPerPixel := 0;
7223 rid.PaletteColorCount := 0;
7225 aImage.DataDescription := rid;
7228 if not Assigned(aImage.PixelData) then
7229 raise EglBitmap.Create('error while creating LazIntfImage');
7230 Move(Data^, aImage.PixelData^, FormatDesc.GetSize(Dimension));
7235 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7236 function TglBitmapData.AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
7239 FormatDesc: TFormatDescriptor;
7243 Mask: TglBitmapRec4ul;
7245 procedure CopyConvert;
7247 bfFormat: TbmpBitfieldFormat;
7248 pSourceLine, pDestLine: PByte;
7249 pSourceMD, pDestMD: Pointer;
7250 Shift, Prec: TglBitmapRec4ub;
7252 pixel: TglBitmapPixelData;
7254 bfFormat := TbmpBitfieldFormat.Create;
7255 with aImage.DataDescription do begin
7257 Prec.g := GreenPrec;
7259 Prec.a := AlphaPrec;
7260 Shift.r := RedShift;
7261 Shift.g := GreenShift;
7262 Shift.b := BlueShift;
7263 Shift.a := AlphaShift;
7264 bfFormat.SetCustomValues(BitsPerPixel, Prec, Shift);
7266 pSourceMD := bfFormat.CreateMappingData;
7267 pDestMD := FormatDesc.CreateMappingData;
7269 for y := 0 to aImage.Height-1 do begin
7270 pSourceLine := aImage.PixelData + y {%H-}* aImage.DataDescription.BytesPerLine;
7271 pDestLine := ImageData + y * Round(FormatDesc.BytesPerPixel * aImage.Width);
7272 for x := 0 to aImage.Width-1 do begin
7273 bfFormat.Unmap(pSourceLine, pixel, pSourceMD);
7274 FormatDesc.Map(pixel, pDestLine, pDestMD);
7278 FormatDesc.FreeMappingData(pDestMD);
7279 bfFormat.FreeMappingData(pSourceMD);
7286 if not Assigned(aImage) then
7289 with aImage.DataDescription do begin
7290 Mask.r := (QWord(1 shl RedPrec )-1) shl RedShift;
7291 Mask.g := (QWord(1 shl GreenPrec)-1) shl GreenShift;
7292 Mask.b := (QWord(1 shl BluePrec )-1) shl BlueShift;
7293 Mask.a := (QWord(1 shl AlphaPrec)-1) shl AlphaShift;
7295 FormatDesc := TFormatDescriptor.GetFromMask(Mask);
7296 f := FormatDesc.Format;
7297 if (f = tfEmpty) then
7301 (FormatDesc.BitsPerPixel = aImage.DataDescription.Depth) and
7302 (aImage.DataDescription.BitsPerPixel = aImage.DataDescription.Depth);
7304 ImageSize := FormatDesc.GetSize(aImage.Width, aImage.Height);
7305 ImageData := GetMem(ImageSize);
7308 Move(aImage.PixelData^, ImageData^, ImageSize)
7311 SetData(ImageData, f, aImage.Width, aImage.Height);
7313 if Assigned(ImageData) then
7321 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7322 function TglBitmapData.AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
7324 rid: TRawImageDescription;
7325 FormatDesc: TFormatDescriptor;
7326 Pixel: TglBitmapPixelData;
7332 if not Assigned(aImage) or (Format = tfEmpty) then
7334 FormatDesc := TFormatDescriptor.Get(Format);
7335 if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
7338 FillChar(rid{%H-}, SizeOf(rid), 0);
7339 rid.Format := ricfGray;
7341 rid.Height := Height;
7342 rid.Depth := CountSetBits(FormatDesc.Range.a);
7343 rid.BitOrder := riboBitsInOrder;
7344 rid.ByteOrder := riboLSBFirst;
7345 rid.LineOrder := riloTopToBottom;
7346 rid.LineEnd := rileTight;
7347 rid.BitsPerPixel := 8 * Ceil(rid.Depth / 8);
7348 rid.RedPrec := CountSetBits(FormatDesc.Range.a);
7353 rid.GreenShift := 0;
7355 rid.AlphaShift := 0;
7357 rid.MaskBitsPerPixel := 0;
7358 rid.PaletteColorCount := 0;
7360 aImage.DataDescription := rid;
7363 srcMD := FormatDesc.CreateMappingData;
7365 FormatDesc.PreparePixel(Pixel);
7367 dst := aImage.PixelData;
7368 for y := 0 to Height-1 do
7369 for x := 0 to Width-1 do begin
7370 FormatDesc.Unmap(src, Pixel, srcMD);
7371 case rid.BitsPerPixel of
7373 dst^ := Pixel.Data.a;
7377 PWord(dst)^ := Pixel.Data.a;
7381 PByteArray(dst)^[0] := PByteArray(@Pixel.Data.a)^[0];
7382 PByteArray(dst)^[1] := PByteArray(@Pixel.Data.a)^[1];
7383 PByteArray(dst)^[2] := PByteArray(@Pixel.Data.a)^[2];
7387 PCardinal(dst)^ := Pixel.Data.a;
7391 raise EglBitmapUnsupportedFormat.Create(Format);
7395 FormatDesc.FreeMappingData(srcMD);
7400 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7401 function TglBitmapData.AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
7403 data: TglBitmapData;
7405 data := TglBitmapData.Create;
7407 data.AssignFromLazIntfImage(aImage);
7408 result := AddAlphaFromDataObj(data, aFunc, aArgs);
7415 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7416 function TglBitmapData.AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar;
7417 const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
7419 rs: TResourceStream;
7421 PrepareResType(aResource, aResType);
7422 rs := TResourceStream.Create(aInstance, aResource, aResType);
7424 result := AddAlphaFromStream(rs, aFunc, aArgs);
7430 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7431 function TglBitmapData.AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
7432 const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
7434 rs: TResourceStream;
7436 rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
7438 result := AddAlphaFromStream(rs, aFunc, aArgs);
7444 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7445 function TglBitmapData.AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
7447 if TFormatDescriptor.Get(Format).IsCompressed then
7448 raise EglBitmapUnsupportedFormat.Create(Format);
7449 result := Convert(Self, aFunc, false, TFormatDescriptor.Get(Format).WithAlpha, aArgs);
7452 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7453 function TglBitmapData.AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
7457 FS := TFileStream.Create(aFileName, fmOpenRead);
7459 result := AddAlphaFromStream(FS, aFunc, aArgs);
7465 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7466 function TglBitmapData.AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
7468 data: TglBitmapData;
7470 data := TglBitmapData.Create(aStream);
7472 result := AddAlphaFromDataObj(data, aFunc, aArgs);
7478 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7479 function TglBitmapData.AddAlphaFromDataObj(const aDataObj: TglBitmapData; aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
7481 DestData, DestData2, SourceData: pByte;
7482 TempHeight, TempWidth: Integer;
7483 SourceFD, DestFD: TFormatDescriptor;
7484 SourceMD, DestMD, DestMD2: Pointer;
7486 FuncRec: TglBitmapFunctionRec;
7490 Assert(Assigned(Data));
7491 Assert(Assigned(aDataObj));
7492 Assert(Assigned(aDataObj.Data));
7494 if ((aDataObj.Width = Width) and (aDataObj.Height = Height)) then begin
7495 result := ConvertTo(TFormatDescriptor.Get(Format).WithAlpha);
7497 SourceFD := TFormatDescriptor.Get(aDataObj.Format);
7498 DestFD := TFormatDescriptor.Get(Format);
7500 if not Assigned(aFunc) then begin
7501 aFunc := glBitmapAlphaFunc;
7502 FuncRec.Args := {%H-}Pointer(SourceFD.HasAlpha);
7504 FuncRec.Args := aArgs;
7507 TempWidth := aDataObj.Width;
7508 TempHeight := aDataObj.Height;
7509 if (TempWidth <= 0) or (TempHeight <= 0) then
7512 FuncRec.Sender := Self;
7513 FuncRec.Size := Dimension;
7514 FuncRec.Position.Fields := FuncRec.Size.Fields;
7518 SourceData := aDataObj.Data;
7521 SourceFD.PreparePixel(FuncRec.Source);
7522 DestFD.PreparePixel (FuncRec.Dest);
7524 SourceMD := SourceFD.CreateMappingData;
7525 DestMD := DestFD.CreateMappingData;
7526 DestMD2 := DestFD.CreateMappingData;
7528 FuncRec.Position.Y := 0;
7529 while FuncRec.Position.Y < TempHeight do begin
7530 FuncRec.Position.X := 0;
7531 while FuncRec.Position.X < TempWidth do begin
7532 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
7533 DestFD.Unmap (DestData, FuncRec.Dest, DestMD);
7535 DestFD.Map(FuncRec.Dest, DestData2, DestMD2);
7536 inc(FuncRec.Position.X);
7538 inc(FuncRec.Position.Y);
7541 SourceFD.FreeMappingData(SourceMD);
7542 DestFD.FreeMappingData(DestMD);
7543 DestFD.FreeMappingData(DestMD2);
7548 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7549 function TglBitmapData.AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte): Boolean;
7551 result := AddAlphaFromColorKeyFloat(aRed / $FF, aGreen / $FF, aBlue / $FF, aDeviation / $FF);
7554 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7555 function TglBitmapData.AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal): Boolean;
7557 PixelData: TglBitmapPixelData;
7559 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
7560 result := AddAlphaFromColorKeyFloat(
7561 aRed / PixelData.Range.r,
7562 aGreen / PixelData.Range.g,
7563 aBlue / PixelData.Range.b,
7564 aDeviation / Max(PixelData.Range.r, Max(PixelData.Range.g, PixelData.Range.b)));
7567 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7568 function TglBitmapData.AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single): Boolean;
7570 values: array[0..2] of Single;
7573 PixelData: TglBitmapPixelData;
7575 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
7576 with PixelData do begin
7578 values[1] := aGreen;
7581 for i := 0 to 2 do begin
7582 tmp := Trunc(Range.arr[i] * aDeviation);
7583 Data.arr[i] := Min(Range.arr[i], Trunc(Range.arr[i] * values[i] + tmp));
7584 Range.arr[i] := Max(0, Trunc(Range.arr[i] * values[i] - tmp));
7589 result := AddAlphaFromFunc(glBitmapColorKeyAlphaFunc, @PixelData);
7592 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7593 function TglBitmapData.AddAlphaFromValue(const aAlpha: Byte): Boolean;
7595 result := AddAlphaFromValueFloat(aAlpha / $FF);
7598 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7599 function TglBitmapData.AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
7601 PixelData: TglBitmapPixelData;
7603 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
7604 result := AddAlphaFromValueFloat(aAlpha / PixelData.Range.a);
7607 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7608 function TglBitmapData.AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
7610 PixelData: TglBitmapPixelData;
7612 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
7614 Data.a := Min(Range.a, Max(0, Round(Range.a * aAlpha)));
7615 result := AddAlphaFromFunc(glBitmapValueAlphaFunc, @PixelData.Data.a);
7618 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7619 function TglBitmapData.RemoveAlpha: Boolean;
7621 FormatDesc: TFormatDescriptor;
7624 FormatDesc := TFormatDescriptor.Get(Format);
7625 if Assigned(Data) then begin
7626 if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
7627 raise EglBitmapUnsupportedFormat.Create(Format);
7628 result := ConvertTo(FormatDesc.WithoutAlpha);
7632 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7633 procedure TglBitmapData.FillWithColor(const aRed, aGreen, aBlue: Byte;
7634 const aAlpha: Byte);
7636 FillWithColorFloat(aRed/$FF, aGreen/$FF, aBlue/$FF, aAlpha/$FF);
7639 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7640 procedure TglBitmapData.FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal);
7642 PixelData: TglBitmapPixelData;
7644 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
7646 aRed / PixelData.Range.r,
7647 aGreen / PixelData.Range.g,
7648 aBlue / PixelData.Range.b,
7649 aAlpha / PixelData.Range.a);
7652 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7653 procedure TglBitmapData.FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single);
7655 PixelData: TglBitmapPixelData;
7657 TFormatDescriptor.Get(Format).PreparePixel(PixelData);
7658 with PixelData do begin
7659 Data.r := Max(0, Min(Range.r, Trunc(Range.r * aRed)));
7660 Data.g := Max(0, Min(Range.g, Trunc(Range.g * aGreen)));
7661 Data.b := Max(0, Min(Range.b, Trunc(Range.b * aBlue)));
7662 Data.a := Max(0, Min(Range.a, Trunc(Range.a * aAlpha)));
7664 Convert(glBitmapFillWithColorFunc, false, @PixelData);
7667 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7668 procedure TglBitmapData.SetData(const aData: PByte; const aFormat: TglBitmapFormat; const aWidth: Integer; const aHeight: Integer);
7670 if (Data <> aData) then begin
7671 if (Assigned(Data)) then
7676 if Assigned(fData) then begin
7677 FillChar(fDimension, SizeOf(fDimension), 0);
7678 if aWidth <> -1 then begin
7679 fDimension.Fields := fDimension.Fields + [ffX];
7680 fDimension.X := aWidth;
7683 if aHeight <> -1 then begin
7684 fDimension.Fields := fDimension.Fields + [ffY];
7685 fDimension.Y := aHeight;
7695 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7696 function TglBitmapData.Clone: TglBitmapData;
7698 Temp: TglBitmapData;
7703 Temp := (ClassType.Create as TglBitmapData);
7705 // copy texture data if assigned
7706 if Assigned(Data) then begin
7707 Size := TFormatDescriptor.Get(Format).GetSize(fDimension);
7708 GetMem(TempPtr, Size);
7710 Move(Data^, TempPtr^, Size);
7711 Temp.SetData(TempPtr, Format, Width, Height);
7713 if Assigned(TempPtr) then
7719 Temp.SetData(TempPtr, Format, Width, Height);
7723 Temp.fFormat := Format;
7731 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7732 procedure TglBitmapData.Invert(const aRed, aGreen, aBlue, aAlpha: Boolean);
7737 (Byte(aRed) and 1) or
7738 ((Byte(aGreen) and 1) shl 1) or
7739 ((Byte(aBlue) and 1) shl 2) or
7740 ((Byte(aAlpha) and 1) shl 3);
7742 Convert(glBitmapInvertFunc, false, {%H-}Pointer(mask));
7745 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7747 TMatrixItem = record
7752 PglBitmapToNormalMapRec = ^TglBitmapToNormalMapRec;
7753 TglBitmapToNormalMapRec = Record
7755 Heights: array of Single;
7756 MatrixU : array of TMatrixItem;
7757 MatrixV : array of TMatrixItem;
7761 ONE_OVER_255 = 1 / 255;
7763 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7764 procedure glBitmapToNormalMapPrepareFunc(var FuncRec: TglBitmapFunctionRec);
7768 with FuncRec do begin
7770 Source.Data.r * LUMINANCE_WEIGHT_R +
7771 Source.Data.g * LUMINANCE_WEIGHT_G +
7772 Source.Data.b * LUMINANCE_WEIGHT_B;
7773 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Val * ONE_OVER_255;
7777 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7778 procedure glBitmapToNormalMapPrepareAlphaFunc(var FuncRec: TglBitmapFunctionRec);
7781 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Source.Data.a * ONE_OVER_255;
7784 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7785 procedure glBitmapToNormalMapFunc (var FuncRec: TglBitmapFunctionRec);
7787 TVec = Array[0..2] of Single;
7794 function GetHeight(X, Y: Integer): Single;
7796 with FuncRec do begin
7797 X := Max(0, Min(Size.X -1, X));
7798 Y := Max(0, Min(Size.Y -1, Y));
7799 result := PglBitmapToNormalMapRec(Args)^.Heights[Y * Size.X + X];
7804 with FuncRec do begin
7805 with PglBitmapToNormalMapRec(Args)^ do begin
7807 for Idx := Low(MatrixU) to High(MatrixU) do
7808 du := du + GetHeight(Position.X + MatrixU[Idx].X, Position.Y + MatrixU[Idx].Y) * MatrixU[Idx].W;
7811 for Idx := Low(MatrixU) to High(MatrixU) do
7812 dv := dv + GetHeight(Position.X + MatrixV[Idx].X, Position.Y + MatrixV[Idx].Y) * MatrixV[Idx].W;
7814 Vec[0] := -du * Scale;
7815 Vec[1] := -dv * Scale;
7820 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
7821 if Len <> 0 then begin
7822 Vec[0] := Vec[0] * Len;
7823 Vec[1] := Vec[1] * Len;
7824 Vec[2] := Vec[2] * Len;
7828 Dest.Data.r := Trunc((Vec[0] + 1) * 127.5);
7829 Dest.Data.g := Trunc((Vec[1] + 1) * 127.5);
7830 Dest.Data.b := Trunc((Vec[2] + 1) * 127.5);
7834 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7835 procedure TglBitmapData.GenerateNormalMap(const aFunc: TglBitmapNormalMapFunc; const aScale: Single; const aUseAlpha: Boolean);
7837 Rec: TglBitmapToNormalMapRec;
7839 procedure SetEntry (var Matrix: array of TMatrixItem; Index, X, Y: Integer; W: Single);
7841 if (Index >= Low(Matrix)) and (Index <= High(Matrix)) then begin
7842 Matrix[Index].X := X;
7843 Matrix[Index].Y := Y;
7844 Matrix[Index].W := W;
7849 if TFormatDescriptor.Get(Format).IsCompressed then
7850 raise EglBitmapUnsupportedFormat.Create(Format);
7852 if aScale > 100 then
7854 else if aScale < -100 then
7857 Rec.Scale := aScale;
7859 SetLength(Rec.Heights, Width * Height);
7863 SetLength(Rec.MatrixU, 2);
7864 SetEntry(Rec.MatrixU, 0, -1, 0, -0.5);
7865 SetEntry(Rec.MatrixU, 1, 1, 0, 0.5);
7867 SetLength(Rec.MatrixV, 2);
7868 SetEntry(Rec.MatrixV, 0, 0, 1, 0.5);
7869 SetEntry(Rec.MatrixV, 1, 0, -1, -0.5);
7873 SetLength(Rec.MatrixU, 6);
7874 SetEntry(Rec.MatrixU, 0, -1, 1, -1.0);
7875 SetEntry(Rec.MatrixU, 1, -1, 0, -2.0);
7876 SetEntry(Rec.MatrixU, 2, -1, -1, -1.0);
7877 SetEntry(Rec.MatrixU, 3, 1, 1, 1.0);
7878 SetEntry(Rec.MatrixU, 4, 1, 0, 2.0);
7879 SetEntry(Rec.MatrixU, 5, 1, -1, 1.0);
7881 SetLength(Rec.MatrixV, 6);
7882 SetEntry(Rec.MatrixV, 0, -1, 1, 1.0);
7883 SetEntry(Rec.MatrixV, 1, 0, 1, 2.0);
7884 SetEntry(Rec.MatrixV, 2, 1, 1, 1.0);
7885 SetEntry(Rec.MatrixV, 3, -1, -1, -1.0);
7886 SetEntry(Rec.MatrixV, 4, 0, -1, -2.0);
7887 SetEntry(Rec.MatrixV, 5, 1, -1, -1.0);
7891 SetLength(Rec.MatrixU, 6);
7892 SetEntry(Rec.MatrixU, 0, -1, 1, -1/6);
7893 SetEntry(Rec.MatrixU, 1, -1, 0, -1/6);
7894 SetEntry(Rec.MatrixU, 2, -1, -1, -1/6);
7895 SetEntry(Rec.MatrixU, 3, 1, 1, 1/6);
7896 SetEntry(Rec.MatrixU, 4, 1, 0, 1/6);
7897 SetEntry(Rec.MatrixU, 5, 1, -1, 1/6);
7899 SetLength(Rec.MatrixV, 6);
7900 SetEntry(Rec.MatrixV, 0, -1, 1, 1/6);
7901 SetEntry(Rec.MatrixV, 1, 0, 1, 1/6);
7902 SetEntry(Rec.MatrixV, 2, 1, 1, 1/6);
7903 SetEntry(Rec.MatrixV, 3, -1, -1, -1/6);
7904 SetEntry(Rec.MatrixV, 4, 0, -1, -1/6);
7905 SetEntry(Rec.MatrixV, 5, 1, -1, -1/6);
7909 SetLength(Rec.MatrixU, 20);
7910 SetEntry(Rec.MatrixU, 0, -2, 2, -1 / 16);
7911 SetEntry(Rec.MatrixU, 1, -1, 2, -1 / 10);
7912 SetEntry(Rec.MatrixU, 2, 1, 2, 1 / 10);
7913 SetEntry(Rec.MatrixU, 3, 2, 2, 1 / 16);
7914 SetEntry(Rec.MatrixU, 4, -2, 1, -1 / 10);
7915 SetEntry(Rec.MatrixU, 5, -1, 1, -1 / 8);
7916 SetEntry(Rec.MatrixU, 6, 1, 1, 1 / 8);
7917 SetEntry(Rec.MatrixU, 7, 2, 1, 1 / 10);
7918 SetEntry(Rec.MatrixU, 8, -2, 0, -1 / 2.8);
7919 SetEntry(Rec.MatrixU, 9, -1, 0, -0.5);
7920 SetEntry(Rec.MatrixU, 10, 1, 0, 0.5);
7921 SetEntry(Rec.MatrixU, 11, 2, 0, 1 / 2.8);
7922 SetEntry(Rec.MatrixU, 12, -2, -1, -1 / 10);
7923 SetEntry(Rec.MatrixU, 13, -1, -1, -1 / 8);
7924 SetEntry(Rec.MatrixU, 14, 1, -1, 1 / 8);
7925 SetEntry(Rec.MatrixU, 15, 2, -1, 1 / 10);
7926 SetEntry(Rec.MatrixU, 16, -2, -2, -1 / 16);
7927 SetEntry(Rec.MatrixU, 17, -1, -2, -1 / 10);
7928 SetEntry(Rec.MatrixU, 18, 1, -2, 1 / 10);
7929 SetEntry(Rec.MatrixU, 19, 2, -2, 1 / 16);
7931 SetLength(Rec.MatrixV, 20);
7932 SetEntry(Rec.MatrixV, 0, -2, 2, 1 / 16);
7933 SetEntry(Rec.MatrixV, 1, -1, 2, 1 / 10);
7934 SetEntry(Rec.MatrixV, 2, 0, 2, 0.25);
7935 SetEntry(Rec.MatrixV, 3, 1, 2, 1 / 10);
7936 SetEntry(Rec.MatrixV, 4, 2, 2, 1 / 16);
7937 SetEntry(Rec.MatrixV, 5, -2, 1, 1 / 10);
7938 SetEntry(Rec.MatrixV, 6, -1, 1, 1 / 8);
7939 SetEntry(Rec.MatrixV, 7, 0, 1, 0.5);
7940 SetEntry(Rec.MatrixV, 8, 1, 1, 1 / 8);
7941 SetEntry(Rec.MatrixV, 9, 2, 1, 1 / 16);
7942 SetEntry(Rec.MatrixV, 10, -2, -1, -1 / 16);
7943 SetEntry(Rec.MatrixV, 11, -1, -1, -1 / 8);
7944 SetEntry(Rec.MatrixV, 12, 0, -1, -0.5);
7945 SetEntry(Rec.MatrixV, 13, 1, -1, -1 / 8);
7946 SetEntry(Rec.MatrixV, 14, 2, -1, -1 / 10);
7947 SetEntry(Rec.MatrixV, 15, -2, -2, -1 / 16);
7948 SetEntry(Rec.MatrixV, 16, -1, -2, -1 / 10);
7949 SetEntry(Rec.MatrixV, 17, 0, -2, -0.25);
7950 SetEntry(Rec.MatrixV, 18, 1, -2, -1 / 10);
7951 SetEntry(Rec.MatrixV, 19, 2, -2, -1 / 16);
7956 if aUseAlpha and TFormatDescriptor.Get(Format).HasAlpha then
7957 Convert(glBitmapToNormalMapPrepareAlphaFunc, false, @Rec)
7959 Convert(glBitmapToNormalMapPrepareFunc, false, @Rec);
7960 Convert(glBitmapToNormalMapFunc, false, @Rec);
7962 SetLength(Rec.Heights, 0);
7966 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7967 constructor TglBitmapData.Create;
7970 fFormat := glBitmapDefaultFormat;
7973 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7974 constructor TglBitmapData.Create(const aFileName: String);
7977 LoadFromFile(aFileName);
7980 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7981 constructor TglBitmapData.Create(const aStream: TStream);
7984 LoadFromStream(aStream);
7987 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7988 constructor TglBitmapData.Create(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat; aData: PByte);
7993 if not Assigned(aData) then begin
7994 ImageSize := TFormatDescriptor.Get(aFormat).GetSize(aSize);
7995 GetMem(aData, ImageSize);
7997 FillChar(aData^, ImageSize, #$FF);
7998 SetData(aData, aFormat, aSize.X, aSize.Y);
8000 if Assigned(aData) then
8005 SetData(aData, aFormat, aSize.X, aSize.Y);
8009 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8010 constructor TglBitmapData.Create(const aSize: TglBitmapSize; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer);
8013 LoadFromFunc(aSize, aFormat, aFunc, aArgs);
8016 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8017 constructor TglBitmapData.Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar);
8020 LoadFromResource(aInstance, aResource, aResType);
8023 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8024 constructor TglBitmapData.Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
8027 LoadFromResourceID(aInstance, aResourceID, aResType);
8030 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8031 destructor TglBitmapData.Destroy;
8033 SetData(nil, tfEmpty);
8037 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8038 //TglBitmap - PROTECTED///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8039 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8040 function TglBitmap.GetWidth: Integer;
8042 if (ffX in fDimension.Fields) then
8043 result := fDimension.X
8048 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8049 function TglBitmap.GetHeight: Integer;
8051 if (ffY in fDimension.Fields) then
8052 result := fDimension.Y
8057 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8058 procedure TglBitmap.SetCustomData(const aValue: Pointer);
8060 if fCustomData = aValue then
8062 fCustomData := aValue;
8065 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8066 procedure TglBitmap.SetCustomName(const aValue: String);
8068 if fCustomName = aValue then
8070 fCustomName := aValue;
8073 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8074 procedure TglBitmap.SetCustomNameW(const aValue: WideString);
8076 if fCustomNameW = aValue then
8078 fCustomNameW := aValue;
8081 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8082 procedure TglBitmap.SetDeleteTextureOnFree(const aValue: Boolean);
8084 if fDeleteTextureOnFree = aValue then
8086 fDeleteTextureOnFree := aValue;
8089 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8090 procedure TglBitmap.SetID(const aValue: Cardinal);
8092 if fID = aValue then
8097 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8098 procedure TglBitmap.SetMipMap(const aValue: TglBitmapMipMap);
8100 if fMipMap = aValue then
8105 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8106 procedure TglBitmap.SetTarget(const aValue: Cardinal);
8108 if fTarget = aValue then
8113 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8114 procedure TglBitmap.SetAnisotropic(const aValue: Integer);
8115 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_EXT)}
8117 MaxAnisotropic: Integer;
8120 fAnisotropic := aValue;
8121 if (ID > 0) then begin
8122 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_EXT)}
8123 if GL_EXT_texture_filter_anisotropic then begin
8124 if fAnisotropic > 0 then begin
8125 Bind({$IFNDEF OPENGL_ES}false{$ENDIF});
8126 glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @MaxAnisotropic);
8127 if aValue > MaxAnisotropic then
8128 fAnisotropic := MaxAnisotropic;
8129 glTexParameteri(Target, GL_TEXTURE_MAX_ANISOTROPY_EXT, fAnisotropic);
8140 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8141 procedure TglBitmap.CreateID;
8144 glDeleteTextures(1, @fID);
8145 glGenTextures(1, @fID);
8146 Bind({$IFNDEF OPENGL_ES}false{$ENDIF});
8149 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8150 procedure TglBitmap.SetupParameters({$IFNDEF OPENGL_ES}out aBuildWithGlu: Boolean{$ENDIF});
8152 // Set Up Parameters
8153 SetWrap(fWrapS, fWrapT, fWrapR);
8154 SetFilter(fFilterMin, fFilterMag);
8155 SetAnisotropic(fAnisotropic);
8158 SetBorderColor(fBorderColor[0], fBorderColor[1], fBorderColor[2], fBorderColor[3]);
8159 if (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
8160 SetSwizzle(fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
8164 // Mip Maps Generation Mode
8165 aBuildWithGlu := false;
8166 if (MipMap = mmMipmap) then begin
8167 if (GL_VERSION_1_4 or GL_SGIS_generate_mipmap) then
8168 glTexParameteri(Target, GL_GENERATE_MIPMAP, GLint(GL_TRUE))
8170 aBuildWithGlu := true;
8171 end else if (MipMap = mmMipmapGlu) then
8172 aBuildWithGlu := true;
8174 if (MipMap = mmMipmap) then
8175 glGenerateMipmap(Target);
8179 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8180 //TglBitmap - PUBLIC//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8181 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8182 procedure TglBitmap.AfterConstruction;
8184 inherited AfterConstruction;
8189 fIsResident := false;
8192 fMipMap := glBitmapDefaultMipmap;
8193 fDeleteTextureOnFree := glBitmapGetDefaultDeleteTextureOnFree;
8195 glBitmapGetDefaultFilter (fFilterMin, fFilterMag);
8196 glBitmapGetDefaultTextureWrap(fWrapS, fWrapT, fWrapR);
8198 glBitmapGetDefaultSwizzle (fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
8202 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8203 procedure TglBitmap.BeforeDestruction;
8205 if (fID > 0) and fDeleteTextureOnFree then
8206 glDeleteTextures(1, @fID);
8207 inherited BeforeDestruction;
8211 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8212 procedure TglBitmap.SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
8214 fBorderColor[0] := aRed;
8215 fBorderColor[1] := aGreen;
8216 fBorderColor[2] := aBlue;
8217 fBorderColor[3] := aAlpha;
8218 if (ID > 0) then begin
8220 glTexParameterfv(Target, GL_TEXTURE_BORDER_COLOR, @fBorderColor[0]);
8225 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8226 procedure TglBitmap.SetFilter(const aMin, aMag: GLenum);
8231 fFilterMin := GL_NEAREST;
8233 fFilterMin := GL_LINEAR;
8234 GL_NEAREST_MIPMAP_NEAREST:
8235 fFilterMin := GL_NEAREST_MIPMAP_NEAREST;
8236 GL_LINEAR_MIPMAP_NEAREST:
8237 fFilterMin := GL_LINEAR_MIPMAP_NEAREST;
8238 GL_NEAREST_MIPMAP_LINEAR:
8239 fFilterMin := GL_NEAREST_MIPMAP_LINEAR;
8240 GL_LINEAR_MIPMAP_LINEAR:
8241 fFilterMin := GL_LINEAR_MIPMAP_LINEAR;
8243 raise EglBitmap.Create('SetFilter - Unknow MIN filter.');
8249 fFilterMag := GL_NEAREST;
8251 fFilterMag := GL_LINEAR;
8253 raise EglBitmap.Create('SetFilter - Unknow MAG filter.');
8257 if (ID > 0) then begin
8258 Bind({$IFNDEF OPENGL_ES}false{$ENDIF});
8259 glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, fFilterMag);
8261 if (MipMap = mmNone) {$IFNDEF OPENGL_ES}or (Target = GL_TEXTURE_RECTANGLE){$ENDIF} then begin
8263 GL_NEAREST, GL_LINEAR:
8264 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
8265 GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR:
8266 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
8267 GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR:
8268 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
8271 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
8275 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8276 procedure TglBitmap.SetWrap(const S: GLenum; const T: GLenum; const R: GLenum);
8278 procedure CheckAndSetWrap(const aValue: Cardinal; var aTarget: Cardinal);
8283 aTarget := GL_CLAMP;
8287 aTarget := GL_REPEAT;
8289 GL_CLAMP_TO_EDGE: begin
8291 if not GL_VERSION_1_2 and not GL_EXT_texture_edge_clamp then
8295 aTarget := GL_CLAMP_TO_EDGE;
8299 GL_CLAMP_TO_BORDER: begin
8300 if GL_VERSION_1_3 or GL_ARB_texture_border_clamp then
8301 aTarget := GL_CLAMP_TO_BORDER
8303 aTarget := GL_CLAMP;
8307 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
8308 GL_MIRRORED_REPEAT: begin
8310 if GL_VERSION_1_4 or GL_ARB_texture_mirrored_repeat or GL_IBM_texture_mirrored_repeat then
8312 if GL_VERSION_2_0 then
8314 aTarget := GL_MIRRORED_REPEAT
8316 raise EglBitmap.Create('SetWrap - Unsupported Texturewrap GL_MIRRORED_REPEAT (S).');
8320 raise EglBitmap.Create('SetWrap - Unknow Texturewrap');
8325 CheckAndSetWrap(S, fWrapS);
8326 CheckAndSetWrap(T, fWrapT);
8327 CheckAndSetWrap(R, fWrapR);
8329 if (ID > 0) then begin
8330 Bind({$IFNDEF OPENGL_ES}false{$ENDIF});
8331 glTexParameteri(Target, GL_TEXTURE_WRAP_S, fWrapS);
8332 glTexParameteri(Target, GL_TEXTURE_WRAP_T, fWrapT);
8333 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
8334 {$IFDEF OPENGL_ES} if GL_VERSION_3_0 then{$ENDIF}
8335 glTexParameteri(Target, GL_TEXTURE_WRAP_R, fWrapR);
8340 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
8341 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8342 procedure TglBitmap.SetSwizzle(const r, g, b, a: GLenum);
8344 procedure CheckAndSetValue(const aValue: GLenum; const aIndex: Integer);
8346 if (aValue = GL_ZERO) or (aValue = GL_ONE) or (aValue = GL_ALPHA) or
8347 (aValue = GL_RED) or (aValue = GL_GREEN) or (aValue = GL_BLUE) then
8348 fSwizzle[aIndex] := aValue
8350 raise EglBitmap.Create('SetSwizzle - Unknow Swizle Value');
8355 if not (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
8356 raise EglBitmapNotSupported.Create('texture swizzle is not supported');
8358 if not GL_VERSION_3_0 then
8359 raise EglBitmapNotSupported.Create('texture swizzle is not supported');
8361 CheckAndSetValue(r, 0);
8362 CheckAndSetValue(g, 1);
8363 CheckAndSetValue(b, 2);
8364 CheckAndSetValue(a, 3);
8366 if (ID > 0) then begin
8369 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_RGBA, PGLint(@fSwizzle[0]));
8371 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_R, PGLint(@fSwizzle[0]));
8372 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_G, PGLint(@fSwizzle[1]));
8373 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_B, PGLint(@fSwizzle[2]));
8374 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_A, PGLint(@fSwizzle[3]));
8380 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8381 procedure TglBitmap.Bind({$IFNDEF OPENGL_ES}const aEnableTextureUnit: Boolean{$ENDIF});
8384 if aEnableTextureUnit then
8388 glBindTexture(Target, ID);
8391 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8392 procedure TglBitmap.Unbind({$IFNDEF OPENGL_ES}const aDisableTextureUnit: Boolean{$ENDIF});
8395 if aDisableTextureUnit then
8398 glBindTexture(Target, 0);
8401 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8402 procedure TglBitmap.UploadData(const aDataObj: TglBitmapData; const aCheckSize: Boolean);
8406 w := aDataObj.Width;
8407 h := aDataObj.Height;
8408 fDimension.Fields := [];
8410 fDimension.Fields := fDimension.Fields + [ffX];
8412 fDimension.Fields := fDimension.Fields + [ffY];
8418 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8419 function TglBitmap.DownloadData(const aDataObj: TglBitmapData): Boolean;
8422 TempWidth, TempHeight: Integer;
8423 TempIntFormat: GLint;
8424 IntFormat: TglBitmapFormat;
8425 FormatDesc: TFormatDescriptor;
8431 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_WIDTH, @TempWidth);
8432 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT, @TempHeight);
8433 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat);
8435 FormatDesc := (TglBitmapFormatDescriptor.GetByFormat(TempIntFormat) as TFormatDescriptor);
8436 IntFormat := FormatDesc.Format;
8438 // Getting data from OpenGL
8439 FormatDesc := TFormatDescriptor.Get(IntFormat);
8440 GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight));
8442 if FormatDesc.IsCompressed then begin
8443 if not Assigned(glGetCompressedTexImage) then
8444 raise EglBitmap.Create('compressed formats not supported by video adapter');
8445 glGetCompressedTexImage(Target, 0, Temp)
8447 glGetTexImage(Target, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
8448 aDataObj.SetData(Temp, IntFormat, TempWidth, TempHeight);
8451 if Assigned(Temp) then
8458 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8459 constructor TglBitmap.Create;
8461 if (ClassType = TglBitmap) then
8462 raise EglBitmap.Create('Don''t create TglBitmap directly. Use one of the deviated classes (TglBitmap2D) instead.');
8466 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8467 constructor TglBitmap.Create(const aData: TglBitmapData);
8474 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8475 //TglBitmap1D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8476 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8477 procedure TglBitmap1D.UploadDataIntern(const aDataObj: TglBitmapData; const aBuildWithGlu: Boolean);
8479 fd: TglBitmapFormatDescriptor;
8482 fd := aDataObj.FormatDescriptor;
8483 if (fd.glFormat = 0) or (fd.glInternalFormat = 0) or (fd.glDataFormat = 0) then
8484 raise EglBitmap.Create('format is not supported by video adapter, please convert before uploading data');
8486 if fd.IsCompressed then begin
8487 if not Assigned(glCompressedTexImage1D) then
8488 raise EglBitmap.Create('compressed formats not supported by video adapter');
8489 glCompressedTexImage1D(Target, 0, fd.glInternalFormat, aDataObj.Width, 0, fd.GetSize(aDataObj.Width, 1), aDataObj.Data)
8490 end else if aBuildWithGlu then
8491 gluBuild1DMipmaps(Target, fd.glInternalFormat, aDataObj.Width, fd.glFormat, fd.glDataFormat, aDataObj.Data)
8493 glTexImage1D(Target, 0, fd.glInternalFormat, aDataObj.Width, 0, fd.glFormat, fd.glDataFormat, aDataObj.Data);
8496 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8497 procedure TglBitmap1D.AfterConstruction;
8500 Target := GL_TEXTURE_1D;
8503 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8504 procedure TglBitmap1D.UploadData(const aDataObj: TglBitmapData; const aCheckSize: Boolean);
8506 BuildWithGlu, TexRec: Boolean;
8509 if not Assigned(aDataObj) then
8512 // Check Texture Size
8513 if (aCheckSize) then begin
8514 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
8516 if (aDataObj.Width > TexSize) then
8517 raise EglBitmapSizeToLarge.Create('TglBitmap1D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
8519 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and
8520 (Target = GL_TEXTURE_RECTANGLE);
8521 if not (IsPowerOfTwo(aDataObj.Width) or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
8522 raise EglBitmapNonPowerOfTwo.Create('TglBitmap1D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8527 SetupParameters(BuildWithGlu);
8528 UploadDataIntern(aDataObj, BuildWithGlu);
8529 glAreTexturesResident(1, @fID, @fIsResident);
8531 inherited UploadData(aDataObj, aCheckSize);
8535 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8536 //TglBitmap2D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8537 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8538 procedure TglBitmap2D.UploadDataIntern(const aDataObj: TglBitmapData; const aTarget: GLenum{$IFNDEF OPENGL_ES}; const aBuildWithGlu: Boolean{$ENDIF});
8540 fd: TglBitmapFormatDescriptor;
8542 fd := aDataObj.FormatDescriptor;
8543 if (fd.glFormat = 0) or (fd.glInternalFormat = 0) or (fd.glDataFormat = 0) then
8544 raise EglBitmap.Create('format is not supported by video adapter, please convert before uploading data');
8546 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
8548 if fd.IsCompressed then begin
8549 if not Assigned(glCompressedTexImage2D) then
8550 raise EglBitmap.Create('compressed formats not supported by video adapter');
8551 glCompressedTexImage2D(aTarget, 0, fd.glInternalFormat, aDataObj.Width, aDataObj.Height, 0, fd.GetSize(fDimension), aDataObj.Data)
8553 end else if aBuildWithGlu then begin
8554 gluBuild2DMipmaps(aTarget, fd.ChannelCount, aDataObj.Width, aDataObj.Height, fd.glFormat, fd.glDataFormat, aDataObj.Data)
8557 glTexImage2D(aTarget, 0, fd.glInternalFormat, aDataObj.Width, aDataObj.Height, 0, fd.glFormat, fd.glDataFormat, aDataObj.Data);
8561 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8562 procedure TglBitmap2D.AfterConstruction;
8565 Target := GL_TEXTURE_2D;
8568 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8569 procedure TglBitmap2D.UploadData(const aDataObj: TglBitmapData; const aCheckSize: Boolean);
8572 BuildWithGlu, TexRec: Boolean;
8577 if not Assigned(aDataObj) then
8580 // Check Texture Size
8581 if (aCheckSize) then begin
8582 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
8584 if ((aDataObj.Width > TexSize) or (aDataObj.Height > TexSize)) then
8585 raise EglBitmapSizeToLarge.Create('TglBitmap2D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
8587 PotTex := IsPowerOfTwo(aDataObj.Width) and IsPowerOfTwo(aDataObj.Height);
8588 {$IF NOT DEFINED(OPENGL_ES)}
8589 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and (Target = GL_TEXTURE_RECTANGLE);
8590 if not (PotTex or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
8591 raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8592 {$ELSEIF DEFINED(OPENGL_ES_EXT)}
8593 if not PotTex and not GL_OES_texture_npot then
8594 raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8597 raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8603 SetupParameters({$IFNDEF OPENGL_ES}BuildWithGlu{$ENDIF});
8604 UploadDataIntern(aDataObj, Target{$IFNDEF OPENGL_ES}, BuildWithGlu{$ENDIF});
8606 glAreTexturesResident(1, @fID, @fIsResident);
8609 inherited UploadData(aDataObj, aCheckSize);
8612 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8613 class procedure TglBitmap2D.GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat; const aDataObj: TglBitmapData);
8616 Size, w, h: Integer;
8617 FormatDesc: TFormatDescriptor;
8619 FormatDesc := TFormatDescriptor.Get(aFormat);
8620 if FormatDesc.IsCompressed then
8621 raise EglBitmapUnsupportedFormat.Create(aFormat);
8623 w := aRight - aLeft;
8624 h := aBottom - aTop;
8625 Size := FormatDesc.GetSize(w, h);
8628 glPixelStorei(GL_PACK_ALIGNMENT, 1);
8629 glReadPixels(aLeft, aTop, w, h, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
8630 aDataObj.SetData(Temp, aFormat, w, h);
8633 if Assigned(Temp) then
8639 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
8640 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8641 //TglBitmapCubeMap////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8642 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8643 procedure TglBitmapCubeMap.AfterConstruction;
8648 if not (GL_VERSION_1_3 or GL_ARB_texture_cube_map or GL_EXT_texture_cube_map) then
8649 raise EglBitmap.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
8651 if not (GL_VERSION_2_0) then
8652 raise EglBitmap.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
8656 Target := GL_TEXTURE_CUBE_MAP;
8658 fGenMode := GL_REFLECTION_MAP;
8662 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8663 procedure TglBitmapCubeMap.UploadData(const aDataObj: TglBitmapData; const aCheckSize: Boolean);
8665 Assert(false, 'TglBitmapCubeMap.UploadData - Don''t call UploadData directly, use UploadCubeMap instead');
8668 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8669 procedure TglBitmapCubeMap.UploadCubeMap(const aDataObj: TglBitmapData; const aCubeTarget: Cardinal; const aCheckSize: Boolean);
8672 BuildWithGlu: Boolean;
8676 if (aCheckSize) then begin
8677 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, @TexSize);
8679 if (aDataObj.Width > TexSize) or (aDataObj.Height > TexSize) then
8680 raise EglBitmapSizeToLarge.Create('TglBitmapCubeMap.GenerateCubeMap - The size for the Cubemap is to large. It''s may be not conform with the Hardware.');
8682 {$IF NOT DEFINED(OPENGL_ES)}
8683 if not ((IsPowerOfTwo(aDataObj.Width) and IsPowerOfTwo(aDataObj.Height)) or GL_VERSION_2_0 or GL_ARB_texture_non_power_of_two) then
8684 raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenerateCubeMap - Cubemaps dosn''t support non power of two texture.');
8685 {$ELSEIF DEFINED(OPENGL_ES_EXT)}
8686 if not (IsPowerOfTwo(aDataObj.Width) and IsPowerOfTwo(aDataObj.Height)) and not GL_OES_texture_npot then
8687 raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenerateCubeMap - Cubemaps dosn''t support non power of two texture.');
8689 if not (IsPowerOfTwo(aDataObj.Width) and IsPowerOfTwo(aDataObj.Height)) then
8690 raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenerateCubeMap - Cubemaps dosn''t support non power of two texture.');
8696 SetupParameters({$IFNDEF OPENGL_ES}BuildWithGlu{$ENDIF});
8697 UploadDataIntern(aDataObj, aCubeTarget{$IFNDEF OPENGL_ES}, BuildWithGlu{$ENDIF});
8699 inherited UploadData(aDataObj, aCheckSize);
8702 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8703 procedure TglBitmapCubeMap.Bind({$IFNDEF OPENGL_ES}const aEnableTexCoordsGen: Boolean; const aEnableTextureUnit: Boolean{$ENDIF});
8705 inherited Bind({$IFNDEF OPENGL_ES}aEnableTextureUnit{$ENDIF});
8707 if aEnableTexCoordsGen then begin
8708 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, fGenMode);
8709 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, fGenMode);
8710 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, fGenMode);
8711 glEnable(GL_TEXTURE_GEN_S);
8712 glEnable(GL_TEXTURE_GEN_T);
8713 glEnable(GL_TEXTURE_GEN_R);
8718 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8719 procedure TglBitmapCubeMap.Unbind({$IFNDEF OPENGL_ES}const aDisableTexCoordsGen: Boolean; const aDisableTextureUnit: Boolean{$ENDIF});
8721 inherited Unbind({$IFNDEF OPENGL_ES}aDisableTextureUnit{$ENDIF});
8723 if aDisableTexCoordsGen then begin
8724 glDisable(GL_TEXTURE_GEN_S);
8725 glDisable(GL_TEXTURE_GEN_T);
8726 glDisable(GL_TEXTURE_GEN_R);
8732 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
8733 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8734 //TglBitmapNormalMap//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8735 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8737 TVec = Array[0..2] of Single;
8738 TglBitmapNormalMapGetVectorFunc = procedure (out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8740 PglBitmapNormalMapRec = ^TglBitmapNormalMapRec;
8741 TglBitmapNormalMapRec = record
8743 Func: TglBitmapNormalMapGetVectorFunc;
8746 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8747 procedure glBitmapNormalMapPosX(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8749 aVec[0] := aHalfSize;
8750 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8751 aVec[2] := - (aPosition.X + 0.5 - aHalfSize);
8754 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8755 procedure glBitmapNormalMapNegX(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8757 aVec[0] := - aHalfSize;
8758 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8759 aVec[2] := aPosition.X + 0.5 - aHalfSize;
8762 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8763 procedure glBitmapNormalMapPosY(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8765 aVec[0] := aPosition.X + 0.5 - aHalfSize;
8766 aVec[1] := aHalfSize;
8767 aVec[2] := aPosition.Y + 0.5 - aHalfSize;
8770 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8771 procedure glBitmapNormalMapNegY(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8773 aVec[0] := aPosition.X + 0.5 - aHalfSize;
8774 aVec[1] := - aHalfSize;
8775 aVec[2] := - (aPosition.Y + 0.5 - aHalfSize);
8778 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8779 procedure glBitmapNormalMapPosZ(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8781 aVec[0] := aPosition.X + 0.5 - aHalfSize;
8782 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8783 aVec[2] := aHalfSize;
8786 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8787 procedure glBitmapNormalMapNegZ(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8789 aVec[0] := - (aPosition.X + 0.5 - aHalfSize);
8790 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8791 aVec[2] := - aHalfSize;
8794 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8795 procedure glBitmapNormalMapFunc(var FuncRec: TglBitmapFunctionRec);
8801 with FuncRec do begin
8802 with PglBitmapNormalMapRec(Args)^ do begin
8803 Func(Vec, Position, HalfSize);
8806 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
8807 if Len <> 0 then begin
8808 Vec[0] := Vec[0] * Len;
8809 Vec[1] := Vec[1] * Len;
8810 Vec[2] := Vec[2] * Len;
8813 // Scale Vector and AddVectro
8814 Vec[0] := Vec[0] * 0.5 + 0.5;
8815 Vec[1] := Vec[1] * 0.5 + 0.5;
8816 Vec[2] := Vec[2] * 0.5 + 0.5;
8821 Dest.Data.arr[i] := Round(Vec[i] * 255);
8825 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8826 procedure TglBitmapNormalMap.AfterConstruction;
8830 fGenMode := GL_NORMAL_MAP;
8834 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8835 procedure TglBitmapNormalMap.GenerateNormalMap(const aSize: Integer; const aCheckSize: Boolean);
8837 Rec: TglBitmapNormalMapRec;
8838 SizeRec: TglBitmapSize;
8839 DataObj: TglBitmapData;
8841 Rec.HalfSize := aSize div 2;
8843 SizeRec.Fields := [ffX, ffY];
8847 DataObj := TglBitmapData.Create;
8850 Rec.Func := glBitmapNormalMapPosX;
8851 DataObj.LoadFromFunc(SizeRec, tfBGR8ub3, glBitmapNormalMapFunc, @Rec);
8852 UploadCubeMap(DataObj, GL_TEXTURE_CUBE_MAP_POSITIVE_X, aCheckSize);
8855 Rec.Func := glBitmapNormalMapNegX;
8856 DataObj.LoadFromFunc(SizeRec, tfBGR8ub3, glBitmapNormalMapFunc, @Rec);
8857 UploadCubeMap(DataObj, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, aCheckSize);
8860 Rec.Func := glBitmapNormalMapPosY;
8861 DataObj.LoadFromFunc(SizeRec, tfBGR8ub3, glBitmapNormalMapFunc, @Rec);
8862 UploadCubeMap(DataObj, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, aCheckSize);
8865 Rec.Func := glBitmapNormalMapNegY;
8866 DataObj.LoadFromFunc(SizeRec, tfBGR8ub3, glBitmapNormalMapFunc, @Rec);
8867 UploadCubeMap(DataObj, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, aCheckSize);
8870 Rec.Func := glBitmapNormalMapPosZ;
8871 DataObj.LoadFromFunc(SizeRec, tfBGR8ub3, glBitmapNormalMapFunc, @Rec);
8872 UploadCubeMap(DataObj, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, aCheckSize);
8875 Rec.Func := glBitmapNormalMapNegZ;
8876 DataObj.LoadFromFunc(SizeRec, tfBGR8ub3, glBitmapNormalMapFunc, @Rec);
8877 UploadCubeMap(DataObj, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, aCheckSize);
8879 FreeAndNil(DataObj);
8885 glBitmapSetDefaultFormat (tfEmpty);
8886 glBitmapSetDefaultMipmap (mmMipmap);
8887 glBitmapSetDefaultFilter (GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
8888 glBitmapSetDefaultWrap (GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
8889 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
8890 glBitmapSetDefaultSwizzle(GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA);
8893 glBitmapSetDefaultFreeDataAfterGenTexture(true);
8894 glBitmapSetDefaultDeleteTextureOnFree (true);
8896 TFormatDescriptor.Init;
8899 TFormatDescriptor.Finalize;