1 {***********************************************************
2 glBitmap by Steffen Xonna aka Lossy eX (2003-2008)
3 http://www.opengl24.de/index.php?cat=header&file=glbitmap
4 ------------------------------------------------------------
5 The contents of this file are used with permission, subject to
6 the Mozilla Public License Version 1.1 (the "License"); you may
7 not use this file except in compliance with the License. You may
8 obtain a copy of the License at
9 http://www.mozilla.org/MPL/MPL-1.1.html
10 ------------------------------------------------------------
12 ------------------------------------------------------------
15 - The define GLB_DELPHI dosn't check versions anymore. If you say you are using delphi
16 then it's your problem if that isn't true. This prevents the unit for incompatibility
17 with newer versions of Delphi.
18 - Problems with D2009+ resolved (Thanks noeska and all i forgot)
19 - GetPixel isn't set if you are loading textures inside the constructor (Thanks Wilson)
21 - AddAlphaFromglBitmap used the custom pointer instead the imagedatapointer (Thanks Wilson)
22 - Additional Datapointer for functioninterface now has the name CustomData
24 - AssigneAlphaToBitmap overwrites his own palette (Thanks Wilson)
25 - If you load an texture from an file the property Filename will be set to the name of the file
26 - Three new properties to attach custom data to the Texture objects
27 - CustomName (free for use string)
28 - CustomNameW (free for use widestring)
29 - CustomDataPointer (free for use pointer to attach other objects or complex structures)
31 - RLE TGAs loaded much faster
33 - fixed some problem with reading RLE TGAs.
35 - function clone now only copys data if it's assigned and now it also copies the ID
36 - it seems that lazarus dont like comments in comments.
38 - It's possible to set the id of the texture
39 - define GLB_NO_NATIVE_GL deactivated by default
41 - Now supports the following libraries
45 - Linux compatibillity via free pascal compatibility (delphi sources optional)
46 - BMPs now loaded manuel
48 - Property DataPtr now has the name Data
49 - Functions are more flexible between RGB(A) and BGR(A). RGB can be saved as Bitmap and will be saved as BGR
50 - Unused Depth removed
51 - Function FreeData to freeing image data added
53 - ImageID flag of TGAs was ignored. (Thanks Zwoetzen)
55 - Function SetBorderColor implemented (only used by opengl if wrap is set to GL_CLAMP_TO_BORDER)
56 - Function AddAlphaFromValue implemented to use an fixed Value as Alphachannel
57 - Function ReadOpenGLExtension is now only intern
59 - pngimage now disabled by default like all other versions.
61 - Setting up an anisotropic filter of 0 isnt allowed by nvidia (Thanks Ogridi)
63 - Fixed some Problem with Delphi 5
64 - Now uses the newest version of pngimage. Makes saving pngs much easier.
66 - Property IsCompressed and Size removed. Not really supported by Spec (Thanks Ogridi)
68 - Internal Format ifDepth8 added
69 - function GrabScreen now supports all uncompressed formats
71 - AddAlphaFromglBitmap implemented
73 - LoadFromResource and LoadFromResourceId now needs an Instance and an ResourceType (for ID)
75 - Width, Height and Depth internal changed to TglBitmapPixelPosition.
76 property Width, Height, Depth are still existing and new property Dimension are avail
78 - Added native OpenGL Support. Breaking the dglOpenGL "barrier".
80 - Added function GrabScreen to class TglBitmap2D
82 - Added support to Save images
83 - Added function Clone to Clone Instance
85 - Functions now works with Cardinals for each channel. Up to 32 Bits per channel.
87 - Several speed optimizations
89 - Internal structure change. Loading of TGA, PNG and DDS improved.
90 Data, format and size will now set directly with SetDataPtr.
91 - AddFunc now works with all Types of Images and Formats
92 - Some Funtions moved to Baseclass TglBitmap
94 - Added Support to decompress DXT3 and DXT5 compressed Images.
95 - Added Mapping to convert data from one format into an other.
97 - Added method ConvertTo in Class TglBitmap2D. Method allows to convert every
98 supported Input format (supported by GetPixel) into any uncompresed Format
99 - Added Support to decompress DXT1 compressed Images.
100 - SwapColors replaced by ConvertTo
102 - Added Support for compressed DDSs
103 - Added new internal formats (DXT1, DXT3, DXT5)
105 - Parameter Components renamed to InternalFormat
107 - Some AllocMem replaced with GetMem (little speed change)
108 - better exception handling. Better protection from memory leaks.
110 - Added support for Direct Draw Surfaces (.DDS) (uncompressed images only)
111 - Added new internal formats (RGB8, RGBA8, RGBA4, RGB5A1, RGB10A2, R5G6B5)
113 - Added support for Grayscale textures
114 - Added internal formats (Alpha, Luminance, LuminanceAlpha, BGR8, BGRA8)
116 - Added support for GL_VERSION_2_0
117 - Added support for GL_EXT_texture_filter_anisotropic
119 - Function FillWithColor fills the Image with one Color
120 - Function LoadNormalMap added
122 - ToNormalMap allows to Create an NormalMap from the Alphachannel
123 - ToNormalMap now supports Sobel (nmSobel) function.
125 - support for RLE Compressed RGB TGAs added
127 - Class TglBitmapNormalMap added to support Normalmap generation
128 - Added function ToNormalMap in class TglBitmap2D to genereate normal maps from textures.
129 3 Filters are supported. (4 Samples, 3x3 and 5x5)
131 - Method LoadCubeMapClass removed
132 - LoadCubeMap returnvalue is now the Texture paramter. Such as LoadTextures
133 - virtual abstract method GenTexture in class TglBitmap now is protected
135 - now support DescriptionFlag in LoadTga. Allows vertical flipped images to be loaded as normal
137 - little enhancement for IsPowerOfTwo
138 - TglBitmap1D.GenTexture now tests NPOT Textures
140 - some little name changes. All properties or function with Texture in name are
141 now without texture in name. We have allways texture so we dosn't name it.
143 - GenTexture now tests if texture is NPOT and NPOT-Texture are supported or
144 TextureTarget is GL_TEXTURE_RECTANGLE. Else it raised an exception.
146 - added support for GL_ARB_texture_rectangle, GL_EXT_texture_rectangle and GL_NV_texture_rectangle
148 - Function Unbind added
149 - call of SetFilter or SetTextureWrap if TextureID exists results in setting properties to opengl texture.
151 - class TglBitmapCubeMap added (allows to Create Cubemaps)
153 - Added Support for PNG Images. (http://pngdelphi.sourceforge.net/)
154 To Enable png's use the define pngimage
156 - New Functioninterface added
157 - Function GetPixel added
159 - Property BuildMipMaps renamed to MipMap
161 - property Name removed.
162 - BuildMipMaps is now a set of 3 values. None, GluBuildMipmaps and SGIS_generate_mipmap
164 - property name added. Only used in glForms!
166 - property FreeDataAfterGenTexture is now available as default (default = true)
167 - BuildMipmaps now implemented in TglBitmap1D (i've forgotten it)
168 - function MoveMemory replaced with function Move (little speed change)
169 - several calculations stored in variables (little speed change)
171 - property BuildMipsMaps added (default = true)
172 if BuildMipMaps isn't set GenTextures uses glTexImage[12]D else it use gluBuild[12]dMipmaps
173 - property FreeDataAfterGenTexture added (default = true)
174 if FreeDataAfterGenTexture is set the texturedata were deleted after the texture was generated.
175 - parameter DisableOtherTextureUnits of Bind removed
176 - parameter FreeDataAfterGeneration of GenTextures removed
178 - TglBitmap dosn't delete data if class was destroyed (fixed)
180 - Bind now enables TextureUnits (by params)
181 - GenTextures can leave data (by param)
182 - LoadTextures now optimal
184 - Performance optimization in AddFunc
185 - procedure Bind moved to subclasses
186 - Added new Class TglBitmap1D to support real OpenGL 1D Textures
188 - Texturefilter and texturewrap now also as defaults
189 Minfilter = GL_LINEAR_MIPMAP_LINEAR
190 Magfilter = GL_LINEAR
191 Wrap(str) = GL_CLAMP_TO_EDGE
192 - Added new format tfCompressed to create a compressed texture.
193 - propertys IsCompressed, TextureSize and IsResident added
194 IsCompressed and TextureSize only contains data from level 0
196 - Added function AddFunc to add PerPixelEffects to Image
197 - LoadFromFunc now based on AddFunc
198 - Invert now based on AddFunc
199 - SwapColors now based on AddFunc
201 - Added function FlipHorz
203 - Added function LaodFromFunc to create images with function
204 - Added function FlipVert
205 - Added internal format RGB(A) if GL_EXT_bgra or OpenGL 1.2 isn't supported
207 - Added Alphafunctions to calculate alpha per function
208 - Added Alpha from ColorKey using alphafunctions
210 - First full functionally Version of glBitmap
211 - Support for 24Bit and 32Bit TGA Pictures added
213 - begin of programming
214 ***********************************************************}
217 {.$MESSAGE warn 'Hey. I''m the glBitmap.pas and i need to be configured. My master tell me your preferences! ;)'}
218 // Please uncomment the defines below to configure the glBitmap to your preferences.
219 // If you have configured the unit you can uncomment the warning above.
221 // ###### Start of preferences ################################################
223 {$DEFINE GLB_NO_NATIVE_GL}
224 // To enable the dglOpenGL.pas Header
225 // With native GL then bindings are staticlly declared to support other headers
226 // or use the glBitmap inside of DLLs (minimize codesize).
230 // To enable the support for SDL_surfaces
232 {.$DEFINE GLB_DELPHI}
233 // To enable the support for TBitmap from Delphi (not lazarus)
236 // *** image libs ***
238 {.$DEFINE GLB_SDL_IMAGE}
239 // To enable the support of SDL_image to load files. (READ ONLY)
240 // If you enable SDL_image all other libraries will be ignored!
243 {.$DEFINE GLB_PNGIMAGE}
244 // to enable png support with the unit pngimage. You can download it from http://pngdelphi.sourceforge.net/
245 // if you enable pngimage the libPNG will be ignored
247 {.$DEFINE GLB_LIB_PNG}
248 // to use the libPNG http://www.libpng.org/
249 // You will need an aditional header.
250 // http://www.opengl24.de/index.php?cat=header&file=libpng
252 {.$DEFINE GLB_DELPHI_JPEG}
253 // if you enable delphi jpegs the libJPEG will be ignored
255 {.$DEFINE GLB_LIB_JPEG}
256 // to use the libJPEG http://www.ijg.org/
257 // You will need an aditional header.
258 // http://www.opengl24.de/index.php?cat=header&file=libjpeg
260 // ###### End of preferences ##################################################
263 // ###### PRIVATE. Do not change anything. ####################################
264 // *** old defines for compatibility ***
265 {$IFDEF NO_NATIVE_GL}
266 {$DEFINE GLB_NO_NATIVE_GL}
269 {$definde GLB_PNGIMAGE}
272 // *** Delphi Versions ***
286 // *** checking define combinations ***
287 {$IFDEF GLB_SDL_IMAGE}
289 {$MESSAGE warn 'SDL_image won''t work without SDL. SDL will be activated.'}
292 {$IFDEF GLB_PNGIMAGE}
293 {$MESSAGE warn 'The unit pngimage will be ignored because you are using SDL_image.'}
294 {$undef GLB_PNGIMAGE}
296 {$IFDEF GLB_DELPHI_JPEG}
297 {$MESSAGE warn 'The unit JPEG will be ignored because you are using SDL_image.'}
298 {$undef GLB_DELPHI_JPEG}
301 {$MESSAGE warn 'The library libPNG will be ignored because you are using SDL_image.'}
304 {$IFDEF GLB_LIB_JPEG}
305 {$MESSAGE warn 'The library libJPEG will be ignored because you are using SDL_image.'}
306 {$undef GLB_LIB_JPEG}
309 {$DEFINE GLB_SUPPORT_PNG_READ}
310 {$DEFINE GLB_SUPPORT_JPEG_READ}
313 {$IFDEF GLB_PNGIMAGE}
315 {$MESSAGE warn 'The library libPNG will be ignored if you are using pngimage.'}
319 {$DEFINE GLB_SUPPORT_PNG_READ}
320 {$DEFINE GLB_SUPPORT_PNG_WRITE}
324 {$DEFINE GLB_SUPPORT_PNG_READ}
325 {$DEFINE GLB_SUPPORT_PNG_WRITE}
328 {$IFDEF GLB_DELPHI_JPEG}
329 {$IFDEF GLB_LIB_JPEG}
330 {$MESSAGE warn 'The library libJPEG will be ignored if you are using the unit JPEG.'}
331 {$undef GLB_LIB_JPEG}
334 {$DEFINE GLB_SUPPORT_JPEG_READ}
335 {$DEFINE GLB_SUPPORT_JPEG_WRITE}
338 {$IFDEF GLB_LIB_JPEG}
339 {$DEFINE GLB_SUPPORT_JPEG_READ}
340 {$DEFINE GLB_SUPPORT_JPEG_WRITE}
343 // *** general options ***
354 {$IFDEF GLB_NO_NATIVE_GL} dglOpenGL, {$ENDIF}
356 {$IFDEF GLB_SDL} SDL, {$ENDIF}
357 {$IFDEF GLB_DELPHI} Dialogs, Windows, Graphics, {$ENDIF}
359 {$IFDEF GLB_SDL_IMAGE} SDL_image, {$ENDIF}
361 {$IFDEF GLB_PNGIMAGE} pngimage, {$ENDIF}
362 {$IFDEF GLB_LIB_PNG} libPNG, {$ENDIF}
364 {$IFDEF GLB_DELPHI_JPEG} JPEG, {$ENDIF}
365 {$IFDEF GLB_LIB_JPEG} libJPEG, {$ENDIF}
374 TRGBQuad = packed record
383 {$IFNDEF GLB_NO_NATIVE_GL}
384 // Native OpenGL Implementation
386 PByteBool = ^ByteBool;
396 GL_EXTENSIONS = $1F03;
401 GL_TEXTURE_1D = $0DE0;
402 GL_TEXTURE_2D = $0DE1;
404 GL_MAX_TEXTURE_SIZE = $0D33;
405 GL_PACK_ALIGNMENT = $0D05;
406 GL_UNPACK_ALIGNMENT = $0CF5;
419 GL_LUMINANCE4 = $803F;
420 GL_LUMINANCE8 = $8040;
421 GL_LUMINANCE4_ALPHA4 = $8043;
422 GL_LUMINANCE8_ALPHA8 = $8045;
423 GL_DEPTH_COMPONENT = $1902;
425 GL_UNSIGNED_BYTE = $1401;
427 GL_LUMINANCE = $1909;
428 GL_LUMINANCE_ALPHA = $190A;
430 GL_TEXTURE_WIDTH = $1000;
431 GL_TEXTURE_HEIGHT = $1001;
432 GL_TEXTURE_INTERNAL_FORMAT = $1003;
433 GL_TEXTURE_RED_SIZE = $805C;
434 GL_TEXTURE_GREEN_SIZE = $805D;
435 GL_TEXTURE_BLUE_SIZE = $805E;
436 GL_TEXTURE_ALPHA_SIZE = $805F;
437 GL_TEXTURE_LUMINANCE_SIZE = $8060;
440 GL_UNSIGNED_SHORT_5_6_5 = $8363;
441 GL_UNSIGNED_SHORT_5_6_5_REV = $8364;
442 GL_UNSIGNED_SHORT_4_4_4_4_REV = $8365;
443 GL_UNSIGNED_SHORT_1_5_5_5_REV = $8366;
444 GL_UNSIGNED_INT_2_10_10_10_REV = $8368;
449 GL_NEAREST_MIPMAP_NEAREST = $2700;
450 GL_LINEAR_MIPMAP_NEAREST = $2701;
451 GL_NEAREST_MIPMAP_LINEAR = $2702;
452 GL_LINEAR_MIPMAP_LINEAR = $2703;
453 GL_TEXTURE_MAG_FILTER = $2800;
454 GL_TEXTURE_MIN_FILTER = $2801;
457 GL_TEXTURE_WRAP_S = $2802;
458 GL_TEXTURE_WRAP_T = $2803;
461 GL_CLAMP_TO_EDGE = $812F;
462 GL_CLAMP_TO_BORDER = $812D;
463 GL_TEXTURE_WRAP_R = $8072;
465 GL_MIRRORED_REPEAT = $8370;
468 GL_TEXTURE_BORDER_COLOR = $1004;
471 GL_NORMAL_MAP = $8511;
472 GL_REFLECTION_MAP = $8512;
476 GL_TEXTURE_GEN_MODE = $2500;
477 GL_TEXTURE_GEN_S = $0C60;
478 GL_TEXTURE_GEN_T = $0C61;
479 GL_TEXTURE_GEN_R = $0C62;
482 GL_MAX_CUBE_MAP_TEXTURE_SIZE = $851C;
483 GL_TEXTURE_CUBE_MAP = $8513;
484 GL_TEXTURE_BINDING_CUBE_MAP = $8514;
485 GL_TEXTURE_CUBE_MAP_POSITIVE_X = $8515;
486 GL_TEXTURE_CUBE_MAP_NEGATIVE_X = $8516;
487 GL_TEXTURE_CUBE_MAP_POSITIVE_Y = $8517;
488 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y = $8518;
489 GL_TEXTURE_CUBE_MAP_POSITIVE_Z = $8519;
490 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z = $851A;
492 GL_TEXTURE_RECTANGLE_ARB = $84F5;
494 // GL_SGIS_generate_mipmap
495 GL_GENERATE_MIPMAP = $8191;
497 // GL_EXT_texture_compression_s3tc
498 GL_COMPRESSED_RGB_S3TC_DXT1_EXT = $83F0;
499 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = $83F1;
500 GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = $83F2;
501 GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = $83F3;
503 // GL_EXT_texture_filter_anisotropic
504 GL_TEXTURE_MAX_ANISOTROPY_EXT = $84FE;
505 GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = $84FF;
507 // GL_ARB_texture_compression
508 GL_COMPRESSED_RGB = $84ED;
509 GL_COMPRESSED_RGBA = $84EE;
510 GL_COMPRESSED_ALPHA = $84E9;
511 GL_COMPRESSED_LUMINANCE = $84EA;
512 GL_COMPRESSED_LUMINANCE_ALPHA = $84EB;
521 GL_ARB_texture_border_clamp,
522 GL_ARB_texture_cube_map,
523 GL_ARB_texture_compression,
524 GL_ARB_texture_non_power_of_two,
525 GL_ARB_texture_rectangle,
526 GL_ARB_texture_mirrored_repeat,
528 GL_EXT_texture_edge_clamp,
529 GL_EXT_texture_cube_map,
530 GL_EXT_texture_compression_s3tc,
531 GL_EXT_texture_filter_anisotropic,
532 GL_EXT_texture_rectangle,
533 GL_NV_texture_rectangle,
534 GL_IBM_texture_mirrored_repeat,
535 GL_SGIS_generate_mipmap: Boolean;
539 libglu = 'libGLU.so.1';
540 libopengl = 'libGL.so.1';
542 libglu = 'glu32.dll';
543 libopengl = 'opengl32.dll';
547 function glXGetProcAddress(ProcName: PAnsiChar): Pointer; cdecl; external libopengl;
549 function wglGetProcAddress(ProcName: PAnsiChar): Pointer; stdcall; external libopengl;
552 function glGetString(name: Cardinal): PAnsiChar; {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
554 procedure glEnable(cap: Cardinal); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
555 procedure glDisable(cap: Cardinal); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
556 procedure glGetIntegerv(pname: Cardinal; params: PInteger); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
558 procedure glTexImage1D(target: Cardinal; level, internalformat, width, border: Integer; format, atype: Cardinal; const pixels: Pointer); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
559 procedure glTexImage2D(target: Cardinal; level, internalformat, width, height, border: Integer; format, atype: Cardinal; const pixels: Pointer); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
561 procedure glGenTextures(n: Integer; Textures: PCardinal); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
562 procedure glBindTexture(target: Cardinal; Texture: Cardinal); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
563 procedure glDeleteTextures(n: Integer; const textures: PCardinal); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
565 procedure glReadPixels(x, y: Integer; width, height: Integer; format, atype: Cardinal; pixels: Pointer); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
566 procedure glPixelStorei(pname: Cardinal; param: Integer); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
567 procedure glGetTexImage(target: Cardinal; level: Integer; format: Cardinal; _type: Cardinal; pixels: Pointer); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
569 function glAreTexturesResident(n: Integer; const Textures: PCardinal; residences: PByteBool): ByteBool; {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
570 procedure glTexParameteri(target: Cardinal; pname: Cardinal; param: Integer); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
571 procedure glTexParameterfv(target: Cardinal; pname: Cardinal; const params: PSingle); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
572 procedure glGetTexLevelParameteriv(target: Cardinal; level: Integer; pname: Cardinal; params: PInteger); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
573 procedure glTexGeni(coord, pname: Cardinal; param: Integer); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libopengl;
575 function gluBuild1DMipmaps(Target: Cardinal; Components, Width: Integer; Format, atype: Cardinal; Data: Pointer): Integer; {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libglu;
576 function gluBuild2DMipmaps(Target: Cardinal; Components, Width, Height: Integer; Format, aType: Cardinal; Data: Pointer): Integer; {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF} external libglu;
579 glCompressedTexImage2D : procedure(target: Cardinal; level: Integer; internalformat: Cardinal; width, height: Integer; border: Integer; imageSize: Integer; const data: Pointer); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF}
580 glCompressedTexImage1D : procedure(target: Cardinal; level: Integer; internalformat: Cardinal; width: Integer; border: Integer; imageSize: Integer; const data: Pointer); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF}
581 glGetCompressedTexImage : procedure(target: Cardinal; level: Integer; img: Pointer); {$IFDEF WINDOWS}stdcall; {$else}cdecl; {$ENDIF}
586 ////////////////////////////////////////////////////////////////////////////////////////////////////
587 EglBitmapException = class(Exception);
588 EglBitmapSizeToLargeException = class(EglBitmapException);
589 EglBitmapNonPowerOfTwoException = class(EglBitmapException);
590 EglBitmapUnsupportedFormatFormat = class(EglBitmapException);
592 ////////////////////////////////////////////////////////////////////////////////////////////////////
610 //tfLuminance12Alpha12,
611 tfLuminance16Alpha16,
651 TglBitmapFileType = (
652 {$IFDEF GLB_SUPPORT_PNG_WRITE} ftPNG, {$ENDIF}
653 {$IFDEF GLB_SUPPORT_JPEG_WRITE}ftJPEG, {$ENDIF}
657 TglBitmapFileTypes = set of TglBitmapFileType;
664 TglBitmapNormalMapFunc = (
670 ////////////////////////////////////////////////////////////////////////////////////////////////////
671 TglBitmapColorRec = packed record
673 0: (r, g, b, a: Cardinal);
674 1: (arr: array[0..3] of Cardinal);
677 TglBitmapPixelData = packed record
678 Data, Range: TglBitmapColorRec;
679 Format: TglBitmapFormat;
681 PglBitmapPixelData = ^TglBitmapPixelData;
683 ////////////////////////////////////////////////////////////////////////////////////////////////////
684 TglBitmapPixelPositionFields = set of (ffX, ffY);
685 TglBitmapPixelPosition = record
686 Fields : TglBitmapPixelPositionFields;
691 ////////////////////////////////////////////////////////////////////////////////////////////////////
693 TglBitmapFunctionRec = record
695 Size: TglBitmapPixelPosition;
696 Position: TglBitmapPixelPosition;
697 Source: TglBitmapPixelData;
698 Dest: TglBitmapPixelData;
701 TglBitmapFunction = procedure(var FuncRec: TglBitmapFunctionRec);
703 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
708 fAnisotropic: Integer;
709 fDeleteTextureOnFree: Boolean;
710 fFreeDataAfterGenTexture: Boolean;
712 fIsResident: Boolean;
713 fBorderColor: array[0..3] of Single;
715 fDimension: TglBitmapPixelPosition;
716 fMipMap: TglBitmapMipMap;
717 fFormat: TglBitmapFormat;
724 fFilterMin: Cardinal;
725 fFilterMag: Cardinal;
735 fCustomNameW: WideString;
736 fCustomData: Pointer;
739 function GetWidth: Integer; virtual;
740 function GetHeight: Integer; virtual;
742 function GetFileWidth: Integer; virtual;
743 function GetFileHeight: Integer; virtual;
746 procedure SetCustomData(const aValue: Pointer);
747 procedure SetCustomName(const aValue: String);
748 procedure SetCustomNameW(const aValue: WideString);
749 procedure SetDeleteTextureOnFree(const aValue: Boolean);
750 procedure SetFormat(const aValue: TglBitmapFormat);
751 procedure SetFreeDataAfterGenTexture(const aValue: Boolean);
752 procedure SetID(const aValue: Cardinal);
753 procedure SetMipMap(const aValue: TglBitmapMipMap);
754 procedure SetTarget(const aValue: Cardinal);
755 procedure SetAnisotropic(const aValue: Integer);
758 procedure SetupParameters(var aBuildWithGlu: Boolean);
759 procedure SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
760 const aWidth: Integer = -1; const aHeight: Integer = -1); virtual;
761 procedure GenTexture(const aTestTextureSize: Boolean = true); virtual; abstract;
763 function FlipHorz: Boolean; virtual;
764 function FlipVert: Boolean; virtual;
766 property Width: Integer read GetWidth;
767 property Height: Integer read GetHeight;
769 property FileWidth: Integer read GetFileWidth;
770 property FileHeight: Integer read GetFileHeight;
773 property ID: Cardinal read fID write SetID;
774 property Target: Cardinal read fTarget write SetTarget;
775 property Format: TglBitmapFormat read fFormat write SetFormat;
776 property MipMap: TglBitmapMipMap read fMipMap write SetMipMap;
777 property Anisotropic: Integer read fAnisotropic write SetAnisotropic;
779 property Filename: String read fFilename;
780 property CustomName: String read fCustomName write SetCustomName;
781 property CustomNameW: WideString read fCustomNameW write SetCustomNameW;
782 property CustomData: Pointer read fCustomData write SetCustomData;
784 property DeleteTextureOnFree: Boolean read fDeleteTextureOnFree write SetDeleteTextureOnFree;
785 property FreeDataAfterGenTexture: Boolean read fFreeDataAfterGenTexture write SetFreeDataAfterGenTexture;
787 property Dimension: TglBitmapPixelPosition read fDimension;
788 property Data: PByte read fData;
789 property IsResident: Boolean read fIsResident;
791 procedure AfterConstruction; override;
792 procedure BeforeDestruction; override;
795 procedure LoadFromFile(const aFilename: String);
796 procedure LoadFromStream(const aStream: TStream); virtual;
797 procedure LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
798 const aFormat: TglBitmapFormat; const aArgs: PtrInt = 0);
800 procedure LoadFromResource(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil);
801 procedure LoadFromResourceID(const sInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
805 procedure SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
806 procedure SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType); virtual;
809 function AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: PtrInt = 0): Boolean; overload;
810 function AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
811 const aFormat: TglBitmapFormat; const aArgs: PtrInt = 0): Boolean; overload;
815 function AssignToSurface(out aSurface: PSDL_Surface): Boolean;
816 function AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
817 function AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
818 function AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil;
819 const aArgs: PtrInt = 0): Boolean;
823 function AssignToBitmap(const aBitmap: TBitmap): Boolean;
824 function AssignFromBitmap(const aBitmap: TBitmap): Boolean;
825 function AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
826 function AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction = nil;
827 const aArgs: PtrInt = 0): Boolean;
828 function AddAlphaFromResource(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil;
829 const aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
830 function AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
831 const aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
834 function AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: PtrInt = 0): Boolean; virtual;
835 function AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
836 function AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
837 function AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction = nil; const aArgs: PtrInt = 0): Boolean;
839 function AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte = 0): Boolean;
840 function AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal = 0): Boolean;
841 function AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single = 0): Boolean;
843 function AddAlphaFromValue(const aAlpha: Byte): Boolean;
844 function AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
845 function AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
847 function RemoveAlpha: Boolean; virtual;
850 function Clone: TglBitmap;
851 function ConvertTo(const aFormat: TglBitmapFormat): Boolean; virtual;
852 procedure Invert(const aUseRGB: Boolean = true; const aUseAlpha: Boolean = false);
853 procedure SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
857 procedure FillWithColor(const aRed, aGreen, aBlue: Byte; const aAlpha: Byte = 255);
858 procedure FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal = $FFFFFFFF);
859 procedure FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha : Single = 1);
862 procedure SetFilter(const aMin, aMag: Cardinal);
864 const S: Cardinal = GL_CLAMP_TO_EDGE;
865 const T: Cardinal = GL_CLAMP_TO_EDGE;
866 const R: Cardinal = GL_CLAMP_TO_EDGE);
868 procedure GetPixel(const aPos: TglBitmapPixelPosition; var aPixel: TglBitmapPixelData); virtual;
869 procedure SetPixel(const aPos: TglBitmapPixelPosition; const aPixel: TglBitmapPixelData); virtual;
871 procedure Bind(const aEnableTextureUnit: Boolean = true); virtual;
872 procedure Unbind(const aDisableTextureUnit: Boolean = true); virtual;
875 constructor Create; overload;
876 constructor Create(const aFileName: String); overload;
877 constructor Create(const aStream: TStream); overload;
878 constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat); overload;
879 constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: PtrInt = 0); overload;
881 constructor Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil); overload;
882 constructor Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar); overload;
885 {$IFDEF GLB_SUPPORT_PNG_READ}
886 function LoadPNG(const aStream: TStream): Boolean; virtual;
887 procedure SavePNG(const aStream: TStream); virtual;
889 {$IFDEF GLB_SUPPORT_JPEG_READ}
890 function LoadJPEG(const aStream: TStream): Boolean; virtual;
891 procedure SaveJPEG(const aStream: TStream); virtual;
893 function LoadBMP(const aStream: TStream): Boolean; virtual;
894 procedure SaveBMP(const aStream: TStream); virtual;
896 function LoadTGA(const aStream: TStream): Boolean; virtual;
897 procedure SaveTGA(const aStream: TStream); virtual;
899 function LoadDDS(const aStream: TStream): Boolean; virtual;
900 procedure SaveDDS(const aStream: TStream); virtual;
903 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
904 TglBitmap2D = class(TglBitmap)
907 fLines: array of PByte;
910 procedure GetDXTColorBlock(pData: pByte; relX, relY: Integer; var Pixel: TglBitmapPixelData);
911 procedure GetPixel2DDXT1(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
912 procedure GetPixel2DDXT3(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
913 procedure GetPixel2DDXT5(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
914 procedure GetPixel2DUnmap(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
915 procedure SetPixel2DUnmap(const Pos: TglBitmapPixelPosition; const Pixel: TglBitmapPixelData);
918 function GetScanline(const aIndex: Integer): Pointer;
919 procedure SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
920 const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
921 procedure UploadData(const aTarget: Cardinal; const aBuildWithGlu: Boolean);
925 property Scanline[const aIndex: Integer]: Pointer read GetScanline;
927 procedure AfterConstruction; override;
929 procedure GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
930 procedure GetDataFromTexture;
931 procedure GenTexture(const aTestTextureSize: Boolean = true); override;
933 function FlipHorz: Boolean; override;
934 function FlipVert: Boolean; override;
936 procedure ToNormalMap(const aFunc: TglBitmapNormalMapFunc = nm3x3;
937 const aScale: Single = 2; const aUseAlpha: Boolean = false);
941 TglBitmapCubeMap = class(TglBitmap2D)
946 procedure GenTexture(TestTextureSize: Boolean = true); reintroduce;
948 procedure AfterConstruction; override;
950 procedure GenerateCubeMap(CubeTarget: Cardinal; TestTextureSize: Boolean = true);
952 procedure Unbind(DisableTexCoordsGen: Boolean = true; DisableTextureUnit: Boolean = true); reintroduce; virtual;
953 procedure Bind(EnableTexCoordsGen: Boolean = true; EnableTextureUnit: Boolean = true); reintroduce; virtual;
957 TglBitmapNormalMap = class(TglBitmapCubeMap)
959 procedure AfterConstruction; override;
961 procedure GenerateNormalMap(Size: Integer = 32; TestTextureSize: Boolean = true);
965 TglBitmap1D = class(TglBitmap)
967 procedure GetPixel1DUnmap(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
969 procedure SetDataPointer(Data: pByte; Format: TglBitmapInternalFormat; Width: Integer = -1; Height: Integer = -1); override;
970 procedure UploadData (Target, Format, InternalFormat, Typ: Cardinal; BuildWithGlu: Boolean);
975 procedure AfterConstruction; override;
978 function FlipHorz: Boolean; override;
981 procedure GenTexture(TestTextureSize: Boolean = true); override;
986 NULL_SIZE: TglBitmapPixelPosition = (Fields: []; X: 0; Y: 0);
988 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
989 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
990 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
991 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
992 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
993 procedure glBitmapSetDefaultWrap(
994 const S: Cardinal = GL_CLAMP_TO_EDGE;
995 const T: Cardinal = GL_CLAMP_TO_EDGE;
996 const R: Cardinal = GL_CLAMP_TO_EDGE);
998 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
999 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
1000 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
1001 function glBitmapGetDefaultFormat: TglBitmapFormat;
1002 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
1003 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
1005 function glBitmapPosition(X: Integer = -1; Y: Integer = -1): TglBitmapPixelPosition;
1006 function glBitmapColorRec(const r, g, b, a: Cardinal): TglBitmapColorRec;
1009 glBitmapDefaultDeleteTextureOnFree: Boolean;
1010 glBitmapDefaultFreeDataAfterGenTextures: Boolean;
1011 glBitmapDefaultFormat: TglBitmapFormat;
1012 glBitmapDefaultMipmap: TglBitmapMipMap;
1013 glBitmapDefaultFilterMin: Cardinal;
1014 glBitmapDefaultFilterMag: Cardinal;
1015 glBitmapDefaultWrapS: Cardinal;
1016 glBitmapDefaultWrapT: Cardinal;
1017 glBitmapDefaultWrapR: Cardinal;
1020 function CreateGrayPalette: HPALETTE;
1027 function FormatIsCompressed(Format: TglBitmapInternalFormat): boolean;
1028 function FormatIsUncompressed(Format: TglBitmapInternalFormat): boolean;
1029 function LoadTexture(Filename: String; var Texture: Cardinal{$IFDEF GLB_DELPHI}; LoadFromRes : Boolean; Instance: Cardinal = 0{$ENDIF}): Boolean;
1030 function LoadCubeMap(PositiveX, NegativeX, PositiveY, NegativeY, PositiveZ, NegativeZ: String; var Texture: Cardinal{$IFDEF GLB_DELPHI}; LoadFromRes : Boolean; Instance: Cardinal = 0{$ENDIF}): Boolean;
1031 function LoadNormalMap(Size: Integer; var Texture: Cardinal): Boolean;
1038 ////////////////////////////////////////////////////////////////////////////////////////////////////
1039 TShiftRec = packed record
1041 0: (r, g, b, a: Byte);
1042 1: (arr: array[0..3] of Byte);
1045 TFormatDescriptor = class(TObject)
1047 function GetRedMask: UInt64;
1048 function GetGreenMask: UInt64;
1049 function GetBlueMask: UInt64;
1050 function GetAlphaMask: UInt64;
1052 fFormat: TglBitmapFormat;
1053 fWithAlpha: TglBitmapFormat;
1054 fWithoutAlpha: TglBitmapFormat;
1057 fRange: TglBitmapColorRec;
1060 fglFormat: Cardinal;
1061 fglInternalFormat: Cardinal;
1062 fglDataFormat: Cardinal;
1064 function GetComponents: Integer; virtual;
1066 property Format: TglBitmapFormat read fFormat;
1067 property WithAlpha: TglBitmapFormat read fWithAlpha;
1068 property WithoutAlpha: TglBitmapFormat read fWithoutAlpha;
1069 property Components: Integer read GetComponents;
1070 property PixelSize: Single read fPixelSize;
1072 property glFormat: Cardinal read fglFormat;
1073 property glInternalFormat: Cardinal read fglInternalFormat;
1074 property glDataFormat: Cardinal read fglDataFormat;
1076 property Range: TglBitmapColorRec read fRange;
1077 property Shift: TShiftRec read fShift;
1079 property RedMask: UInt64 read GetRedMask;
1080 property GreenMask: UInt64 read GetGreenMask;
1081 property BlueMask: UInt64 read GetBlueMask;
1082 property AlphaMask: UInt64 read GetAlphaMask;
1084 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); virtual; abstract;
1085 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); virtual; abstract;
1087 function GetSize(const aSize: TglBitmapPixelPosition): Integer; virtual; overload;
1088 function GetSize(const aWidth, aHeight: Integer): Integer; virtual; overload;
1090 function CreateMappingData: Pointer; virtual;
1091 procedure FreeMappingData(var aMappingData: Pointer); virtual;
1093 function IsEmpty: Boolean; virtual;
1094 function HasAlpha: Boolean; virtual;
1095 function MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: UInt64): Boolean; virtual;
1097 procedure PreparePixel(var aPixel: TglBitmapPixelData); virtual;
1099 constructor Create; virtual;
1101 class procedure Init;
1102 class function Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
1103 class function GetWithAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
1104 class procedure Clear;
1105 class procedure Finalize;
1107 TFormatDescriptorClass = class of TFormatDescriptor;
1109 TfdEmpty = class(TFormatDescriptor);
1111 TfdAlpha8 = class(TFormatDescriptor)
1112 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1113 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1114 constructor Create; override;
1117 TfdAlpha16 = class(TFormatDescriptor)
1118 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1119 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1120 constructor Create; override;
1123 TfdLuminance8 = class(TFormatDescriptor)
1124 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1125 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1126 constructor Create; override;
1129 TfdLuminance16 = class(TFormatDescriptor)
1130 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1131 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1132 constructor Create; override;
1135 TfdLuminance4Alpha4 = class(TFormatDescriptor)
1136 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1137 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1138 constructor Create; override;
1141 TfdLuminance6Alpha2 = class(TfdLuminance4Alpha4)
1142 constructor Create; override;
1145 TfdLuminance8Alpha8 = class(TFormatDescriptor)
1146 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1147 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1148 constructor Create; override;
1151 TfdLuminance12Alpha4 = class(TfdLuminance8Alpha8)
1152 constructor Create; override;
1155 TfdLuminance16Alpha16 = class(TFormatDescriptor)
1156 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1157 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1158 constructor Create; override;
1161 TfdR3G3B2 = class(TFormatDescriptor)
1162 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1163 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1164 constructor Create; override;
1167 TfdRGB4 = class(TFormatDescriptor)
1168 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1169 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1170 constructor Create; override;
1173 TfdR5G6B5 = class(TfdRGB4)
1174 constructor Create; override;
1177 TfdRGB5 = class(TfdRGB4)
1178 constructor Create; override;
1181 TfdRGB8 = class(TFormatDescriptor)
1182 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1183 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1184 constructor Create; override;
1187 TfdRGB10 = class(TFormatDescriptor)
1188 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1189 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1190 constructor Create; override;
1193 TfdRGB16 = class(TFormatDescriptor)
1194 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1195 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1196 constructor Create; override;
1199 TfdRGBA2 = class(TfdR3G3B2)
1200 constructor Create; override;
1203 TfdRGBA4 = class(TfdRGB4)
1204 constructor Create; override;
1207 TfdRGB5A1 = class(TfdRGB5)
1208 constructor Create; override;
1211 TfdRGBA8 = class(TfdRGB8)
1212 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1213 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1214 constructor Create; override;
1217 TfdRGB10A2 = class(TfdRGB10)
1218 constructor Create; override;
1221 TfdRGBA16 = class(TfdRGB16)
1222 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1223 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1224 constructor Create; override;
1227 TfdBGR4 = class(TfdRGB4)
1228 constructor Create; override;
1231 TfdB5G6R5 = class(TfdRGB4)
1232 constructor Create; override;
1235 TfdBGR5 = class(TfdRGB5)
1236 constructor Create; override;
1239 TfdBGR8 = class(TFormatDescriptor)
1240 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1241 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1242 constructor Create; override;
1245 TfdBGR10 = class(TfdRGB10)
1246 constructor Create; override;
1249 TfdBGR16 = class(TFormatDescriptor)
1250 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1251 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1252 constructor Create; override;
1255 TfdBGRA2 = class(TfdRGBA2)
1256 constructor Create; override;
1259 TfdBGRA4 = class(TfdRGBA4)
1260 constructor Create; override;
1263 TfdBGR5A1 = class(TfdRGB5A1)
1264 constructor Create; override;
1267 TfdBGRA8 = class(TfdBGR8)
1268 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1269 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1270 constructor Create; override;
1273 TfdBGR10A2 = class(TfdRGB10A2)
1274 constructor Create; override;
1277 TfdBGRA16 = class(TfdBGR16)
1278 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1279 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1280 constructor Create; override;
1283 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1284 TBitfieldFormat = class(TFormatDescriptor)
1286 procedure SetRedMask (const aValue: UInt64);
1287 procedure SetGreenMask(const aValue: UInt64);
1288 procedure SetBlueMask (const aValue: UInt64);
1289 procedure SetAlphaMask(const aValue: UInt64);
1291 procedure Update(aMask: UInt64; out aRange: Cardinal; out aShift: Byte);
1293 property RedMask: UInt64 read GetRedMask write SetRedMask;
1294 property GreenMask: UInt64 read GetGreenMask write SetGreenMask;
1295 property BlueMask: UInt64 read GetBlueMask write SetBlueMask;
1296 property AlphaMask: UInt64 read GetAlphaMask write SetAlphaMask;
1298 property PixelSize: Single read fPixelSize write fPixelSize;
1300 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1301 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1304 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1305 TColorTableEnty = packed record
1308 TColorTable = array of TColorTableEnty;
1309 TColorTableFormat = class(TFormatDescriptor)
1311 fColorTable: TColorTable;
1313 property PixelSize: Single read fPixelSize write fPixelSize;
1314 property ColorTable: TColorTable read fColorTable write fColorTable;
1315 property Range: TglBitmapColorRec read fRange write fRange;
1317 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1318 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1319 destructor Destroy; override;
1323 LUMINANCE_WEIGHT_R = 0.30;
1324 LUMINANCE_WEIGHT_G = 0.59;
1325 LUMINANCE_WEIGHT_B = 0.11;
1327 ALPHA_WEIGHT_R = 0.30;
1328 ALPHA_WEIGHT_G = 0.59;
1329 ALPHA_WEIGHT_B = 0.11;
1331 UNSUPPORTED_FORMAT = 'the given format isn''t supported by this function.';
1333 FORMAT_DESCRIPTOR_CLASSES: array[TglBitmapFormat] of TFormatDescriptorClass = (
1346 TfdLuminance4Alpha4,
1347 TfdLuminance6Alpha2,
1348 TfdLuminance8Alpha8,
1349 TfdLuminance12Alpha4,
1350 //TfdLuminance12Alpha12,
1351 TfdLuminance16Alpha16,
1392 FormatDescriptorCS: TCriticalSection;
1393 FormatDescriptors: array[TglBitmapFormat] of TFormatDescriptor;
1395 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1396 function glBitmapPosition(X, Y: Integer): TglBitmapPixelPosition;
1398 result.Fields := [];
1401 result.Fields := result.Fields + [ffX];
1403 result.Fields := result.Fields + [ffY];
1405 result.X := Max(0, X);
1406 result.Y := Max(0, Y);
1409 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1410 function glBitmapColorRec(const r, g, b, a: Cardinal): TglBitmapColorRec;
1418 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1419 function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes;
1421 //TODO Supported File Formats!
1422 result := [ftDDS, ftTGA, ftBMP];
1424 {$IFDEF GLB_SUPPORT_PNG_WRITE}
1426 tfAlpha4, tfAlpha8, tfAlpha12, tfAlpha16,
1427 tfLuminance4, tfLuminance8, tfLuminance12, tfLuminance16,
1428 tfuminance4Alpha4, tfLuminance6Alpha2, tfLuminance8Alpha8, tfLuminance12Alpha4, tfLuminance12Alpha12, tfLuminance16Alpha16,
1429 tfR3G3B2, tfRGB4, tfRGB5, tfRGB8, tfRGB10, tfRGB12, tfRGB16,
1430 tfRGBA2, tfRGBA4, tfRGB5A1, tfRGBA8, tfRGB10A2, tfRGBA12, tfRGBA16,
1431 tfDepth16, tfDepth24, tfDepth32]
1433 result := result + [ftPNG];
1436 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
1438 tfAlpha4, tfAlpha8, tfAlpha12, tfAlpha16,
1439 tfLuminance4, tfLuminance8, tfLuminance12, tfLuminance16,
1440 tfR3G3B2, tfRGB4, tfRGB5, tfRGB8, tfRGB10, tfRGB12, tfRGB16,
1441 tfDepth16, tfDepth24, tfDepth32]
1443 result := result + [ftJPEG];
1447 tfAlpha4, tfAlpha8, tfAlpha12, tfAlpha16,
1448 tfLuminance4, tfLuminance8, tfLuminance12, tfLuminance16,
1449 tfuminance4Alpha4, tfLuminance6Alpha2, tfLuminance8Alpha8, tfLuminance12Alpha4, tfLuminance12Alpha12, tfLuminance16Alpha16,
1450 tfR3G3B2, tfRGB4, tfRGB5, tfRGB8, tfRGB10, tfRGB12, tfRGB16,
1451 tfRGBA2, tfRGBA4, tfRGB5A1, tfRGBA8, tfRGB10A2, tfRGBA12, tfRGBA16,
1452 tfDepth16, tfDepth24, tfDepth32]
1454 result := result + [ftDDS, ftTGA, ftBMP];
1458 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1459 function IsPowerOfTwo(aNumber: Integer): Boolean;
1461 while (aNumber and 1) = 0 do
1462 aNumber := aNumber shr 1;
1463 result := aNumber = 1;
1466 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1467 function GetTopMostBit(aBitSet: UInt64): Integer;
1470 while aBitSet > 0 do begin
1472 aBitSet := aBitSet shr 1;
1476 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1477 function CountSetBits(aBitSet: UInt64): Integer;
1480 while aBitSet > 0 do begin
1481 if (aBitSet and 1) = 1 then
1483 aBitSet := aBitSet shr 1;
1487 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1488 function LuminanceWeight(const aPixel: TglBitmapPixelData): Cardinal;
1491 LUMINANCE_WEIGHT_R * aPixel.Data.r +
1492 LUMINANCE_WEIGHT_G * aPixel.Data.g +
1493 LUMINANCE_WEIGHT_B * aPixel.Data.b);
1496 //TODO check _ARB functions and constants
1499 {$IFNDEF GLB_NO_NATIVE_GL}
1500 procedure ReadOpenGLExtensions;
1506 MajorVersion, MinorVersion: Integer;
1509 procedure TrimVersionString(Buffer: AnsiString; var Major, Minor: Integer);
1516 Separator := Pos(AnsiString('.'), Buffer);
1518 if (Separator > 1) and (Separator < Length(Buffer)) and
1519 (Buffer[Separator - 1] in ['0'..'9']) and
1520 (Buffer[Separator + 1] in ['0'..'9']) then begin
1523 while (Separator > 0) and (Buffer[Separator] in ['0'..'9']) do
1526 Delete(Buffer, 1, Separator);
1527 Separator := Pos(AnsiString('.'), Buffer) + 1;
1529 while (Separator <= Length(Buffer)) and (AnsiChar(Buffer[Separator]) in ['0'..'9']) do
1532 Delete(Buffer, Separator, 255);
1533 Separator := Pos(AnsiString('.'), Buffer);
1535 Major := StrToInt(Copy(String(Buffer), 1, Separator - 1));
1536 Minor := StrToInt(Copy(String(Buffer), Separator + 1, 1));
1541 function CheckExtension(const Extension: AnsiString): Boolean;
1545 ExtPos := Pos(Extension, Buffer);
1546 result := ExtPos > 0;
1549 result := ((ExtPos + Length(Extension) - 1) = Length(Buffer)) or not (Buffer[ExtPos + Length(Extension)] in ['_', 'A'..'Z', 'a'..'z']);
1553 function glLoad (aFunc: pAnsiChar): pointer;
1556 result := glXGetProcAddress(aFunc);
1558 result := wglGetProcAddress(aFunc);
1565 Context := wglGetCurrentContext;
1567 if Context <> gLastContext then begin
1568 gLastContext := Context;
1572 Buffer := glGetString(GL_VERSION);
1573 TrimVersionString(Buffer, MajorVersion, MinorVersion);
1575 GL_VERSION_1_2 := false;
1576 GL_VERSION_1_3 := false;
1577 GL_VERSION_1_4 := false;
1578 GL_VERSION_2_0 := false;
1580 if MajorVersion = 1 then begin
1581 if MinorVersion >= 1 then begin
1582 if MinorVersion >= 2 then
1583 GL_VERSION_1_2 := true;
1585 if MinorVersion >= 3 then
1586 GL_VERSION_1_3 := true;
1588 if MinorVersion >= 4 then
1589 GL_VERSION_1_4 := true;
1593 if MajorVersion >= 2 then begin
1594 GL_VERSION_1_2 := true;
1595 GL_VERSION_1_3 := true;
1596 GL_VERSION_1_4 := true;
1597 GL_VERSION_2_0 := true;
1601 Buffer := glGetString(GL_EXTENSIONS);
1602 GL_ARB_texture_border_clamp := CheckExtension('GL_ARB_texture_border_clamp');
1603 GL_ARB_texture_cube_map := CheckExtension('GL_ARB_texture_cube_map');
1604 GL_ARB_texture_compression := CheckExtension('GL_ARB_texture_compression');
1605 GL_ARB_texture_non_power_of_two := CheckExtension('GL_ARB_texture_non_power_of_two');
1606 GL_ARB_texture_rectangle := CheckExtension('GL_ARB_texture_rectangle');
1607 GL_ARB_texture_mirrored_repeat := CheckExtension('GL_ARB_texture_mirrored_repeat');
1608 GL_EXT_bgra := CheckExtension('GL_EXT_bgra');
1609 GL_EXT_texture_edge_clamp := CheckExtension('GL_EXT_texture_edge_clamp');
1610 GL_EXT_texture_cube_map := CheckExtension('GL_EXT_texture_cube_map');
1611 GL_EXT_texture_compression_s3tc := CheckExtension('GL_EXT_texture_compression_s3tc');
1612 GL_EXT_texture_filter_anisotropic := CheckExtension('GL_EXT_texture_filter_anisotropic');
1613 GL_EXT_texture_rectangle := CheckExtension('GL_EXT_texture_rectangle');
1614 GL_NV_texture_rectangle := CheckExtension('GL_NV_texture_rectangle');
1615 GL_IBM_texture_mirrored_repeat := CheckExtension('GL_IBM_texture_mirrored_repeat');
1616 GL_SGIS_generate_mipmap := CheckExtension('GL_SGIS_generate_mipmap');
1619 if GL_VERSION_1_3 then begin
1621 glCompressedTexImage1D := glLoad('glCompressedTexImage1D');
1622 glCompressedTexImage2D := glLoad('glCompressedTexImage2D');
1623 glGetCompressedTexImage := glLoad('glGetCompressedTexImage');
1627 // Try loading Extension
1628 glCompressedTexImage1D := glLoad('glCompressedTexImage1DARB');
1629 glCompressedTexImage2D := glLoad('glCompressedTexImage2DARB');
1630 glGetCompressedTexImage := glLoad('glGetCompressedTexImageARB');
1641 function CreateGrayPalette: HPALETTE;
1646 GetMem(Pal, SizeOf(TLogPalette) + (SizeOf(TPaletteEntry) * 256));
1648 Pal.palVersion := $300;
1649 Pal.palNumEntries := 256;
1652 {$DEFINE GLB_TEMPRANGECHECK}
1656 for Idx := 0 to 256 - 1 do begin
1657 Pal.palPalEntry[Idx].peRed := Idx;
1658 Pal.palPalEntry[Idx].peGreen := Idx;
1659 Pal.palPalEntry[Idx].peBlue := Idx;
1660 Pal.palPalEntry[Idx].peFlags := 0;
1663 {$IFDEF GLB_TEMPRANGECHECK}
1664 {$UNDEF GLB_TEMPRANGECHECK}
1668 result := CreatePalette(Pal^);
1675 (* TODO GLB_SDL_IMAGE
1676 {$IFDEF GLB_SDL_IMAGE}
1677 function glBitmapRWseek(context: PSDL_RWops; offset: Integer; whence: Integer): Integer; cdecl;
1679 result := TStream(context^.unknown.data1).Seek(offset, whence);
1682 function glBitmapRWread(context: PSDL_RWops; Ptr: Pointer; size: Integer; maxnum : Integer): Integer; cdecl;
1684 result := TStream(context^.unknown.data1).Read(Ptr^, size * maxnum);
1687 function glBitmapRWwrite(context: PSDL_RWops; Ptr: Pointer; size: Integer; num: Integer): Integer; cdecl;
1689 result := TStream(context^.unknown.data1).Write(Ptr^, size * num);
1692 function glBitmapRWclose(context: PSDL_RWops): Integer; cdecl;
1697 function glBitmapCreateRWops(Stream: TStream): PSDL_RWops;
1699 result := SDL_AllocRW;
1701 if result = nil then
1702 raise EglBitmapException.Create('glBitmapCreateRWops - SDL_AllocRW failed.');
1704 result^.seek := glBitmapRWseek;
1705 result^.read := glBitmapRWread;
1706 result^.write := glBitmapRWwrite;
1707 result^.close := glBitmapRWclose;
1708 result^.unknown.data1 := Stream;
1714 function LoadTexture(Filename: String; var Texture: Cardinal{$IFDEF GLB_DELPHI}; LoadFromRes : Boolean; Instance: Cardinal{$ENDIF}): Boolean;
1716 glBitmap: TglBitmap2D;
1722 if Instance = 0 then
1723 Instance := HInstance;
1725 if (LoadFromRes) then
1726 glBitmap := TglBitmap2D.CreateFromResourceName(Instance, FileName)
1729 glBitmap := TglBitmap2D.Create(FileName);
1732 glBitmap.DeleteTextureOnFree := false;
1733 glBitmap.FreeDataAfterGenTexture := false;
1734 glBitmap.GenTexture(true);
1735 if (glBitmap.ID > 0) then begin
1736 Texture := glBitmap.ID;
1744 function LoadCubeMap(PositiveX, NegativeX, PositiveY, NegativeY, PositiveZ, NegativeZ: String; var Texture: Cardinal{$IFDEF GLB_DELPHI}; LoadFromRes : Boolean; Instance: Cardinal{$ENDIF}): Boolean;
1746 CM: TglBitmapCubeMap;
1751 if Instance = 0 then
1752 Instance := HInstance;
1755 CM := TglBitmapCubeMap.Create;
1757 CM.DeleteTextureOnFree := false;
1761 if (LoadFromRes) then
1762 CM.LoadFromResource(Instance, PositiveX)
1765 CM.LoadFromFile(PositiveX);
1766 CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X);
1769 if (LoadFromRes) then
1770 CM.LoadFromResource(Instance, NegativeX)
1773 CM.LoadFromFile(NegativeX);
1774 CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_X);
1777 if (LoadFromRes) then
1778 CM.LoadFromResource(Instance, PositiveY)
1781 CM.LoadFromFile(PositiveY);
1782 CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Y);
1785 if (LoadFromRes) then
1786 CM.LoadFromResource(Instance, NegativeY)
1789 CM.LoadFromFile(NegativeY);
1790 CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);
1793 if (LoadFromRes) then
1794 CM.LoadFromResource(Instance, PositiveZ)
1797 CM.LoadFromFile(PositiveZ);
1798 CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Z);
1801 if (LoadFromRes) then
1802 CM.LoadFromResource(Instance, NegativeZ)
1805 CM.LoadFromFile(NegativeZ);
1806 CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
1815 function LoadNormalMap(Size: Integer; var Texture: Cardinal): Boolean;
1817 NM: TglBitmapNormalMap;
1821 NM := TglBitmapNormalMap.Create;
1823 NM.DeleteTextureOnFree := false;
1824 NM.GenerateNormalMap(Size);
1834 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1835 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
1837 glBitmapDefaultDeleteTextureOnFree := aDeleteTextureOnFree;
1840 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1841 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
1843 glBitmapDefaultFreeDataAfterGenTextures := aFreeData;
1846 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1847 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
1849 glBitmapDefaultMipmap := aValue;
1852 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1853 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
1855 glBitmapDefaultFormat := aFormat;
1858 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1859 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
1861 glBitmapDefaultFilterMin := aMin;
1862 glBitmapDefaultFilterMag := aMag;
1865 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1866 procedure glBitmapSetDefaultWrap(const S: Cardinal = GL_CLAMP_TO_EDGE; const T: Cardinal = GL_CLAMP_TO_EDGE; const R: Cardinal = GL_CLAMP_TO_EDGE);
1868 glBitmapDefaultWrapS := S;
1869 glBitmapDefaultWrapT := T;
1870 glBitmapDefaultWrapR := R;
1873 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1874 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
1876 result := glBitmapDefaultDeleteTextureOnFree;
1879 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1880 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
1882 result := glBitmapDefaultFreeDataAfterGenTextures;
1885 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1886 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
1888 result := glBitmapDefaultMipmap;
1891 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1892 function glBitmapGetDefaultFormat: TglBitmapFormat;
1894 result := glBitmapDefaultFormat;
1897 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1898 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
1900 aMin := glBitmapDefaultFilterMin;
1901 aMag := glBitmapDefaultFilterMag;
1904 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1905 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
1907 S := glBitmapDefaultWrapS;
1908 T := glBitmapDefaultWrapT;
1909 R := glBitmapDefaultWrapR;
1912 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1913 //TglBitmapFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1914 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1915 function TFormatDescriptor.GetRedMask: UInt64;
1917 result := fRange.r shl fShift.r;
1920 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1921 function TFormatDescriptor.GetGreenMask: UInt64;
1923 result := fRange.g shl fShift.g;
1926 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1927 function TFormatDescriptor.GetBlueMask: UInt64;
1929 result := fRange.b shl fShift.b;
1932 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1933 function TFormatDescriptor.GetAlphaMask: UInt64;
1935 result := fRange.a shl fShift.a;
1938 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1939 function TFormatDescriptor.GetComponents: Integer;
1945 if (fRange.arr[i] > 0) then
1949 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1950 function TFormatDescriptor.GetSize(const aSize: TglBitmapPixelPosition): Integer;
1954 if (ffX in aSize.Fields) or (ffY in aSize.Fields) then begin
1955 w := Max(1, aSize.X);
1956 h := Max(1, aSize.Y);
1957 result := GetSize(w, h);
1962 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1963 function TFormatDescriptor.GetSize(const aWidth, aHeight: Integer): Integer;
1966 if (aWidth <= 0) or (aHeight <= 0) then
1968 result := Ceil(aWidth * aHeight * fPixelSize);
1971 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1972 function TFormatDescriptor.CreateMappingData: Pointer;
1977 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1978 procedure TFormatDescriptor.FreeMappingData(var aMappingData: Pointer);
1983 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1984 function TFormatDescriptor.IsEmpty: Boolean;
1986 result := (fFormat = tfEmpty);
1989 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1990 function TFormatDescriptor.HasAlpha: Boolean;
1992 result := (fRange.a > 0);
1995 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1996 function TFormatDescriptor.MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: UInt64): Boolean;
2000 if (aRedMask = 0) and (aGreenMask = 0) and (aBlueMask = 0) and (aAlphaMask = 0) then
2001 raise EglBitmapException.Create('FormatCheckFormat - All Masks are 0');
2003 if (aRedMask <> RedMask) then
2005 if (aGreenMask <> GreenMask) then
2007 if (aBlueMask <> BlueMask) then
2009 if (aAlphaMask <> AlphaMask) then
2014 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2015 procedure TFormatDescriptor.PreparePixel(var aPixel: TglBitmapPixelData);
2017 FillChar(aPixel, SizeOf(aPixel), 0);
2018 aPixel.Data := fRange;
2019 aPixel.Range := fRange;
2020 aPixel.Format := fFormat;
2023 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2024 constructor TFormatDescriptor.Create;
2029 fWithAlpha := tfEmpty;
2030 fWithoutAlpha := tfEmpty;
2034 fglInternalFormat := 0;
2037 FillChar(fRange, 0, SizeOf(fRange));
2038 FillChar(fShift, 0, SizeOf(fShift));
2041 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2042 //TfdAlpha8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2043 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2044 procedure TfdAlpha8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2046 aData^ := aPixel.Data.a;
2050 procedure TfdAlpha8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2055 aPixel.Data.a := aData^;
2059 constructor TfdAlpha8.Create;
2063 fFormat := tfAlpha8;
2065 fglFormat := GL_ALPHA;
2066 fglInternalFormat := GL_ALPHA8;
2067 fglDataFormat := GL_UNSIGNED_BYTE;
2070 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2071 //TfdAlpha16//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2072 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2073 procedure TfdAlpha16.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2075 PWord(aData)^ := aPixel.Data.a;
2079 procedure TfdAlpha16.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2084 aPixel.Data.a := PWord(aData)^;
2088 constructor TfdAlpha16.Create;
2092 fFormat := tfAlpha16;
2094 fglFormat := GL_ALPHA;
2095 fglInternalFormat := GL_ALPHA16;
2096 fglDataFormat := GL_UNSIGNED_SHORT;
2099 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2100 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2101 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2102 procedure TfdLuminance8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2104 aData^ := LuminanceWeight(aPixel);
2108 procedure TfdLuminance8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2110 aPixel.Data.r := aData^;
2111 aPixel.Data.g := aData^;
2112 aPixel.Data.b := aData^;
2117 constructor TfdLuminance8.Create;
2121 fFormat := tfLuminance8;
2122 fWithAlpha := tfLuminance8Alpha8;
2123 fWithoutAlpha := tfLuminance8;
2127 fglFormat := GL_LUMINANCE;
2128 fglInternalFormat := GL_LUMINANCE8;
2129 fglDataFormat := GL_UNSIGNED_BYTE;
2132 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2133 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2134 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2135 procedure TfdLuminance16.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2137 PWord(aData)^ := LuminanceWeight(aPixel);
2141 procedure TfdLuminance16.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2143 aPixel.Data.r := PWord(aData)^;
2144 aPixel.Data.g := PWord(aData)^;
2145 aPixel.Data.b := PWord(aData)^;
2150 constructor TfdLuminance16.Create;
2154 fFormat := tfLuminance16;
2155 fWithAlpha := tfLuminance16Alpha16;
2156 fWithoutAlpha := tfLuminance16;
2160 fglFormat := GL_LUMINANCE;
2161 fglInternalFormat := GL_LUMINANCE16;
2162 fglDataFormat := GL_UNSIGNED_SHORT;
2165 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2166 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2167 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2168 procedure TfdLuminance4Alpha4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2171 ((LuminanceWeight(aPixel) and fRange.r) shl fShift.r) or
2172 ((aPixel.Data.a and fRange.a) shl fShift.a);
2176 procedure TfdLuminance4Alpha4.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2181 aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and fRange.arr[i];
2185 constructor TfdLuminance4Alpha4.Create;
2189 fFormat := tfLuminance4Alpha4;
2190 fWithAlpha := tfLuminance4Alpha4;
2191 fWithoutAlpha := tfLuminance8;
2197 fglFormat := GL_LUMINANCE;
2198 fglInternalFormat := GL_LUMINANCE4_ALPHA4;
2199 fglDataFormat := GL_UNSIGNED_BYTE;
2202 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2203 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2204 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2205 constructor TfdLuminance6Alpha2.Create;
2208 fFormat := tfLuminance6Alpha2;
2209 fWithAlpha := tfLuminance6Alpha2;
2210 fWithoutAlpha := tfLuminance8;
2216 fglFormat := GL_LUMINANCE;
2217 fglInternalFormat := GL_LUMINANCE6_ALPHA2;
2218 fglDataFormat := GL_UNSIGNED_BYTE;
2221 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2222 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2223 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2224 procedure TfdLuminance8Alpha8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2227 ((LuminanceWeight(aPixel) and fRange.r) shl fShift.r) or
2228 ((aPixel.Data.a and fRange.a) shl fShift.a);
2232 procedure TfdLuminance8Alpha8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2237 aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and fRange.arr[i];
2241 constructor TfdLuminance8Alpha8.Create;
2245 fFormat := tfLuminance8Alpha8;
2246 fWithAlpha := tfLuminance8Alpha8;
2247 fWithoutAlpha := tfLuminance8;
2253 fglFormat := GL_LUMINANCE;
2254 fglInternalFormat := GL_LUMINANCE8_ALPHA8;
2255 fglDataFormat := GL_UNSIGNED_SHORT;
2258 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2259 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2260 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2261 constructor TfdLuminance12Alpha4.Create;
2264 fFormat := tfLuminance12Alpha4;
2265 fWithAlpha := tfLuminance12Alpha4;
2266 fWithoutAlpha := tfLuminance16;
2272 fglFormat := GL_LUMINANCE;
2273 fglInternalFormat := GL_LUMINANCE12_ALPHA4;
2274 fglDataFormat := GL_UNSIGNED_SHORT;
2277 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2278 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2279 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2280 procedure TfdLuminance16Alpha16.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2282 PCardinal(aData)^ :=
2283 ((LuminanceWeight(aPixel) and fRange.r) shl fShift.r) or
2284 ((aPixel.Data.a and fRange.a) shl fShift.a);
2288 procedure TfdLuminance16Alpha16.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2293 aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and fRange.arr[i];
2297 constructor TfdLuminance16Alpha16.Create;
2300 fFormat := tfLuminance16Alpha16;
2301 fWithAlpha := tfLuminance16Alpha16;
2302 fWithoutAlpha := tfLuminance16;
2308 fglFormat := GL_LUMINANCE;
2309 fglInternalFormat := GL_LUMINANCE16_ALPHA16;
2310 fglDataFormat := GL_UNSIGNED_INT;
2313 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2314 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2315 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2316 procedure TfdR3G3B2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2322 if (fRange.arr[i] > 0) then
2323 aData^ := aData^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
2327 procedure TfdR3G3B2.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2332 aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and fRange.arr[i];
2336 constructor TfdR3G3B2.Create;
2340 fFormat := tfR3G3B2;
2341 fWithAlpha := tfRGBA2;
2342 fWithoutAlpha := tfR3G3B2;
2349 fglFormat := GL_RGB;
2350 fglInternalFormat := GL_R3_G3_B2;
2351 fglDataFormat := GL_UNSIGNED_BYTE_2_3_3_REV;
2354 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2355 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2356 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2357 procedure TfdRGB4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2363 if (fRange.arr[i] > 0) then
2364 PWord(aData)^ := PWord(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
2368 procedure TfdRGB4.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2373 aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and fRange.arr[i];
2377 constructor TfdRGB4.Create;
2382 fWithAlpha := tfRGBA4;
2383 fWithoutAlpha := tfRGB4;
2390 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
2391 fglInternalFormat := GL_RGB4;
2392 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
2395 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2396 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2397 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2398 constructor TfdR5G6B5.Create;
2402 fFormat := tfR5G6B5;
2403 fWithAlpha := tfRGBA4;
2404 fWithoutAlpha := tfR5G6B5;
2411 fglFormat := GL_RGB;
2412 fglInternalFormat := GL_RGB8;
2413 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5_REV;
2416 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2417 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2418 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2419 constructor TfdRGB5.Create;
2424 fWithAlpha := tfRGB5A1;
2425 fWithoutAlpha := tfRGB5;
2432 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
2433 fglInternalFormat := GL_RGB5;
2434 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
2437 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2438 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2439 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2440 procedure TfdRGB8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2442 aData^ := aPixel.Data.r;
2444 aData^ := aPixel.Data.g;
2446 aData^ := aPixel.Data.b;
2450 procedure TfdRGB8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2452 aPixel.Data.r := aData^;
2454 aPixel.Data.g := aData^;
2456 aPixel.Data.b := aData^;
2461 constructor TfdRGB8.Create;
2466 fWithAlpha := tfRGBA8;
2467 fWithoutAlpha := tfRGB8;
2474 fglFormat := GL_RGB;
2475 fglInternalFormat := GL_RGB8;
2476 fglDataFormat := GL_UNSIGNED_BYTE;
2479 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2480 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2481 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2482 procedure TfdRGB10.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2486 PCardinal(aData)^ := 0;
2488 if (fRange.arr[i] > 0) then
2489 PCardinal(aData)^ := PCardinal(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
2493 procedure TfdRGB10.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2498 aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and fRange.arr[i];
2502 constructor TfdRGB10.Create;
2507 fWithAlpha := tfRGB10A2;
2508 fWithoutAlpha := tfRGB10;
2515 fglFormat := GL_RGB;
2516 fglInternalFormat := GL_RGB10;
2517 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
2520 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2521 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2522 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2523 procedure TfdRGB16.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2525 PWord(aData)^ := aPixel.Data.r;
2527 PWord(aData)^ := aPixel.Data.g;
2529 PWord(aData)^ := aPixel.Data.b;
2533 procedure TfdRGB16.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2535 aPixel.Data.r := PWord(aData)^;
2537 aPixel.Data.g := PWord(aData)^;
2539 aPixel.Data.b := PWord(aData)^;
2544 constructor TfdRGB16.Create;
2549 fWithAlpha := tfRGBA16;
2550 fWithoutAlpha := tfRGB16;
2557 fglFormat := GL_RGB;
2558 fglInternalFormat := GL_RGB16;
2559 fglDataFormat := GL_UNSIGNED_SHORT;
2562 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2563 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2564 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2565 constructor TfdRGBA2.Create;
2569 fWithAlpha := tfRGBA2;
2570 fWithoutAlpha := tfR3G3B2;
2579 fglFormat := GL_RGBA;
2580 fglInternalFormat := GL_RGBA2;
2581 fglDataFormat := GL_UNSIGNED_BYTE;
2584 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2585 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2586 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2587 constructor TfdRGBA4.Create;
2591 fWithAlpha := tfRGBA4;
2592 fWithoutAlpha := tfRGB4;
2601 fglFormat := GL_RGBA;
2602 fglInternalFormat := GL_RGBA4;
2603 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
2606 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2607 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2608 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2609 constructor TfdRGB5A1.Create;
2612 fFormat := tfRGB5A1;
2613 fWithAlpha := tfRGB5A1;
2614 fWithoutAlpha := tfRGB5;
2623 fglFormat := GL_RGBA;
2624 fglInternalFormat := GL_RGB5_A1;
2625 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
2628 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2629 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2630 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2631 procedure TfdRGBA8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2633 inherited Map(aPixel, aData, aMapData);
2634 aData^ := aPixel.Data.a;
2638 procedure TfdRGBA8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2640 inherited Unmap(aData, aPixel, aMapData);
2641 aPixel.Data.a := aData^;
2645 constructor TfdRGBA8.Create;
2650 fWithAlpha := tfRGBA8;
2651 fWithoutAlpha := tfRGB8;
2660 fglFormat := GL_RGBA;
2661 fglInternalFormat := GL_RGBA8;
2662 fglDataFormat := GL_UNSIGNED_BYTE;
2665 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2666 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2667 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2668 constructor TfdRGB10A2.Create;
2671 fFormat := tfRGB10A2;
2672 fWithAlpha := tfRGB10A2;
2673 fWithoutAlpha := tfRGB10;
2682 fglFormat := GL_RGBA;
2683 fglInternalFormat := GL_RGB10_A2;
2684 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
2687 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2688 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2689 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2690 procedure TfdRGBA16.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2692 inherited Map(aPixel, aData, aMapData);
2693 PWord(aData)^ := aPixel.Data.a;
2697 procedure TfdRGBA16.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2699 inherited Unmap(aData, aPixel, aMapData);
2700 aPixel.Data.a := PWord(aData)^;
2704 constructor TfdRGBA16.Create;
2708 fFormat := tfRGBA16;
2709 fWithAlpha := tfRGBA16;
2710 fWithoutAlpha := tfRGB16;
2719 fglFormat := GL_RGBA;
2720 fglInternalFormat := GL_RGBA16;
2721 fglDataFormat := GL_UNSIGNED_SHORT;
2724 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2725 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2726 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2727 constructor TfdBGR4.Create;
2732 fWithAlpha := tfBGRA4;
2733 fWithoutAlpha := tfBGR4;
2742 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
2743 fglInternalFormat := GL_RGB4;
2744 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
2747 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2748 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2749 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2750 constructor TfdB5G6R5.Create;
2754 fFormat := tfB5G6R5;
2755 fWithAlpha := tfBGRA4;
2756 fWithoutAlpha := tfB5G6R5;
2763 fglFormat := GL_RGB;
2764 fglInternalFormat := GL_RGB8;
2765 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5;
2768 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2769 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2770 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2771 constructor TfdBGR5.Create;
2776 fWithAlpha := tfBGR5A1;
2777 fWithoutAlpha := tfBGR5;
2786 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
2787 fglInternalFormat := GL_RGB5;
2788 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
2791 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2792 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2793 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2794 procedure TfdBGR8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2796 aData^ := aPixel.Data.b;
2798 aData^ := aPixel.Data.g;
2800 aData^ := aPixel.Data.r;
2804 procedure TfdBGR8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2806 aPixel.Data.b := aData^;
2808 aPixel.Data.g := aData^;
2810 aPixel.Data.r := aData^;
2815 constructor TfdBGR8.Create;
2820 fWithAlpha := tfBGRA8;
2821 fWithoutAlpha := tfBGR8;
2830 fglFormat := GL_BGR;
2831 fglInternalFormat := GL_RGB8;
2832 fglDataFormat := GL_UNSIGNED_BYTE;
2835 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2836 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2837 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2838 constructor TfdBGR10.Create;
2842 fWithAlpha := tfBGR10A2;
2843 fWithoutAlpha := tfBGR10;
2852 fglFormat := GL_BGR;
2853 fglInternalFormat := GL_RGB10;
2854 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
2857 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2858 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2859 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2860 procedure TfdBGR16.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2862 PWord(aData)^ := aPixel.Data.b;
2864 PWord(aData)^ := aPixel.Data.g;
2866 PWord(aData)^ := aPixel.Data.r;
2870 procedure TfdBGR16.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2872 aPixel.Data.b := PWord(aData)^;
2874 aPixel.Data.g := PWord(aData)^;
2876 aPixel.Data.r := PWord(aData)^;
2881 constructor TfdBGR16.Create;
2886 fWithAlpha := tfBGRA16;
2887 fWithoutAlpha := tfBGR16;
2896 fglFormat := GL_BGR;
2897 fglInternalFormat := GL_RGB16;
2898 fglDataFormat := GL_UNSIGNED_SHORT;
2901 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2902 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2903 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2904 constructor TfdBGRA2.Create;
2908 fWithAlpha := tfBGRA4;
2909 fWithoutAlpha := tfBGR4;
2918 fglFormat := GL_BGRA;
2919 fglInternalFormat := GL_RGBA2;
2920 fglDataFormat := GL_UNSIGNED_BYTE;
2923 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2924 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2925 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2926 constructor TfdBGRA4.Create;
2930 fWithAlpha := tfBGRA4;
2931 fWithoutAlpha := tfBGR4;
2940 fglFormat := GL_BGRA;
2941 fglInternalFormat := GL_RGBA4;
2942 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
2945 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2946 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2947 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2948 constructor TfdBGR5A1.Create;
2951 fFormat := tfBGR5A1;
2952 fWithAlpha := tfBGR5A1;
2953 fWithoutAlpha := tfBGR5;
2962 fglFormat := GL_BGRA;
2963 fglInternalFormat := GL_RGB5_A1;
2964 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
2967 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2968 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2969 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////s
2970 procedure TfdBGRA8.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2972 inherited Map(aPixel, aData, aMapData);
2973 aData^ := aPixel.Data.a;
2977 procedure TfdBGRA8.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2979 inherited Unmap(aData, aPixel, aMapData);
2980 aPixel.Data.a := aData^;
2984 constructor TfdBGRA8.Create;
2989 fWithAlpha := tfBGRA8;
2990 fWithoutAlpha := tfBGR8;
2999 fglFormat := GL_BGRA;
3000 fglInternalFormat := GL_RGBA8;
3001 fglDataFormat := GL_UNSIGNED_BYTE;
3004 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3005 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3006 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3007 constructor TfdBGR10A2.Create;
3010 fFormat := tfBGR10A2;
3011 fWithAlpha := tfBGR10A2;
3012 fWithoutAlpha := tfBGR10;
3021 fglFormat := GL_BGRA;
3022 fglInternalFormat := GL_RGB10_A2;
3023 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3026 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3027 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3028 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3029 procedure TfdBGRA16.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3031 inherited Map(aPixel, aData, aMapData);
3032 PWord(aData)^ := aPixel.Data.a;
3036 procedure TfdBGRA16.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
3038 inherited Unmap(aData, aPixel, aMapData);
3039 aPixel.Data.a := PWord(aData)^;
3043 constructor TfdBGRA16.Create;
3047 fFormat := tfBGRA16;
3048 fWithAlpha := tfBGRA16;
3049 fWithoutAlpha := tfBGR16;
3058 fglFormat := GL_BGRA;
3059 fglInternalFormat := GL_RGBA16;
3060 fglDataFormat := GL_UNSIGNED_SHORT;
3063 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3064 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3065 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3066 class procedure TFormatDescriptor.Init;
3068 if not Assigned(FormatDescriptorCS) then
3069 FormatDescriptorCS := TCriticalSection.Create;
3072 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3073 class function TFormatDescriptor.Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
3075 FormatDescriptorCS.Enter;
3077 result := FormatDescriptors[aFormat];
3078 if not Assigned(result) then begin
3079 result := FORMAT_DESCRIPTOR_CLASSES[aFormat].Create;
3080 FormatDescriptors[aFormat] := result;
3083 FormatDescriptorCS.Leave;
3087 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3088 class function TFormatDescriptor.GetWithAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
3090 result := Get(Get(aFormat).WithAlpha);
3093 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3094 class procedure TFormatDescriptor.Clear;
3098 FormatDescriptorCS.Enter;
3100 for f := low(FormatDescriptors) to high(FormatDescriptors) do
3101 FreeAndNil(FormatDescriptors[f]);
3103 FormatDescriptorCS.Leave;
3107 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3108 class procedure TFormatDescriptor.Finalize;
3111 FreeAndNil(FormatDescriptorCS);
3114 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3115 //TBitfieldFormat/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3116 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3117 procedure TBitfieldFormat.SetRedMask(const aValue: UInt64);
3119 Update(aValue, fRange.r, fShift.r);
3122 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3123 procedure TBitfieldFormat.SetGreenMask(const aValue: UInt64);
3125 Update(aValue, fRange.g, fShift.g);
3128 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3129 procedure TBitfieldFormat.SetBlueMask(const aValue: UInt64);
3131 Update(aValue, fRange.b, fShift.b);
3134 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3135 procedure TBitfieldFormat.SetAlphaMask(const aValue: UInt64);
3137 Update(aValue, fRange.a, fShift.a);
3140 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3141 procedure TBitfieldFormat.Update(aMask: UInt64; out aRange: Cardinal; out
3148 while (aMask > 0) and ((aMask and 1) = 0) do begin
3150 aMask := aMask shr 1;
3153 while (aMask > 0) do begin
3154 aRange := aRange shl 1;
3155 aMask := aMask shr 1;
3159 fPixelSize := Round(GetTopMostBit(RedMask or GreenMask or BlueMask or AlphaMask) / 8);
3162 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3163 procedure TBitfieldFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3171 ((aPixel.Data.r and fRange.r) shl fShift.r) or
3172 ((aPixel.Data.g and fRange.g) shl fShift.g) or
3173 ((aPixel.Data.b and fRange.b) shl fShift.b) or
3174 ((aPixel.Data.a and fRange.a) shl fShift.a);
3175 s := Round(fPixelSize);
3178 2: PWord(aData)^ := data;
3179 4: PCardinal(aData)^ := data;
3180 8: PUInt64(aData)^ := data;
3182 raise EglBitmapException.CreateFmt('invalid pixel size: %.1f', [fPixelSize]);
3187 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3188 procedure TBitfieldFormat.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
3195 s := Round(fPixelSize);
3198 2: data := PWord(aData)^;
3199 4: data := PCardinal(aData)^;
3200 8: data := PUInt64(aData)^;
3202 raise EglBitmapException.CreateFmt('invalid pixel size: %.1f', [fPixelSize]);
3205 aPixel.Data.arr[i] := (data shr fShift.arr[i]) and fRange.arr[i];
3209 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3210 //TColorTableFormat///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3211 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3212 procedure TColorTableFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3214 raise EglBitmapException.Create('mapping of color table formats is not supported');
3217 procedure TColorTableFormat.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
3226 s := Trunc(fPixelSize);
3227 f := fPixelSize - s;
3228 bits := Round(8 * f);
3230 0: idx := (aData^ shr (8 - bits - PtrInt(aMapData))) and ((1 shl bits) - 1);
3232 2: idx := PWord(aData)^;
3233 4: idx := PCardinal(aData)^;
3234 8: idx := PUInt64(aData)^;
3236 raise EglBitmapException.CreateFmt('invalid pixel size: %.3f', [fPixelSize]);
3238 if (idx >= Length(fColorTable)) then
3239 raise EglBitmapException.CreateFmt('invalid color index: %d', [idx]);
3240 with fColorTable[idx] do begin
3246 inc(aMapData, bits);
3247 if (PtrInt(aMapData) >= 8) then begin
3254 destructor TColorTableFormat.Destroy;
3256 SetLength(fColorTable, 0);
3260 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3261 //TglBitmap - Helper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3262 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3263 procedure glBitmapConvertCopyFunc(var aFuncRec: TglBitmapFunctionRec);
3265 with aFuncRec do begin
3266 if (Source.Range.r > 0) then
3267 Dest.Data.r := Source.Data.r;
3268 if (Source.Range.g > 0) then
3269 Dest.Data.g := Source.Data.g;
3270 if (Source.Range.b > 0) then
3271 Dest.Data.b := Source.Data.b;
3272 if (Source.Range.a > 0) then
3273 Dest.Data.a := Source.Data.a;
3277 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3278 procedure glBitmapConvertCalculateRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
3282 with aFuncRec do begin
3284 if (Source.Range.arr[i] > 0) then
3285 Dest.Data.arr[i] := Round(Dest.Range.arr[i] * Source.Data.arr[i] / Source.Range.arr[i]);
3290 TShiftData = packed record
3292 0: (r, g, b, a: SmallInt);
3293 1: (arr: array[0..3] of SmallInt);
3295 PShiftData = ^TShiftData;
3297 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3298 procedure glBitmapConvertShiftRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
3304 if (Source.Range.arr[i] > 0) then
3305 Dest.Data.arr[i] := Source.Data.arr[i] shr PShiftData(Args)^.arr[i];
3308 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3309 procedure glBitmapInvertFunc(var aFuncRec: TglBitmapFunctionRec);
3311 with aFuncRec do begin
3312 Dest.Data.r := Source.Data.r;
3313 Dest.Data.g := Source.Data.g;
3314 Dest.Data.b := Source.Data.b;
3315 Dest.Data.a := Source.Data.a;
3316 if (Args and $1 > 0) then begin
3317 Dest.Data.r := Dest.Data.r xor Dest.Range.r;
3318 Dest.Data.g := Dest.Data.g xor Dest.Range.g;
3319 Dest.Data.b := Dest.Data.b xor Dest.Range.b;
3321 if (Args and $2 > 0) then begin
3322 Dest.Data.a := Dest.Data.a xor Dest.Range.a;
3327 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3328 procedure glBitmapFillWithColorFunc(var aFuncRec: TglBitmapFunctionRec);
3332 with aFuncRec do begin
3334 Dest.Data.arr[i] := PglBitmapPixelData(Args)^.Data.arr[i];
3338 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3339 procedure glBitmapAlphaFunc(var FuncRec: TglBitmapFunctionRec);
3343 with FuncRec do begin
3344 if (FuncRec.Args = 0) then begin //source has no alpha
3346 Source.Data.r / Source.Range.r * ALPHA_WEIGHT_R +
3347 Source.Data.g / Source.Range.g * ALPHA_WEIGHT_G +
3348 Source.Data.b / Source.Range.b * ALPHA_WEIGHT_B;
3349 Dest.Data.a := Round(Dest.Range.a * Temp);
3351 Dest.Data.a := Round(Source.Data.a / Source.Range.a * Dest.Range.a);
3355 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3356 procedure glBitmapColorKeyAlphaFunc(var FuncRec: TglBitmapFunctionRec);
3358 PglBitmapPixelData = ^TglBitmapPixelData;
3360 with FuncRec do begin
3361 Dest.Data.r := Source.Data.r;
3362 Dest.Data.g := Source.Data.g;
3363 Dest.Data.b := Source.Data.b;
3365 with PglBitmapPixelData(Args)^ do
3366 if ((Dest.Data.r <= Data.r) and (Dest.Data.r >= Range.r) and
3367 (Dest.Data.g <= Data.g) and (Dest.Data.g >= Range.g) and
3368 (Dest.Data.b <= Data.b) and (Dest.Data.b >= Range.b)) then
3371 Dest.Data.a := Dest.Range.a;
3375 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3376 procedure glBitmapValueAlphaFunc(var FuncRec: TglBitmapFunctionRec);
3378 PglBitmapPixelData = ^TglBitmapPixelData;
3380 with FuncRec do begin
3381 Dest.Data.r := Source.Data.r;
3382 Dest.Data.g := Source.Data.g;
3383 Dest.Data.b := Source.Data.b;
3384 Dest.Data.a := PCardinal(Args)^;
3388 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3389 procedure SwapRGB(aData: PByte; aWidth: Integer; const aHasAlpha: Boolean);
3392 TRGBPix = array [0..2] of byte;
3396 while aWidth > 0 do begin
3397 Temp := PRGBPix(aData)^[0];
3398 PRGBPix(aData)^[0] := PRGBPix(aData)^[2];
3399 PRGBPix(aData)^[2] := Temp;
3409 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3410 //TglBitmap - PROTECTED///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3411 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3412 function TglBitmap.GetWidth: Integer;
3414 if (ffX in fDimension.Fields) then
3415 result := fDimension.X
3420 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3421 function TglBitmap.GetHeight: Integer;
3423 if (ffY in fDimension.Fields) then
3424 result := fDimension.Y
3429 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3430 function TglBitmap.GetFileWidth: Integer;
3432 result := Max(1, Width);
3435 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3436 function TglBitmap.GetFileHeight: Integer;
3438 result := Max(1, Height);
3441 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3442 procedure TglBitmap.SetCustomData(const aValue: Pointer);
3444 if fCustomData = aValue then
3446 fCustomData := aValue;
3449 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3450 procedure TglBitmap.SetCustomName(const aValue: String);
3452 if fCustomName = aValue then
3454 fCustomName := aValue;
3457 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3458 procedure TglBitmap.SetCustomNameW(const aValue: WideString);
3460 if fCustomNameW = aValue then
3462 fCustomNameW := aValue;
3465 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3466 procedure TglBitmap.SetDeleteTextureOnFree(const aValue: Boolean);
3468 if fDeleteTextureOnFree = aValue then
3470 fDeleteTextureOnFree := aValue;
3473 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3474 procedure TglBitmap.SetFormat(const aValue: TglBitmapFormat);
3476 if fFormat = aValue then
3478 if TFormatDescriptor.Get(Format).PixelSize <> TFormatDescriptor.Get(aValue).PixelSize then
3479 raise EglBitmapUnsupportedFormatFormat.Create('SetInternalFormat - ' + UNSUPPORTED_FORMAT);
3480 SetDataPointer(Data, aValue, Width, Height);
3483 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3484 procedure TglBitmap.SetFreeDataAfterGenTexture(const aValue: Boolean);
3486 if fFreeDataAfterGenTexture = aValue then
3488 fFreeDataAfterGenTexture := aValue;
3491 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3492 procedure TglBitmap.SetID(const aValue: Cardinal);
3494 if fID = aValue then
3499 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3500 procedure TglBitmap.SetMipMap(const aValue: TglBitmapMipMap);
3502 if fMipMap = aValue then
3507 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3508 procedure TglBitmap.SetTarget(const aValue: Cardinal);
3510 if fTarget = aValue then
3515 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3516 procedure TglBitmap.SetAnisotropic(const aValue: Integer);
3518 MaxAnisotropic: Integer;
3520 fAnisotropic := aValue;
3521 if (ID > 0) then begin
3522 if GL_EXT_texture_filter_anisotropic then begin
3523 if fAnisotropic > 0 then begin
3525 glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @MaxAnisotropic);
3526 if aValue > MaxAnisotropic then
3527 fAnisotropic := MaxAnisotropic;
3528 glTexParameteri(Target, GL_TEXTURE_MAX_ANISOTROPY_EXT, fAnisotropic);
3536 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3537 procedure TglBitmap.CreateID;
3540 glDeleteTextures(1, @fID);
3541 glGenTextures(1, @fID);
3545 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3546 procedure TglBitmap.SetupParameters(var aBuildWithGlu: Boolean);
3548 // Set Up Parameters
3549 SetWrap(fWrapS, fWrapT, fWrapR);
3550 SetFilter(fFilterMin, fFilterMag);
3551 SetAnisotropic(fAnisotropic);
3552 SetBorderColor(fBorderColor[0], fBorderColor[1], fBorderColor[2], fBorderColor[3]);
3554 // Mip Maps Generation Mode
3555 aBuildWithGlu := false;
3556 if (MipMap = mmMipmap) then begin
3557 if (GL_VERSION_1_4 or GL_SGIS_generate_mipmap) then
3558 glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE)
3560 aBuildWithGlu := true;
3561 end else if (MipMap = mmMipmapGlu) then
3562 aBuildWithGlu := true;
3565 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3566 procedure TglBitmap.SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
3567 const aWidth: Integer; const aHeight: Integer);
3571 if (Data <> aData) then begin
3572 if (Assigned(Data)) then
3577 FillChar(fDimension, SizeOf(fDimension), 0);
3578 if not Assigned(fData) then begin
3583 if aWidth <> -1 then begin
3584 fDimension.Fields := fDimension.Fields + [ffX];
3585 fDimension.X := aWidth;
3588 if aHeight <> -1 then begin
3589 fDimension.Fields := fDimension.Fields + [ffY];
3590 fDimension.Y := aHeight;
3593 s := TFormatDescriptor.Get(aFormat).PixelSize;
3595 fPixelSize := Ceil(s);
3596 fRowSize := Ceil(s * aWidth);
3600 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3601 function TglBitmap.FlipHorz: Boolean;
3606 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3607 function TglBitmap.FlipVert: Boolean;
3612 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3613 //TglBitmap - PUBLIC//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3614 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3615 procedure TglBitmap.AfterConstruction;
3617 inherited AfterConstruction;
3621 fIsResident := false;
3623 fFormat := glBitmapGetDefaultFormat;
3624 fMipMap := glBitmapDefaultMipmap;
3625 fFreeDataAfterGenTexture := glBitmapGetDefaultFreeDataAfterGenTexture;
3626 fDeleteTextureOnFree := glBitmapGetDefaultDeleteTextureOnFree;
3628 glBitmapGetDefaultFilter (fFilterMin, fFilterMag);
3629 glBitmapGetDefaultTextureWrap(fWrapS, fWrapT, fWrapR);
3632 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3633 procedure TglBitmap.BeforeDestruction;
3635 SetDataPointer(nil, tfEmpty);
3636 if (fID > 0) and fDeleteTextureOnFree then
3637 glDeleteTextures(1, @fID);
3638 inherited BeforeDestruction;
3641 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3642 procedure TglBitmap.LoadFromFile(const aFilename: String);
3646 fFilename := aFilename;
3647 fs := TFileStream.Create(fFilename, fmOpenRead);
3656 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3657 procedure TglBitmap.LoadFromStream(const aStream: TStream);
3659 {$IFDEF GLB_SUPPORT_PNG_READ}
3660 if not LoadPNG(aStream) then
3662 {$IFDEF GLB_SUPPORT_JPEG_READ}
3663 if not LoadJPEG(aStream) then
3665 if not LoadDDS(aStream) then
3666 if not LoadTGA(aStream) then
3667 if not LoadBMP(aStream) then
3668 raise EglBitmapException.Create('LoadFromStream - Couldn''t load Stream. It''s possible to be an unknow Streamtype.');
3671 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3672 procedure TglBitmap.LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
3673 const aFormat: TglBitmapFormat; const aArgs: PtrInt);
3678 size := TFormatDescriptor.Get(aFormat).GetSize(aSize);
3679 GetMem(tmpData, size);
3681 FillChar(tmpData^, size, #$FF);
3682 SetDataPointer(tmpData, aFormat, aSize.X, aSize.Y);
3687 AddFunc(Self, aFunc, false, Format, aArgs);
3691 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3692 procedure TglBitmap.LoadFromResource(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil);
3694 rs: TResourceStream;
3699 if not Assigned(ResType) then begin
3700 TempPos := Pos('.', Resource);
3701 ResTypeStr := UpperCase(Copy(Resource, TempPos + 1, Length(Resource) - TempPos));
3702 Resource := UpperCase(Copy(Resource, 0, TempPos -1));
3703 TempResType := PChar(ResTypeStr);
3705 TempResType := ResType
3707 rs := TResourceStream.Create(Instance, Resource, TempResType);
3715 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3716 procedure TglBitmap.LoadFromResourceID(const sInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
3718 rs: TResourceStream;
3720 rs := TResourceStream.CreateFromID(Instance, ResourceID, ResType);
3729 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3730 procedure TglBitmap.SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
3734 fs := TFileStream.Create(aFileName, fmCreate);
3737 SaveToStream(fs, aFileType);
3743 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3744 procedure TglBitmap.SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType);
3747 {$IFDEF GLB_SUPPORT_PNG_WRITE}
3748 ftPNG: SavePng(aStream);
3750 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
3751 ftJPEG: SaveJPEG(aStream);
3753 ftDDS: SaveDDS(aStream);
3754 ftTGA: SaveTGA(aStream);
3755 ftBMP: SaveBMP(aStream);
3759 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3760 function TglBitmap.AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: PtrInt): Boolean;
3762 result := AddFunc(Self, aFunc, aCreateTemp, Format, aArgs);
3765 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3766 function TglBitmap.AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
3767 const aFormat: TglBitmapFormat; const aArgs: PtrInt): Boolean;
3769 DestData, TmpData, SourceData: pByte;
3770 TempHeight, TempWidth: Integer;
3771 SourceFD, DestFD: TFormatDescriptor;
3772 SourceMD, DestMD: Pointer;
3774 FuncRec: TglBitmapFunctionRec;
3776 Assert(Assigned(Data));
3777 Assert(Assigned(aSource));
3778 Assert(Assigned(aSource.Data));
3781 if Assigned(aSource.Data) and ((aSource.Height > 0) or (aSource.Width > 0)) then begin
3782 SourceFD := TFormatDescriptor.Get(aSource.Format);
3783 DestFD := TFormatDescriptor.Get(aFormat);
3785 // inkompatible Formats so CreateTemp
3786 if (SourceFD.PixelSize <> DestFD.PixelSize) then
3787 aCreateTemp := true;
3790 TempHeight := Max(1, aSource.Height);
3791 TempWidth := Max(1, aSource.Width);
3793 FuncRec.Sender := Self;
3794 FuncRec.Args := aArgs;
3797 if aCreateTemp then begin
3798 GetMem(TmpData, TFormatDescriptor.Get(aFormat).GetSize(TempWidth, TempHeight));
3799 DestData := TmpData;
3804 SourceFD.PreparePixel(FuncRec.Source);
3805 DestFD.PreparePixel (FuncRec.Dest);
3807 SourceMD := SourceFD.CreateMappingData;
3808 DestMD := DestFD.CreateMappingData;
3810 FuncRec.Size := aSource.Dimension;
3811 FuncRec.Position.Fields := FuncRec.Size.Fields;
3814 SourceData := aSource.Data;
3815 FuncRec.Position.Y := 0;
3816 while FuncRec.Position.Y < TempHeight do begin
3817 FuncRec.Position.X := 0;
3818 while FuncRec.Position.X < TempWidth do begin
3819 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
3821 DestFD.Map(FuncRec.Dest, DestData, DestMD);
3822 inc(FuncRec.Position.X);
3824 inc(FuncRec.Position.Y);
3827 // Updating Image or InternalFormat
3829 SetDataPointer(TmpData, aFormat, aSource.Width, aSource.Height)
3830 else if (aFormat <> fFormat) then
3835 SourceFD.FreeMappingData(SourceMD);
3836 DestFD.FreeMappingData(DestMD);
3847 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3848 function TglBitmap.AssignToSurface(out aSurface: PSDL_Surface): Boolean;
3850 Row, RowSize: Integer;
3851 SourceData, TmpData: PByte;
3853 Pix: TglBitmapPixelData;
3854 FormatDesc: TglBitmapFormatDescriptor;
3856 function GetRowPointer(Row: Integer): pByte;
3858 result := Surface.pixels;
3859 Inc(result, Row * RowSize);
3866 if not FormatIsUncompressed(InternalFormat) then
3867 raise EglBitmapUnsupportedInternalFormat.Create('AssignToSurface - ' + UNSUPPORTED_INTERNAL_FORMAT);
3870 FormatDesc := FORMAT_DESCRIPTORS[Format];
3871 if Assigned(Data) then begin
3872 case Trunc(FormatDesc.GetSize) of
3878 raise EglBitmapException.Create('AssignToSurface - ' + UNSUPPORTED_INTERNAL_FORMAT);
3880 FormatDesc.PreparePixel(Pix);
3881 with Pix.PixelDesc do
3882 Surface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, TempDepth,
3883 RedRange shl RedShift, GreenRange shl GreenShift, BlueRange shl BlueShift, AlphaRange shl AlphaShift);
3886 RowSize := Ceil(FileWidth * FormatDesc.GetSize);
3888 for Row := 0 to FileHeight -1 do begin
3889 TmpData := GetRowPointer(Row);
3890 if Assigned(TmpData) then begin
3891 Move(SourceData^, TmpData^, RowSize);
3892 inc(SourceData, RowSize);
3899 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3900 function TglBitmap.AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
3902 pSource, pData, pTempData: PByte;
3903 Row, RowSize, TempWidth, TempHeight: Integer;
3904 IntFormat, f: TglBitmapInternalFormat;
3905 FormatDesc: TglBitmapFormatDescriptor;
3907 function GetRowPointer(Row: Integer): pByte;
3909 result := Surface^.pixels;
3910 Inc(result, Row * RowSize);
3915 if (Assigned(Surface)) then begin
3916 with Surface^.format^ do begin
3917 IntFormat := tfEmpty;
3918 for f := Low(f) to High(f) do begin
3919 if FORMAT_DESCRIPTORS[f].MaskMatch(RMask, GMask, BMask, AMask) then begin
3924 if (IntFormat = tfEmpty) then
3925 raise EglBitmapException.Create('AssignFromSurface - Invalid Pixelformat.');
3928 FormatDesc := FORMAT_DESCRIPTORS[IntFormat];
3929 TempWidth := Surface^.w;
3930 TempHeight := Surface^.h;
3931 RowSize := Trunc(TempWidth * FormatDesc.GetSize);
3932 GetMem(pData, TempHeight * RowSize);
3935 for Row := 0 to TempHeight -1 do begin
3936 pSource := GetRowPointer(Row);
3937 if (Assigned(pSource)) then begin
3938 Move(pSource^, pTempData^, RowSize);
3939 Inc(pTempData, RowSize);
3942 SetDataPointer(pData, IntFormat, TempWidth, TempHeight);
3951 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3952 function TglBitmap.AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
3954 Row, Col, AlphaInterleave: Integer;
3955 pSource, pDest: PByte;
3957 function GetRowPointer(Row: Integer): pByte;
3959 result := aSurface.pixels;
3960 Inc(result, Row * Width);
3965 if Assigned(Data) then begin
3966 if Format in [tfAlpha8, tfLuminance8Alpha8, tfBGRA8, tfRGBA8] then begin
3967 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, 8, $FF, $FF, $FF, 0);
3969 AlphaInterleave := 0;
3972 AlphaInterleave := 1;
3974 AlphaInterleave := 3;
3978 for Row := 0 to Height -1 do begin
3979 pDest := GetRowPointer(Row);
3980 if Assigned(pDest) then begin
3981 for Col := 0 to Width -1 do begin
3982 Inc(pSource, AlphaInterleave);
3994 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3995 function TglBitmap.AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
3999 bmp := TglBitmap2D.Create;
4001 bmp.AssignFromSurface(Surface);
4002 result := AddAlphaFromGlBitmap(bmp, Func, CustomData);
4010 //TODO rework & test
4011 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4012 function TglBitmap.AssignToBitmap(const aBitmap: TBitmap): Boolean;
4015 pSource, pData: PByte;
4018 if Assigned(Data) then begin
4019 if Assigned(aBitmap) then begin
4020 aBitmap.Width := Width;
4021 aBitmap.Height := Height;
4024 tfAlpha8, ifLuminance, ifDepth8:
4026 Bitmap.PixelFormat := pf8bit;
4027 Bitmap.Palette := CreateGrayPalette;
4030 Bitmap.PixelFormat := pf15bit;
4032 Bitmap.PixelFormat := pf16bit;
4034 Bitmap.PixelFormat := pf24bit;
4036 Bitmap.PixelFormat := pf32bit;
4038 raise EglBitmapException.Create('AssignToBitmap - Invalid Pixelformat.');
4042 for Row := 0 to FileHeight -1 do begin
4043 pData := Bitmap.Scanline[Row];
4045 Move(pSource^, pData^, fRowSize);
4046 Inc(pSource, fRowSize);
4048 // swap RGB(A) to BGR(A)
4049 if InternalFormat in [ifRGB8, ifRGBA8] then
4050 SwapRGB(pData, FileWidth, InternalFormat = ifRGBA8);
4058 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4059 function TglBitmap.AssignFromBitmap(const aBitmap: TBitmap): Boolean;
4061 pSource, pData, pTempData: PByte;
4062 Row, RowSize, TempWidth, TempHeight: Integer;
4063 IntFormat: TglBitmapInternalFormat;
4067 if (Assigned(Bitmap)) then begin
4068 case Bitmap.PixelFormat of
4070 IntFormat := ifLuminance;
4072 IntFormat := ifRGB5A1;
4074 IntFormat := ifR5G6B5;
4076 IntFormat := ifBGR8;
4078 IntFormat := ifBGRA8;
4080 raise EglBitmapException.Create('AssignFromBitmap - Invalid Pixelformat.');
4083 TempWidth := Bitmap.Width;
4084 TempHeight := Bitmap.Height;
4086 RowSize := Trunc(TempWidth * FormatGetSize(IntFormat));
4088 GetMem(pData, TempHeight * RowSize);
4092 for Row := 0 to TempHeight -1 do begin
4093 pSource := Bitmap.Scanline[Row];
4095 if (Assigned(pSource)) then begin
4096 Move(pSource^, pTempData^, RowSize);
4097 Inc(pTempData, RowSize);
4101 SetDataPointer(pData, IntFormat, TempWidth, TempHeight);
4111 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4112 function TglBitmap.AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
4114 Row, Col, AlphaInterleave: Integer;
4115 pSource, pDest: PByte;
4119 if Assigned(Data) then begin
4120 if InternalFormat in [ifAlpha, ifLuminanceAlpha, ifRGBA8, ifBGRA8] then begin
4121 if Assigned(Bitmap) then begin
4122 Bitmap.PixelFormat := pf8bit;
4123 Bitmap.Palette := CreateGrayPalette;
4124 Bitmap.Width := Width;
4125 Bitmap.Height := Height;
4127 case InternalFormat of
4129 AlphaInterleave := 1;
4131 AlphaInterleave := 3;
4133 AlphaInterleave := 0;
4139 for Row := 0 to Height -1 do begin
4140 pDest := Bitmap.Scanline[Row];
4142 if Assigned(pDest) then begin
4143 for Col := 0 to Width -1 do begin
4144 Inc(pSource, AlphaInterleave);
4158 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4159 function TglBitmap.AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
4163 tex := TglBitmap2D.Create;
4165 tex.AssignFromBitmap(Bitmap);
4166 result := AddAlphaFromglBitmap(tex, Func, CustomData);
4172 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4173 function TglBitmap.AddAlphaFromResource(const aInstance: Cardinal; const aResource: String; const aResType: PChar;
4174 const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
4176 RS: TResourceStream;
4181 if Assigned(ResType) then
4182 TempResType := ResType
4185 TempPos := Pos('.', Resource);
4186 ResTypeStr := UpperCase(Copy(Resource, TempPos + 1, Length(Resource) - TempPos));
4187 Resource := UpperCase(Copy(Resource, 0, TempPos -1));
4188 TempResType := PChar(ResTypeStr);
4191 RS := TResourceStream.Create(Instance, Resource, TempResType);
4193 result := AddAlphaFromStream(RS, Func, CustomData);
4199 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4200 function TglBitmap.AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
4201 const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
4203 RS: TResourceStream;
4205 RS := TResourceStream.CreateFromID(Instance, ResourceID, ResType);
4207 result := AddAlphaFromStream(RS, Func, CustomData);
4214 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4215 function TglBitmap.AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
4218 if not FormatIsUncompressed(InternalFormat) then
4219 raise EglBitmapUnsupportedFormatFormat.Create('AddAlphaFromFunc - ' + UNSUPPORTED_FORMAT);
4221 result := AddFunc(Self, aFunc, false, TFormatDescriptor.Get(Format).WithAlpha, aArgs);
4224 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4225 function TglBitmap.AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
4229 FS := TFileStream.Create(FileName, fmOpenRead);
4231 result := AddAlphaFromStream(FS, aFunc, aArgs);
4237 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4238 function TglBitmap.AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
4242 tex := TglBitmap2D.Create(aStream);
4244 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
4250 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4251 function TglBitmap.AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
4253 DestData, DestData2, SourceData: pByte;
4254 TempHeight, TempWidth: Integer;
4255 SourceFD, DestFD: TFormatDescriptor;
4256 SourceMD, DestMD, DestMD2: Pointer;
4258 FuncRec: TglBitmapFunctionRec;
4262 Assert(Assigned(Data));
4263 Assert(Assigned(aBitmap));
4264 Assert(Assigned(aBitmap.Data));
4266 if ((aBitmap.Width = Width) and (aBitmap.Height = Height)) then begin
4267 result := ConvertTo(TFormatDescriptor.Get(Format).WithAlpha);
4268 if not Assigned(aFunc) then
4269 aFunc := glBitmapAlphaFunc;
4271 SourceFD := TFormatDescriptor.Get(aBitmap.Format);
4272 DestFD := TFormatDescriptor.Get(Format);
4275 TempHeight := aBitmap.FileHeight;
4276 TempWidth := aBitmap.FileWidth;
4278 FuncRec.Sender := Self;
4279 FuncRec.Args := aArgs;
4280 FuncRec.Size := Dimension;
4281 FuncRec.Position.Fields := FuncRec.Size.Fields;
4282 FuncRec.Args := PtrInt(SourceFD.HasAlpha) and 1;
4286 SourceData := aBitmap.Data;
4289 SourceFD.PreparePixel(FuncRec.Source);
4290 DestFD.PreparePixel (FuncRec.Dest);
4292 SourceMD := SourceFD.CreateMappingData;
4293 DestMD := DestFD.CreateMappingData;
4294 DestMD2 := DestFD.CreateMappingData;
4296 FuncRec.Position.Y := 0;
4297 while FuncRec.Position.Y < TempHeight do begin
4298 FuncRec.Position.X := 0;
4299 while FuncRec.Position.X < TempWidth do begin
4300 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
4301 DestFD.Unmap (DestData, FuncRec.Dest, DestMD);
4303 DestFD.Map(FuncRec.Dest, DestData2, DestMD2);
4304 inc(FuncRec.Position.X);
4306 inc(FuncRec.Position.Y);
4309 SourceFD.FreeMappingData(SourceMD);
4310 DestFD.FreeMappingData(DestMD);
4311 DestFD.FreeMappingData(DestMD2);
4316 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4317 function TglBitmap.AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte): Boolean;
4319 result := AddAlphaFromColorKeyFloat(aRed / $FF, aGreen / $FF, aBlue / $FF, aDeviation / $FF);
4322 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4323 function TglBitmap.AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal): Boolean;
4325 PixelData: TglBitmapPixelData;
4327 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
4328 result := AddAlphaFromColorKeyFloat(
4329 aRed / PixelData.Range.r,
4330 aGreen / PixelData.Range.g,
4331 aBlue / PixelData.Range.b,
4332 aDeviation / Max(PixelData.Range.r, Max(PixelData.Range.g, PixelData.Range.b)));
4335 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4336 function TglBitmap.AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single): Boolean;
4338 values: array[0..2] of Single;
4341 PixelData: TglBitmapPixelData;
4343 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
4344 with PixelData do begin
4346 values[1] := aGreen;
4349 for i := 0 to 2 do begin
4350 tmp := Trunc(Range.arr[i] * aDeviation);
4351 Data.arr[i] := Min(Range.arr[i], Trunc(Range.arr[i] * values[i] + tmp));
4352 Range.arr[i] := Max(0, Trunc(Range.arr[i] * values[i] - tmp));
4357 result := AddAlphaFromFunc(glBitmapColorKeyAlphaFunc, PtrInt(@PixelData));
4360 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4361 function TglBitmap.AddAlphaFromValue(const aAlpha: Byte): Boolean;
4363 result := AddAlphaFromValueFloat(aAlpha / $FF);
4366 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4367 function TglBitmap.AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
4369 PixelData: TglBitmapPixelData;
4371 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
4372 result := AddAlphaFromValueFloat(aAlpha / PixelData.Range.a);
4375 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4376 function TglBitmap.AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
4378 PixelData: TglBitmapPixelData;
4380 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
4382 Data.a := Min(Range.a, Max(0, Round(Range.a * aAlpha)));
4383 result := AddAlphaFromFunc(glBitmapValueAlphaFunc, PtrInt(@PixelData.Data.a));
4386 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4387 function TglBitmap.RemoveAlpha: Boolean;
4389 FormatDesc: TFormatDescriptor;
4392 FormatDesc := TFormatDescriptor.Get(Format);
4393 if Assigned(Data) then begin
4394 if not ({FormatDesc.IsUncompressed or }FormatDesc.HasAlpha) then
4395 raise EglBitmapUnsupportedFormatFormat.Create('RemoveAlpha - ' + UNSUPPORTED_FORMAT);
4396 result := ConvertTo(FormatDesc.WithoutAlpha);
4400 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4401 function TglBitmap.Clone: TglBitmap;
4408 Temp := (ClassType.Create as TglBitmap);
4410 // copy texture data if assigned
4411 if Assigned(Data) then begin
4412 Size := TFormatDescriptor.Get(Format).GetSize(fDimension);
4413 GetMem(TempPtr, Size);
4415 Move(Data^, TempPtr^, Size);
4416 Temp.SetDataPointer(TempPtr, Format, Width, Height);
4422 Temp.SetDataPointer(nil, Format, Width, Height);
4426 Temp.fTarget := Target;
4427 Temp.fFormat := Format;
4428 Temp.fMipMap := MipMap;
4429 Temp.fAnisotropic := Anisotropic;
4430 Temp.fBorderColor := fBorderColor;
4431 Temp.fDeleteTextureOnFree := DeleteTextureOnFree;
4432 Temp.fFreeDataAfterGenTexture := FreeDataAfterGenTexture;
4433 Temp.fFilterMin := fFilterMin;
4434 Temp.fFilterMag := fFilterMag;
4435 Temp.fWrapS := fWrapS;
4436 Temp.fWrapT := fWrapT;
4437 Temp.fWrapR := fWrapR;
4438 Temp.fFilename := fFilename;
4439 Temp.fCustomName := fCustomName;
4440 Temp.fCustomNameW := fCustomNameW;
4441 Temp.fCustomData := fCustomData;
4450 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4451 function TglBitmap.ConvertTo(const aFormat: TglBitmapFormat): Boolean;
4453 SourceFD, DestFD: TFormatDescriptor;
4454 SourcePD, DestPD: TglBitmapPixelData;
4455 ShiftData: TShiftData;
4457 function CanCopyDirect: Boolean;
4460 ((SourcePD.Range.r = DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
4461 ((SourcePD.Range.g = DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
4462 ((SourcePD.Range.b = DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
4463 ((SourcePD.Range.a = DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
4466 function CanShift: Boolean;
4469 ((SourcePD.Range.r >= DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
4470 ((SourcePD.Range.g >= DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
4471 ((SourcePD.Range.b >= DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
4472 ((SourcePD.Range.a >= DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
4475 function GetShift(aSource, aDest: Cardinal) : ShortInt;
4478 while (aSource > aDest) and (aSource > 0) do begin
4480 aSource := aSource shr 1;
4485 if aFormat <> fFormat then begin
4486 SourceFD := TFormatDescriptor.Get(Format);
4487 DestFD := TFormatDescriptor.Get(aFormat);
4489 SourceFD.PreparePixel(SourcePD);
4490 DestFD.PreparePixel (DestPD);
4492 if CanCopyDirect then
4493 result := AddFunc(Self, glBitmapConvertCopyFunc, false, aFormat)
4494 else if CanShift then begin
4495 ShiftData.r := GetShift(SourcePD.Range.r, DestPD.Range.r);
4496 ShiftData.g := GetShift(SourcePD.Range.g, DestPD.Range.g);
4497 ShiftData.b := GetShift(SourcePD.Range.b, DestPD.Range.b);
4498 ShiftData.a := GetShift(SourcePD.Range.a, DestPD.Range.a);
4499 result := AddFunc(Self, glBitmapConvertShiftRGBAFunc, false, aFormat, PtrInt(@ShiftData));
4501 result := AddFunc(Self, glBitmapConvertCalculateRGBAFunc, false, aFormat);
4506 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4507 procedure TglBitmap.Invert(const aUseRGB: Boolean; const aUseAlpha: Boolean);
4509 if aUseRGB or aUseAlpha then
4510 AddFunc(glBitmapInvertFunc, false, ((PtrInt(aUseAlpha) and 1) shl 1) or (PtrInt(aUseRGB) and 1));
4513 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4514 procedure TglBitmap.SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
4516 fBorderColor[0] := aRed;
4517 fBorderColor[1] := aGreen;
4518 fBorderColor[2] := aBlue;
4519 fBorderColor[3] := aAlpha;
4520 if (ID > 0) then begin
4522 glTexParameterfv(Target, GL_TEXTURE_BORDER_COLOR, @fBorderColor[0]);
4526 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4527 procedure TglBitmap.FreeData;
4529 SetDataPointer(nil, tfEmpty);
4532 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4533 procedure TglBitmap.FillWithColor(const aRed, aGreen, aBlue: Byte;
4534 const aAlpha: Byte);
4536 FillWithColorFloat(aRed/$FF, aGreen/$FF, aBlue/$FF, aAlpha/$FF);
4539 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4540 procedure TglBitmap.FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal);
4542 PixelData: TglBitmapPixelData;
4544 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
4546 aRed / PixelData.Range.r,
4547 aGreen / PixelData.Range.g,
4548 aBlue / PixelData.Range.b,
4549 aAlpha / PixelData.Range.a);
4552 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4553 procedure TglBitmap.FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single);
4555 PixelData: TglBitmapPixelData;
4557 TFormatDescriptor.Get(Format).PreparePixel(PixelData);
4558 with PixelData do begin
4559 Data.r := Max(0, Min(Range.r, Trunc(Range.r * aRed)));
4560 Data.g := Max(0, Min(Range.g, Trunc(Range.g * aGreen)));
4561 Data.b := Max(0, Min(Range.b, Trunc(Range.b * aBlue)));
4562 Data.a := Max(0, Min(Range.a, Trunc(Range.a * aAlpha)));
4564 AddFunc(glBitmapFillWithColorFunc, false, PtrInt(@PixelData));
4567 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4568 procedure TglBitmap.SetFilter(const aMin, aMag: Cardinal);
4573 fFilterMin := GL_NEAREST;
4575 fFilterMin := GL_LINEAR;
4576 GL_NEAREST_MIPMAP_NEAREST:
4577 fFilterMin := GL_NEAREST_MIPMAP_NEAREST;
4578 GL_LINEAR_MIPMAP_NEAREST:
4579 fFilterMin := GL_LINEAR_MIPMAP_NEAREST;
4580 GL_NEAREST_MIPMAP_LINEAR:
4581 fFilterMin := GL_NEAREST_MIPMAP_LINEAR;
4582 GL_LINEAR_MIPMAP_LINEAR:
4583 fFilterMin := GL_LINEAR_MIPMAP_LINEAR;
4585 raise EglBitmapException.Create('SetFilter - Unknow MIN filter.');
4591 fFilterMag := GL_NEAREST;
4593 fFilterMag := GL_LINEAR;
4595 raise EglBitmapException.Create('SetFilter - Unknow MAG filter.');
4599 if (ID > 0) then begin
4601 glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, fFilterMag);
4603 if (MipMap = mmNone) or (Target = GL_TEXTURE_RECTANGLE) then begin
4605 GL_NEAREST, GL_LINEAR:
4606 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
4607 GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR:
4608 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4609 GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR:
4610 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4613 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
4617 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4618 procedure TglBitmap.SetWrap(const S: Cardinal; const T: Cardinal; const R: Cardinal);
4620 procedure CheckAndSetWrap(const aValue: Cardinal; var aTarget: Cardinal);
4624 aTarget := GL_CLAMP;
4627 aTarget := GL_REPEAT;
4629 GL_CLAMP_TO_EDGE: begin
4630 if GL_VERSION_1_2 or GL_EXT_texture_edge_clamp then
4631 aTarget := GL_CLAMP_TO_EDGE
4633 aTarget := GL_CLAMP;
4636 GL_CLAMP_TO_BORDER: begin
4637 if GL_VERSION_1_3 or GL_ARB_texture_border_clamp then
4638 aTarget := GL_CLAMP_TO_BORDER
4640 aTarget := GL_CLAMP;
4643 GL_MIRRORED_REPEAT: begin
4644 if GL_VERSION_1_4 or GL_ARB_texture_mirrored_repeat or GL_IBM_texture_mirrored_repeat then
4645 aTarget := GL_MIRRORED_REPEAT
4647 raise EglBitmapException.Create('SetWrap - Unsupported Texturewrap GL_MIRRORED_REPEAT (S).');
4650 raise EglBitmapException.Create('SetWrap - Unknow Texturewrap (S).');
4655 CheckAndSetWrap(S, fWrapS);
4656 CheckAndSetWrap(T, fWrapT);
4657 CheckAndSetWrap(R, fWrapR);
4659 if (ID > 0) then begin
4661 glTexParameteri(Target, GL_TEXTURE_WRAP_S, fWrapS);
4662 glTexParameteri(Target, GL_TEXTURE_WRAP_T, fWrapT);
4663 glTexParameteri(Target, GL_TEXTURE_WRAP_R, fWrapR);
4667 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4668 procedure TglBitmap.GetPixel(const aPos: TglBitmapPixelPosition; var aPixel: TglBitmapPixelData);
4671 if Assigned (fGetPixelFunc) then
4672 fGetPixelFunc(aPos, aPixel);
4676 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4677 procedure TglBitmap.SetPixel(const aPos: TglBitmapPixelPosition; const aPixel: TglBitmapPixelData);
4680 if Assigned (fSetPixelFunc) then
4681 fSetPixelFuc(aPos, aPixel);
4685 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4686 procedure TglBitmap.Bind(const aEnableTextureUnit: Boolean);
4688 if aEnableTextureUnit then
4691 glBindTexture(Target, ID);
4694 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4695 procedure TglBitmap.Unbind(const aDisableTextureUnit: Boolean);
4697 if aDisableTextureUnit then
4699 glBindTexture(Target, 0);
4702 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4703 constructor TglBitmap.Create;
4705 {$IFNDEF GLB_NO_NATIVE_GL}
4706 ReadOpenGLExtensions;
4708 if (ClassType = TglBitmap) then
4709 raise EglBitmapException.Create('Don''t create TglBitmap directly. Use one of the deviated classes (TglBitmap2D) instead.');
4713 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4714 constructor TglBitmap.Create(const aFileName: String);
4717 LoadFromFile(FileName);
4720 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4721 constructor TglBitmap.Create(const aStream: TStream);
4724 LoadFromStream(aStream);
4727 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4728 constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat);
4734 TFormatDescriptor.Get(aFormat).GetSize(aSize);
4735 GetMem(Image, ImageSize);
4737 FillChar(Image^, ImageSize, #$FF);
4738 SetDataPointer(Image, aFormat, aSize.X, aSize.Y);
4745 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4746 constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat;
4747 const aFunc: TglBitmapFunction; const aArgs: PtrInt);
4750 LoadFromFunc(aSize, aFunc, aFormat, aArgs);
4754 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4755 constructor TglBitmap.Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar);
4758 LoadFromResource(aInstance, aResource, aResType);
4761 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4762 constructor TglBitmap.Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
4765 LoadFromResourceID(aInstance, aResourceID, aResType);
4769 {$IFDEF GLB_SUPPORT_PNG_READ}
4770 {$IF DEFINED(GLB_SDL_IMAGE)}
4771 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4772 //PNG/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4773 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4774 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
4776 Surface: PSDL_Surface;
4780 RWops := glBitmapCreateRWops(aStream);
4782 if IMG_isPNG(RWops) > 0 then begin
4783 Surface := IMG_LoadPNG_RW(RWops);
4785 AssignFromSurface(Surface);
4788 SDL_FreeSurface(Surface);
4796 {$ELSEIF DEFINED(GLB_LIB_PNG)}
4797 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4798 procedure glBitmap_libPNG_read_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
4800 TStream(png_get_io_ptr(png)).Read(buffer^, size);
4803 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4804 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
4807 signature: array [0..7] of byte;
4809 png_info: png_infop;
4811 TempHeight, TempWidth: Integer;
4812 Format: TglBitmapInternalFormat;
4815 png_rows: array of pByte;
4816 Row, LineSize: Integer;
4820 if not init_libPNG then
4821 raise Exception.Create('LoadPNG - unable to initialize libPNG.');
4825 StreamPos := Stream.Position;
4826 Stream.Read(signature, 8);
4827 Stream.Position := StreamPos;
4829 if png_check_sig(@signature, 8) <> 0 then begin
4831 png := png_create_read_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
4833 raise EglBitmapException.Create('LoadPng - couldn''t create read struct.');
4836 png_info := png_create_info_struct(png);
4837 if png_info = nil then begin
4838 png_destroy_read_struct(@png, nil, nil);
4839 raise EglBitmapException.Create('LoadPng - couldn''t create info struct.');
4842 // set read callback
4843 png_set_read_fn(png, stream, glBitmap_libPNG_read_func);
4845 // read informations
4846 png_read_info(png, png_info);
4849 TempHeight := png_get_image_height(png, png_info);
4850 TempWidth := png_get_image_width(png, png_info);
4853 case png_get_color_type(png, png_info) of
4854 PNG_COLOR_TYPE_GRAY:
4855 Format := tfLuminance8;
4856 PNG_COLOR_TYPE_GRAY_ALPHA:
4857 Format := tfLuminance8Alpha8;
4860 PNG_COLOR_TYPE_RGB_ALPHA:
4863 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
4866 // cut upper 8 bit from 16 bit formats
4867 if png_get_bit_depth(png, png_info) > 8 then
4868 png_set_strip_16(png);
4870 // expand bitdepth smaller than 8
4871 if png_get_bit_depth(png, png_info) < 8 then
4872 png_set_expand(png);
4874 // allocating mem for scanlines
4875 LineSize := png_get_rowbytes(png, png_info);
4876 GetMem(png_data, TempHeight * LineSize);
4878 SetLength(png_rows, TempHeight);
4879 for Row := Low(png_rows) to High(png_rows) do begin
4880 png_rows[Row] := png_data;
4881 Inc(png_rows[Row], Row * LineSize);
4884 // read complete image into scanlines
4885 png_read_image(png, @png_rows[0]);
4888 png_read_end(png, png_info);
4890 // destroy read struct
4891 png_destroy_read_struct(@png, @png_info, nil);
4893 SetLength(png_rows, 0);
4896 SetDataPointer(png_data, Format, TempWidth, TempHeight);
4909 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
4910 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4911 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
4915 Header: Array[0..7] of Byte;
4916 Row, Col, PixSize, LineSize: Integer;
4917 NewImage, pSource, pDest, pAlpha: pByte;
4918 Format: TglBitmapInternalFormat;
4921 PngHeader: Array[0..7] of Byte = (#137, #80, #78, #71, #13, #10, #26, #10);
4926 StreamPos := Stream.Position;
4927 Stream.Read(Header[0], SizeOf(Header));
4928 Stream.Position := StreamPos;
4930 {Test if the header matches}
4931 if Header = PngHeader then begin
4932 Png := TPNGObject.Create;
4934 Png.LoadFromStream(Stream);
4936 case Png.Header.ColorType of
4938 Format := ifLuminance;
4939 COLOR_GRAYSCALEALPHA:
4940 Format := ifLuminanceAlpha;
4946 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
4949 PixSize := Trunc(FormatGetSize(Format));
4950 LineSize := Integer(Png.Header.Width) * PixSize;
4952 GetMem(NewImage, LineSize * Integer(Png.Header.Height));
4956 case Png.Header.ColorType of
4957 COLOR_RGB, COLOR_GRAYSCALE:
4959 for Row := 0 to Png.Height -1 do begin
4960 Move (Png.Scanline[Row]^, pDest^, LineSize);
4961 Inc(pDest, LineSize);
4964 COLOR_RGBALPHA, COLOR_GRAYSCALEALPHA:
4966 PixSize := PixSize -1;
4968 for Row := 0 to Png.Height -1 do begin
4969 pSource := Png.Scanline[Row];
4970 pAlpha := pByte(Png.AlphaScanline[Row]);
4972 for Col := 0 to Png.Width -1 do begin
4973 Move (pSource^, pDest^, PixSize);
4974 Inc(pSource, PixSize);
4975 Inc(pDest, PixSize);
4984 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
4987 SetDataPointer(NewImage, Format, Png.Header.Width, Png.Header.Height);
5002 {$IFDEF GLB_SUPPORT_PNG_WRITE}
5003 {$IFDEF GLB_LIB_PNG}
5004 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5005 procedure glBitmap_libPNG_write_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
5007 TStream(png_get_io_ptr(png)).Write(buffer^, size);
5011 {$IF DEFINED(GLB_LIB_PNG)}
5012 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5013 procedure TglBitmap.SavePNG(const aStream: TStream);
5016 png_info: png_infop;
5017 png_rows: array of pByte;
5022 if not (ftPNG in FormatGetSupportedFiles (InternalFormat)) then
5023 raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
5025 if not init_libPNG then
5026 raise Exception.Create('SavePNG - unable to initialize libPNG.');
5029 case FInternalFormat of
5030 ifAlpha, ifLuminance, ifDepth8:
5031 ColorType := PNG_COLOR_TYPE_GRAY;
5033 ColorType := PNG_COLOR_TYPE_GRAY_ALPHA;
5035 ColorType := PNG_COLOR_TYPE_RGB;
5037 ColorType := PNG_COLOR_TYPE_RGBA;
5039 raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
5041 LineSize := Trunc(FormatGetSize(FInternalFormat) * Width);
5043 // creating array for scanline
5044 SetLength(png_rows, Height);
5046 for Row := 0 to Height - 1 do begin
5047 png_rows[Row] := Data;
5048 Inc(png_rows[Row], Row * LineSize)
5052 png := png_create_write_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
5054 raise EglBitmapException.Create('SavePng - couldn''t create write struct.');
5057 png_info := png_create_info_struct(png);
5058 if png_info = nil then begin
5059 png_destroy_write_struct(@png, nil);
5060 raise EglBitmapException.Create('SavePng - couldn''t create info struct.');
5063 // set read callback
5064 png_set_write_fn(png, stream, glBitmap_libPNG_write_func, nil);
5067 png_set_compression_level(png, 6);
5069 if InternalFormat in [ifBGR8, ifBGRA8] then
5072 png_set_IHDR(png, png_info, Width, Height, 8, ColorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
5073 png_write_info(png, png_info);
5074 png_write_image(png, @png_rows[0]);
5075 png_write_end(png, png_info);
5076 png_destroy_write_struct(@png, @png_info);
5078 SetLength(png_rows, 0);
5085 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
5086 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5087 procedure TglBitmap.SavePNG(const aStream: TStream);
5091 pSource, pDest: pByte;
5092 X, Y, PixSize: Integer;
5093 ColorType: Cardinal;
5099 if not (ftPNG in FormatGetSupportedFiles (InternalFormat)) then
5100 raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
5102 case FInternalFormat of
5103 ifAlpha, ifLuminance, ifDepth8: begin
5104 ColorType := COLOR_GRAYSCALE;
5108 ifLuminanceAlpha: begin
5109 ColorType := COLOR_GRAYSCALEALPHA;
5113 ifBGR8, ifRGB8: begin
5114 ColorType := COLOR_RGB;
5118 ifBGRA8, ifRGBA8: begin
5119 ColorType := COLOR_RGBALPHA;
5124 raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
5127 Png := TPNGObject.CreateBlank(ColorType, 8, Width, Height);
5131 for Y := 0 to Height -1 do begin
5132 pDest := png.ScanLine[Y];
5133 for X := 0 to Width -1 do begin
5134 Move(pSource^, pDest^, PixSize);
5135 Inc(pDest, PixSize);
5136 Inc(pSource, PixSize);
5138 png.AlphaScanline[Y]^[X] := pSource^;
5143 // convert RGB line to BGR
5144 if InternalFormat in [ifRGB8, ifRGBA8] then begin
5145 pTemp := png.ScanLine[Y];
5146 for X := 0 to Width -1 do begin
5147 Temp := pByteArray(pTemp)^[0];
5148 pByteArray(pTemp)^[0] := pByteArray(pTemp)^[2];
5149 pByteArray(pTemp)^[2] := Temp;
5156 Png.CompressionLevel := 6;
5157 Png.SaveToStream(Stream);
5165 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5166 //JPEG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5167 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5168 {$IFDEF GLB_LIB_JPEG}
5170 glBitmap_libJPEG_source_mgr_ptr = ^glBitmap_libJPEG_source_mgr;
5171 glBitmap_libJPEG_source_mgr = record
5172 pub: jpeg_source_mgr;
5175 SrcBuffer: array [1..4096] of byte;
5178 glBitmap_libJPEG_dest_mgr_ptr = ^glBitmap_libJPEG_dest_mgr;
5179 glBitmap_libJPEG_dest_mgr = record
5180 pub: jpeg_destination_mgr;
5182 DestStream: TStream;
5183 DestBuffer: array [1..4096] of byte;
5186 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5188 procedure glBitmap_libJPEG_error_exit(cinfo: j_common_ptr); cdecl;
5192 SetLength(Msg, 256);
5193 cinfo^.err^.format_message(cinfo, pChar(Msg));
5194 Writeln('ERROR [' + IntToStr(cinfo^.err^.msg_code) + '] ' + Msg);
5195 cinfo^.global_state := 0;
5200 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5202 procedure glBitmap_libJPEG_output_message(cinfo: j_common_ptr); cdecl;
5206 SetLength(Msg, 256);
5207 cinfo^.err^.format_message(cinfo, pChar(Msg));
5208 Writeln('OUTPUT [' + IntToStr(cinfo^.err^.msg_code) + '] ' + Msg);
5209 cinfo^.global_state := 0;
5213 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5215 procedure glBitmap_libJPEG_init_source(cinfo: j_decompress_ptr); cdecl;
5220 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5221 function glBitmap_libJPEG_fill_input_buffer(cinfo: j_decompress_ptr): boolean; cdecl;
5223 src: glBitmap_libJPEG_source_mgr_ptr;
5226 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
5228 bytes := src^.SrcStream.Read(src^.SrcBuffer[1], 4096);
5229 if (bytes <= 0) then begin
5230 src^.SrcBuffer[1] := $FF;
5231 src^.SrcBuffer[2] := JPEG_EOI;
5235 src^.pub.next_input_byte := @(src^.SrcBuffer[1]);
5236 src^.pub.bytes_in_buffer := bytes;
5241 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5242 procedure glBitmap_libJPEG_skip_input_data(cinfo: j_decompress_ptr; num_bytes: Longint); cdecl;
5244 src: glBitmap_libJPEG_source_mgr_ptr;
5246 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
5248 if num_bytes > 0 then begin
5249 // wanted byte isn't in buffer so set stream position and read buffer
5250 if num_bytes > src^.pub.bytes_in_buffer then begin
5251 src^.SrcStream.Position := src^.SrcStream.Position + num_bytes - src^.pub.bytes_in_buffer;
5252 src^.pub.fill_input_buffer(cinfo);
5254 // wanted byte is in buffer so only skip
5255 inc(src^.pub.next_input_byte, num_bytes);
5256 dec(src^.pub.bytes_in_buffer, num_bytes);
5261 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5263 procedure glBitmap_libJPEG_term_source(cinfo: j_decompress_ptr); cdecl;
5268 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5270 procedure glBitmap_libJPEG_init_destination(cinfo: j_compress_ptr); cdecl;
5275 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5276 function glBitmap_libJPEG_empty_output_buffer(cinfo: j_compress_ptr): boolean; cdecl;
5278 dest: glBitmap_libJPEG_dest_mgr_ptr;
5280 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
5282 if dest^.pub.free_in_buffer < Cardinal(Length(dest^.DestBuffer)) then begin
5283 // write complete buffer
5284 dest^.DestStream.Write(dest^.DestBuffer[1], SizeOf(dest^.DestBuffer));
5287 dest^.pub.next_output_byte := @dest^.DestBuffer[1];
5288 dest^.pub.free_in_buffer := Length(dest^.DestBuffer);
5294 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5295 procedure glBitmap_libJPEG_term_destination(cinfo: j_compress_ptr); cdecl;
5298 dest: glBitmap_libJPEG_dest_mgr_ptr;
5300 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
5302 for Idx := Low(dest^.DestBuffer) to High(dest^.DestBuffer) do begin
5303 // check for endblock
5304 if (Idx < High(dest^.DestBuffer)) and (dest^.DestBuffer[Idx] = $FF) and (dest^.DestBuffer[Idx +1] = JPEG_EOI) then begin
5306 dest^.DestStream.Write(dest^.DestBuffer[Idx], 2);
5311 dest^.DestStream.Write(dest^.DestBuffer[Idx], 1);
5316 {$IFDEF GLB_SUPPORT_JPEG_READ}
5317 {$IF DEFINED(GLB_SDL_IMAGE)}
5318 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5319 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
5321 Surface: PSDL_Surface;
5326 RWops := glBitmapCreateRWops(Stream);
5328 if IMG_isJPG(RWops) > 0 then begin
5329 Surface := IMG_LoadJPG_RW(RWops);
5331 AssignFromSurface(Surface);
5334 SDL_FreeSurface(Surface);
5342 {$ELSEIF DEFINED(GLB_LIB_JPEG)}
5343 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5344 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
5347 Temp: array[0..1]of Byte;
5349 jpeg: jpeg_decompress_struct;
5350 jpeg_err: jpeg_error_mgr;
5352 IntFormat: TglBitmapInternalFormat;
5354 TempHeight, TempWidth: Integer;
5361 if not init_libJPEG then
5362 raise Exception.Create('LoadJPG - unable to initialize libJPEG.');
5365 // reading first two bytes to test file and set cursor back to begin
5366 StreamPos := Stream.Position;
5367 Stream.Read(Temp[0], 2);
5368 Stream.Position := StreamPos;
5370 // if Bitmap then read file.
5371 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
5372 FillChar(jpeg, SizeOf(jpeg_decompress_struct), $00);
5373 FillChar(jpeg_err, SizeOf(jpeg_error_mgr), $00);
5376 jpeg.err := jpeg_std_error(@jpeg_err);
5377 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
5378 jpeg_err.output_message := glBitmap_libJPEG_output_message;
5380 // decompression struct
5381 jpeg_create_decompress(@jpeg);
5383 // allocation space for streaming methods
5384 jpeg.src := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_source_mgr));
5386 // seeting up custom functions
5387 with glBitmap_libJPEG_source_mgr_ptr(jpeg.src)^ do begin
5388 pub.init_source := glBitmap_libJPEG_init_source;
5389 pub.fill_input_buffer := glBitmap_libJPEG_fill_input_buffer;
5390 pub.skip_input_data := glBitmap_libJPEG_skip_input_data;
5391 pub.resync_to_restart := jpeg_resync_to_restart; // use default method
5392 pub.term_source := glBitmap_libJPEG_term_source;
5394 pub.bytes_in_buffer := 0; // forces fill_input_buffer on first read
5395 pub.next_input_byte := nil; // until buffer loaded
5397 SrcStream := Stream;
5400 // set global decoding state
5401 jpeg.global_state := DSTATE_START;
5403 // read header of jpeg
5404 jpeg_read_header(@jpeg, false);
5406 // setting output parameter
5407 case jpeg.jpeg_color_space of
5410 jpeg.out_color_space := JCS_GRAYSCALE;
5411 IntFormat := ifLuminance;
5414 jpeg.out_color_space := JCS_RGB;
5415 IntFormat := ifRGB8;
5419 jpeg_start_decompress(@jpeg);
5421 TempHeight := jpeg.output_height;
5422 TempWidth := jpeg.output_width;
5424 // creating new image
5425 GetMem(pImage, FormatGetImageSize(glBitmapPosition(TempWidth, TempHeight), IntFormat));
5429 for Row := 0 to TempHeight -1 do begin
5430 jpeg_read_scanlines(@jpeg, @pTemp, 1);
5431 Inc(pTemp, Trunc(FormatGetSize(IntFormat) * TempWidth));
5434 // finish decompression
5435 jpeg_finish_decompress(@jpeg);
5437 // destroy decompression
5438 jpeg_destroy_decompress(@jpeg);
5440 SetDataPointer(pImage, IntFormat, TempWidth, TempHeight);
5453 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
5454 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5455 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
5460 Temp: array[0..1]of Byte;
5464 // reading first two bytes to test file and set cursor back to begin
5465 StreamPos := Stream.Position;
5466 Stream.Read(Temp[0], 2);
5467 Stream.Position := StreamPos;
5469 // if Bitmap then read file.
5470 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
5471 bmp := TBitmap.Create;
5473 jpg := TJPEGImage.Create;
5475 jpg.LoadFromStream(Stream);
5477 result := AssignFromBitmap(bmp);
5489 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
5490 {$IF DEFEFINED(GLB_LIB_JPEG)}
5491 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5492 procedure TglBitmap.SaveJPEG(Stream: TStream);
5494 jpeg: jpeg_compress_struct;
5495 jpeg_err: jpeg_error_mgr;
5497 pTemp, pTemp2: pByte;
5499 procedure CopyRow(pDest, pSource: pByte);
5503 for X := 0 to Width - 1 do begin
5504 pByteArray(pDest)^[0] := pByteArray(pSource)^[2];
5505 pByteArray(pDest)^[1] := pByteArray(pSource)^[1];
5506 pByteArray(pDest)^[2] := pByteArray(pSource)^[0];
5513 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
5514 raise EglBitmapUnsupportedInternalFormat.Create('SaveJpg - ' + UNSUPPORTED_INTERNAL_FORMAT);
5516 if not init_libJPEG then
5517 raise Exception.Create('SaveJPG - unable to initialize libJPEG.');
5520 FillChar(jpeg, SizeOf(jpeg_compress_struct), $00);
5521 FillChar(jpeg_err, SizeOf(jpeg_error_mgr), $00);
5524 jpeg.err := jpeg_std_error(@jpeg_err);
5525 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
5526 jpeg_err.output_message := glBitmap_libJPEG_output_message;
5528 // compression struct
5529 jpeg_create_compress(@jpeg);
5531 // allocation space for streaming methods
5532 jpeg.dest := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_dest_mgr));
5534 // seeting up custom functions
5535 with glBitmap_libJPEG_dest_mgr_ptr(jpeg.dest)^ do begin
5536 pub.init_destination := glBitmap_libJPEG_init_destination;
5537 pub.empty_output_buffer := glBitmap_libJPEG_empty_output_buffer;
5538 pub.term_destination := glBitmap_libJPEG_term_destination;
5540 pub.next_output_byte := @DestBuffer[1];
5541 pub.free_in_buffer := Length(DestBuffer);
5543 DestStream := Stream;
5546 // very important state
5547 jpeg.global_state := CSTATE_START;
5548 jpeg.image_width := Width;
5549 jpeg.image_height := Height;
5550 case InternalFormat of
5551 ifAlpha, ifLuminance, ifDepth8: begin
5552 jpeg.input_components := 1;
5553 jpeg.in_color_space := JCS_GRAYSCALE;
5555 ifRGB8, ifBGR8: begin
5556 jpeg.input_components := 3;
5557 jpeg.in_color_space := JCS_RGB;
5561 jpeg_set_defaults(@jpeg);
5562 jpeg_set_quality(@jpeg, 95, true);
5563 jpeg_start_compress(@jpeg, true);
5566 if InternalFormat = ifBGR8 then
5567 GetMem(pTemp2, fRowSize)
5572 for Row := 0 to jpeg.image_height -1 do begin
5574 if InternalFormat = ifBGR8 then
5575 CopyRow(pTemp2, pTemp)
5580 jpeg_write_scanlines(@jpeg, @pTemp2, 1);
5581 inc(pTemp, fRowSize);
5585 if InternalFormat = ifBGR8 then
5588 jpeg_finish_compress(@jpeg);
5589 jpeg_destroy_compress(@jpeg);
5595 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
5596 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5597 procedure TglBitmap.SaveJPEG(Stream: TStream);
5602 if not (ftJPEG in FormatGetSupportedFiles (InternalFormat)) then
5603 raise EglBitmapUnsupportedInternalFormat.Create('SaveJpg - ' + UNSUPPORTED_INTERNAL_FORMAT);
5605 Bmp := TBitmap.Create;
5607 Jpg := TJPEGImage.Create;
5609 AssignToBitmap(Bmp);
5610 if FInternalFormat in [ifAlpha, ifLuminance, ifDepth8] then begin
5611 Jpg.Grayscale := true;
5612 Jpg.PixelFormat := jf8Bit;
5615 Jpg.SaveToStream(Stream);
5626 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5627 //BMP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5628 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5635 BMP_COMP_BITFIELDS = 3;
5638 TBMPHeader = packed record
5643 bfOffBits: Cardinal;
5646 TBMPInfo = packed record
5652 biCompression: Cardinal;
5653 biSizeImage: Cardinal;
5654 biXPelsPerMeter: Longint;
5655 biYPelsPerMeter: Longint;
5656 biClrUsed: Cardinal;
5657 biClrImportant: Cardinal;
5661 TBMPInfoOS = packed record
5670 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5671 function TglBitmap.LoadBMP(const aStream: TStream): Boolean;
5673 //////////////////////////////////////////////////////////////////////////////////////////////////
5674 function ReadInfo(var aInfo: TBMPInfo; var aMask: TglBitmapColorRec): TglBitmapFormat;
5677 aStream.Read(aInfo, SizeOf(aInfo));
5678 FillChar(aMask, SizeOf(aMask), 0);
5681 case aInfo.biCompression of
5683 BMP_COMP_RLE8: begin
5684 raise EglBitmapException.Create('RLE compression is not supported');
5686 BMP_COMP_BITFIELDS: begin
5687 if (aInfo.biBitCount = 16) or (aInfo.biBitCount = 32) then begin
5688 aStream.Read(aMask.r, SizeOf(aMask.r));
5689 aStream.Read(aMask.g, SizeOf(aMask.g));
5690 aStream.Read(aMask.b, SizeOf(aMask.b));
5691 aStream.Read(aMask.a, SizeOf(aMask.a));
5693 raise EglBitmapException.Create('Bitfields are only supported for 16bit and 32bit formats');
5697 //get suitable format
5698 case aInfo.biBitCount of
5699 8: result := tfLuminance8;
5700 16: result := tfBGR5;
5701 24: result := tfBGR8;
5702 32: result := tfBGRA8;
5706 function ReadColorTable(var aFormat: TglBitmapFormat; const aInfo: TBMPInfo): TColorTableFormat;
5709 ColorTable: TColorTable;
5712 if (aInfo.biBitCount >= 16) then
5714 aFormat := tfLuminance8;
5715 c := aInfo.biClrUsed;
5717 c := 1 shl aInfo.biBitCount;
5718 SetLength(ColorTable, c);
5719 for i := 0 to c-1 do begin
5720 aStream.Read(ColorTable[i], SizeOf(TColorTableEnty));
5721 if (ColorTable[i].r <> ColorTable[i].g) or (ColorTable[i].g <> ColorTable[i].b) then
5725 result := TColorTableFormat.Create;
5726 result.PixelSize := aInfo.biBitCount / 8;
5727 result.ColorTable := ColorTable;
5728 result.Range := glBitmapColorRec($FF, $FF, $FF, $00);
5731 //////////////////////////////////////////////////////////////////////////////////////////////////
5732 function CheckBitfields(var aFormat: TglBitmapFormat; const aMask: TglBitmapColorRec;
5733 const aInfo: TBMPInfo): TBitfieldFormat;
5735 TmpFormat: TglBitmapFormat;
5736 FormatDesc: TFormatDescriptor;
5739 if (aMask.r <> 0) or (aMask.g <> 0) or (aMask.b <> 0) or (aMask.a <> 0) then begin
5740 for TmpFormat := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
5741 FormatDesc := TFormatDescriptor.Get(TmpFormat);
5742 if FormatDesc.MaskMatch(aMask.r, aMask.g, aMask.b, aMask.a) then begin
5743 aFormat := FormatDesc.Format;
5748 if (aMask.a = 0) and TFormatDescriptor.Get(aFormat).HasAlpha then
5749 aFormat := TFormatDescriptor.Get(aFormat).WithoutAlpha;
5750 if (aMask.a <> 0) and not TFormatDescriptor.Get(aFormat).HasAlpha then
5751 aFormat := TFormatDescriptor.Get(aFormat).WithAlpha;
5753 result := TBitfieldFormat.Create;
5754 result.PixelSize := aInfo.biBitCount / 8;
5755 result.RedMask := aMask.r;
5756 result.GreenMask := aMask.g;
5757 result.BlueMask := aMask.b;
5758 result.AlphaMask := aMask.a;
5765 ImageSize, rbLineSize, wbLineSize, Padding, i: Integer;
5766 PaddingBuff: Cardinal;
5767 LineBuf, ImageData, TmpData: PByte;
5768 SourceMD, DestMD: Pointer;
5769 BmpFormat: TglBitmapFormat;
5770 ColorTable: TColorTable;
5773 Mask: TglBitmapColorRec;
5778 SpecialFormat: TFormatDescriptor;
5779 FormatDesc: TFormatDescriptor;
5781 //////////////////////////////////////////////////////////////////////////////////////////////////
5782 procedure SpecialFormatReadLine(aData: PByte; aLineBuf: PByte);
5785 Pixel: TglBitmapPixelData;
5787 aStream.Read(aLineBuf^, rbLineSize);
5788 SpecialFormat.PreparePixel(Pixel);
5789 for i := 0 to Info.biWidth-1 do begin
5790 SpecialFormat.Unmap(aLineBuf, Pixel, SourceMD);
5791 with FormatDesc do begin
5792 //TODO: use convert function
5794 if (SpecialFormat.Range.arr[j] <> Range.arr[j]) then begin
5795 if (SpecialFormat.Range.arr[j] > 0) then
5796 Pixel.Data.arr[j] := Round(Pixel.Data.arr[j] / SpecialFormat.Range.arr[j] * Range.arr[j])
5798 Pixel.Data.arr[j] := 0;
5801 FormatDesc.Map(Pixel, aData, DestMD);
5807 BmpFormat := tfEmpty;
5808 SpecialFormat := nil;
5814 StartPos := aStream.Position;
5815 aStream.Read(Header, SizeOf(Header));
5817 if Header.bfType = BMP_MAGIC then begin
5819 BmpFormat := ReadInfo(Info, Mask);
5820 SpecialFormat := ReadColorTable(BmpFormat, Info);
5821 if not Assigned(SpecialFormat) then
5822 SpecialFormat := CheckBitfields(BmpFormat, Mask, Info);
5823 aStream.Position := StartPos + Header.bfOffBits;
5825 if (BmpFormat <> tfEmpty) then begin
5826 FormatDesc := TFormatDescriptor.Get(BmpFormat);
5827 rbLineSize := Round(Info.biWidth * Info.biBitCount / 8); //ReadBuffer LineSize
5828 wbLineSize := Trunc(Info.biWidth * FormatDesc.PixelSize);
5829 Padding := (((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3) - rbLineSize;
5832 DestMD := FormatDesc.CreateMappingData;
5833 ImageSize := FormatDesc.GetSize(Info.biWidth, abs(Info.biHeight));
5834 GetMem(ImageData, ImageSize);
5835 if Assigned(SpecialFormat) then begin
5836 GetMem(LineBuf, rbLineSize); //tmp Memory for converting Bitfields
5837 SourceMD := SpecialFormat.CreateMappingData;
5842 FillChar(ImageData^, ImageSize, $FF);
5843 TmpData := ImageData;
5844 if (Info.biHeight > 0) then
5845 Inc(TmpData, wbLineSize * (Info.biHeight-1));
5846 for i := 0 to Abs(Info.biHeight)-1 do begin
5847 if Assigned(SpecialFormat) then
5848 SpecialFormatReadLine(TmpData, LineBuf) //if is special format read and convert data
5850 aStream.Read(TmpData^, wbLineSize); //else only read data
5851 if (Info.biHeight > 0) then
5852 dec(TmpData, wbLineSize)
5854 inc(TmpData, wbLineSize);
5855 aStream.Read(PaddingBuff, Padding);
5857 SetDataPointer(ImageData, BmpFormat, Info.biWidth, abs(Info.biHeight));
5860 if Assigned(LineBuf) then
5862 if Assigned(SourceMD) then
5863 SpecialFormat.FreeMappingData(SourceMD);
5864 FormatDesc.FreeMappingData(DestMD);
5871 raise EglBitmapException.Create('LoadBMP - No suitable format found');
5873 aStream.Position := StartPos;
5877 FreeAndNil(SpecialFormat);
5880 else aStream.Position := StartPos;
5883 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5884 procedure TglBitmap.SaveBMP(const aStream: TStream);
5888 pData, pTemp: pByte;
5890 PixelFormat: TglBitmapPixelData;
5891 FormatDesc: TFormatDescriptor;
5892 ImageSize, LineSize, Padding, LineIdx, ColorIdx: Integer;
5893 Temp, RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
5895 PaddingBuff: Cardinal;
5897 function GetLineWidth : Integer;
5899 result := ((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3;
5903 if not (ftBMP in FormatGetSupportedFiles(Format)) then
5904 raise EglBitmapUnsupportedFormatFormat.Create('SaveBMP - ' + UNSUPPORTED_FORMAT);
5906 ImageSize := TFormatDescriptor.Get(Format).GetSize(Dimension);
5908 Header.bfType := BMP_MAGIC;
5909 Header.bfSize := SizeOf(Header) + SizeOf(Info) + ImageSize;
5910 Header.bfReserved1 := 0;
5911 Header.bfReserved2 := 0;
5912 Header.bfOffBits := SizeOf(Header) + SizeOf(Info);
5914 FillChar(Info, SizeOf(Info), 0);
5915 Info.biSize := SizeOf(Info);
5916 Info.biWidth := Width;
5917 Info.biHeight := Height;
5919 Info.biCompression := BMP_COMP_RGB;
5920 Info.biSizeImage := ImageSize;
5922 //TODO tfAlpha8, ifLuminance8, ifDepth8:
5925 Info.biBitCount := 8;
5927 Header.bfSize := Header.bfSize + 256 * SizeOf(Cardinal);
5928 Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal);
5930 Info.biClrUsed := 256;
5931 Info.biClrImportant := 256;
5933 //TODO ifLuminance8Alpha8, tfRGBA4, ifR5G6B5, tfRGB5A1:
5934 tfLuminance8Alpha8, tfRGB5A1:
5936 Info.biBitCount := 16;
5937 Info.biCompression := BMP_COMP_BITFIELDS;
5940 Info.biBitCount := 24;
5941 //TODO tfBGRA8, tfRGBA8, tfRGB10A2:
5944 Info.biBitCount := 32;
5945 Info.biCompression := BMP_COMP_BITFIELDS;
5948 raise EglBitmapUnsupportedFormatFormat.Create('SaveBMP - ' + UNSUPPORTED_FORMAT);
5950 Info.biXPelsPerMeter := 2835;
5951 Info.biYPelsPerMeter := 2835;
5954 if Info.biCompression = BMP_COMP_BITFIELDS then begin
5955 Info.biSize := Info.biSize + 4 * SizeOf(Cardinal);
5956 Header.bfSize := Header.bfSize + 4 * SizeOf(Cardinal);
5957 Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal);
5959 FormatDesc := TFormatDescriptor.Get(Format);
5960 RedMask := FormatDesc.RedMask;
5961 GreenMask := FormatDesc.GreenMask;
5962 BlueMask := FormatDesc.BlueMask;
5963 AlphaMask := FormatDesc.AlphaMask;
5967 aStream.Write(Header, SizeOf(Header));
5968 aStream.Write(Info, SizeOf(Info));
5971 if Info.biBitCount = 8 then begin
5973 for ColorIdx := Low(Byte) to High(Byte) do begin
5974 aStream.Write(Temp, 4);
5975 Temp := Temp + $00010101;
5980 if Info.biCompression = BMP_COMP_BITFIELDS then begin
5981 aStream.Write(RedMask, SizeOf(Cardinal));
5982 aStream.Write(GreenMask, SizeOf(Cardinal));
5983 aStream.Write(BlueMask, SizeOf(Cardinal));
5984 aStream.Write(AlphaMask, SizeOf(Cardinal));
5988 LineSize := Trunc(Width * TFormatDescriptor.Get(Format).PixelSize);
5989 Padding := GetLineWidth - LineSize;
5993 Inc(pData, (Height -1) * LineSize);
5995 // prepare row buffer. But only for RGB because RGBA supports color masks
5996 // so it's possible to change color within the image.
5997 if (Format = tfRGB8) then
5998 GetMem(pTemp, fRowSize)
6004 for LineIdx := 0 to Height - 1 do begin
6006 if Format = tfRGB8 then begin
6007 Move(pData^, pTemp^, fRowSize);
6008 SwapRGB(pTemp, Width, false);
6011 aStream.Write(pTemp^, LineSize);
6012 Dec(pData, LineSize);
6014 aStream.Write(PaddingBuff, Padding);
6017 // destroy row buffer
6018 if Format = tfRGB8 then
6023 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6024 //TGA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6025 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6027 TTGAHeader = packed record
6031 ColorMapSpec: Array[0..4] of Byte;
6041 TGA_UNCOMPRESSED_RGB = 2;
6042 TGA_UNCOMPRESSED_GRAY = 3;
6043 TGA_COMPRESSED_RGB = 10;
6044 TGA_COMPRESSED_GRAY = 11;
6046 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6047 function TglBitmap.LoadTGA(const aStream: TStream): Boolean;
6050 NewImage, pData: PByte;
6052 PixelSize, LineSize, YStart, YEnd, YInc: Integer;
6053 Format: TglBitmapFormat;
6058 ////////////////////////////////////////////////////////////////////////////////////////
6059 procedure ReadUncompressed;
6063 RowSize := Header.Width * PixelSize;
6064 // copy line by line
6065 while YStart <> YEnd + YInc do begin
6067 Inc(pData, YStart * LineSize);
6068 aStream.Read(pData^, RowSize);
6073 ////////////////////////////////////////////////////////////////////////////////////////
6074 procedure ReadCompressed;
6076 HeaderWidth, HeaderHeight: Integer;
6077 LinePixelsRead, ImgPixelsRead, ImgPixelsToRead: Integer;
6080 CacheSize, CachePos: Integer;
6083 TempBuf: Array [0..15] of Byte;
6085 PixelRepeat: Boolean;
6086 PixelToRead, TempPixels: Integer;
6088 /////////////////////////////////////////////////////////////////
6089 procedure CheckLine;
6091 if LinePixelsRead >= HeaderWidth then begin
6092 LinePixelsRead := 0;
6095 Inc(pData, YStart * LineSize);
6099 /////////////////////////////////////////////////////////////////
6100 procedure CachedRead(out Buffer; Count: Integer);
6104 if (CachePos + Count) > CacheSize then begin
6108 if CacheSize - CachePos > 0 then begin
6109 BytesRead := CacheSize - CachePos;
6110 Move(pByteArray(Cache)^[CachePos], Buffer, BytesRead);
6111 Inc(CachePos, BytesRead);
6115 CacheSize := Min(CACHE_SIZE, aStream.Size - aStream.Position);
6116 aStream.Read(Cache^, CacheSize);
6120 if Count - BytesRead > 0 then begin
6121 Move(pByteArray(Cache)^[CachePos], TByteArray(Buffer)[BytesRead], Count - BytesRead);
6122 Inc(CachePos, Count - BytesRead);
6125 Move(pByteArray(Cache)^[CachePos], Buffer, Count);
6126 Inc(CachePos, Count);
6134 HeaderWidth := Header.Width;
6135 HeaderHeight := Header.Height;
6137 GetMem(Cache, CACHE_SIZE); // 16K Buffer
6139 ImgPixelsToRead := HeaderWidth * HeaderHeight;
6141 LinePixelsRead := 0;
6144 Inc(pData, YStart * LineSize);
6146 // Read until all Pixels
6148 CachedRead(Temp, 1);
6150 PixelRepeat := Temp and $80 > 0;
6151 PixelToRead := (Temp and $7F) + 1;
6153 Inc(ImgPixelsRead, PixelToRead);
6155 if PixelRepeat then begin
6156 // repeat one pixel x times
6157 CachedRead(TempBuf[0], PixelSize);
6160 while PixelToRead > 0 do begin
6163 TempPixels := HeaderWidth - LinePixelsRead;
6164 if PixelToRead < TempPixels then
6165 TempPixels := PixelToRead;
6167 Inc(LinePixelsRead, TempPixels);
6168 Dec(PixelToRead, TempPixels);
6170 while TempPixels > 0 do begin
6173 pData^ := TempBuf[0];
6177 pWord(pData)^ := pWord(@TempBuf[0])^;
6181 pWord(pData)^ := pWord(@TempBuf[0])^;
6183 pData^ := TempBuf[2];
6187 pDWord(pData)^ := pDWord(@TempBuf[0])^;
6196 while PixelToRead > 0 do begin
6198 TempPixels := HeaderWidth - LinePixelsRead;
6199 if PixelToRead < TempPixels then
6200 TempPixels := PixelToRead;
6201 CachedRead(pData^, PixelSize * TempPixels);
6202 Inc(pData, PixelSize * TempPixels);
6203 Inc(LinePixelsRead, TempPixels);
6204 Dec(PixelToRead, TempPixels);
6207 until ImgPixelsRead >= ImgPixelsToRead;
6216 // reading header to test file and set cursor back to begin
6217 StreamPos := aStream.Position;
6218 aStream.Read(Header, SizeOf(Header));
6220 // no colormapped files
6221 if (Header.ColorMapType = 0) then begin
6222 if Header.ImageType in [TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY] then begin
6224 //TODO 8: Format := tfAlpha8;
6225 16: Format := tfLuminance8Alpha8;
6226 24: Format := tfBGR8;
6227 32: Format := tfBGRA8;
6229 raise EglBitmapException.Create('LoadTga - unsupported BitsPerPixel found.');
6233 if Header.ImageID <> 0 then
6234 aStream.Position := aStream.Position + Header.ImageID;
6236 PixelSize := TFormatDescriptor.Get(Format).GetSize(1, 1);
6237 LineSize := Trunc(Header.Width * PixelSize);
6239 GetMem(NewImage, LineSize * Header.Height);
6242 if (Header.ImageDes and $20 > 0) then begin
6244 YEnd := Header.Height -1;
6247 YStart := Header.Height -1;
6253 case Header.ImageType of
6254 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY:
6256 TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY:
6260 SetDataPointer(NewImage, Format, Header.Width, Header.Height);
6267 else aStream.Position := StreamPos;
6269 else aStream.Position := StreamPos;
6272 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6273 procedure TglBitmap.SaveTGA(const aStream: TStream);
6278 FormatDesc: TFormatDescriptor;
6280 procedure ConvertData(pTemp: pByte);
6282 Idx, PixelSize: Integer;
6285 PixelSize := fPixelSize;
6286 for Idx := 1 to Height * Width do begin
6287 Temp := pByteArray(pTemp)^[2];
6288 pByteArray(pTemp)^[2] := pByteArray(pTemp)^[0];
6289 pByteArray(pTemp)^[0] := Temp;
6290 Inc(pTemp, PixelSize);
6295 if not (ftTGA in FormatGetSupportedFiles(Format)) then
6296 raise EglBitmapUnsupportedFormatFormat.Create('SaveTGA - ' + UNSUPPORTED_FORMAT);
6298 FillChar(Header, SizeOf(Header), 0);
6300 //TODO ifAlpha8, ifLuminance8, ifDepth8: begin
6302 Header.ImageType := TGA_UNCOMPRESSED_GRAY;
6305 tfLuminance8Alpha8: begin
6306 Header.ImageType := TGA_UNCOMPRESSED_GRAY;
6309 tfRGB8, tfBGR8: begin
6310 Header.ImageType := TGA_UNCOMPRESSED_RGB;
6313 tfRGBA8, tfBGRA8: begin
6314 Header.ImageType := TGA_UNCOMPRESSED_RGB;
6318 raise EglBitmapUnsupportedFormatFormat.Create('SaveTGA - ' + UNSUPPORTED_FORMAT);
6321 Header.Width := Width;
6322 Header.Height := Height;
6323 Header.ImageDes := $20;
6324 FormatDesc := TFormatDescriptor.Get(Format);
6326 if FormatDesc.HasAlpha then
6327 Header.ImageDes := Header.ImageDes or $08;
6328 aStream.Write(Header, SizeOf(Header));
6330 // convert RGB(A) to BGR(A)
6331 Size := FormatDesc.GetSize(Dimension);
6332 if Format in [tfRGB8, tfRGBA8] then begin
6333 GetMem(pTemp, Size);
6339 if Format in [tfRGB8, tfRGBA8] then begin
6340 Move(Data^, pTemp^, Size);
6345 aStream.Write(pTemp^, Size);
6348 if Format in [tfRGB8, tfRGBA8] then
6353 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6354 //DDS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6355 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6357 DDS_MAGIC = $20534444;
6359 // DDS_header.dwFlags
6360 DDSD_CAPS = $00000001;
6361 DDSD_HEIGHT = $00000002;
6362 DDSD_WIDTH = $00000004;
6363 DDSD_PITCH = $00000008;
6364 DDSD_PIXELFORMAT = $00001000;
6365 DDSD_MIPMAPCOUNT = $00020000;
6366 DDSD_LINEARSIZE = $00080000;
6367 DDSD_DEPTH = $00800000;
6369 // DDS_header.sPixelFormat.dwFlags
6370 DDPF_ALPHAPIXELS = $00000001;
6371 DDPF_FOURCC = $00000004;
6372 DDPF_INDEXED = $00000020;
6373 DDPF_RGB = $00000040;
6375 // DDS_header.sCaps.dwCaps1
6376 DDSCAPS_COMPLEX = $00000008;
6377 DDSCAPS_TEXTURE = $00001000;
6378 DDSCAPS_MIPMAP = $00400000;
6380 // DDS_header.sCaps.dwCaps2
6381 DDSCAPS2_CUBEMAP = $00000200;
6382 DDSCAPS2_CUBEMAP_POSITIVEX = $00000400;
6383 DDSCAPS2_CUBEMAP_NEGATIVEX = $00000800;
6384 DDSCAPS2_CUBEMAP_POSITIVEY = $00001000;
6385 DDSCAPS2_CUBEMAP_NEGATIVEY = $00002000;
6386 DDSCAPS2_CUBEMAP_POSITIVEZ = $00004000;
6387 DDSCAPS2_CUBEMAP_NEGATIVEZ = $00008000;
6388 DDSCAPS2_VOLUME = $00200000;
6390 D3DFMT_DXT1 = $31545844;
6391 D3DFMT_DXT3 = $33545844;
6392 D3DFMT_DXT5 = $35545844;
6395 TDDSPixelFormat = packed record
6399 dwRGBBitCount: Cardinal;
6400 dwRBitMask: Cardinal;
6401 dwGBitMask: Cardinal;
6402 dwBBitMask: Cardinal;
6403 dwABitMask: Cardinal;
6406 TDDSCaps = packed record
6410 dwReserved: Cardinal;
6413 TDDSHeader = packed record
6419 dwPitchOrLinearSize: Cardinal;
6421 dwMipMapCount: Cardinal;
6422 dwReserved: array[0..10] of Cardinal;
6423 PixelFormat: TDDSPixelFormat;
6425 dwReserved2: Cardinal;
6428 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6429 function TglBitmap.LoadDDS(const aStream: TStream): Boolean;
6433 Y, LineSize: Cardinal;
6435 NewImage, pData: pByte;
6436 ddsFormat: TglBitmapFormat;
6438 function RaiseEx : Exception;
6440 result := EglBitmapException.Create('LoadDDS - unsupported Pixelformat found.');
6443 function GetDDSFormat: TglBitmapFormat;
6445 with Header.PixelFormat do begin
6447 if (dwFlags and DDPF_FOURCC) > 0 then begin
6449 case Header.PixelFormat.dwFourCC of
6450 D3DFMT_DXT1: result := ifDXT1;
6451 D3DFMT_DXT3: result := ifDXT3;
6452 D3DFMT_DXT5: result := ifDXT5;
6461 if (dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS)) > 0 then begin
6462 case dwRGBBitCount of
6464 (* TODO if dwFlags and DDPF_ALPHAPIXELS > 0 then
6468 result := tfLuminance8;
6471 if dwFlags and DDPF_ALPHAPIXELS > 0 then begin
6473 case CountSetBits(dwRBitMask) of
6474 5: result := tfRGB5A1;
6475 //TODO 4: result := tfRGBA4;
6477 result := tfLuminance8Alpha8;
6481 //TODO result := ifR5G6B5;
6486 if dwRBitMask > dwBBitMask then
6492 if CountSetBits(dwRBitMask) = 10 then
6493 //TODO result := tfRGB10A2
6497 if dwRBitMask > dwBBitMask then
6514 StreamPos := aStream.Position;
6515 aStream.Read(Header, sizeof(Header));
6517 if ((Header.dwMagic <> DDS_MAGIC) or (Header.dwSize <> 124) or
6518 ((Header.dwFlags and DDSD_PIXELFORMAT) = 0) or ((Header.dwFlags and DDSD_CAPS) = 0)) then begin
6519 aStream.Position := StreamPos;
6523 ddsFormat := GetDDSFormat;
6524 LineSize := Trunc(Header.dwWidth * TFormatDescriptor.Get(ddsFormat).PixelSize);
6525 GetMem(NewImage, Header.dwHeight * LineSize);
6530 if (Header.PixelFormat.dwFlags and DDPF_FOURCC) > 0 then begin
6531 RowSize := Header.dwPitchOrLinearSize div Header.dwWidth;
6532 for Y := 0 to Header.dwHeight -1 do begin
6533 aStream.Read(pData^, RowSize);
6534 Inc(pData, LineSize);
6539 if (Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS)) > 0 then begin
6540 RowSize := Header.dwPitchOrLinearSize;
6542 for Y := 0 to Header.dwHeight -1 do begin
6543 aStream.Read(pData^, RowSize);
6544 Inc(pData, LineSize);
6549 SetDataPointer(NewImage, ddsFormat, Header.dwWidth, Header.dwHeight);
6557 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6558 procedure TglBitmap.SaveDDS(const aStream: TStream);
6561 Pix: TglBitmapPixelData;
6562 FormatDesc: TFormatDescriptor;
6564 //if not FormatIsUncompressed(InternalFormat) then
6565 // raise EglBitmapUnsupportedFormatFormat.Create('SaveDDS - ' + UNSUPPORTED_FORMAT);
6567 (* TODO if Format = tfAlpha8 then
6568 FORMAT_DESCRIPTORS[tfLuminance8].PreparePixel(Pix);
6570 TFormatDescriptor.Get(Format).PreparePixel(Pix);
6573 FillChar(Header, SizeOf(Header), 0);
6574 Header.dwMagic := DDS_MAGIC;
6575 Header.dwSize := 124;
6576 Header.dwFlags := DDSD_PITCH or DDSD_CAPS or DDSD_PIXELFORMAT;
6578 if Width > 0 then begin
6579 Header.dwWidth := Width;
6580 Header.dwFlags := Header.dwFlags or DDSD_WIDTH;
6583 if Height > 0 then begin
6584 Header.dwHeight := Height;
6585 Header.dwFlags := Header.dwFlags or DDSD_HEIGHT;
6588 Header.dwPitchOrLinearSize := fRowSize;
6589 Header.dwMipMapCount := 1;
6592 Header.Caps.dwCaps1 := DDSCAPS_TEXTURE;
6595 Header.PixelFormat.dwSize := Sizeof(Header.PixelFormat);
6596 Header.PixelFormat.dwFlags := DDPF_RGB;
6599 if FORMAT_DESCRIPTORS[Format].HasAlpha and (Format <> tfAlpha8) then
6600 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHAPIXELS;
6603 FormatDesc := TFormatDescriptor.Get(Format);
6604 Header.PixelFormat.dwRGBBitCount := Trunc(FormatDesc.PixelSize * 8);
6605 Header.PixelFormat.dwRBitMask := FormatDesc.RedMask;
6606 Header.PixelFormat.dwGBitMask := FormatDesc.GreenMask;
6607 Header.PixelFormat.dwBBitMask := FormatDesc.BlueMask;
6608 Header.PixelFormat.dwABitMask := FormatDesc.AlphaMask;
6610 aStream.Write(Header, SizeOf(Header));
6611 aStream.Write(Data^, FormatDesc.GetSize(Dimension));
6614 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6615 //TglBitmap2D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6616 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6617 function TglBitmap2D.GetScanline(const aIndex: Integer): Pointer;
6619 if (aIndex >= Low(fLines)) and (aIndex <= High(fLines)) then
6620 result := fLines[aIndex]
6625 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6626 procedure TglBitmap2D.SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
6627 const aWidth: Integer; const aHeight: Integer);
6629 Idx, LineWidth: Integer;
6631 inherited SetDataPointer(aData, aFormat, aWidth, aHeight);
6634 if {FormatIsUncompressed(Format)} true then begin
6636 fGetPixelFunc := GetPixel2DUnmap;
6637 fSetPixelFunc := SetPixel2DUnmap;
6640 if Assigned(Data) then begin
6641 SetLength(fLines, GetHeight);
6642 LineWidth := Trunc(GetWidth * TFormatDescriptor.Get(Format).PixelSize);
6644 for Idx := 0 to GetHeight -1 do begin
6645 fLines[Idx] := Data;
6646 Inc(fLines[Idx], Idx * LineWidth);
6649 else SetLength(fLines, 0);
6652 SetLength(fLines, 0);
6654 fSetPixelFunc := nil;
6658 fGetPixelFunc := GetPixel2DDXT1;
6660 fGetPixelFunc := GetPixel2DDXT3;
6662 fGetPixelFunc := GetPixel2DDXT5;
6664 fGetPixelFunc := nil;
6670 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6671 procedure TglBitmap2D.UploadData(const aTarget: Cardinal; const aBuildWithGlu: Boolean);
6673 FormatDesc: TFormatDescriptor;
6675 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
6678 if Self.InternalFormat in [ifDXT1, ifDXT3, ifDXT5] then
6679 glCompressedTexImage2D(Target, 0, InternalFormat, Width, Height, 0, Trunc(Width * Height * FormatGetSize(Self.InternalFormat)), Data)
6683 FormatDesc := TFormatDescriptor.Get(Format);
6684 if aBuildWithGlu then
6685 gluBuild2DMipmaps(aTarget, FormatDesc.Components, Width, Height,
6686 FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
6688 glTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0,
6689 FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
6692 if (FreeDataAfterGenTexture) then
6696 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6697 procedure TglBitmap2D.AfterConstruction;
6700 Target := GL_TEXTURE_2D;
6703 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6704 procedure TglBitmap2D.GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
6707 Size, w, h: Integer;
6708 FormatDesc: TFormatDescriptor;
6711 if not FormatIsUncompressed(Format) then
6712 raise EglBitmapUnsupportedFormatFormat.Create('TglBitmap2D.GrabScreen - ' + UNSUPPORTED_FORMAT);
6715 w := aRight - aLeft;
6716 h := aBottom - aTop;
6717 FormatDesc := TFormatDescriptor.Get(Format);
6718 Size := FormatDesc.GetSize(w, h);
6721 glPixelStorei(GL_PACK_ALIGNMENT, 1);
6722 glReadPixels(aLeft, aTop, w, h, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
6723 SetDataPointer(Temp, Format, w, h);
6731 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6732 procedure TglBitmap2D.GetDataFromTexture;
6735 TempWidth, TempHeight: Integer;
6736 TempType, TempIntFormat: Cardinal;
6737 IntFormat, f: TglBitmapFormat;
6738 FormatDesc: TFormatDescriptor;
6743 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_WIDTH, @TempWidth);
6744 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT, @TempHeight);
6745 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat);
6747 IntFormat := tfEmpty;
6748 for f := Low(TglBitmapFormat) to High(TglBitmapFormat) do
6749 if (TFormatDescriptor.Get(f).glInternalFormat = TempIntFormat) then begin
6750 IntFormat := FormatDesc.Format;
6754 // Getting data from OpenGL
6755 FormatDesc := TFormatDescriptor.Get(IntFormat);
6756 GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight));
6759 if FormatIsCompressed(IntFormat) and (GL_VERSION_1_3 or GL_ARB_texture_compression) then
6760 glGetCompressedTexImage(Target, 0, Temp)
6763 glGetTexImage(Target, 0, FormatDesc.glInternalFormat, FormatDesc.glDataFormat, Temp);
6764 SetDataPointer(Temp, IntFormat, TempWidth, TempHeight);
6771 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6772 procedure TglBitmap2D.GenTexture(const aTestTextureSize: Boolean);
6774 BuildWithGlu, PotTex, TexRec: Boolean;
6777 if Assigned(Data) then begin
6778 // Check Texture Size
6779 if (aTestTextureSize) then begin
6780 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
6782 if ((Height > TexSize) or (Width > TexSize)) then
6783 raise EglBitmapSizeToLargeException.Create('TglBitmap2D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
6785 PotTex := IsPowerOfTwo(Height) and IsPowerOfTwo(Width);
6786 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and (Target = GL_TEXTURE_RECTANGLE_ARB);
6788 if not (PotTex or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
6789 raise EglBitmapNonPowerOfTwoException.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
6793 SetupParameters(BuildWithGlu);
6794 UploadData(Target, BuildWithGlu);
6795 glAreTexturesResident(1, @fID, @fIsResident);
6799 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6800 function TglBitmap2D.FlipHorz: Boolean;
6803 TempDestData, DestData, SourceData: PByte;
6806 result := inherited FlipHorz;
6807 if Assigned(Data) then begin
6809 ImgSize := Height * fRowSize;
6810 GetMem(DestData, ImgSize);
6812 TempDestData := DestData;
6813 Dec(TempDestData, fRowSize + fPixelSize);
6814 for Row := 0 to Height -1 do begin
6815 Inc(TempDestData, fRowSize * 2);
6816 for Col := 0 to Width -1 do begin
6817 Move(SourceData^, TempDestData^, fPixelSize);
6818 Inc(SourceData, fPixelSize);
6819 Dec(TempDestData, fPixelSize);
6822 SetDataPointer(DestData, Format);
6831 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6832 function TglBitmap2D.FlipVert: Boolean;
6835 TempDestData, DestData, SourceData: PByte;
6837 result := inherited FlipVert;
6838 if Assigned(Data) then begin
6840 GetMem(DestData, Height * fRowSize);
6842 TempDestData := DestData;
6843 Inc(TempDestData, Width * (Height -1) * fPixelSize);
6844 for Row := 0 to Height -1 do begin
6845 Move(SourceData^, TempDestData^, fRowSize);
6846 Dec(TempDestData, fRowSize);
6847 Inc(SourceData, fRowSize);
6849 SetDataPointer(DestData, Format);
6858 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6859 //TglBitmap2D - ToNormalMap///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6860 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6862 TMatrixItem = record
6867 PglBitmapToNormalMapRec = ^TglBitmapToNormalMapRec;
6868 TglBitmapToNormalMapRec = Record
6870 Heights: array of Single;
6871 MatrixU : array of TMatrixItem;
6872 MatrixV : array of TMatrixItem;
6876 ONE_OVER_255 = 1 / 255;
6878 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6879 procedure glBitmapToNormalMapPrepareFunc(var FuncRec: TglBitmapFunctionRec);
6883 with FuncRec do begin
6885 Source.Data.r * LUMINANCE_WEIGHT_R +
6886 Source.Data.g * LUMINANCE_WEIGHT_G +
6887 Source.Data.b * LUMINANCE_WEIGHT_B;
6888 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Val * ONE_OVER_255;
6892 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6893 procedure glBitmapToNormalMapPrepareAlphaFunc(var FuncRec: TglBitmapFunctionRec);
6896 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Source.Data.a * ONE_OVER_255;
6899 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6900 procedure glBitmapToNormalMapFunc (var FuncRec: TglBitmapFunctionRec);
6902 TVec = Array[0..2] of Single;
6909 function GetHeight(X, Y: Integer): Single;
6911 with FuncRec do begin
6912 X := Max(0, Min(Size.X -1, X));
6913 Y := Max(0, Min(Size.Y -1, Y));
6914 result := PglBitmapToNormalMapRec(Args)^.Heights[Y * Size.X + X];
6919 with FuncRec do begin
6920 with PglBitmapToNormalMapRec(Args)^ do begin
6922 for Idx := Low(MatrixU) to High(MatrixU) do
6923 du := du + GetHeight(Position.X + MatrixU[Idx].X, Position.Y + MatrixU[Idx].Y) * MatrixU[Idx].W;
6926 for Idx := Low(MatrixU) to High(MatrixU) do
6927 dv := dv + GetHeight(Position.X + MatrixV[Idx].X, Position.Y + MatrixV[Idx].Y) * MatrixV[Idx].W;
6929 Vec[0] := -du * Scale;
6930 Vec[1] := -dv * Scale;
6935 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
6936 if Len <> 0 then begin
6937 Vec[0] := Vec[0] * Len;
6938 Vec[1] := Vec[1] * Len;
6939 Vec[2] := Vec[2] * Len;
6943 Dest.Data.r := Trunc((Vec[0] + 1) * 127.5);
6944 Dest.Data.g := Trunc((Vec[1] + 1) * 127.5);
6945 Dest.Data.b := Trunc((Vec[2] + 1) * 127.5);
6949 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6950 procedure TglBitmap2D.ToNormalMap(const aFunc: TglBitmapNormalMapFunc; const aScale: Single; const aUseAlpha: Boolean);
6952 Rec: TglBitmapToNormalMapRec;
6954 procedure SetEntry (var Matrix: array of TMatrixItem; Index, X, Y: Integer; W: Single);
6956 if (Index >= Low(Matrix)) and (Index <= High(Matrix)) then begin
6957 Matrix[Index].X := X;
6958 Matrix[Index].Y := Y;
6959 Matrix[Index].W := W;
6965 if not FormatIsUncompressed(InternalFormat) then
6966 raise EglBitmapUnsupportedFormatFormat.Create('TglBitmap2D.ToNormalMap - ' + UNSUPPORTED_FORMAT);
6969 if aScale > 100 then
6971 else if aScale < -100 then
6974 Rec.Scale := aScale;
6976 SetLength(Rec.Heights, Width * Height);
6980 SetLength(Rec.MatrixU, 2);
6981 SetEntry(Rec.MatrixU, 0, -1, 0, -0.5);
6982 SetEntry(Rec.MatrixU, 1, 1, 0, 0.5);
6984 SetLength(Rec.MatrixV, 2);
6985 SetEntry(Rec.MatrixV, 0, 0, 1, 0.5);
6986 SetEntry(Rec.MatrixV, 1, 0, -1, -0.5);
6990 SetLength(Rec.MatrixU, 6);
6991 SetEntry(Rec.MatrixU, 0, -1, 1, -1.0);
6992 SetEntry(Rec.MatrixU, 1, -1, 0, -2.0);
6993 SetEntry(Rec.MatrixU, 2, -1, -1, -1.0);
6994 SetEntry(Rec.MatrixU, 3, 1, 1, 1.0);
6995 SetEntry(Rec.MatrixU, 4, 1, 0, 2.0);
6996 SetEntry(Rec.MatrixU, 5, 1, -1, 1.0);
6998 SetLength(Rec.MatrixV, 6);
6999 SetEntry(Rec.MatrixV, 0, -1, 1, 1.0);
7000 SetEntry(Rec.MatrixV, 1, 0, 1, 2.0);
7001 SetEntry(Rec.MatrixV, 2, 1, 1, 1.0);
7002 SetEntry(Rec.MatrixV, 3, -1, -1, -1.0);
7003 SetEntry(Rec.MatrixV, 4, 0, -1, -2.0);
7004 SetEntry(Rec.MatrixV, 5, 1, -1, -1.0);
7008 SetLength(Rec.MatrixU, 6);
7009 SetEntry(Rec.MatrixU, 0, -1, 1, -1/6);
7010 SetEntry(Rec.MatrixU, 1, -1, 0, -1/6);
7011 SetEntry(Rec.MatrixU, 2, -1, -1, -1/6);
7012 SetEntry(Rec.MatrixU, 3, 1, 1, 1/6);
7013 SetEntry(Rec.MatrixU, 4, 1, 0, 1/6);
7014 SetEntry(Rec.MatrixU, 5, 1, -1, 1/6);
7016 SetLength(Rec.MatrixV, 6);
7017 SetEntry(Rec.MatrixV, 0, -1, 1, 1/6);
7018 SetEntry(Rec.MatrixV, 1, 0, 1, 1/6);
7019 SetEntry(Rec.MatrixV, 2, 1, 1, 1/6);
7020 SetEntry(Rec.MatrixV, 3, -1, -1, -1/6);
7021 SetEntry(Rec.MatrixV, 4, 0, -1, -1/6);
7022 SetEntry(Rec.MatrixV, 5, 1, -1, -1/6);
7026 SetLength(Rec.MatrixU, 20);
7027 SetEntry(Rec.MatrixU, 0, -2, 2, -1 / 16);
7028 SetEntry(Rec.MatrixU, 1, -1, 2, -1 / 10);
7029 SetEntry(Rec.MatrixU, 2, 1, 2, 1 / 10);
7030 SetEntry(Rec.MatrixU, 3, 2, 2, 1 / 16);
7031 SetEntry(Rec.MatrixU, 4, -2, 1, -1 / 10);
7032 SetEntry(Rec.MatrixU, 5, -1, 1, -1 / 8);
7033 SetEntry(Rec.MatrixU, 6, 1, 1, 1 / 8);
7034 SetEntry(Rec.MatrixU, 7, 2, 1, 1 / 10);
7035 SetEntry(Rec.MatrixU, 8, -2, 0, -1 / 2.8);
7036 SetEntry(Rec.MatrixU, 9, -1, 0, -0.5);
7037 SetEntry(Rec.MatrixU, 10, 1, 0, 0.5);
7038 SetEntry(Rec.MatrixU, 11, 2, 0, 1 / 2.8);
7039 SetEntry(Rec.MatrixU, 12, -2, -1, -1 / 10);
7040 SetEntry(Rec.MatrixU, 13, -1, -1, -1 / 8);
7041 SetEntry(Rec.MatrixU, 14, 1, -1, 1 / 8);
7042 SetEntry(Rec.MatrixU, 15, 2, -1, 1 / 10);
7043 SetEntry(Rec.MatrixU, 16, -2, -2, -1 / 16);
7044 SetEntry(Rec.MatrixU, 17, -1, -2, -1 / 10);
7045 SetEntry(Rec.MatrixU, 18, 1, -2, 1 / 10);
7046 SetEntry(Rec.MatrixU, 19, 2, -2, 1 / 16);
7048 SetLength(Rec.MatrixV, 20);
7049 SetEntry(Rec.MatrixV, 0, -2, 2, 1 / 16);
7050 SetEntry(Rec.MatrixV, 1, -1, 2, 1 / 10);
7051 SetEntry(Rec.MatrixV, 2, 0, 2, 0.25);
7052 SetEntry(Rec.MatrixV, 3, 1, 2, 1 / 10);
7053 SetEntry(Rec.MatrixV, 4, 2, 2, 1 / 16);
7054 SetEntry(Rec.MatrixV, 5, -2, 1, 1 / 10);
7055 SetEntry(Rec.MatrixV, 6, -1, 1, 1 / 8);
7056 SetEntry(Rec.MatrixV, 7, 0, 1, 0.5);
7057 SetEntry(Rec.MatrixV, 8, 1, 1, 1 / 8);
7058 SetEntry(Rec.MatrixV, 9, 2, 1, 1 / 16);
7059 SetEntry(Rec.MatrixV, 10, -2, -1, -1 / 16);
7060 SetEntry(Rec.MatrixV, 11, -1, -1, -1 / 8);
7061 SetEntry(Rec.MatrixV, 12, 0, -1, -0.5);
7062 SetEntry(Rec.MatrixV, 13, 1, -1, -1 / 8);
7063 SetEntry(Rec.MatrixV, 14, 2, -1, -1 / 10);
7064 SetEntry(Rec.MatrixV, 15, -2, -2, -1 / 16);
7065 SetEntry(Rec.MatrixV, 16, -1, -2, -1 / 10);
7066 SetEntry(Rec.MatrixV, 17, 0, -2, -0.25);
7067 SetEntry(Rec.MatrixV, 18, 1, -2, -1 / 10);
7068 SetEntry(Rec.MatrixV, 19, 2, -2, -1 / 16);
7073 if aUseAlpha and TFormatDescriptor.Get(Format).HasAlpha then
7074 AddFunc(glBitmapToNormalMapPrepareAlphaFunc, false, PtrInt(@Rec))
7076 AddFunc(glBitmapToNormalMapPrepareFunc, false, PtrInt(@Rec));
7077 AddFunc(glBitmapToNormalMapFunc, false, PtrInt(@Rec));
7079 SetLength(Rec.Heights, 0);
7092 procedure TglBitmap1D.SetDataPointer(Data: pByte; Format: TglBitmapInternalFormat; Width, Height: Integer);
7097 if Height > 1 then begin
7098 // extract first line of the data
7099 Size := FormatGetImageSize(glBitmapPosition(Width), Format);
7100 GetMem(pTemp, Size);
7102 Move(Data^, pTemp^, Size);
7109 inherited SetDataPointer(pTemp, Format, Width);
7111 if FormatIsUncompressed(Format) then begin
7112 fUnmapFunc := FormatGetUnMapFunc(Format);
7113 fGetPixelFunc := GetPixel1DUnmap;
7118 procedure TglBitmap1D.GetPixel1DUnmap(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
7123 Inc(pTemp, Pos.X * fPixelSize);
7125 fUnmapFunc(pTemp, Pixel);
7129 function TglBitmap1D.FlipHorz: Boolean;
7132 pTempDest, pDest, pSource: pByte;
7134 result := inherited FlipHorz;
7136 if Assigned(Data) and FormatIsUncompressed(InternalFormat) then begin
7139 GetMem(pDest, fRowSize);
7143 Inc(pTempDest, fRowSize);
7144 for Col := 0 to Width -1 do begin
7145 Move(pSource^, pTempDest^, fPixelSize);
7147 Inc(pSource, fPixelSize);
7148 Dec(pTempDest, fPixelSize);
7151 SetDataPointer(pDest, InternalFormat);
7161 procedure TglBitmap1D.UploadData (Target, Format, InternalFormat, Typ: Cardinal; BuildWithGlu: Boolean);
7164 if Self.InternalFormat in [ifDXT1, ifDXT3, ifDXT5] then
7165 glCompressedTexImage1D(Target, 0, InternalFormat, Width, 0, Trunc(Width * FormatGetSize(Self.InternalFormat)), Data)
7169 if BuildWithGlu then
7170 gluBuild1DMipmaps(Target, InternalFormat, Width, Format, Typ, Data)
7172 glTexImage1D(Target, 0, InternalFormat, Width, 0, Format, Typ, Data);
7175 if (FreeDataAfterGenTexture) then
7180 procedure TglBitmap1D.GenTexture(TestTextureSize: Boolean);
7182 BuildWithGlu, TexRec: Boolean;
7183 glFormat, glInternalFormat, glType: Cardinal;
7186 if Assigned(Data) then begin
7187 // Check Texture Size
7188 if (TestTextureSize) then begin
7189 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
7191 if (Width > TexSize) then
7192 raise EglBitmapSizeToLargeException.Create('TglBitmap1D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
7194 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and
7195 (Target = GL_TEXTURE_RECTANGLE_ARB);
7197 if not (IsPowerOfTwo (Width) or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
7198 raise EglBitmapNonPowerOfTwoException.Create('TglBitmap1D.GenTexture - Rendercontex dosn''t support non power of two texture.');
7203 SetupParameters(BuildWithGlu);
7204 SelectFormat(InternalFormat, glFormat, glInternalFormat, glType);
7206 UploadData(Target, glFormat, glInternalFormat, glType, BuildWithGlu);
7209 glAreTexturesResident(1, @fID, @fIsResident);
7214 procedure TglBitmap1D.AfterConstruction;
7218 Target := GL_TEXTURE_1D;
7222 { TglBitmapCubeMap }
7224 procedure TglBitmapCubeMap.AfterConstruction;
7228 if not (GL_VERSION_1_3 or GL_ARB_texture_cube_map or GL_EXT_texture_cube_map) then
7229 raise EglBitmapException.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
7231 SetWrap; // set all to GL_CLAMP_TO_EDGE
7232 Target := GL_TEXTURE_CUBE_MAP;
7233 fGenMode := GL_REFLECTION_MAP;
7237 procedure TglBitmapCubeMap.Bind(EnableTexCoordsGen, EnableTextureUnit: Boolean);
7239 inherited Bind (EnableTextureUnit);
7241 if EnableTexCoordsGen then begin
7242 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, fGenMode);
7243 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, fGenMode);
7244 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, fGenMode);
7245 glEnable(GL_TEXTURE_GEN_S);
7246 glEnable(GL_TEXTURE_GEN_T);
7247 glEnable(GL_TEXTURE_GEN_R);
7252 procedure TglBitmapCubeMap.GenerateCubeMap(CubeTarget: Cardinal; TestTextureSize: Boolean);
7254 glFormat, glInternalFormat, glType: Cardinal;
7255 BuildWithGlu: Boolean;
7258 // Check Texture Size
7259 if (TestTextureSize) then begin
7260 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, @TexSize);
7262 if ((Height > TexSize) or (Width > TexSize)) then
7263 raise EglBitmapSizeToLargeException.Create('TglBitmapCubeMap.GenTexture - The size for the Cubemap is to large. It''s may be not conform with the Hardware.');
7265 if not ((IsPowerOfTwo (Height) and IsPowerOfTwo (Width)) or GL_VERSION_2_0 or GL_ARB_texture_non_power_of_two) then
7266 raise EglBitmapNonPowerOfTwoException.Create('TglBitmapCubeMap.GenTexture - Cubemaps dosn''t support non power of two texture.');
7270 if ID = 0 then begin
7272 SetupParameters(BuildWithGlu);
7275 SelectFormat(InternalFormat, glFormat, glInternalFormat, glType);
7277 UploadData (CubeTarget, glFormat, glInternalFormat, glType, BuildWithGlu);
7281 procedure TglBitmapCubeMap.GenTexture(TestTextureSize: Boolean);
7283 Assert(false, 'TglBitmapCubeMap.GenTexture - Don''t call GenTextures directly.');
7287 procedure TglBitmapCubeMap.Unbind(DisableTexCoordsGen,
7288 DisableTextureUnit: Boolean);
7290 inherited Unbind (DisableTextureUnit);
7292 if DisableTexCoordsGen then begin
7293 glDisable(GL_TEXTURE_GEN_S);
7294 glDisable(GL_TEXTURE_GEN_T);
7295 glDisable(GL_TEXTURE_GEN_R);
7300 { TglBitmapNormalMap }
7303 TVec = Array[0..2] of Single;
7304 TglBitmapNormalMapGetVectorFunc = procedure (var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
7306 PglBitmapNormalMapRec = ^TglBitmapNormalMapRec;
7307 TglBitmapNormalMapRec = record
7309 Func: TglBitmapNormalMapGetVectorFunc;
7313 procedure glBitmapNormalMapPosX(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
7316 Vec[1] := - (Position.Y + 0.5 - HalfSize);
7317 Vec[2] := - (Position.X + 0.5 - HalfSize);
7321 procedure glBitmapNormalMapNegX(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
7323 Vec[0] := - HalfSize;
7324 Vec[1] := - (Position.Y + 0.5 - HalfSize);
7325 Vec[2] := Position.X + 0.5 - HalfSize;
7329 procedure glBitmapNormalMapPosY(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
7331 Vec[0] := Position.X + 0.5 - HalfSize;
7333 Vec[2] := Position.Y + 0.5 - HalfSize;
7337 procedure glBitmapNormalMapNegY(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
7339 Vec[0] := Position.X + 0.5 - HalfSize;
7340 Vec[1] := - HalfSize;
7341 Vec[2] := - (Position.Y + 0.5 - HalfSize);
7345 procedure glBitmapNormalMapPosZ(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
7347 Vec[0] := Position.X + 0.5 - HalfSize;
7348 Vec[1] := - (Position.Y + 0.5 - HalfSize);
7353 procedure glBitmapNormalMapNegZ(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
7355 Vec[0] := - (Position.X + 0.5 - HalfSize);
7356 Vec[1] := - (Position.Y + 0.5 - HalfSize);
7357 Vec[2] := - HalfSize;
7361 procedure glBitmapNormalMapFunc(var FuncRec: TglBitmapFunctionRec);
7366 with FuncRec do begin
7367 with PglBitmapNormalMapRec (CustomData)^ do begin
7368 Func(Vec, Position, HalfSize);
7371 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
7372 if Len <> 0 then begin
7373 Vec[0] := Vec[0] * Len;
7374 Vec[1] := Vec[1] * Len;
7375 Vec[2] := Vec[2] * Len;
7378 // Scale Vector and AddVectro
7379 Vec[0] := Vec[0] * 0.5 + 0.5;
7380 Vec[1] := Vec[1] * 0.5 + 0.5;
7381 Vec[2] := Vec[2] * 0.5 + 0.5;
7385 Dest.Red := Round(Vec[0] * 255);
7386 Dest.Green := Round(Vec[1] * 255);
7387 Dest.Blue := Round(Vec[2] * 255);
7392 procedure TglBitmapNormalMap.AfterConstruction;
7396 fGenMode := GL_NORMAL_MAP;
7400 procedure TglBitmapNormalMap.GenerateNormalMap(Size: Integer;
7401 TestTextureSize: Boolean);
7403 Rec: TglBitmapNormalMapRec;
7404 SizeRec: TglBitmapPixelPosition;
7406 Rec.HalfSize := Size div 2;
7408 FreeDataAfterGenTexture := false;
7410 SizeRec.Fields := [ffX, ffY];
7415 Rec.Func := glBitmapNormalMapPosX;
7416 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
7417 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X, TestTextureSize);
7420 Rec.Func := glBitmapNormalMapNegX;
7421 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
7422 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, TestTextureSize);
7425 Rec.Func := glBitmapNormalMapPosY;
7426 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
7427 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, TestTextureSize);
7430 Rec.Func := glBitmapNormalMapNegY;
7431 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
7432 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, TestTextureSize);
7435 Rec.Func := glBitmapNormalMapPosZ;
7436 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
7437 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, TestTextureSize);
7440 Rec.Func := glBitmapNormalMapNegZ;
7441 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
7442 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, TestTextureSize);
7447 glBitmapSetDefaultFormat(tfEmpty);
7448 glBitmapSetDefaultMipmap(mmMipmap);
7449 glBitmapSetDefaultFilter(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
7450 glBitmapSetDefaultWrap (GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
7452 glBitmapSetDefaultFreeDataAfterGenTexture(true);
7453 glBitmapSetDefaultDeleteTextureOnFree (true);
7455 TFormatDescriptor.Init;
7458 TFormatDescriptor.Finalize;