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 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1112 TfdAlpha_UB1 = class(TFormatDescriptor) //1* unsigned byte
1113 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1114 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1115 constructor Create; override;
1118 TfdLuminance_UB1 = class(TFormatDescriptor) //1* unsigned byte
1119 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1120 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1121 constructor Create; override;
1124 TfdUniversal_UB1 = class(TFormatDescriptor) //1* unsigned byte
1125 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1126 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1127 constructor Create; override;
1130 TfdLuminanceAlpha_UB2 = class(TfdLuminance_UB1) //2* unsigned byte
1131 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1132 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1133 constructor Create; override;
1136 TfdRGB_UB3 = class(TFormatDescriptor) //3* unsigned byte
1137 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1138 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1139 constructor Create; override;
1142 TfdBGR_UB3 = class(TFormatDescriptor) //3* unsigned byte (inverse)
1143 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1144 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1145 constructor Create; override;
1148 TfdRGBA_UB4 = class(TfdRGB_UB3) //4* unsigned byte
1149 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1150 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1151 constructor Create; override;
1154 TfdBGRA_UB4 = class(TfdBGR_UB3) //4* unsigned byte (inverse)
1155 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1156 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1157 constructor Create; override;
1160 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1161 TfdAlpha_US1 = class(TFormatDescriptor) //1* unsigned short
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 TfdLuminance_US1 = class(TFormatDescriptor) //1* unsigned short
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 TfdUniversal_US1 = class(TFormatDescriptor) //1* unsigned short
1174 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1175 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1176 constructor Create; override;
1179 TfdDepth_US1 = class(TFormatDescriptor) //1* unsigned short
1180 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1181 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1182 constructor Create; override;
1185 TfdLuminanceAlpha_US2 = class(TfdLuminance_US1) //2* unsigned short
1186 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1187 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1188 constructor Create; override;
1191 TfdRGB_US3 = class(TFormatDescriptor) //3* unsigned short
1192 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1193 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1194 constructor Create; override;
1197 TfdBGR_US3 = class(TFormatDescriptor) //3* unsigned short (inverse)
1198 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1199 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1200 constructor Create; override;
1203 TfdRGBA_US4 = class(TfdRGB_US3) //4* unsigned short
1204 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1205 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1206 constructor Create; override;
1209 TfdBGRA_US4 = class(TfdBGR_US3) //4* unsigned short (inverse)
1210 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1211 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1212 constructor Create; override;
1215 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1216 TfdUniversal_UI1 = class(TFormatDescriptor) //1* unsigned int
1217 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1218 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1219 constructor Create; override;
1222 TfdDepth_UI1 = class(TFormatDescriptor) //1* unsigned int
1223 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1224 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1225 constructor Create; override;
1228 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1229 TfdAlpha4 = class(TfdAlpha_UB1)
1230 constructor Create; override;
1233 TfdAlpha8 = class(TfdAlpha_UB1)
1234 constructor Create; override;
1237 TfdAlpha12 = class(TfdAlpha_US1)
1238 constructor Create; override;
1241 TfdAlpha16 = class(TfdAlpha_US1)
1242 constructor Create; override;
1245 TfdLuminance4 = class(TfdLuminance_UB1)
1246 constructor Create; override;
1249 TfdLuminance8 = class(TfdLuminance_UB1)
1250 constructor Create; override;
1253 TfdLuminance12 = class(TfdLuminance_US1)
1254 constructor Create; override;
1257 TfdLuminance16 = class(TfdLuminance_US1)
1258 constructor Create; override;
1261 TfdLuminance4Alpha4 = class(TfdLuminanceAlpha_UB2)
1262 constructor Create; override;
1265 TfdLuminance6Alpha2 = class(TfdLuminanceAlpha_UB2)
1266 constructor Create; override;
1269 TfdLuminance8Alpha8 = class(TfdLuminanceAlpha_UB2)
1270 constructor Create; override;
1273 TfdLuminance12Alpha4 = class(TfdLuminanceAlpha_US2)
1274 constructor Create; override;
1277 TfdLuminance12Alpha12 = class(TfdLuminanceAlpha_US2)
1278 constructor Create; override;
1281 TfdLuminance16Alpha16 = class(TfdLuminanceAlpha_US2)
1282 constructor Create; override;
1285 TfdR3G3B2 = class(TfdUniversal_UB1)
1286 constructor Create; override;
1289 TfdRGB4 = class(TfdUniversal_US1)
1290 constructor Create; override;
1293 TfdR5G6B5 = class(TfdUniversal_US1)
1294 constructor Create; override;
1297 TfdRGB5 = class(TfdUniversal_US1)
1298 constructor Create; override;
1301 TfdRGB8 = class(TfdRGB_UB3)
1302 constructor Create; override;
1305 TfdRGB10 = class(TfdUniversal_UI1)
1306 constructor Create; override;
1309 TfdRGB12 = class(TfdRGB_US3)
1310 constructor Create; override;
1313 TfdRGB16 = class(TfdRGB_US3)
1314 constructor Create; override;
1317 TfdRGBA2 = class(TfdRGBA_UB4)
1318 constructor Create; override;
1321 TfdRGBA4 = class(TfdUniversal_US1)
1322 constructor Create; override;
1325 TfdRGB5A1 = class(TfdUniversal_US1)
1326 constructor Create; override;
1329 TfdRGBA8 = class(TfdRGBA_UB4)
1330 constructor Create; override;
1333 TfdRGB10A2 = class(TfdUniversal_UI1)
1334 constructor Create; override;
1337 TfdRGBA12 = class(TfdRGBA_US4)
1338 constructor Create; override;
1341 TfdRGBA16 = class(TfdRGBA_US4)
1342 constructor Create; override;
1345 TfdBGR4 = class(TfdUniversal_US1)
1346 constructor Create; override;
1349 TfdB5G6R5 = class(TfdUniversal_US1)
1350 constructor Create; override;
1353 TfdBGR5 = class(TfdUniversal_US1)
1354 constructor Create; override;
1357 TfdBGR8 = class(TfdBGR_UB3)
1358 constructor Create; override;
1361 TfdBGR10 = class(TfdUniversal_UI1)
1362 constructor Create; override;
1365 TfdBGR12 = class(TfdBGR_US3)
1366 constructor Create; override;
1369 TfdBGR16 = class(TfdBGR_US3)
1370 constructor Create; override;
1373 TfdBGRA2 = class(TfdBGRA_UB4)
1374 constructor Create; override;
1377 TfdBGRA4 = class(TfdUniversal_US1)
1378 constructor Create; override;
1381 TfdBGR5A1 = class(TfdUniversal_US1)
1382 constructor Create; override;
1385 TfdBGRA8 = class(TfdBGRA_UB4)
1386 constructor Create; override;
1389 TfdBGR10A2 = class(TfdUniversal_UI1)
1390 constructor Create; override;
1393 TfdBGRA12 = class(TfdBGRA_US4)
1394 constructor Create; override;
1397 TfdBGRA16 = class(TfdBGRA_US4)
1398 constructor Create; override;
1401 TfdDepth16 = class(TfdDepth_US1)
1402 constructor Create; override;
1405 TfdDepth24 = class(TfdDepth_UI1)
1406 constructor Create; override;
1409 TfdDepth32 = class(TfdDepth_UI1)
1410 constructor Create; override;
1413 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1414 TBitfieldFormat = class(TFormatDescriptor)
1416 procedure SetRedMask (const aValue: UInt64);
1417 procedure SetGreenMask(const aValue: UInt64);
1418 procedure SetBlueMask (const aValue: UInt64);
1419 procedure SetAlphaMask(const aValue: UInt64);
1421 procedure Update(aMask: UInt64; out aRange: Cardinal; out aShift: Byte);
1423 property RedMask: UInt64 read GetRedMask write SetRedMask;
1424 property GreenMask: UInt64 read GetGreenMask write SetGreenMask;
1425 property BlueMask: UInt64 read GetBlueMask write SetBlueMask;
1426 property AlphaMask: UInt64 read GetAlphaMask write SetAlphaMask;
1428 property PixelSize: Single read fPixelSize write fPixelSize;
1430 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1431 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1434 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1435 TColorTableEnty = packed record
1438 TColorTable = array of TColorTableEnty;
1439 TColorTableFormat = class(TFormatDescriptor)
1441 fColorTable: TColorTable;
1443 property PixelSize: Single read fPixelSize write fPixelSize;
1444 property ColorTable: TColorTable read fColorTable write fColorTable;
1445 property Range: TglBitmapColorRec read fRange write fRange;
1447 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1448 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1449 destructor Destroy; override;
1453 LUMINANCE_WEIGHT_R = 0.30;
1454 LUMINANCE_WEIGHT_G = 0.59;
1455 LUMINANCE_WEIGHT_B = 0.11;
1457 ALPHA_WEIGHT_R = 0.30;
1458 ALPHA_WEIGHT_G = 0.59;
1459 ALPHA_WEIGHT_B = 0.11;
1461 DEPTH_WEIGHT_R = 0.333333333;
1462 DEPTH_WEIGHT_G = 0.333333333;
1463 DEPTH_WEIGHT_B = 0.333333333;
1465 UNSUPPORTED_FORMAT = 'the given format isn''t supported by this function.';
1467 FORMAT_DESCRIPTOR_CLASSES: array[TglBitmapFormat] of TFormatDescriptorClass = (
1480 TfdLuminance4Alpha4,
1481 TfdLuminance6Alpha2,
1482 TfdLuminance8Alpha8,
1483 TfdLuminance12Alpha4,
1484 TfdLuminance12Alpha12,
1485 TfdLuminance16Alpha16,
1526 FormatDescriptorCS: TCriticalSection;
1527 FormatDescriptors: array[TglBitmapFormat] of TFormatDescriptor;
1529 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1530 function glBitmapPosition(X, Y: Integer): TglBitmapPixelPosition;
1532 result.Fields := [];
1535 result.Fields := result.Fields + [ffX];
1537 result.Fields := result.Fields + [ffY];
1539 result.X := Max(0, X);
1540 result.Y := Max(0, Y);
1543 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1544 function glBitmapColorRec(const r, g, b, a: Cardinal): TglBitmapColorRec;
1552 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1553 function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes;
1555 //TODO Supported File Formats!
1556 result := [ftDDS, ftTGA, ftBMP];
1558 {$IFDEF GLB_SUPPORT_PNG_WRITE}
1560 tfAlpha4, tfAlpha8, tfAlpha12, tfAlpha16,
1561 tfLuminance4, tfLuminance8, tfLuminance12, tfLuminance16,
1562 tfuminance4Alpha4, tfLuminance6Alpha2, tfLuminance8Alpha8, tfLuminance12Alpha4, tfLuminance12Alpha12, tfLuminance16Alpha16,
1563 tfR3G3B2, tfRGB4, tfRGB5, tfRGB8, tfRGB10, tfRGB12, tfRGB16,
1564 tfRGBA2, tfRGBA4, tfRGB5A1, tfRGBA8, tfRGB10A2, tfRGBA12, tfRGBA16,
1565 tfDepth16, tfDepth24, tfDepth32]
1567 result := result + [ftPNG];
1570 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
1572 tfAlpha4, tfAlpha8, tfAlpha12, tfAlpha16,
1573 tfLuminance4, tfLuminance8, tfLuminance12, tfLuminance16,
1574 tfR3G3B2, tfRGB4, tfRGB5, tfRGB8, tfRGB10, tfRGB12, tfRGB16,
1575 tfDepth16, tfDepth24, tfDepth32]
1577 result := result + [ftJPEG];
1581 tfAlpha4, tfAlpha8, tfAlpha12, tfAlpha16,
1582 tfLuminance4, tfLuminance8, tfLuminance12, tfLuminance16,
1583 tfuminance4Alpha4, tfLuminance6Alpha2, tfLuminance8Alpha8, tfLuminance12Alpha4, tfLuminance12Alpha12, tfLuminance16Alpha16,
1584 tfR3G3B2, tfRGB4, tfRGB5, tfRGB8, tfRGB10, tfRGB12, tfRGB16,
1585 tfRGBA2, tfRGBA4, tfRGB5A1, tfRGBA8, tfRGB10A2, tfRGBA12, tfRGBA16,
1586 tfDepth16, tfDepth24, tfDepth32]
1588 result := result + [ftDDS, ftTGA, ftBMP];
1592 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1593 function IsPowerOfTwo(aNumber: Integer): Boolean;
1595 while (aNumber and 1) = 0 do
1596 aNumber := aNumber shr 1;
1597 result := aNumber = 1;
1600 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1601 function GetTopMostBit(aBitSet: UInt64): Integer;
1604 while aBitSet > 0 do begin
1606 aBitSet := aBitSet shr 1;
1610 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1611 function CountSetBits(aBitSet: UInt64): Integer;
1614 while aBitSet > 0 do begin
1615 if (aBitSet and 1) = 1 then
1617 aBitSet := aBitSet shr 1;
1621 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1622 function LuminanceWeight(const aPixel: TglBitmapPixelData): Cardinal;
1625 LUMINANCE_WEIGHT_R * aPixel.Data.r +
1626 LUMINANCE_WEIGHT_G * aPixel.Data.g +
1627 LUMINANCE_WEIGHT_B * aPixel.Data.b);
1630 function DepthWeight(const aPixel: TglBitmapPixelData): Cardinal;
1633 DEPTH_WEIGHT_R * aPixel.Data.r +
1634 DEPTH_WEIGHT_G * aPixel.Data.g +
1635 DEPTH_WEIGHT_B * aPixel.Data.b);
1638 //TODO check _ARB functions and constants
1641 {$IFNDEF GLB_NO_NATIVE_GL}
1642 procedure ReadOpenGLExtensions;
1648 MajorVersion, MinorVersion: Integer;
1651 procedure TrimVersionString(Buffer: AnsiString; var Major, Minor: Integer);
1658 Separator := Pos(AnsiString('.'), Buffer);
1660 if (Separator > 1) and (Separator < Length(Buffer)) and
1661 (Buffer[Separator - 1] in ['0'..'9']) and
1662 (Buffer[Separator + 1] in ['0'..'9']) then begin
1665 while (Separator > 0) and (Buffer[Separator] in ['0'..'9']) do
1668 Delete(Buffer, 1, Separator);
1669 Separator := Pos(AnsiString('.'), Buffer) + 1;
1671 while (Separator <= Length(Buffer)) and (AnsiChar(Buffer[Separator]) in ['0'..'9']) do
1674 Delete(Buffer, Separator, 255);
1675 Separator := Pos(AnsiString('.'), Buffer);
1677 Major := StrToInt(Copy(String(Buffer), 1, Separator - 1));
1678 Minor := StrToInt(Copy(String(Buffer), Separator + 1, 1));
1683 function CheckExtension(const Extension: AnsiString): Boolean;
1687 ExtPos := Pos(Extension, Buffer);
1688 result := ExtPos > 0;
1691 result := ((ExtPos + Length(Extension) - 1) = Length(Buffer)) or not (Buffer[ExtPos + Length(Extension)] in ['_', 'A'..'Z', 'a'..'z']);
1695 function glLoad (aFunc: pAnsiChar): pointer;
1698 result := glXGetProcAddress(aFunc);
1700 result := wglGetProcAddress(aFunc);
1707 Context := wglGetCurrentContext;
1709 if Context <> gLastContext then begin
1710 gLastContext := Context;
1714 Buffer := glGetString(GL_VERSION);
1715 TrimVersionString(Buffer, MajorVersion, MinorVersion);
1717 GL_VERSION_1_2 := false;
1718 GL_VERSION_1_3 := false;
1719 GL_VERSION_1_4 := false;
1720 GL_VERSION_2_0 := false;
1722 if MajorVersion = 1 then begin
1723 if MinorVersion >= 1 then begin
1724 if MinorVersion >= 2 then
1725 GL_VERSION_1_2 := true;
1727 if MinorVersion >= 3 then
1728 GL_VERSION_1_3 := true;
1730 if MinorVersion >= 4 then
1731 GL_VERSION_1_4 := true;
1735 if MajorVersion >= 2 then begin
1736 GL_VERSION_1_2 := true;
1737 GL_VERSION_1_3 := true;
1738 GL_VERSION_1_4 := true;
1739 GL_VERSION_2_0 := true;
1743 Buffer := glGetString(GL_EXTENSIONS);
1744 GL_ARB_texture_border_clamp := CheckExtension('GL_ARB_texture_border_clamp');
1745 GL_ARB_texture_cube_map := CheckExtension('GL_ARB_texture_cube_map');
1746 GL_ARB_texture_compression := CheckExtension('GL_ARB_texture_compression');
1747 GL_ARB_texture_non_power_of_two := CheckExtension('GL_ARB_texture_non_power_of_two');
1748 GL_ARB_texture_rectangle := CheckExtension('GL_ARB_texture_rectangle');
1749 GL_ARB_texture_mirrored_repeat := CheckExtension('GL_ARB_texture_mirrored_repeat');
1750 GL_EXT_bgra := CheckExtension('GL_EXT_bgra');
1751 GL_EXT_texture_edge_clamp := CheckExtension('GL_EXT_texture_edge_clamp');
1752 GL_EXT_texture_cube_map := CheckExtension('GL_EXT_texture_cube_map');
1753 GL_EXT_texture_compression_s3tc := CheckExtension('GL_EXT_texture_compression_s3tc');
1754 GL_EXT_texture_filter_anisotropic := CheckExtension('GL_EXT_texture_filter_anisotropic');
1755 GL_EXT_texture_rectangle := CheckExtension('GL_EXT_texture_rectangle');
1756 GL_NV_texture_rectangle := CheckExtension('GL_NV_texture_rectangle');
1757 GL_IBM_texture_mirrored_repeat := CheckExtension('GL_IBM_texture_mirrored_repeat');
1758 GL_SGIS_generate_mipmap := CheckExtension('GL_SGIS_generate_mipmap');
1761 if GL_VERSION_1_3 then begin
1763 glCompressedTexImage1D := glLoad('glCompressedTexImage1D');
1764 glCompressedTexImage2D := glLoad('glCompressedTexImage2D');
1765 glGetCompressedTexImage := glLoad('glGetCompressedTexImage');
1769 // Try loading Extension
1770 glCompressedTexImage1D := glLoad('glCompressedTexImage1DARB');
1771 glCompressedTexImage2D := glLoad('glCompressedTexImage2DARB');
1772 glGetCompressedTexImage := glLoad('glGetCompressedTexImageARB');
1783 function CreateGrayPalette: HPALETTE;
1788 GetMem(Pal, SizeOf(TLogPalette) + (SizeOf(TPaletteEntry) * 256));
1790 Pal.palVersion := $300;
1791 Pal.palNumEntries := 256;
1794 {$DEFINE GLB_TEMPRANGECHECK}
1798 for Idx := 0 to 256 - 1 do begin
1799 Pal.palPalEntry[Idx].peRed := Idx;
1800 Pal.palPalEntry[Idx].peGreen := Idx;
1801 Pal.palPalEntry[Idx].peBlue := Idx;
1802 Pal.palPalEntry[Idx].peFlags := 0;
1805 {$IFDEF GLB_TEMPRANGECHECK}
1806 {$UNDEF GLB_TEMPRANGECHECK}
1810 result := CreatePalette(Pal^);
1817 (* TODO GLB_SDL_IMAGE
1818 {$IFDEF GLB_SDL_IMAGE}
1819 function glBitmapRWseek(context: PSDL_RWops; offset: Integer; whence: Integer): Integer; cdecl;
1821 result := TStream(context^.unknown.data1).Seek(offset, whence);
1824 function glBitmapRWread(context: PSDL_RWops; Ptr: Pointer; size: Integer; maxnum : Integer): Integer; cdecl;
1826 result := TStream(context^.unknown.data1).Read(Ptr^, size * maxnum);
1829 function glBitmapRWwrite(context: PSDL_RWops; Ptr: Pointer; size: Integer; num: Integer): Integer; cdecl;
1831 result := TStream(context^.unknown.data1).Write(Ptr^, size * num);
1834 function glBitmapRWclose(context: PSDL_RWops): Integer; cdecl;
1839 function glBitmapCreateRWops(Stream: TStream): PSDL_RWops;
1841 result := SDL_AllocRW;
1843 if result = nil then
1844 raise EglBitmapException.Create('glBitmapCreateRWops - SDL_AllocRW failed.');
1846 result^.seek := glBitmapRWseek;
1847 result^.read := glBitmapRWread;
1848 result^.write := glBitmapRWwrite;
1849 result^.close := glBitmapRWclose;
1850 result^.unknown.data1 := Stream;
1856 function LoadTexture(Filename: String; var Texture: Cardinal{$IFDEF GLB_DELPHI}; LoadFromRes : Boolean; Instance: Cardinal{$ENDIF}): Boolean;
1858 glBitmap: TglBitmap2D;
1864 if Instance = 0 then
1865 Instance := HInstance;
1867 if (LoadFromRes) then
1868 glBitmap := TglBitmap2D.CreateFromResourceName(Instance, FileName)
1871 glBitmap := TglBitmap2D.Create(FileName);
1874 glBitmap.DeleteTextureOnFree := false;
1875 glBitmap.FreeDataAfterGenTexture := false;
1876 glBitmap.GenTexture(true);
1877 if (glBitmap.ID > 0) then begin
1878 Texture := glBitmap.ID;
1886 function LoadCubeMap(PositiveX, NegativeX, PositiveY, NegativeY, PositiveZ, NegativeZ: String; var Texture: Cardinal{$IFDEF GLB_DELPHI}; LoadFromRes : Boolean; Instance: Cardinal{$ENDIF}): Boolean;
1888 CM: TglBitmapCubeMap;
1893 if Instance = 0 then
1894 Instance := HInstance;
1897 CM := TglBitmapCubeMap.Create;
1899 CM.DeleteTextureOnFree := false;
1903 if (LoadFromRes) then
1904 CM.LoadFromResource(Instance, PositiveX)
1907 CM.LoadFromFile(PositiveX);
1908 CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X);
1911 if (LoadFromRes) then
1912 CM.LoadFromResource(Instance, NegativeX)
1915 CM.LoadFromFile(NegativeX);
1916 CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_X);
1919 if (LoadFromRes) then
1920 CM.LoadFromResource(Instance, PositiveY)
1923 CM.LoadFromFile(PositiveY);
1924 CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Y);
1927 if (LoadFromRes) then
1928 CM.LoadFromResource(Instance, NegativeY)
1931 CM.LoadFromFile(NegativeY);
1932 CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);
1935 if (LoadFromRes) then
1936 CM.LoadFromResource(Instance, PositiveZ)
1939 CM.LoadFromFile(PositiveZ);
1940 CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Z);
1943 if (LoadFromRes) then
1944 CM.LoadFromResource(Instance, NegativeZ)
1947 CM.LoadFromFile(NegativeZ);
1948 CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
1957 function LoadNormalMap(Size: Integer; var Texture: Cardinal): Boolean;
1959 NM: TglBitmapNormalMap;
1963 NM := TglBitmapNormalMap.Create;
1965 NM.DeleteTextureOnFree := false;
1966 NM.GenerateNormalMap(Size);
1976 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1977 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
1979 glBitmapDefaultDeleteTextureOnFree := aDeleteTextureOnFree;
1982 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1983 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
1985 glBitmapDefaultFreeDataAfterGenTextures := aFreeData;
1988 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1989 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
1991 glBitmapDefaultMipmap := aValue;
1994 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1995 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
1997 glBitmapDefaultFormat := aFormat;
2000 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2001 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
2003 glBitmapDefaultFilterMin := aMin;
2004 glBitmapDefaultFilterMag := aMag;
2007 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2008 procedure glBitmapSetDefaultWrap(const S: Cardinal = GL_CLAMP_TO_EDGE; const T: Cardinal = GL_CLAMP_TO_EDGE; const R: Cardinal = GL_CLAMP_TO_EDGE);
2010 glBitmapDefaultWrapS := S;
2011 glBitmapDefaultWrapT := T;
2012 glBitmapDefaultWrapR := R;
2015 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2016 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
2018 result := glBitmapDefaultDeleteTextureOnFree;
2021 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2022 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
2024 result := glBitmapDefaultFreeDataAfterGenTextures;
2027 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2028 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
2030 result := glBitmapDefaultMipmap;
2033 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2034 function glBitmapGetDefaultFormat: TglBitmapFormat;
2036 result := glBitmapDefaultFormat;
2039 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2040 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
2042 aMin := glBitmapDefaultFilterMin;
2043 aMag := glBitmapDefaultFilterMag;
2046 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2047 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
2049 S := glBitmapDefaultWrapS;
2050 T := glBitmapDefaultWrapT;
2051 R := glBitmapDefaultWrapR;
2054 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2055 //TglBitmapFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2056 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2057 function TFormatDescriptor.GetRedMask: UInt64;
2059 result := fRange.r shl fShift.r;
2062 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2063 function TFormatDescriptor.GetGreenMask: UInt64;
2065 result := fRange.g shl fShift.g;
2068 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2069 function TFormatDescriptor.GetBlueMask: UInt64;
2071 result := fRange.b shl fShift.b;
2074 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2075 function TFormatDescriptor.GetAlphaMask: UInt64;
2077 result := fRange.a shl fShift.a;
2080 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2081 function TFormatDescriptor.GetComponents: Integer;
2087 if (fRange.arr[i] > 0) then
2091 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2092 function TFormatDescriptor.GetSize(const aSize: TglBitmapPixelPosition): Integer;
2096 if (ffX in aSize.Fields) or (ffY in aSize.Fields) then begin
2097 w := Max(1, aSize.X);
2098 h := Max(1, aSize.Y);
2099 result := GetSize(w, h);
2104 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2105 function TFormatDescriptor.GetSize(const aWidth, aHeight: Integer): Integer;
2108 if (aWidth <= 0) or (aHeight <= 0) then
2110 result := Ceil(aWidth * aHeight * fPixelSize);
2113 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2114 function TFormatDescriptor.CreateMappingData: Pointer;
2119 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2120 procedure TFormatDescriptor.FreeMappingData(var aMappingData: Pointer);
2125 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2126 function TFormatDescriptor.IsEmpty: Boolean;
2128 result := (fFormat = tfEmpty);
2131 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2132 function TFormatDescriptor.HasAlpha: Boolean;
2134 result := (fRange.a > 0);
2137 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2138 function TFormatDescriptor.MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: UInt64): Boolean;
2142 if (aRedMask = 0) and (aGreenMask = 0) and (aBlueMask = 0) and (aAlphaMask = 0) then
2143 raise EglBitmapException.Create('FormatCheckFormat - All Masks are 0');
2145 if (aRedMask <> RedMask) then
2147 if (aGreenMask <> GreenMask) then
2149 if (aBlueMask <> BlueMask) then
2151 if (aAlphaMask <> AlphaMask) then
2156 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2157 procedure TFormatDescriptor.PreparePixel(var aPixel: TglBitmapPixelData);
2159 FillChar(aPixel, SizeOf(aPixel), 0);
2160 aPixel.Data := fRange;
2161 aPixel.Range := fRange;
2162 aPixel.Format := fFormat;
2165 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2166 constructor TFormatDescriptor.Create;
2171 fWithAlpha := tfEmpty;
2172 fWithoutAlpha := tfEmpty;
2176 fglInternalFormat := 0;
2179 FillChar(fRange, 0, SizeOf(fRange));
2180 FillChar(fShift, 0, SizeOf(fShift));
2183 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2184 //TfdAlpha_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2185 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2186 procedure TfdAlpha_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2188 aData^ := aPixel.Data.a;
2192 procedure TfdAlpha_UB1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2197 aPixel.Data.a := aData^;
2201 constructor TfdAlpha_UB1.Create;
2206 fglFormat := GL_ALPHA;
2207 fglDataFormat := GL_UNSIGNED_BYTE;
2210 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2211 //TfdLuminance_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2212 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2213 procedure TfdLuminance_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2215 aData^ := LuminanceWeight(aPixel);
2219 procedure TfdLuminance_UB1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2221 aPixel.Data.r := aData^;
2222 aPixel.Data.g := aData^;
2223 aPixel.Data.b := aData^;
2228 constructor TfdLuminance_UB1.Create;
2235 fglFormat := GL_LUMINANCE;
2236 fglDataFormat := GL_UNSIGNED_BYTE;
2239 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2240 //TfdUniversal_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2241 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2242 procedure TfdUniversal_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2248 if (fRange.arr[i] > 0) then
2249 aData^ := aData^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
2253 procedure TfdUniversal_UB1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2258 aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and fRange.arr[i];
2262 constructor TfdUniversal_UB1.Create;
2268 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2269 //TfdLuminanceAlpha_UB2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2270 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2271 procedure TfdLuminanceAlpha_UB2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2273 inherited Map(aPixel, aData, aMapData);
2274 aData^ := aPixel.Data.a;
2278 procedure TfdLuminanceAlpha_UB2.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2280 inherited Unmap(aData, aPixel, aMapData);
2281 aPixel.Data.a := aData^;
2285 constructor TfdLuminanceAlpha_UB2.Create;
2291 fglFormat := GL_LUMINANCE_ALPHA;
2292 fglDataFormat := GL_UNSIGNED_BYTE;
2295 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2296 //TfdRGB_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2297 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2298 procedure TfdRGB_UB3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2300 aData^ := aPixel.Data.r;
2302 aData^ := aPixel.Data.g;
2304 aData^ := aPixel.Data.b;
2308 procedure TfdRGB_UB3.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2310 aPixel.Data.r := aData^;
2312 aPixel.Data.g := aData^;
2314 aPixel.Data.b := aData^;
2319 constructor TfdRGB_UB3.Create;
2329 fglFormat := GL_RGB;
2330 fglDataFormat := GL_UNSIGNED_BYTE;
2333 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2334 //TfdBGR_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2335 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2336 procedure TfdBGR_UB3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2338 aData^ := aPixel.Data.b;
2340 aData^ := aPixel.Data.g;
2342 aData^ := aPixel.Data.r;
2346 procedure TfdBGR_UB3.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2348 aPixel.Data.b := aData^;
2350 aPixel.Data.g := aData^;
2352 aPixel.Data.r := aData^;
2357 constructor TfdBGR_UB3.Create;
2366 fglFormat := GL_BGR;
2367 fglDataFormat := GL_UNSIGNED_BYTE;
2370 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2371 //TdfRGBA_UB4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2372 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2373 procedure TfdRGBA_UB4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2375 inherited Map(aPixel, aData, aMapData);
2376 aData^ := aPixel.Data.a;
2380 procedure TfdRGBA_UB4.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2382 inherited Unmap(aData, aPixel, aMapData);
2383 aPixel.Data.a := aData^;
2387 constructor TfdRGBA_UB4.Create;
2393 fglFormat := GL_RGBA;
2394 fglDataFormat := GL_UNSIGNED_BYTE;
2397 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2398 //TfdBGRA_UB4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2399 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2400 procedure TfdBGRA_UB4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2402 inherited Map(aPixel, aData, aMapData);
2403 aData^ := aPixel.Data.a;
2407 procedure TfdBGRA_UB4.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2409 inherited Unmap(aData, aPixel, aMapData);
2410 aPixel.Data.a := aData^;
2414 constructor TfdBGRA_UB4.Create;
2420 fglFormat := GL_BGRA;
2421 fglDataFormat := GL_UNSIGNED_BYTE;
2424 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2425 //TfdAlpha_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2426 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2427 procedure TfdAlpha_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2429 PWord(aData)^ := aPixel.Data.a;
2433 procedure TfdAlpha_US1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2438 aPixel.Data.a := PWord(aData)^;
2442 constructor TfdAlpha_US1.Create;
2447 fglFormat := GL_ALPHA;
2448 fglDataFormat := GL_UNSIGNED_SHORT;
2451 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2452 //TfdLuminance_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2453 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2454 procedure TfdLuminance_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2456 PWord(aData)^ := LuminanceWeight(aPixel);
2460 procedure TfdLuminance_US1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2462 aPixel.Data.r := PWord(aData)^;
2463 aPixel.Data.g := PWord(aData)^;
2464 aPixel.Data.b := PWord(aData)^;
2469 constructor TfdLuminance_US1.Create;
2476 fglFormat := GL_LUMINANCE;
2477 fglDataFormat := GL_UNSIGNED_SHORT;
2480 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2481 //TfdUniversal_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2482 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2483 procedure TfdUniversal_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2489 if (fRange.arr[i] > 0) then
2490 PWord(aData)^ := PWord(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
2494 procedure TfdUniversal_US1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2499 aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and fRange.arr[i];
2503 constructor TfdUniversal_US1.Create;
2509 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2510 //TfdDepth_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2511 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2512 procedure TfdDepth_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2514 PWord(aData)^ := DepthWeight(aPixel);
2518 procedure TfdDepth_US1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2520 aPixel.Data.r := PWord(aData)^;
2521 aPixel.Data.g := PWord(aData)^;
2522 aPixel.Data.b := PWord(aData)^;
2527 constructor TfdDepth_US1.Create;
2534 fglFormat := GL_DEPTH_COMPONENT;
2535 fglDataFormat := GL_UNSIGNED_SHORT;
2538 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2539 //TfdLuminanceAlpha_US2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2540 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2541 procedure TfdLuminanceAlpha_US2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2543 inherited Map(aPixel, aData, aMapData);
2544 PWord(aData)^ := aPixel.Data.a;
2548 procedure TfdLuminanceAlpha_US2.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2550 inherited Unmap(aData, aPixel, aMapData);
2551 aPixel.Data.a := PWord(aData)^;
2555 constructor TfdLuminanceAlpha_US2.Create;
2561 fglFormat := GL_LUMINANCE_ALPHA;
2562 fglDataFormat := GL_UNSIGNED_SHORT;
2565 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2566 //TfdRGB_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2567 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2568 procedure TfdRGB_US3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2570 PWord(aData)^ := aPixel.Data.r;
2572 PWord(aData)^ := aPixel.Data.g;
2574 PWord(aData)^ := aPixel.Data.b;
2578 procedure TfdRGB_US3.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2580 aPixel.Data.r := PWord(aData)^;
2582 aPixel.Data.g := PWord(aData)^;
2584 aPixel.Data.b := PWord(aData)^;
2589 constructor TfdRGB_US3.Create;
2599 fglFormat := GL_RGB;
2600 fglDataFormat := GL_UNSIGNED_SHORT;
2603 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2604 //TfdBGR_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2605 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2606 procedure TfdBGR_US3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2608 PWord(aData)^ := aPixel.Data.b;
2610 PWord(aData)^ := aPixel.Data.g;
2612 PWord(aData)^ := aPixel.Data.r;
2616 procedure TfdBGR_US3.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2618 aPixel.Data.b := PWord(aData)^;
2620 aPixel.Data.g := PWord(aData)^;
2622 aPixel.Data.r := PWord(aData)^;
2627 constructor TfdBGR_US3.Create;
2637 fglFormat := GL_BGR;
2638 fglDataFormat := GL_UNSIGNED_SHORT;
2641 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2642 //TfdRGBA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2643 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2644 procedure TfdRGBA_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2646 inherited Map(aPixel, aData, aMapData);
2647 PWord(aData)^ := aPixel.Data.a;
2651 procedure TfdRGBA_US4.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2653 inherited Unmap(aData, aPixel, aMapData);
2654 aPixel.Data.a := PWord(aData)^;
2658 constructor TfdRGBA_US4.Create;
2664 fglFormat := GL_RGBA;
2665 fglDataFormat := GL_UNSIGNED_SHORT;
2668 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2669 //TfdBGRA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2670 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2671 procedure TfdBGRA_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2673 inherited Map(aPixel, aData, aMapData);
2674 PWord(aData)^ := aPixel.Data.a;
2678 procedure TfdBGRA_US4.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2680 inherited Unmap(aData, aPixel, aMapData);
2681 aPixel.Data.a := PWord(aData)^;
2685 constructor TfdBGRA_US4.Create;
2691 fglFormat := GL_BGRA;
2692 fglDataFormat := GL_UNSIGNED_SHORT;
2695 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2696 //TfdUniversal_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2697 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2698 procedure TfdUniversal_UI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2702 PCardinal(aData)^ := 0;
2704 if (fRange.arr[i] > 0) then
2705 PCardinal(aData)^ := PCardinal(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
2709 procedure TfdUniversal_UI1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2714 aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and fRange.arr[i];
2718 constructor TfdUniversal_UI1.Create;
2724 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2725 //TfdDepth_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2726 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2727 procedure TfdDepth_UI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2729 PCardinal(aData)^ := DepthWeight(aPixel);
2733 procedure TfdDepth_UI1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2735 aPixel.Data.r := PCardinal(aData)^;
2736 aPixel.Data.g := PCardinal(aData)^;
2737 aPixel.Data.b := PCardinal(aData)^;
2742 constructor TfdDepth_UI1.Create;
2746 fRange.r := $FFFFFFFF;
2747 fRange.g := $FFFFFFFF;
2748 fRange.b := $FFFFFFFF;
2749 fglFormat := GL_DEPTH_COMPONENT;
2750 fglDataFormat := GL_UNSIGNED_INT;
2753 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2754 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2755 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2756 constructor TfdAlpha4.Create;
2759 fFormat := tfAlpha4;
2760 fWithAlpha := tfAlpha4;
2761 fglInternalFormat := GL_ALPHA4;
2764 constructor TfdAlpha8.Create;
2767 fFormat := tfAlpha8;
2768 fWithAlpha := tfAlpha8;
2769 fglInternalFormat := GL_ALPHA8;
2772 constructor TfdAlpha12.Create;
2775 fFormat := tfAlpha12;
2776 fWithAlpha := tfAlpha12;
2777 fglInternalFormat := GL_ALPHA12;
2780 constructor TfdAlpha16.Create;
2783 fFormat := tfAlpha16;
2784 fWithAlpha := tfAlpha16;
2785 fglInternalFormat := GL_ALPHA16;
2788 constructor TfdLuminance4.Create;
2791 fFormat := tfLuminance4;
2792 fWithAlpha := tfLuminance4Alpha4;
2793 fWithoutAlpha := tfLuminance4;
2794 fglInternalFormat := GL_LUMINANCE4;
2797 constructor TfdLuminance8.Create;
2800 fFormat := tfLuminance8;
2801 fWithAlpha := tfLuminance8Alpha8;
2802 fWithoutAlpha := tfLuminance8;
2803 fglInternalFormat := GL_LUMINANCE8;
2806 constructor TfdLuminance12.Create;
2809 fFormat := tfLuminance12;
2810 fWithAlpha := tfLuminance12Alpha12;
2811 fWithoutAlpha := tfLuminance12;
2812 fglInternalFormat := GL_LUMINANCE12;
2815 constructor TfdLuminance16.Create;
2818 fFormat := tfLuminance16;
2819 fWithAlpha := tfLuminance16Alpha16;
2820 fWithoutAlpha := tfLuminance16;
2821 fglInternalFormat := GL_LUMINANCE16;
2824 constructor TfdLuminance4Alpha4.Create;
2827 fFormat := tfLuminance4Alpha4;
2828 fWithAlpha := tfLuminance4Alpha4;
2829 fWithoutAlpha := tfLuminance4;
2830 fglInternalFormat := GL_LUMINANCE4_ALPHA4;
2833 constructor TfdLuminance6Alpha2.Create;
2836 fFormat := tfLuminance6Alpha2;
2837 fWithAlpha := tfLuminance6Alpha2;
2838 fWithoutAlpha := tfLuminance8;
2839 fglInternalFormat := GL_LUMINANCE6_ALPHA2;
2842 constructor TfdLuminance8Alpha8.Create;
2845 fFormat := tfLuminance8Alpha8;
2846 fWithAlpha := tfLuminance8Alpha8;
2847 fWithoutAlpha := tfLuminance8;
2848 fglInternalFormat := GL_LUMINANCE8_ALPHA8;
2851 constructor TfdLuminance12Alpha4.Create;
2854 fFormat := tfLuminance12Alpha4;
2855 fWithAlpha := tfLuminance12Alpha4;
2856 fWithoutAlpha := tfLuminance12;
2857 fglInternalFormat := GL_LUMINANCE12_ALPHA4;
2860 constructor TfdLuminance12Alpha12.Create;
2863 fFormat := tfLuminance12Alpha12;
2864 fWithAlpha := tfLuminance12Alpha12;
2865 fWithoutAlpha := tfLuminance12;
2866 fglInternalFormat := GL_LUMINANCE12_ALPHA12;
2869 constructor TfdLuminance16Alpha16.Create;
2872 fFormat := tfLuminance16Alpha16;
2873 fWithAlpha := tfLuminance16Alpha16;
2874 fWithoutAlpha := tfLuminance16;
2875 fglInternalFormat := GL_LUMINANCE16_ALPHA16;
2878 constructor TfdR3G3B2.Create;
2881 fFormat := tfR3G3B2;
2882 fWithAlpha := tfRGBA2;
2883 fWithoutAlpha := tfR3G3B2;
2890 fglFormat := GL_RGB;
2891 fglInternalFormat := GL_R3_G3_B2;
2892 fglDataFormat := GL_UNSIGNED_BYTE_2_3_3_REV;
2895 constructor TfdRGB4.Create;
2899 fWithAlpha := tfRGBA4;
2900 fWithoutAlpha := tfRGB4;
2907 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
2908 fglInternalFormat := GL_RGB4;
2909 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
2912 constructor TfdR5G6B5.Create;
2915 fFormat := tfR5G6B5;
2916 fWithAlpha := tfRGBA4;
2917 fWithoutAlpha := tfR5G6B5;
2924 fglFormat := GL_RGB;
2925 fglInternalFormat := GL_RGB565;
2926 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5_REV;
2929 constructor TfdRGB5.Create;
2933 fWithAlpha := tfRGB5A1;
2934 fWithoutAlpha := tfRGB5;
2941 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
2942 fglInternalFormat := GL_RGB5;
2943 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
2946 constructor TfdRGB8.Create;
2950 fWithAlpha := tfRGBA8;
2951 fWithoutAlpha := tfRGB8;
2952 fglInternalFormat := GL_RGB8;
2955 constructor TfdRGB10.Create;
2959 fWithAlpha := tfRGB10A2;
2960 fWithoutAlpha := tfRGB10;
2967 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
2968 fglInternalFormat := GL_RGB10;
2969 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
2972 constructor TfdRGB12.Create;
2976 fWithAlpha := tfRGBA12;
2977 fWithoutAlpha := tfRGB12;
2978 fglInternalFormat := GL_RGB12;
2981 constructor TfdRGB16.Create;
2985 fWithAlpha := tfRGBA16;
2986 fWithoutAlpha := tfRGB16;
2987 fglInternalFormat := GL_RGB16;
2990 constructor TfdRGBA2.Create;
2994 fWithAlpha := tfRGBA2;
2995 fWithoutAlpha := tfR3G3B2;
2996 fglInternalFormat := GL_RGBA2;
2999 constructor TfdRGBA4.Create;
3003 fWithAlpha := tfRGBA4;
3004 fWithoutAlpha := tfRGB4;
3013 fglFormat := GL_RGBA;
3014 fglInternalFormat := GL_RGBA4;
3015 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3018 constructor TfdRGB5A1.Create;
3021 fFormat := tfRGB5A1;
3022 fWithAlpha := tfRGB5A1;
3023 fWithoutAlpha := tfRGB5;
3032 fglFormat := GL_RGBA;
3033 fglInternalFormat := GL_RGB5_A1;
3034 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3037 constructor TfdRGBA8.Create;
3041 fWithAlpha := tfRGBA8;
3042 fWithoutAlpha := tfRGB8;
3043 fglInternalFormat := GL_RGBA8;
3046 constructor TfdRGB10A2.Create;
3049 fFormat := tfRGB10A2;
3050 fWithAlpha := tfRGB10A2;
3051 fWithoutAlpha := tfRGB10;
3060 fglFormat := GL_RGBA;
3061 fglInternalFormat := GL_RGB10_A2;
3062 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3065 constructor TfdRGBA12.Create;
3068 fFormat := tfRGBA12;
3069 fWithAlpha := tfRGBA12;
3070 fWithoutAlpha := tfRGB12;
3071 fglInternalFormat := GL_RGBA12;
3074 constructor TfdRGBA16.Create;
3077 fFormat := tfRGBA16;
3078 fWithAlpha := tfRGBA16;
3079 fWithoutAlpha := tfRGB16;
3080 fglInternalFormat := GL_RGBA16;
3083 constructor TfdBGR4.Create;
3088 fWithAlpha := tfBGRA4;
3089 fWithoutAlpha := tfBGR4;
3098 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3099 fglInternalFormat := GL_RGB4;
3100 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3103 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3104 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3105 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3106 constructor TfdB5G6R5.Create;
3109 fFormat := tfB5G6R5;
3110 fWithAlpha := tfBGRA4;
3111 fWithoutAlpha := tfB5G6R5;
3118 fglFormat := GL_RGB; //B5G6R5 is only possible as R5G6B5 -> use reverted dataformat
3119 fglInternalFormat := GL_RGB8;
3120 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5;
3123 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3124 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3125 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3126 constructor TfdBGR5.Create;
3131 fWithAlpha := tfBGR5A1;
3132 fWithoutAlpha := tfBGR5;
3141 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3142 fglInternalFormat := GL_RGB5;
3143 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3146 constructor TfdBGR8.Create;
3150 fWithAlpha := tfBGRA8;
3151 fWithoutAlpha := tfBGR8;
3152 fglInternalFormat := GL_RGB8;
3155 constructor TfdBGR10.Create;
3159 fWithAlpha := tfBGR10A2;
3160 fWithoutAlpha := tfBGR10;
3169 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3170 fglInternalFormat := GL_RGB10;
3171 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3174 constructor TfdBGR12.Create;
3178 fWithAlpha := tfBGRA12;
3179 fWithoutAlpha := tfBGR12;
3180 fglInternalFormat := GL_RGB12;
3183 constructor TfdBGR16.Create;
3187 fWithAlpha := tfBGRA16;
3188 fWithoutAlpha := tfBGR16;
3189 fglInternalFormat := GL_RGB16;
3192 constructor TfdBGRA2.Create;
3196 fWithAlpha := tfBGRA4;
3197 fWithoutAlpha := tfBGR4;
3198 fglInternalFormat := GL_RGBA2;
3201 constructor TfdBGRA4.Create;
3205 fWithAlpha := tfBGRA4;
3206 fWithoutAlpha := tfBGR4;
3215 fglFormat := GL_BGRA;
3216 fglInternalFormat := GL_RGBA4;
3217 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3220 constructor TfdBGR5A1.Create;
3223 fFormat := tfBGR5A1;
3224 fWithAlpha := tfBGR5A1;
3225 fWithoutAlpha := tfBGR5;
3234 fglFormat := GL_BGRA;
3235 fglInternalFormat := GL_RGB5_A1;
3236 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3239 constructor TfdBGRA8.Create;
3243 fWithAlpha := tfBGRA8;
3244 fWithoutAlpha := tfBGR8;
3245 fglInternalFormat := GL_RGBA8;
3248 constructor TfdBGR10A2.Create;
3251 fFormat := tfBGR10A2;
3252 fWithAlpha := tfBGR10A2;
3253 fWithoutAlpha := tfBGR10;
3262 fglFormat := GL_BGRA;
3263 fglInternalFormat := GL_RGB10_A2;
3264 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3267 constructor TfdBGRA12.Create;
3270 fFormat := tfBGRA12;
3271 fWithAlpha := tfBGRA12;
3272 fWithoutAlpha := tfBGR12;
3273 fglInternalFormat := GL_RGBA12;
3276 constructor TfdBGRA16.Create;
3279 fFormat := tfBGRA16;
3280 fWithAlpha := tfBGRA16;
3281 fWithoutAlpha := tfBGR16;
3282 fglInternalFormat := GL_RGBA16;
3285 constructor TfdDepth16.Create;
3288 fFormat := tfDepth16;
3289 fWithAlpha := tfEmpty;
3290 fWithoutAlpha := tfDepth16;
3291 fglInternalFormat := GL_DEPTH_COMPONENT16;
3294 constructor TfdDepth24.Create;
3297 fFormat := tfDepth24;
3298 fWithAlpha := tfEmpty;
3299 fWithoutAlpha := tfDepth24;
3300 fglInternalFormat := GL_DEPTH_COMPONENT24;
3303 constructor TfdDepth32.Create;
3306 fFormat := tfDepth32;
3307 fWithAlpha := tfEmpty;
3308 fWithoutAlpha := tfDepth32;
3309 fglInternalFormat := GL_DEPTH_COMPONENT32;
3312 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3313 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3314 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3315 class procedure TFormatDescriptor.Init;
3317 if not Assigned(FormatDescriptorCS) then
3318 FormatDescriptorCS := TCriticalSection.Create;
3321 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3322 class function TFormatDescriptor.Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
3324 FormatDescriptorCS.Enter;
3326 result := FormatDescriptors[aFormat];
3327 if not Assigned(result) then begin
3328 result := FORMAT_DESCRIPTOR_CLASSES[aFormat].Create;
3329 FormatDescriptors[aFormat] := result;
3332 FormatDescriptorCS.Leave;
3336 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3337 class function TFormatDescriptor.GetWithAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
3339 result := Get(Get(aFormat).WithAlpha);
3342 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3343 class procedure TFormatDescriptor.Clear;
3347 FormatDescriptorCS.Enter;
3349 for f := low(FormatDescriptors) to high(FormatDescriptors) do
3350 FreeAndNil(FormatDescriptors[f]);
3352 FormatDescriptorCS.Leave;
3356 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3357 class procedure TFormatDescriptor.Finalize;
3360 FreeAndNil(FormatDescriptorCS);
3363 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3364 //TBitfieldFormat/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3365 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3366 procedure TBitfieldFormat.SetRedMask(const aValue: UInt64);
3368 Update(aValue, fRange.r, fShift.r);
3371 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3372 procedure TBitfieldFormat.SetGreenMask(const aValue: UInt64);
3374 Update(aValue, fRange.g, fShift.g);
3377 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3378 procedure TBitfieldFormat.SetBlueMask(const aValue: UInt64);
3380 Update(aValue, fRange.b, fShift.b);
3383 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3384 procedure TBitfieldFormat.SetAlphaMask(const aValue: UInt64);
3386 Update(aValue, fRange.a, fShift.a);
3389 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3390 procedure TBitfieldFormat.Update(aMask: UInt64; out aRange: Cardinal; out
3397 while (aMask > 0) and ((aMask and 1) = 0) do begin
3399 aMask := aMask shr 1;
3402 while (aMask > 0) do begin
3403 aRange := aRange shl 1;
3404 aMask := aMask shr 1;
3408 fPixelSize := Round(GetTopMostBit(RedMask or GreenMask or BlueMask or AlphaMask) / 8);
3411 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3412 procedure TBitfieldFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3420 ((aPixel.Data.r and fRange.r) shl fShift.r) or
3421 ((aPixel.Data.g and fRange.g) shl fShift.g) or
3422 ((aPixel.Data.b and fRange.b) shl fShift.b) or
3423 ((aPixel.Data.a and fRange.a) shl fShift.a);
3424 s := Round(fPixelSize);
3427 2: PWord(aData)^ := data;
3428 4: PCardinal(aData)^ := data;
3429 8: PUInt64(aData)^ := data;
3431 raise EglBitmapException.CreateFmt('invalid pixel size: %.1f', [fPixelSize]);
3436 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3437 procedure TBitfieldFormat.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
3444 s := Round(fPixelSize);
3447 2: data := PWord(aData)^;
3448 4: data := PCardinal(aData)^;
3449 8: data := PUInt64(aData)^;
3451 raise EglBitmapException.CreateFmt('invalid pixel size: %.1f', [fPixelSize]);
3454 aPixel.Data.arr[i] := (data shr fShift.arr[i]) and fRange.arr[i];
3458 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3459 //TColorTableFormat///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3460 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3461 procedure TColorTableFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3463 raise EglBitmapException.Create('mapping of color table formats is not supported');
3466 procedure TColorTableFormat.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
3475 s := Trunc(fPixelSize);
3476 f := fPixelSize - s;
3477 bits := Round(8 * f);
3479 0: idx := (aData^ shr (8 - bits - PtrInt(aMapData))) and ((1 shl bits) - 1);
3481 2: idx := PWord(aData)^;
3482 4: idx := PCardinal(aData)^;
3483 8: idx := PUInt64(aData)^;
3485 raise EglBitmapException.CreateFmt('invalid pixel size: %.3f', [fPixelSize]);
3487 if (idx >= Length(fColorTable)) then
3488 raise EglBitmapException.CreateFmt('invalid color index: %d', [idx]);
3489 with fColorTable[idx] do begin
3495 inc(aMapData, bits);
3496 if (PtrInt(aMapData) >= 8) then begin
3503 destructor TColorTableFormat.Destroy;
3505 SetLength(fColorTable, 0);
3509 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3510 //TglBitmap - Helper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3511 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3512 procedure glBitmapConvertCopyFunc(var aFuncRec: TglBitmapFunctionRec);
3514 with aFuncRec do begin
3515 if (Source.Range.r > 0) then
3516 Dest.Data.r := Source.Data.r;
3517 if (Source.Range.g > 0) then
3518 Dest.Data.g := Source.Data.g;
3519 if (Source.Range.b > 0) then
3520 Dest.Data.b := Source.Data.b;
3521 if (Source.Range.a > 0) then
3522 Dest.Data.a := Source.Data.a;
3526 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3527 procedure glBitmapConvertCalculateRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
3531 with aFuncRec do begin
3533 if (Source.Range.arr[i] > 0) then
3534 Dest.Data.arr[i] := Round(Dest.Range.arr[i] * Source.Data.arr[i] / Source.Range.arr[i]);
3539 TShiftData = packed record
3541 0: (r, g, b, a: SmallInt);
3542 1: (arr: array[0..3] of SmallInt);
3544 PShiftData = ^TShiftData;
3546 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3547 procedure glBitmapConvertShiftRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
3553 if (Source.Range.arr[i] > 0) then
3554 Dest.Data.arr[i] := Source.Data.arr[i] shr PShiftData(Args)^.arr[i];
3557 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3558 procedure glBitmapInvertFunc(var aFuncRec: TglBitmapFunctionRec);
3560 with aFuncRec do begin
3561 Dest.Data.r := Source.Data.r;
3562 Dest.Data.g := Source.Data.g;
3563 Dest.Data.b := Source.Data.b;
3564 Dest.Data.a := Source.Data.a;
3565 if (Args and $1 > 0) then begin
3566 Dest.Data.r := Dest.Data.r xor Dest.Range.r;
3567 Dest.Data.g := Dest.Data.g xor Dest.Range.g;
3568 Dest.Data.b := Dest.Data.b xor Dest.Range.b;
3570 if (Args and $2 > 0) then begin
3571 Dest.Data.a := Dest.Data.a xor Dest.Range.a;
3576 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3577 procedure glBitmapFillWithColorFunc(var aFuncRec: TglBitmapFunctionRec);
3581 with aFuncRec do begin
3583 Dest.Data.arr[i] := PglBitmapPixelData(Args)^.Data.arr[i];
3587 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3588 procedure glBitmapAlphaFunc(var FuncRec: TglBitmapFunctionRec);
3592 with FuncRec do begin
3593 if (FuncRec.Args = 0) then begin //source has no alpha
3595 Source.Data.r / Source.Range.r * ALPHA_WEIGHT_R +
3596 Source.Data.g / Source.Range.g * ALPHA_WEIGHT_G +
3597 Source.Data.b / Source.Range.b * ALPHA_WEIGHT_B;
3598 Dest.Data.a := Round(Dest.Range.a * Temp);
3600 Dest.Data.a := Round(Source.Data.a / Source.Range.a * Dest.Range.a);
3604 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3605 procedure glBitmapColorKeyAlphaFunc(var FuncRec: TglBitmapFunctionRec);
3607 PglBitmapPixelData = ^TglBitmapPixelData;
3609 with FuncRec do begin
3610 Dest.Data.r := Source.Data.r;
3611 Dest.Data.g := Source.Data.g;
3612 Dest.Data.b := Source.Data.b;
3614 with PglBitmapPixelData(Args)^ do
3615 if ((Dest.Data.r <= Data.r) and (Dest.Data.r >= Range.r) and
3616 (Dest.Data.g <= Data.g) and (Dest.Data.g >= Range.g) and
3617 (Dest.Data.b <= Data.b) and (Dest.Data.b >= Range.b)) then
3620 Dest.Data.a := Dest.Range.a;
3624 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3625 procedure glBitmapValueAlphaFunc(var FuncRec: TglBitmapFunctionRec);
3627 PglBitmapPixelData = ^TglBitmapPixelData;
3629 with FuncRec do begin
3630 Dest.Data.r := Source.Data.r;
3631 Dest.Data.g := Source.Data.g;
3632 Dest.Data.b := Source.Data.b;
3633 Dest.Data.a := PCardinal(Args)^;
3637 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3638 procedure SwapRGB(aData: PByte; aWidth: Integer; const aHasAlpha: Boolean);
3641 TRGBPix = array [0..2] of byte;
3645 while aWidth > 0 do begin
3646 Temp := PRGBPix(aData)^[0];
3647 PRGBPix(aData)^[0] := PRGBPix(aData)^[2];
3648 PRGBPix(aData)^[2] := Temp;
3658 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3659 //TglBitmap - PROTECTED///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3660 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3661 function TglBitmap.GetWidth: Integer;
3663 if (ffX in fDimension.Fields) then
3664 result := fDimension.X
3669 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3670 function TglBitmap.GetHeight: Integer;
3672 if (ffY in fDimension.Fields) then
3673 result := fDimension.Y
3678 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3679 function TglBitmap.GetFileWidth: Integer;
3681 result := Max(1, Width);
3684 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3685 function TglBitmap.GetFileHeight: Integer;
3687 result := Max(1, Height);
3690 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3691 procedure TglBitmap.SetCustomData(const aValue: Pointer);
3693 if fCustomData = aValue then
3695 fCustomData := aValue;
3698 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3699 procedure TglBitmap.SetCustomName(const aValue: String);
3701 if fCustomName = aValue then
3703 fCustomName := aValue;
3706 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3707 procedure TglBitmap.SetCustomNameW(const aValue: WideString);
3709 if fCustomNameW = aValue then
3711 fCustomNameW := aValue;
3714 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3715 procedure TglBitmap.SetDeleteTextureOnFree(const aValue: Boolean);
3717 if fDeleteTextureOnFree = aValue then
3719 fDeleteTextureOnFree := aValue;
3722 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3723 procedure TglBitmap.SetFormat(const aValue: TglBitmapFormat);
3725 if fFormat = aValue then
3727 if TFormatDescriptor.Get(Format).PixelSize <> TFormatDescriptor.Get(aValue).PixelSize then
3728 raise EglBitmapUnsupportedFormatFormat.Create('SetInternalFormat - ' + UNSUPPORTED_FORMAT);
3729 SetDataPointer(Data, aValue, Width, Height);
3732 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3733 procedure TglBitmap.SetFreeDataAfterGenTexture(const aValue: Boolean);
3735 if fFreeDataAfterGenTexture = aValue then
3737 fFreeDataAfterGenTexture := aValue;
3740 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3741 procedure TglBitmap.SetID(const aValue: Cardinal);
3743 if fID = aValue then
3748 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3749 procedure TglBitmap.SetMipMap(const aValue: TglBitmapMipMap);
3751 if fMipMap = aValue then
3756 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3757 procedure TglBitmap.SetTarget(const aValue: Cardinal);
3759 if fTarget = aValue then
3764 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3765 procedure TglBitmap.SetAnisotropic(const aValue: Integer);
3767 MaxAnisotropic: Integer;
3769 fAnisotropic := aValue;
3770 if (ID > 0) then begin
3771 if GL_EXT_texture_filter_anisotropic then begin
3772 if fAnisotropic > 0 then begin
3774 glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @MaxAnisotropic);
3775 if aValue > MaxAnisotropic then
3776 fAnisotropic := MaxAnisotropic;
3777 glTexParameteri(Target, GL_TEXTURE_MAX_ANISOTROPY_EXT, fAnisotropic);
3785 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3786 procedure TglBitmap.CreateID;
3789 glDeleteTextures(1, @fID);
3790 glGenTextures(1, @fID);
3794 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3795 procedure TglBitmap.SetupParameters(var aBuildWithGlu: Boolean);
3797 // Set Up Parameters
3798 SetWrap(fWrapS, fWrapT, fWrapR);
3799 SetFilter(fFilterMin, fFilterMag);
3800 SetAnisotropic(fAnisotropic);
3801 SetBorderColor(fBorderColor[0], fBorderColor[1], fBorderColor[2], fBorderColor[3]);
3803 // Mip Maps Generation Mode
3804 aBuildWithGlu := false;
3805 if (MipMap = mmMipmap) then begin
3806 if (GL_VERSION_1_4 or GL_SGIS_generate_mipmap) then
3807 glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE)
3809 aBuildWithGlu := true;
3810 end else if (MipMap = mmMipmapGlu) then
3811 aBuildWithGlu := true;
3814 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3815 procedure TglBitmap.SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
3816 const aWidth: Integer; const aHeight: Integer);
3820 if (Data <> aData) then begin
3821 if (Assigned(Data)) then
3826 FillChar(fDimension, SizeOf(fDimension), 0);
3827 if not Assigned(fData) then begin
3832 if aWidth <> -1 then begin
3833 fDimension.Fields := fDimension.Fields + [ffX];
3834 fDimension.X := aWidth;
3837 if aHeight <> -1 then begin
3838 fDimension.Fields := fDimension.Fields + [ffY];
3839 fDimension.Y := aHeight;
3842 s := TFormatDescriptor.Get(aFormat).PixelSize;
3844 fPixelSize := Ceil(s);
3845 fRowSize := Ceil(s * aWidth);
3849 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3850 function TglBitmap.FlipHorz: Boolean;
3855 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3856 function TglBitmap.FlipVert: Boolean;
3861 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3862 //TglBitmap - PUBLIC//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3863 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3864 procedure TglBitmap.AfterConstruction;
3866 inherited AfterConstruction;
3870 fIsResident := false;
3872 fFormat := glBitmapGetDefaultFormat;
3873 fMipMap := glBitmapDefaultMipmap;
3874 fFreeDataAfterGenTexture := glBitmapGetDefaultFreeDataAfterGenTexture;
3875 fDeleteTextureOnFree := glBitmapGetDefaultDeleteTextureOnFree;
3877 glBitmapGetDefaultFilter (fFilterMin, fFilterMag);
3878 glBitmapGetDefaultTextureWrap(fWrapS, fWrapT, fWrapR);
3881 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3882 procedure TglBitmap.BeforeDestruction;
3884 SetDataPointer(nil, tfEmpty);
3885 if (fID > 0) and fDeleteTextureOnFree then
3886 glDeleteTextures(1, @fID);
3887 inherited BeforeDestruction;
3890 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3891 procedure TglBitmap.LoadFromFile(const aFilename: String);
3895 fFilename := aFilename;
3896 fs := TFileStream.Create(fFilename, fmOpenRead);
3905 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3906 procedure TglBitmap.LoadFromStream(const aStream: TStream);
3908 {$IFDEF GLB_SUPPORT_PNG_READ}
3909 if not LoadPNG(aStream) then
3911 {$IFDEF GLB_SUPPORT_JPEG_READ}
3912 if not LoadJPEG(aStream) then
3914 if not LoadDDS(aStream) then
3915 if not LoadTGA(aStream) then
3916 if not LoadBMP(aStream) then
3917 raise EglBitmapException.Create('LoadFromStream - Couldn''t load Stream. It''s possible to be an unknow Streamtype.');
3920 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3921 procedure TglBitmap.LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
3922 const aFormat: TglBitmapFormat; const aArgs: PtrInt);
3927 size := TFormatDescriptor.Get(aFormat).GetSize(aSize);
3928 GetMem(tmpData, size);
3930 FillChar(tmpData^, size, #$FF);
3931 SetDataPointer(tmpData, aFormat, aSize.X, aSize.Y);
3936 AddFunc(Self, aFunc, false, Format, aArgs);
3940 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3941 procedure TglBitmap.LoadFromResource(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil);
3943 rs: TResourceStream;
3948 if not Assigned(ResType) then begin
3949 TempPos := Pos('.', Resource);
3950 ResTypeStr := UpperCase(Copy(Resource, TempPos + 1, Length(Resource) - TempPos));
3951 Resource := UpperCase(Copy(Resource, 0, TempPos -1));
3952 TempResType := PChar(ResTypeStr);
3954 TempResType := ResType
3956 rs := TResourceStream.Create(Instance, Resource, TempResType);
3964 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3965 procedure TglBitmap.LoadFromResourceID(const sInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
3967 rs: TResourceStream;
3969 rs := TResourceStream.CreateFromID(Instance, ResourceID, ResType);
3978 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3979 procedure TglBitmap.SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
3983 fs := TFileStream.Create(aFileName, fmCreate);
3986 SaveToStream(fs, aFileType);
3992 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3993 procedure TglBitmap.SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType);
3996 {$IFDEF GLB_SUPPORT_PNG_WRITE}
3997 ftPNG: SavePng(aStream);
3999 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
4000 ftJPEG: SaveJPEG(aStream);
4002 ftDDS: SaveDDS(aStream);
4003 ftTGA: SaveTGA(aStream);
4004 ftBMP: SaveBMP(aStream);
4008 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4009 function TglBitmap.AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: PtrInt): Boolean;
4011 result := AddFunc(Self, aFunc, aCreateTemp, Format, aArgs);
4014 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4015 function TglBitmap.AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
4016 const aFormat: TglBitmapFormat; const aArgs: PtrInt): Boolean;
4018 DestData, TmpData, SourceData: pByte;
4019 TempHeight, TempWidth: Integer;
4020 SourceFD, DestFD: TFormatDescriptor;
4021 SourceMD, DestMD: Pointer;
4023 FuncRec: TglBitmapFunctionRec;
4025 Assert(Assigned(Data));
4026 Assert(Assigned(aSource));
4027 Assert(Assigned(aSource.Data));
4030 if Assigned(aSource.Data) and ((aSource.Height > 0) or (aSource.Width > 0)) then begin
4031 SourceFD := TFormatDescriptor.Get(aSource.Format);
4032 DestFD := TFormatDescriptor.Get(aFormat);
4034 // inkompatible Formats so CreateTemp
4035 if (SourceFD.PixelSize <> DestFD.PixelSize) then
4036 aCreateTemp := true;
4039 TempHeight := Max(1, aSource.Height);
4040 TempWidth := Max(1, aSource.Width);
4042 FuncRec.Sender := Self;
4043 FuncRec.Args := aArgs;
4046 if aCreateTemp then begin
4047 GetMem(TmpData, TFormatDescriptor.Get(aFormat).GetSize(TempWidth, TempHeight));
4048 DestData := TmpData;
4053 SourceFD.PreparePixel(FuncRec.Source);
4054 DestFD.PreparePixel (FuncRec.Dest);
4056 SourceMD := SourceFD.CreateMappingData;
4057 DestMD := DestFD.CreateMappingData;
4059 FuncRec.Size := aSource.Dimension;
4060 FuncRec.Position.Fields := FuncRec.Size.Fields;
4063 SourceData := aSource.Data;
4064 FuncRec.Position.Y := 0;
4065 while FuncRec.Position.Y < TempHeight do begin
4066 FuncRec.Position.X := 0;
4067 while FuncRec.Position.X < TempWidth do begin
4068 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
4070 DestFD.Map(FuncRec.Dest, DestData, DestMD);
4071 inc(FuncRec.Position.X);
4073 inc(FuncRec.Position.Y);
4076 // Updating Image or InternalFormat
4078 SetDataPointer(TmpData, aFormat, aSource.Width, aSource.Height)
4079 else if (aFormat <> fFormat) then
4084 SourceFD.FreeMappingData(SourceMD);
4085 DestFD.FreeMappingData(DestMD);
4096 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4097 function TglBitmap.AssignToSurface(out aSurface: PSDL_Surface): Boolean;
4099 Row, RowSize: Integer;
4100 SourceData, TmpData: PByte;
4102 Pix: TglBitmapPixelData;
4103 FormatDesc: TglBitmapFormatDescriptor;
4105 function GetRowPointer(Row: Integer): pByte;
4107 result := Surface.pixels;
4108 Inc(result, Row * RowSize);
4115 if not FormatIsUncompressed(InternalFormat) then
4116 raise EglBitmapUnsupportedInternalFormat.Create('AssignToSurface - ' + UNSUPPORTED_INTERNAL_FORMAT);
4119 FormatDesc := FORMAT_DESCRIPTORS[Format];
4120 if Assigned(Data) then begin
4121 case Trunc(FormatDesc.GetSize) of
4127 raise EglBitmapException.Create('AssignToSurface - ' + UNSUPPORTED_INTERNAL_FORMAT);
4129 FormatDesc.PreparePixel(Pix);
4130 with Pix.PixelDesc do
4131 Surface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, TempDepth,
4132 RedRange shl RedShift, GreenRange shl GreenShift, BlueRange shl BlueShift, AlphaRange shl AlphaShift);
4135 RowSize := Ceil(FileWidth * FormatDesc.GetSize);
4137 for Row := 0 to FileHeight -1 do begin
4138 TmpData := GetRowPointer(Row);
4139 if Assigned(TmpData) then begin
4140 Move(SourceData^, TmpData^, RowSize);
4141 inc(SourceData, RowSize);
4148 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4149 function TglBitmap.AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
4151 pSource, pData, pTempData: PByte;
4152 Row, RowSize, TempWidth, TempHeight: Integer;
4153 IntFormat, f: TglBitmapInternalFormat;
4154 FormatDesc: TglBitmapFormatDescriptor;
4156 function GetRowPointer(Row: Integer): pByte;
4158 result := Surface^.pixels;
4159 Inc(result, Row * RowSize);
4164 if (Assigned(Surface)) then begin
4165 with Surface^.format^ do begin
4166 IntFormat := tfEmpty;
4167 for f := Low(f) to High(f) do begin
4168 if FORMAT_DESCRIPTORS[f].MaskMatch(RMask, GMask, BMask, AMask) then begin
4173 if (IntFormat = tfEmpty) then
4174 raise EglBitmapException.Create('AssignFromSurface - Invalid Pixelformat.');
4177 FormatDesc := FORMAT_DESCRIPTORS[IntFormat];
4178 TempWidth := Surface^.w;
4179 TempHeight := Surface^.h;
4180 RowSize := Trunc(TempWidth * FormatDesc.GetSize);
4181 GetMem(pData, TempHeight * RowSize);
4184 for Row := 0 to TempHeight -1 do begin
4185 pSource := GetRowPointer(Row);
4186 if (Assigned(pSource)) then begin
4187 Move(pSource^, pTempData^, RowSize);
4188 Inc(pTempData, RowSize);
4191 SetDataPointer(pData, IntFormat, TempWidth, TempHeight);
4200 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4201 function TglBitmap.AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
4203 Row, Col, AlphaInterleave: Integer;
4204 pSource, pDest: PByte;
4206 function GetRowPointer(Row: Integer): pByte;
4208 result := aSurface.pixels;
4209 Inc(result, Row * Width);
4214 if Assigned(Data) then begin
4215 if Format in [tfAlpha8, tfLuminance8Alpha8, tfBGRA8, tfRGBA8] then begin
4216 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, 8, $FF, $FF, $FF, 0);
4218 AlphaInterleave := 0;
4221 AlphaInterleave := 1;
4223 AlphaInterleave := 3;
4227 for Row := 0 to Height -1 do begin
4228 pDest := GetRowPointer(Row);
4229 if Assigned(pDest) then begin
4230 for Col := 0 to Width -1 do begin
4231 Inc(pSource, AlphaInterleave);
4243 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4244 function TglBitmap.AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
4248 bmp := TglBitmap2D.Create;
4250 bmp.AssignFromSurface(Surface);
4251 result := AddAlphaFromGlBitmap(bmp, Func, CustomData);
4259 //TODO rework & test
4260 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4261 function TglBitmap.AssignToBitmap(const aBitmap: TBitmap): Boolean;
4264 pSource, pData: PByte;
4267 if Assigned(Data) then begin
4268 if Assigned(aBitmap) then begin
4269 aBitmap.Width := Width;
4270 aBitmap.Height := Height;
4273 tfAlpha8, ifLuminance, ifDepth8:
4275 Bitmap.PixelFormat := pf8bit;
4276 Bitmap.Palette := CreateGrayPalette;
4279 Bitmap.PixelFormat := pf15bit;
4281 Bitmap.PixelFormat := pf16bit;
4283 Bitmap.PixelFormat := pf24bit;
4285 Bitmap.PixelFormat := pf32bit;
4287 raise EglBitmapException.Create('AssignToBitmap - Invalid Pixelformat.');
4291 for Row := 0 to FileHeight -1 do begin
4292 pData := Bitmap.Scanline[Row];
4294 Move(pSource^, pData^, fRowSize);
4295 Inc(pSource, fRowSize);
4297 // swap RGB(A) to BGR(A)
4298 if InternalFormat in [ifRGB8, ifRGBA8] then
4299 SwapRGB(pData, FileWidth, InternalFormat = ifRGBA8);
4307 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4308 function TglBitmap.AssignFromBitmap(const aBitmap: TBitmap): Boolean;
4310 pSource, pData, pTempData: PByte;
4311 Row, RowSize, TempWidth, TempHeight: Integer;
4312 IntFormat: TglBitmapInternalFormat;
4316 if (Assigned(Bitmap)) then begin
4317 case Bitmap.PixelFormat of
4319 IntFormat := ifLuminance;
4321 IntFormat := ifRGB5A1;
4323 IntFormat := ifR5G6B5;
4325 IntFormat := ifBGR8;
4327 IntFormat := ifBGRA8;
4329 raise EglBitmapException.Create('AssignFromBitmap - Invalid Pixelformat.');
4332 TempWidth := Bitmap.Width;
4333 TempHeight := Bitmap.Height;
4335 RowSize := Trunc(TempWidth * FormatGetSize(IntFormat));
4337 GetMem(pData, TempHeight * RowSize);
4341 for Row := 0 to TempHeight -1 do begin
4342 pSource := Bitmap.Scanline[Row];
4344 if (Assigned(pSource)) then begin
4345 Move(pSource^, pTempData^, RowSize);
4346 Inc(pTempData, RowSize);
4350 SetDataPointer(pData, IntFormat, TempWidth, TempHeight);
4360 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4361 function TglBitmap.AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
4363 Row, Col, AlphaInterleave: Integer;
4364 pSource, pDest: PByte;
4368 if Assigned(Data) then begin
4369 if InternalFormat in [ifAlpha, ifLuminanceAlpha, ifRGBA8, ifBGRA8] then begin
4370 if Assigned(Bitmap) then begin
4371 Bitmap.PixelFormat := pf8bit;
4372 Bitmap.Palette := CreateGrayPalette;
4373 Bitmap.Width := Width;
4374 Bitmap.Height := Height;
4376 case InternalFormat of
4378 AlphaInterleave := 1;
4380 AlphaInterleave := 3;
4382 AlphaInterleave := 0;
4388 for Row := 0 to Height -1 do begin
4389 pDest := Bitmap.Scanline[Row];
4391 if Assigned(pDest) then begin
4392 for Col := 0 to Width -1 do begin
4393 Inc(pSource, AlphaInterleave);
4407 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4408 function TglBitmap.AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
4412 tex := TglBitmap2D.Create;
4414 tex.AssignFromBitmap(Bitmap);
4415 result := AddAlphaFromglBitmap(tex, Func, CustomData);
4421 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4422 function TglBitmap.AddAlphaFromResource(const aInstance: Cardinal; const aResource: String; const aResType: PChar;
4423 const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
4425 RS: TResourceStream;
4430 if Assigned(ResType) then
4431 TempResType := ResType
4434 TempPos := Pos('.', Resource);
4435 ResTypeStr := UpperCase(Copy(Resource, TempPos + 1, Length(Resource) - TempPos));
4436 Resource := UpperCase(Copy(Resource, 0, TempPos -1));
4437 TempResType := PChar(ResTypeStr);
4440 RS := TResourceStream.Create(Instance, Resource, TempResType);
4442 result := AddAlphaFromStream(RS, Func, CustomData);
4448 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4449 function TglBitmap.AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
4450 const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
4452 RS: TResourceStream;
4454 RS := TResourceStream.CreateFromID(Instance, ResourceID, ResType);
4456 result := AddAlphaFromStream(RS, Func, CustomData);
4463 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4464 function TglBitmap.AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
4467 if not FormatIsUncompressed(InternalFormat) then
4468 raise EglBitmapUnsupportedFormatFormat.Create('AddAlphaFromFunc - ' + UNSUPPORTED_FORMAT);
4470 result := AddFunc(Self, aFunc, false, TFormatDescriptor.Get(Format).WithAlpha, aArgs);
4473 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4474 function TglBitmap.AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
4478 FS := TFileStream.Create(FileName, fmOpenRead);
4480 result := AddAlphaFromStream(FS, aFunc, aArgs);
4486 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4487 function TglBitmap.AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
4491 tex := TglBitmap2D.Create(aStream);
4493 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
4499 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4500 function TglBitmap.AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
4502 DestData, DestData2, SourceData: pByte;
4503 TempHeight, TempWidth: Integer;
4504 SourceFD, DestFD: TFormatDescriptor;
4505 SourceMD, DestMD, DestMD2: Pointer;
4507 FuncRec: TglBitmapFunctionRec;
4511 Assert(Assigned(Data));
4512 Assert(Assigned(aBitmap));
4513 Assert(Assigned(aBitmap.Data));
4515 if ((aBitmap.Width = Width) and (aBitmap.Height = Height)) then begin
4516 result := ConvertTo(TFormatDescriptor.Get(Format).WithAlpha);
4517 if not Assigned(aFunc) then
4518 aFunc := glBitmapAlphaFunc;
4520 SourceFD := TFormatDescriptor.Get(aBitmap.Format);
4521 DestFD := TFormatDescriptor.Get(Format);
4524 TempHeight := aBitmap.FileHeight;
4525 TempWidth := aBitmap.FileWidth;
4527 FuncRec.Sender := Self;
4528 FuncRec.Args := aArgs;
4529 FuncRec.Size := Dimension;
4530 FuncRec.Position.Fields := FuncRec.Size.Fields;
4531 FuncRec.Args := PtrInt(SourceFD.HasAlpha) and 1;
4535 SourceData := aBitmap.Data;
4538 SourceFD.PreparePixel(FuncRec.Source);
4539 DestFD.PreparePixel (FuncRec.Dest);
4541 SourceMD := SourceFD.CreateMappingData;
4542 DestMD := DestFD.CreateMappingData;
4543 DestMD2 := DestFD.CreateMappingData;
4545 FuncRec.Position.Y := 0;
4546 while FuncRec.Position.Y < TempHeight do begin
4547 FuncRec.Position.X := 0;
4548 while FuncRec.Position.X < TempWidth do begin
4549 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
4550 DestFD.Unmap (DestData, FuncRec.Dest, DestMD);
4552 DestFD.Map(FuncRec.Dest, DestData2, DestMD2);
4553 inc(FuncRec.Position.X);
4555 inc(FuncRec.Position.Y);
4558 SourceFD.FreeMappingData(SourceMD);
4559 DestFD.FreeMappingData(DestMD);
4560 DestFD.FreeMappingData(DestMD2);
4565 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4566 function TglBitmap.AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte): Boolean;
4568 result := AddAlphaFromColorKeyFloat(aRed / $FF, aGreen / $FF, aBlue / $FF, aDeviation / $FF);
4571 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4572 function TglBitmap.AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal): Boolean;
4574 PixelData: TglBitmapPixelData;
4576 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
4577 result := AddAlphaFromColorKeyFloat(
4578 aRed / PixelData.Range.r,
4579 aGreen / PixelData.Range.g,
4580 aBlue / PixelData.Range.b,
4581 aDeviation / Max(PixelData.Range.r, Max(PixelData.Range.g, PixelData.Range.b)));
4584 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4585 function TglBitmap.AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single): Boolean;
4587 values: array[0..2] of Single;
4590 PixelData: TglBitmapPixelData;
4592 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
4593 with PixelData do begin
4595 values[1] := aGreen;
4598 for i := 0 to 2 do begin
4599 tmp := Trunc(Range.arr[i] * aDeviation);
4600 Data.arr[i] := Min(Range.arr[i], Trunc(Range.arr[i] * values[i] + tmp));
4601 Range.arr[i] := Max(0, Trunc(Range.arr[i] * values[i] - tmp));
4606 result := AddAlphaFromFunc(glBitmapColorKeyAlphaFunc, PtrInt(@PixelData));
4609 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4610 function TglBitmap.AddAlphaFromValue(const aAlpha: Byte): Boolean;
4612 result := AddAlphaFromValueFloat(aAlpha / $FF);
4615 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4616 function TglBitmap.AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
4618 PixelData: TglBitmapPixelData;
4620 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
4621 result := AddAlphaFromValueFloat(aAlpha / PixelData.Range.a);
4624 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4625 function TglBitmap.AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
4627 PixelData: TglBitmapPixelData;
4629 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
4631 Data.a := Min(Range.a, Max(0, Round(Range.a * aAlpha)));
4632 result := AddAlphaFromFunc(glBitmapValueAlphaFunc, PtrInt(@PixelData.Data.a));
4635 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4636 function TglBitmap.RemoveAlpha: Boolean;
4638 FormatDesc: TFormatDescriptor;
4641 FormatDesc := TFormatDescriptor.Get(Format);
4642 if Assigned(Data) then begin
4643 if not ({FormatDesc.IsUncompressed or }FormatDesc.HasAlpha) then
4644 raise EglBitmapUnsupportedFormatFormat.Create('RemoveAlpha - ' + UNSUPPORTED_FORMAT);
4645 result := ConvertTo(FormatDesc.WithoutAlpha);
4649 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4650 function TglBitmap.Clone: TglBitmap;
4657 Temp := (ClassType.Create as TglBitmap);
4659 // copy texture data if assigned
4660 if Assigned(Data) then begin
4661 Size := TFormatDescriptor.Get(Format).GetSize(fDimension);
4662 GetMem(TempPtr, Size);
4664 Move(Data^, TempPtr^, Size);
4665 Temp.SetDataPointer(TempPtr, Format, Width, Height);
4671 Temp.SetDataPointer(nil, Format, Width, Height);
4675 Temp.fTarget := Target;
4676 Temp.fFormat := Format;
4677 Temp.fMipMap := MipMap;
4678 Temp.fAnisotropic := Anisotropic;
4679 Temp.fBorderColor := fBorderColor;
4680 Temp.fDeleteTextureOnFree := DeleteTextureOnFree;
4681 Temp.fFreeDataAfterGenTexture := FreeDataAfterGenTexture;
4682 Temp.fFilterMin := fFilterMin;
4683 Temp.fFilterMag := fFilterMag;
4684 Temp.fWrapS := fWrapS;
4685 Temp.fWrapT := fWrapT;
4686 Temp.fWrapR := fWrapR;
4687 Temp.fFilename := fFilename;
4688 Temp.fCustomName := fCustomName;
4689 Temp.fCustomNameW := fCustomNameW;
4690 Temp.fCustomData := fCustomData;
4699 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4700 function TglBitmap.ConvertTo(const aFormat: TglBitmapFormat): Boolean;
4702 SourceFD, DestFD: TFormatDescriptor;
4703 SourcePD, DestPD: TglBitmapPixelData;
4704 ShiftData: TShiftData;
4706 function CanCopyDirect: Boolean;
4709 ((SourcePD.Range.r = DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
4710 ((SourcePD.Range.g = DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
4711 ((SourcePD.Range.b = DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
4712 ((SourcePD.Range.a = DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
4715 function CanShift: Boolean;
4718 ((SourcePD.Range.r >= DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
4719 ((SourcePD.Range.g >= DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
4720 ((SourcePD.Range.b >= DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
4721 ((SourcePD.Range.a >= DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
4724 function GetShift(aSource, aDest: Cardinal) : ShortInt;
4727 while (aSource > aDest) and (aSource > 0) do begin
4729 aSource := aSource shr 1;
4734 if (aFormat <> fFormat) and (aFormat <> tfEmpty) then begin
4735 SourceFD := TFormatDescriptor.Get(Format);
4736 DestFD := TFormatDescriptor.Get(aFormat);
4738 SourceFD.PreparePixel(SourcePD);
4739 DestFD.PreparePixel (DestPD);
4741 if CanCopyDirect then
4742 result := AddFunc(Self, glBitmapConvertCopyFunc, false, aFormat)
4743 else if CanShift then begin
4744 ShiftData.r := GetShift(SourcePD.Range.r, DestPD.Range.r);
4745 ShiftData.g := GetShift(SourcePD.Range.g, DestPD.Range.g);
4746 ShiftData.b := GetShift(SourcePD.Range.b, DestPD.Range.b);
4747 ShiftData.a := GetShift(SourcePD.Range.a, DestPD.Range.a);
4748 result := AddFunc(Self, glBitmapConvertShiftRGBAFunc, false, aFormat, PtrInt(@ShiftData));
4750 result := AddFunc(Self, glBitmapConvertCalculateRGBAFunc, false, aFormat);
4755 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4756 procedure TglBitmap.Invert(const aUseRGB: Boolean; const aUseAlpha: Boolean);
4758 if aUseRGB or aUseAlpha then
4759 AddFunc(glBitmapInvertFunc, false, ((PtrInt(aUseAlpha) and 1) shl 1) or (PtrInt(aUseRGB) and 1));
4762 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4763 procedure TglBitmap.SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
4765 fBorderColor[0] := aRed;
4766 fBorderColor[1] := aGreen;
4767 fBorderColor[2] := aBlue;
4768 fBorderColor[3] := aAlpha;
4769 if (ID > 0) then begin
4771 glTexParameterfv(Target, GL_TEXTURE_BORDER_COLOR, @fBorderColor[0]);
4775 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4776 procedure TglBitmap.FreeData;
4778 SetDataPointer(nil, tfEmpty);
4781 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4782 procedure TglBitmap.FillWithColor(const aRed, aGreen, aBlue: Byte;
4783 const aAlpha: Byte);
4785 FillWithColorFloat(aRed/$FF, aGreen/$FF, aBlue/$FF, aAlpha/$FF);
4788 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4789 procedure TglBitmap.FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal);
4791 PixelData: TglBitmapPixelData;
4793 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
4795 aRed / PixelData.Range.r,
4796 aGreen / PixelData.Range.g,
4797 aBlue / PixelData.Range.b,
4798 aAlpha / PixelData.Range.a);
4801 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4802 procedure TglBitmap.FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single);
4804 PixelData: TglBitmapPixelData;
4806 TFormatDescriptor.Get(Format).PreparePixel(PixelData);
4807 with PixelData do begin
4808 Data.r := Max(0, Min(Range.r, Trunc(Range.r * aRed)));
4809 Data.g := Max(0, Min(Range.g, Trunc(Range.g * aGreen)));
4810 Data.b := Max(0, Min(Range.b, Trunc(Range.b * aBlue)));
4811 Data.a := Max(0, Min(Range.a, Trunc(Range.a * aAlpha)));
4813 AddFunc(glBitmapFillWithColorFunc, false, PtrInt(@PixelData));
4816 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4817 procedure TglBitmap.SetFilter(const aMin, aMag: Cardinal);
4822 fFilterMin := GL_NEAREST;
4824 fFilterMin := GL_LINEAR;
4825 GL_NEAREST_MIPMAP_NEAREST:
4826 fFilterMin := GL_NEAREST_MIPMAP_NEAREST;
4827 GL_LINEAR_MIPMAP_NEAREST:
4828 fFilterMin := GL_LINEAR_MIPMAP_NEAREST;
4829 GL_NEAREST_MIPMAP_LINEAR:
4830 fFilterMin := GL_NEAREST_MIPMAP_LINEAR;
4831 GL_LINEAR_MIPMAP_LINEAR:
4832 fFilterMin := GL_LINEAR_MIPMAP_LINEAR;
4834 raise EglBitmapException.Create('SetFilter - Unknow MIN filter.');
4840 fFilterMag := GL_NEAREST;
4842 fFilterMag := GL_LINEAR;
4844 raise EglBitmapException.Create('SetFilter - Unknow MAG filter.');
4848 if (ID > 0) then begin
4850 glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, fFilterMag);
4852 if (MipMap = mmNone) or (Target = GL_TEXTURE_RECTANGLE) then begin
4854 GL_NEAREST, GL_LINEAR:
4855 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
4856 GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR:
4857 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4858 GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR:
4859 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4862 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
4866 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4867 procedure TglBitmap.SetWrap(const S: Cardinal; const T: Cardinal; const R: Cardinal);
4869 procedure CheckAndSetWrap(const aValue: Cardinal; var aTarget: Cardinal);
4873 aTarget := GL_CLAMP;
4876 aTarget := GL_REPEAT;
4878 GL_CLAMP_TO_EDGE: begin
4879 if GL_VERSION_1_2 or GL_EXT_texture_edge_clamp then
4880 aTarget := GL_CLAMP_TO_EDGE
4882 aTarget := GL_CLAMP;
4885 GL_CLAMP_TO_BORDER: begin
4886 if GL_VERSION_1_3 or GL_ARB_texture_border_clamp then
4887 aTarget := GL_CLAMP_TO_BORDER
4889 aTarget := GL_CLAMP;
4892 GL_MIRRORED_REPEAT: begin
4893 if GL_VERSION_1_4 or GL_ARB_texture_mirrored_repeat or GL_IBM_texture_mirrored_repeat then
4894 aTarget := GL_MIRRORED_REPEAT
4896 raise EglBitmapException.Create('SetWrap - Unsupported Texturewrap GL_MIRRORED_REPEAT (S).');
4899 raise EglBitmapException.Create('SetWrap - Unknow Texturewrap (S).');
4904 CheckAndSetWrap(S, fWrapS);
4905 CheckAndSetWrap(T, fWrapT);
4906 CheckAndSetWrap(R, fWrapR);
4908 if (ID > 0) then begin
4910 glTexParameteri(Target, GL_TEXTURE_WRAP_S, fWrapS);
4911 glTexParameteri(Target, GL_TEXTURE_WRAP_T, fWrapT);
4912 glTexParameteri(Target, GL_TEXTURE_WRAP_R, fWrapR);
4916 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4917 procedure TglBitmap.GetPixel(const aPos: TglBitmapPixelPosition; var aPixel: TglBitmapPixelData);
4920 if Assigned (fGetPixelFunc) then
4921 fGetPixelFunc(aPos, aPixel);
4925 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4926 procedure TglBitmap.SetPixel(const aPos: TglBitmapPixelPosition; const aPixel: TglBitmapPixelData);
4929 if Assigned (fSetPixelFunc) then
4930 fSetPixelFuc(aPos, aPixel);
4934 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4935 procedure TglBitmap.Bind(const aEnableTextureUnit: Boolean);
4937 if aEnableTextureUnit then
4940 glBindTexture(Target, ID);
4943 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4944 procedure TglBitmap.Unbind(const aDisableTextureUnit: Boolean);
4946 if aDisableTextureUnit then
4948 glBindTexture(Target, 0);
4951 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4952 constructor TglBitmap.Create;
4954 {$IFNDEF GLB_NO_NATIVE_GL}
4955 ReadOpenGLExtensions;
4957 if (ClassType = TglBitmap) then
4958 raise EglBitmapException.Create('Don''t create TglBitmap directly. Use one of the deviated classes (TglBitmap2D) instead.');
4962 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4963 constructor TglBitmap.Create(const aFileName: String);
4966 LoadFromFile(FileName);
4969 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4970 constructor TglBitmap.Create(const aStream: TStream);
4973 LoadFromStream(aStream);
4976 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4977 constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat);
4983 TFormatDescriptor.Get(aFormat).GetSize(aSize);
4984 GetMem(Image, ImageSize);
4986 FillChar(Image^, ImageSize, #$FF);
4987 SetDataPointer(Image, aFormat, aSize.X, aSize.Y);
4994 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4995 constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat;
4996 const aFunc: TglBitmapFunction; const aArgs: PtrInt);
4999 LoadFromFunc(aSize, aFunc, aFormat, aArgs);
5003 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5004 constructor TglBitmap.Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar);
5007 LoadFromResource(aInstance, aResource, aResType);
5010 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5011 constructor TglBitmap.Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
5014 LoadFromResourceID(aInstance, aResourceID, aResType);
5018 {$IFDEF GLB_SUPPORT_PNG_READ}
5019 {$IF DEFINED(GLB_SDL_IMAGE)}
5020 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5021 //PNG/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5022 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5023 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
5025 Surface: PSDL_Surface;
5029 RWops := glBitmapCreateRWops(aStream);
5031 if IMG_isPNG(RWops) > 0 then begin
5032 Surface := IMG_LoadPNG_RW(RWops);
5034 AssignFromSurface(Surface);
5037 SDL_FreeSurface(Surface);
5045 {$ELSEIF DEFINED(GLB_LIB_PNG)}
5046 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5047 procedure glBitmap_libPNG_read_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
5049 TStream(png_get_io_ptr(png)).Read(buffer^, size);
5052 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5053 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
5056 signature: array [0..7] of byte;
5058 png_info: png_infop;
5060 TempHeight, TempWidth: Integer;
5061 Format: TglBitmapInternalFormat;
5064 png_rows: array of pByte;
5065 Row, LineSize: Integer;
5069 if not init_libPNG then
5070 raise Exception.Create('LoadPNG - unable to initialize libPNG.');
5074 StreamPos := Stream.Position;
5075 Stream.Read(signature, 8);
5076 Stream.Position := StreamPos;
5078 if png_check_sig(@signature, 8) <> 0 then begin
5080 png := png_create_read_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
5082 raise EglBitmapException.Create('LoadPng - couldn''t create read struct.');
5085 png_info := png_create_info_struct(png);
5086 if png_info = nil then begin
5087 png_destroy_read_struct(@png, nil, nil);
5088 raise EglBitmapException.Create('LoadPng - couldn''t create info struct.');
5091 // set read callback
5092 png_set_read_fn(png, stream, glBitmap_libPNG_read_func);
5094 // read informations
5095 png_read_info(png, png_info);
5098 TempHeight := png_get_image_height(png, png_info);
5099 TempWidth := png_get_image_width(png, png_info);
5102 case png_get_color_type(png, png_info) of
5103 PNG_COLOR_TYPE_GRAY:
5104 Format := tfLuminance8;
5105 PNG_COLOR_TYPE_GRAY_ALPHA:
5106 Format := tfLuminance8Alpha8;
5109 PNG_COLOR_TYPE_RGB_ALPHA:
5112 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
5115 // cut upper 8 bit from 16 bit formats
5116 if png_get_bit_depth(png, png_info) > 8 then
5117 png_set_strip_16(png);
5119 // expand bitdepth smaller than 8
5120 if png_get_bit_depth(png, png_info) < 8 then
5121 png_set_expand(png);
5123 // allocating mem for scanlines
5124 LineSize := png_get_rowbytes(png, png_info);
5125 GetMem(png_data, TempHeight * LineSize);
5127 SetLength(png_rows, TempHeight);
5128 for Row := Low(png_rows) to High(png_rows) do begin
5129 png_rows[Row] := png_data;
5130 Inc(png_rows[Row], Row * LineSize);
5133 // read complete image into scanlines
5134 png_read_image(png, @png_rows[0]);
5137 png_read_end(png, png_info);
5139 // destroy read struct
5140 png_destroy_read_struct(@png, @png_info, nil);
5142 SetLength(png_rows, 0);
5145 SetDataPointer(png_data, Format, TempWidth, TempHeight);
5158 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
5159 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5160 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
5164 Header: Array[0..7] of Byte;
5165 Row, Col, PixSize, LineSize: Integer;
5166 NewImage, pSource, pDest, pAlpha: pByte;
5167 Format: TglBitmapInternalFormat;
5170 PngHeader: Array[0..7] of Byte = (#137, #80, #78, #71, #13, #10, #26, #10);
5175 StreamPos := Stream.Position;
5176 Stream.Read(Header[0], SizeOf(Header));
5177 Stream.Position := StreamPos;
5179 {Test if the header matches}
5180 if Header = PngHeader then begin
5181 Png := TPNGObject.Create;
5183 Png.LoadFromStream(Stream);
5185 case Png.Header.ColorType of
5187 Format := ifLuminance;
5188 COLOR_GRAYSCALEALPHA:
5189 Format := ifLuminanceAlpha;
5195 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
5198 PixSize := Trunc(FormatGetSize(Format));
5199 LineSize := Integer(Png.Header.Width) * PixSize;
5201 GetMem(NewImage, LineSize * Integer(Png.Header.Height));
5205 case Png.Header.ColorType of
5206 COLOR_RGB, COLOR_GRAYSCALE:
5208 for Row := 0 to Png.Height -1 do begin
5209 Move (Png.Scanline[Row]^, pDest^, LineSize);
5210 Inc(pDest, LineSize);
5213 COLOR_RGBALPHA, COLOR_GRAYSCALEALPHA:
5215 PixSize := PixSize -1;
5217 for Row := 0 to Png.Height -1 do begin
5218 pSource := Png.Scanline[Row];
5219 pAlpha := pByte(Png.AlphaScanline[Row]);
5221 for Col := 0 to Png.Width -1 do begin
5222 Move (pSource^, pDest^, PixSize);
5223 Inc(pSource, PixSize);
5224 Inc(pDest, PixSize);
5233 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
5236 SetDataPointer(NewImage, Format, Png.Header.Width, Png.Header.Height);
5251 {$IFDEF GLB_SUPPORT_PNG_WRITE}
5252 {$IFDEF GLB_LIB_PNG}
5253 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5254 procedure glBitmap_libPNG_write_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
5256 TStream(png_get_io_ptr(png)).Write(buffer^, size);
5260 {$IF DEFINED(GLB_LIB_PNG)}
5261 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5262 procedure TglBitmap.SavePNG(const aStream: TStream);
5265 png_info: png_infop;
5266 png_rows: array of pByte;
5271 if not (ftPNG in FormatGetSupportedFiles (InternalFormat)) then
5272 raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
5274 if not init_libPNG then
5275 raise Exception.Create('SavePNG - unable to initialize libPNG.');
5278 case FInternalFormat of
5279 ifAlpha, ifLuminance, ifDepth8:
5280 ColorType := PNG_COLOR_TYPE_GRAY;
5282 ColorType := PNG_COLOR_TYPE_GRAY_ALPHA;
5284 ColorType := PNG_COLOR_TYPE_RGB;
5286 ColorType := PNG_COLOR_TYPE_RGBA;
5288 raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
5290 LineSize := Trunc(FormatGetSize(FInternalFormat) * Width);
5292 // creating array for scanline
5293 SetLength(png_rows, Height);
5295 for Row := 0 to Height - 1 do begin
5296 png_rows[Row] := Data;
5297 Inc(png_rows[Row], Row * LineSize)
5301 png := png_create_write_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
5303 raise EglBitmapException.Create('SavePng - couldn''t create write struct.');
5306 png_info := png_create_info_struct(png);
5307 if png_info = nil then begin
5308 png_destroy_write_struct(@png, nil);
5309 raise EglBitmapException.Create('SavePng - couldn''t create info struct.');
5312 // set read callback
5313 png_set_write_fn(png, stream, glBitmap_libPNG_write_func, nil);
5316 png_set_compression_level(png, 6);
5318 if InternalFormat in [ifBGR8, ifBGRA8] then
5321 png_set_IHDR(png, png_info, Width, Height, 8, ColorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
5322 png_write_info(png, png_info);
5323 png_write_image(png, @png_rows[0]);
5324 png_write_end(png, png_info);
5325 png_destroy_write_struct(@png, @png_info);
5327 SetLength(png_rows, 0);
5334 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
5335 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5336 procedure TglBitmap.SavePNG(const aStream: TStream);
5340 pSource, pDest: pByte;
5341 X, Y, PixSize: Integer;
5342 ColorType: Cardinal;
5348 if not (ftPNG in FormatGetSupportedFiles (InternalFormat)) then
5349 raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
5351 case FInternalFormat of
5352 ifAlpha, ifLuminance, ifDepth8: begin
5353 ColorType := COLOR_GRAYSCALE;
5357 ifLuminanceAlpha: begin
5358 ColorType := COLOR_GRAYSCALEALPHA;
5362 ifBGR8, ifRGB8: begin
5363 ColorType := COLOR_RGB;
5367 ifBGRA8, ifRGBA8: begin
5368 ColorType := COLOR_RGBALPHA;
5373 raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
5376 Png := TPNGObject.CreateBlank(ColorType, 8, Width, Height);
5380 for Y := 0 to Height -1 do begin
5381 pDest := png.ScanLine[Y];
5382 for X := 0 to Width -1 do begin
5383 Move(pSource^, pDest^, PixSize);
5384 Inc(pDest, PixSize);
5385 Inc(pSource, PixSize);
5387 png.AlphaScanline[Y]^[X] := pSource^;
5392 // convert RGB line to BGR
5393 if InternalFormat in [ifRGB8, ifRGBA8] then begin
5394 pTemp := png.ScanLine[Y];
5395 for X := 0 to Width -1 do begin
5396 Temp := pByteArray(pTemp)^[0];
5397 pByteArray(pTemp)^[0] := pByteArray(pTemp)^[2];
5398 pByteArray(pTemp)^[2] := Temp;
5405 Png.CompressionLevel := 6;
5406 Png.SaveToStream(Stream);
5414 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5415 //JPEG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5416 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5417 {$IFDEF GLB_LIB_JPEG}
5419 glBitmap_libJPEG_source_mgr_ptr = ^glBitmap_libJPEG_source_mgr;
5420 glBitmap_libJPEG_source_mgr = record
5421 pub: jpeg_source_mgr;
5424 SrcBuffer: array [1..4096] of byte;
5427 glBitmap_libJPEG_dest_mgr_ptr = ^glBitmap_libJPEG_dest_mgr;
5428 glBitmap_libJPEG_dest_mgr = record
5429 pub: jpeg_destination_mgr;
5431 DestStream: TStream;
5432 DestBuffer: array [1..4096] of byte;
5435 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5437 procedure glBitmap_libJPEG_error_exit(cinfo: j_common_ptr); cdecl;
5441 SetLength(Msg, 256);
5442 cinfo^.err^.format_message(cinfo, pChar(Msg));
5443 Writeln('ERROR [' + IntToStr(cinfo^.err^.msg_code) + '] ' + Msg);
5444 cinfo^.global_state := 0;
5449 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5451 procedure glBitmap_libJPEG_output_message(cinfo: j_common_ptr); cdecl;
5455 SetLength(Msg, 256);
5456 cinfo^.err^.format_message(cinfo, pChar(Msg));
5457 Writeln('OUTPUT [' + IntToStr(cinfo^.err^.msg_code) + '] ' + Msg);
5458 cinfo^.global_state := 0;
5462 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5464 procedure glBitmap_libJPEG_init_source(cinfo: j_decompress_ptr); cdecl;
5469 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5470 function glBitmap_libJPEG_fill_input_buffer(cinfo: j_decompress_ptr): boolean; cdecl;
5472 src: glBitmap_libJPEG_source_mgr_ptr;
5475 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
5477 bytes := src^.SrcStream.Read(src^.SrcBuffer[1], 4096);
5478 if (bytes <= 0) then begin
5479 src^.SrcBuffer[1] := $FF;
5480 src^.SrcBuffer[2] := JPEG_EOI;
5484 src^.pub.next_input_byte := @(src^.SrcBuffer[1]);
5485 src^.pub.bytes_in_buffer := bytes;
5490 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5491 procedure glBitmap_libJPEG_skip_input_data(cinfo: j_decompress_ptr; num_bytes: Longint); cdecl;
5493 src: glBitmap_libJPEG_source_mgr_ptr;
5495 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
5497 if num_bytes > 0 then begin
5498 // wanted byte isn't in buffer so set stream position and read buffer
5499 if num_bytes > src^.pub.bytes_in_buffer then begin
5500 src^.SrcStream.Position := src^.SrcStream.Position + num_bytes - src^.pub.bytes_in_buffer;
5501 src^.pub.fill_input_buffer(cinfo);
5503 // wanted byte is in buffer so only skip
5504 inc(src^.pub.next_input_byte, num_bytes);
5505 dec(src^.pub.bytes_in_buffer, num_bytes);
5510 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5512 procedure glBitmap_libJPEG_term_source(cinfo: j_decompress_ptr); cdecl;
5517 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5519 procedure glBitmap_libJPEG_init_destination(cinfo: j_compress_ptr); cdecl;
5524 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5525 function glBitmap_libJPEG_empty_output_buffer(cinfo: j_compress_ptr): boolean; cdecl;
5527 dest: glBitmap_libJPEG_dest_mgr_ptr;
5529 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
5531 if dest^.pub.free_in_buffer < Cardinal(Length(dest^.DestBuffer)) then begin
5532 // write complete buffer
5533 dest^.DestStream.Write(dest^.DestBuffer[1], SizeOf(dest^.DestBuffer));
5536 dest^.pub.next_output_byte := @dest^.DestBuffer[1];
5537 dest^.pub.free_in_buffer := Length(dest^.DestBuffer);
5543 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5544 procedure glBitmap_libJPEG_term_destination(cinfo: j_compress_ptr); cdecl;
5547 dest: glBitmap_libJPEG_dest_mgr_ptr;
5549 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
5551 for Idx := Low(dest^.DestBuffer) to High(dest^.DestBuffer) do begin
5552 // check for endblock
5553 if (Idx < High(dest^.DestBuffer)) and (dest^.DestBuffer[Idx] = $FF) and (dest^.DestBuffer[Idx +1] = JPEG_EOI) then begin
5555 dest^.DestStream.Write(dest^.DestBuffer[Idx], 2);
5560 dest^.DestStream.Write(dest^.DestBuffer[Idx], 1);
5565 {$IFDEF GLB_SUPPORT_JPEG_READ}
5566 {$IF DEFINED(GLB_SDL_IMAGE)}
5567 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5568 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
5570 Surface: PSDL_Surface;
5575 RWops := glBitmapCreateRWops(Stream);
5577 if IMG_isJPG(RWops) > 0 then begin
5578 Surface := IMG_LoadJPG_RW(RWops);
5580 AssignFromSurface(Surface);
5583 SDL_FreeSurface(Surface);
5591 {$ELSEIF DEFINED(GLB_LIB_JPEG)}
5592 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5593 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
5596 Temp: array[0..1]of Byte;
5598 jpeg: jpeg_decompress_struct;
5599 jpeg_err: jpeg_error_mgr;
5601 IntFormat: TglBitmapInternalFormat;
5603 TempHeight, TempWidth: Integer;
5610 if not init_libJPEG then
5611 raise Exception.Create('LoadJPG - unable to initialize libJPEG.');
5614 // reading first two bytes to test file and set cursor back to begin
5615 StreamPos := Stream.Position;
5616 Stream.Read(Temp[0], 2);
5617 Stream.Position := StreamPos;
5619 // if Bitmap then read file.
5620 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
5621 FillChar(jpeg, SizeOf(jpeg_decompress_struct), $00);
5622 FillChar(jpeg_err, SizeOf(jpeg_error_mgr), $00);
5625 jpeg.err := jpeg_std_error(@jpeg_err);
5626 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
5627 jpeg_err.output_message := glBitmap_libJPEG_output_message;
5629 // decompression struct
5630 jpeg_create_decompress(@jpeg);
5632 // allocation space for streaming methods
5633 jpeg.src := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_source_mgr));
5635 // seeting up custom functions
5636 with glBitmap_libJPEG_source_mgr_ptr(jpeg.src)^ do begin
5637 pub.init_source := glBitmap_libJPEG_init_source;
5638 pub.fill_input_buffer := glBitmap_libJPEG_fill_input_buffer;
5639 pub.skip_input_data := glBitmap_libJPEG_skip_input_data;
5640 pub.resync_to_restart := jpeg_resync_to_restart; // use default method
5641 pub.term_source := glBitmap_libJPEG_term_source;
5643 pub.bytes_in_buffer := 0; // forces fill_input_buffer on first read
5644 pub.next_input_byte := nil; // until buffer loaded
5646 SrcStream := Stream;
5649 // set global decoding state
5650 jpeg.global_state := DSTATE_START;
5652 // read header of jpeg
5653 jpeg_read_header(@jpeg, false);
5655 // setting output parameter
5656 case jpeg.jpeg_color_space of
5659 jpeg.out_color_space := JCS_GRAYSCALE;
5660 IntFormat := ifLuminance;
5663 jpeg.out_color_space := JCS_RGB;
5664 IntFormat := ifRGB8;
5668 jpeg_start_decompress(@jpeg);
5670 TempHeight := jpeg.output_height;
5671 TempWidth := jpeg.output_width;
5673 // creating new image
5674 GetMem(pImage, FormatGetImageSize(glBitmapPosition(TempWidth, TempHeight), IntFormat));
5678 for Row := 0 to TempHeight -1 do begin
5679 jpeg_read_scanlines(@jpeg, @pTemp, 1);
5680 Inc(pTemp, Trunc(FormatGetSize(IntFormat) * TempWidth));
5683 // finish decompression
5684 jpeg_finish_decompress(@jpeg);
5686 // destroy decompression
5687 jpeg_destroy_decompress(@jpeg);
5689 SetDataPointer(pImage, IntFormat, TempWidth, TempHeight);
5702 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
5703 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5704 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
5709 Temp: array[0..1]of Byte;
5713 // reading first two bytes to test file and set cursor back to begin
5714 StreamPos := Stream.Position;
5715 Stream.Read(Temp[0], 2);
5716 Stream.Position := StreamPos;
5718 // if Bitmap then read file.
5719 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
5720 bmp := TBitmap.Create;
5722 jpg := TJPEGImage.Create;
5724 jpg.LoadFromStream(Stream);
5726 result := AssignFromBitmap(bmp);
5738 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
5739 {$IF DEFEFINED(GLB_LIB_JPEG)}
5740 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5741 procedure TglBitmap.SaveJPEG(Stream: TStream);
5743 jpeg: jpeg_compress_struct;
5744 jpeg_err: jpeg_error_mgr;
5746 pTemp, pTemp2: pByte;
5748 procedure CopyRow(pDest, pSource: pByte);
5752 for X := 0 to Width - 1 do begin
5753 pByteArray(pDest)^[0] := pByteArray(pSource)^[2];
5754 pByteArray(pDest)^[1] := pByteArray(pSource)^[1];
5755 pByteArray(pDest)^[2] := pByteArray(pSource)^[0];
5762 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
5763 raise EglBitmapUnsupportedInternalFormat.Create('SaveJpg - ' + UNSUPPORTED_INTERNAL_FORMAT);
5765 if not init_libJPEG then
5766 raise Exception.Create('SaveJPG - unable to initialize libJPEG.');
5769 FillChar(jpeg, SizeOf(jpeg_compress_struct), $00);
5770 FillChar(jpeg_err, SizeOf(jpeg_error_mgr), $00);
5773 jpeg.err := jpeg_std_error(@jpeg_err);
5774 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
5775 jpeg_err.output_message := glBitmap_libJPEG_output_message;
5777 // compression struct
5778 jpeg_create_compress(@jpeg);
5780 // allocation space for streaming methods
5781 jpeg.dest := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_dest_mgr));
5783 // seeting up custom functions
5784 with glBitmap_libJPEG_dest_mgr_ptr(jpeg.dest)^ do begin
5785 pub.init_destination := glBitmap_libJPEG_init_destination;
5786 pub.empty_output_buffer := glBitmap_libJPEG_empty_output_buffer;
5787 pub.term_destination := glBitmap_libJPEG_term_destination;
5789 pub.next_output_byte := @DestBuffer[1];
5790 pub.free_in_buffer := Length(DestBuffer);
5792 DestStream := Stream;
5795 // very important state
5796 jpeg.global_state := CSTATE_START;
5797 jpeg.image_width := Width;
5798 jpeg.image_height := Height;
5799 case InternalFormat of
5800 ifAlpha, ifLuminance, ifDepth8: begin
5801 jpeg.input_components := 1;
5802 jpeg.in_color_space := JCS_GRAYSCALE;
5804 ifRGB8, ifBGR8: begin
5805 jpeg.input_components := 3;
5806 jpeg.in_color_space := JCS_RGB;
5810 jpeg_set_defaults(@jpeg);
5811 jpeg_set_quality(@jpeg, 95, true);
5812 jpeg_start_compress(@jpeg, true);
5815 if InternalFormat = ifBGR8 then
5816 GetMem(pTemp2, fRowSize)
5821 for Row := 0 to jpeg.image_height -1 do begin
5823 if InternalFormat = ifBGR8 then
5824 CopyRow(pTemp2, pTemp)
5829 jpeg_write_scanlines(@jpeg, @pTemp2, 1);
5830 inc(pTemp, fRowSize);
5834 if InternalFormat = ifBGR8 then
5837 jpeg_finish_compress(@jpeg);
5838 jpeg_destroy_compress(@jpeg);
5844 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
5845 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5846 procedure TglBitmap.SaveJPEG(Stream: TStream);
5851 if not (ftJPEG in FormatGetSupportedFiles (InternalFormat)) then
5852 raise EglBitmapUnsupportedInternalFormat.Create('SaveJpg - ' + UNSUPPORTED_INTERNAL_FORMAT);
5854 Bmp := TBitmap.Create;
5856 Jpg := TJPEGImage.Create;
5858 AssignToBitmap(Bmp);
5859 if FInternalFormat in [ifAlpha, ifLuminance, ifDepth8] then begin
5860 Jpg.Grayscale := true;
5861 Jpg.PixelFormat := jf8Bit;
5864 Jpg.SaveToStream(Stream);
5875 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5876 //BMP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5877 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5884 BMP_COMP_BITFIELDS = 3;
5887 TBMPHeader = packed record
5892 bfOffBits: Cardinal;
5895 TBMPInfo = packed record
5901 biCompression: Cardinal;
5902 biSizeImage: Cardinal;
5903 biXPelsPerMeter: Longint;
5904 biYPelsPerMeter: Longint;
5905 biClrUsed: Cardinal;
5906 biClrImportant: Cardinal;
5910 TBMPInfoOS = packed record
5919 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5920 function TglBitmap.LoadBMP(const aStream: TStream): Boolean;
5922 //////////////////////////////////////////////////////////////////////////////////////////////////
5923 function ReadInfo(var aInfo: TBMPInfo; var aMask: TglBitmapColorRec): TglBitmapFormat;
5926 aStream.Read(aInfo, SizeOf(aInfo));
5927 FillChar(aMask, SizeOf(aMask), 0);
5930 case aInfo.biCompression of
5932 BMP_COMP_RLE8: begin
5933 raise EglBitmapException.Create('RLE compression is not supported');
5935 BMP_COMP_BITFIELDS: begin
5936 if (aInfo.biBitCount = 16) or (aInfo.biBitCount = 32) then begin
5937 aStream.Read(aMask.r, SizeOf(aMask.r));
5938 aStream.Read(aMask.g, SizeOf(aMask.g));
5939 aStream.Read(aMask.b, SizeOf(aMask.b));
5940 aStream.Read(aMask.a, SizeOf(aMask.a));
5942 raise EglBitmapException.Create('Bitfields are only supported for 16bit and 32bit formats');
5946 //get suitable format
5947 case aInfo.biBitCount of
5948 8: result := tfLuminance8;
5949 16: result := tfBGR5;
5950 24: result := tfBGR8;
5951 32: result := tfBGRA8;
5955 function ReadColorTable(var aFormat: TglBitmapFormat; const aInfo: TBMPInfo): TColorTableFormat;
5958 ColorTable: TColorTable;
5961 if (aInfo.biBitCount >= 16) then
5963 aFormat := tfLuminance8;
5964 c := aInfo.biClrUsed;
5966 c := 1 shl aInfo.biBitCount;
5967 SetLength(ColorTable, c);
5968 for i := 0 to c-1 do begin
5969 aStream.Read(ColorTable[i], SizeOf(TColorTableEnty));
5970 if (ColorTable[i].r <> ColorTable[i].g) or (ColorTable[i].g <> ColorTable[i].b) then
5974 result := TColorTableFormat.Create;
5975 result.PixelSize := aInfo.biBitCount / 8;
5976 result.ColorTable := ColorTable;
5977 result.Range := glBitmapColorRec($FF, $FF, $FF, $00);
5980 //////////////////////////////////////////////////////////////////////////////////////////////////
5981 function CheckBitfields(var aFormat: TglBitmapFormat; const aMask: TglBitmapColorRec;
5982 const aInfo: TBMPInfo): TBitfieldFormat;
5984 TmpFormat: TglBitmapFormat;
5985 FormatDesc: TFormatDescriptor;
5988 if (aMask.r <> 0) or (aMask.g <> 0) or (aMask.b <> 0) or (aMask.a <> 0) then begin
5989 for TmpFormat := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
5990 FormatDesc := TFormatDescriptor.Get(TmpFormat);
5991 if FormatDesc.MaskMatch(aMask.r, aMask.g, aMask.b, aMask.a) then begin
5992 aFormat := FormatDesc.Format;
5997 if (aMask.a = 0) and TFormatDescriptor.Get(aFormat).HasAlpha then
5998 aFormat := TFormatDescriptor.Get(aFormat).WithoutAlpha;
5999 if (aMask.a <> 0) and not TFormatDescriptor.Get(aFormat).HasAlpha then
6000 aFormat := TFormatDescriptor.Get(aFormat).WithAlpha;
6002 result := TBitfieldFormat.Create;
6003 result.PixelSize := aInfo.biBitCount / 8;
6004 result.RedMask := aMask.r;
6005 result.GreenMask := aMask.g;
6006 result.BlueMask := aMask.b;
6007 result.AlphaMask := aMask.a;
6014 ImageSize, rbLineSize, wbLineSize, Padding, i: Integer;
6015 PaddingBuff: Cardinal;
6016 LineBuf, ImageData, TmpData: PByte;
6017 SourceMD, DestMD: Pointer;
6018 BmpFormat: TglBitmapFormat;
6019 ColorTable: TColorTable;
6022 Mask: TglBitmapColorRec;
6027 SpecialFormat: TFormatDescriptor;
6028 FormatDesc: TFormatDescriptor;
6030 //////////////////////////////////////////////////////////////////////////////////////////////////
6031 procedure SpecialFormatReadLine(aData: PByte; aLineBuf: PByte);
6034 Pixel: TglBitmapPixelData;
6036 aStream.Read(aLineBuf^, rbLineSize);
6037 SpecialFormat.PreparePixel(Pixel);
6038 for i := 0 to Info.biWidth-1 do begin
6039 SpecialFormat.Unmap(aLineBuf, Pixel, SourceMD);
6040 with FormatDesc do begin
6041 //TODO: use convert function
6043 if (SpecialFormat.Range.arr[j] <> Range.arr[j]) then begin
6044 if (SpecialFormat.Range.arr[j] > 0) then
6045 Pixel.Data.arr[j] := Round(Pixel.Data.arr[j] / SpecialFormat.Range.arr[j] * Range.arr[j])
6047 Pixel.Data.arr[j] := 0;
6050 FormatDesc.Map(Pixel, aData, DestMD);
6056 BmpFormat := tfEmpty;
6057 SpecialFormat := nil;
6063 StartPos := aStream.Position;
6064 aStream.Read(Header, SizeOf(Header));
6066 if Header.bfType = BMP_MAGIC then begin
6068 BmpFormat := ReadInfo(Info, Mask);
6069 SpecialFormat := ReadColorTable(BmpFormat, Info);
6070 if not Assigned(SpecialFormat) then
6071 SpecialFormat := CheckBitfields(BmpFormat, Mask, Info);
6072 aStream.Position := StartPos + Header.bfOffBits;
6074 if (BmpFormat <> tfEmpty) then begin
6075 FormatDesc := TFormatDescriptor.Get(BmpFormat);
6076 rbLineSize := Round(Info.biWidth * Info.biBitCount / 8); //ReadBuffer LineSize
6077 wbLineSize := Trunc(Info.biWidth * FormatDesc.PixelSize);
6078 Padding := (((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3) - rbLineSize;
6081 DestMD := FormatDesc.CreateMappingData;
6082 ImageSize := FormatDesc.GetSize(Info.biWidth, abs(Info.biHeight));
6083 GetMem(ImageData, ImageSize);
6084 if Assigned(SpecialFormat) then begin
6085 GetMem(LineBuf, rbLineSize); //tmp Memory for converting Bitfields
6086 SourceMD := SpecialFormat.CreateMappingData;
6091 FillChar(ImageData^, ImageSize, $FF);
6092 TmpData := ImageData;
6093 if (Info.biHeight > 0) then
6094 Inc(TmpData, wbLineSize * (Info.biHeight-1));
6095 for i := 0 to Abs(Info.biHeight)-1 do begin
6096 if Assigned(SpecialFormat) then
6097 SpecialFormatReadLine(TmpData, LineBuf) //if is special format read and convert data
6099 aStream.Read(TmpData^, wbLineSize); //else only read data
6100 if (Info.biHeight > 0) then
6101 dec(TmpData, wbLineSize)
6103 inc(TmpData, wbLineSize);
6104 aStream.Read(PaddingBuff, Padding);
6106 SetDataPointer(ImageData, BmpFormat, Info.biWidth, abs(Info.biHeight));
6109 if Assigned(LineBuf) then
6111 if Assigned(SourceMD) then
6112 SpecialFormat.FreeMappingData(SourceMD);
6113 FormatDesc.FreeMappingData(DestMD);
6120 raise EglBitmapException.Create('LoadBMP - No suitable format found');
6122 aStream.Position := StartPos;
6126 FreeAndNil(SpecialFormat);
6129 else aStream.Position := StartPos;
6132 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6133 procedure TglBitmap.SaveBMP(const aStream: TStream);
6137 pData, pTemp: pByte;
6139 PixelFormat: TglBitmapPixelData;
6140 FormatDesc: TFormatDescriptor;
6141 ImageSize, LineSize, Padding, LineIdx, ColorIdx: Integer;
6142 Temp, RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
6144 PaddingBuff: Cardinal;
6146 function GetLineWidth : Integer;
6148 result := ((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3;
6152 if not (ftBMP in FormatGetSupportedFiles(Format)) then
6153 raise EglBitmapUnsupportedFormatFormat.Create('SaveBMP - ' + UNSUPPORTED_FORMAT);
6155 ImageSize := TFormatDescriptor.Get(Format).GetSize(Dimension);
6157 Header.bfType := BMP_MAGIC;
6158 Header.bfSize := SizeOf(Header) + SizeOf(Info) + ImageSize;
6159 Header.bfReserved1 := 0;
6160 Header.bfReserved2 := 0;
6161 Header.bfOffBits := SizeOf(Header) + SizeOf(Info);
6163 FillChar(Info, SizeOf(Info), 0);
6164 Info.biSize := SizeOf(Info);
6165 Info.biWidth := Width;
6166 Info.biHeight := Height;
6168 Info.biCompression := BMP_COMP_RGB;
6169 Info.biSizeImage := ImageSize;
6171 tfR3G3B2, tfLuminance8: begin
6172 Info.biBitCount := 8;
6173 Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal);
6176 tfRGB5, tfRGB5A1, tfR5G6B5, tfRGB4, tfRGBA4,
6177 tfBGR5, tfBGR5A1, tfB5G6R5, tfBGR4, tfBGRA4: begin
6178 Info.biBitCount := 16;
6179 Info.biCompression := BMP_COMP_BITFIELDS;
6182 tfBGR8, tfRGB8: begin
6183 Info.biBitCount := 24;
6186 tfRGB10, tfRGB10A2, tfRGBA8,
6187 tfBGR10, tfBGR10A2, tfBGRA8: begin
6188 Info.biBitCount := 32;
6189 Info.biCompression := BMP_COMP_BITFIELDS;
6192 raise EglBitmapUnsupportedFormatFormat.Create('SaveBMP - ' + UNSUPPORTED_FORMAT);
6194 Info.biXPelsPerMeter := 2835;
6195 Info.biYPelsPerMeter := 2835;
6198 if Info.biCompression = BMP_COMP_BITFIELDS then begin
6199 Info.biSize := Info.biSize + 4 * SizeOf(Cardinal);
6200 Header.bfSize := Header.bfSize + 4 * SizeOf(Cardinal);
6201 Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal);
6203 FormatDesc := TFormatDescriptor.Get(Format);
6204 RedMask := FormatDesc.RedMask;
6205 GreenMask := FormatDesc.GreenMask;
6206 BlueMask := FormatDesc.BlueMask;
6207 AlphaMask := FormatDesc.AlphaMask;
6211 aStream.Write(Header, SizeOf(Header));
6212 aStream.Write(Info, SizeOf(Info));
6215 if Info.biBitCount = 8 then begin
6217 for ColorIdx := Low(Byte) to High(Byte) do begin
6218 aStream.Write(Temp, 4);
6219 Temp := Temp + $00010101;
6224 if Info.biCompression = BMP_COMP_BITFIELDS then begin
6225 aStream.Write(RedMask, SizeOf(Cardinal));
6226 aStream.Write(GreenMask, SizeOf(Cardinal));
6227 aStream.Write(BlueMask, SizeOf(Cardinal));
6228 aStream.Write(AlphaMask, SizeOf(Cardinal));
6232 LineSize := Trunc(Width * TFormatDescriptor.Get(Format).PixelSize);
6233 Padding := GetLineWidth - LineSize;
6237 Inc(pData, (Height -1) * LineSize);
6239 // prepare row buffer. But only for RGB because RGBA supports color masks
6240 // so it's possible to change color within the image.
6241 if (Format = tfRGB8) then
6242 GetMem(pTemp, fRowSize)
6248 for LineIdx := 0 to Height - 1 do begin
6250 if Format = tfRGB8 then begin
6251 Move(pData^, pTemp^, fRowSize);
6252 SwapRGB(pTemp, Width, false);
6255 aStream.Write(pTemp^, LineSize);
6256 Dec(pData, LineSize);
6258 aStream.Write(PaddingBuff, Padding);
6261 // destroy row buffer
6262 if Format = tfRGB8 then
6267 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6268 //TGA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6269 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6271 TTGAHeader = packed record
6275 ColorMapSpec: Array[0..4] of Byte;
6285 TGA_UNCOMPRESSED_RGB = 2;
6286 TGA_UNCOMPRESSED_GRAY = 3;
6287 TGA_COMPRESSED_RGB = 10;
6288 TGA_COMPRESSED_GRAY = 11;
6290 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6291 function TglBitmap.LoadTGA(const aStream: TStream): Boolean;
6294 NewImage, pData: PByte;
6296 PixelSize, LineSize, YStart, YEnd, YInc: Integer;
6297 Format: TglBitmapFormat;
6302 ////////////////////////////////////////////////////////////////////////////////////////
6303 procedure ReadUncompressed;
6307 RowSize := Header.Width * PixelSize;
6308 // copy line by line
6309 while YStart <> YEnd + YInc do begin
6311 Inc(pData, YStart * LineSize);
6312 aStream.Read(pData^, RowSize);
6317 ////////////////////////////////////////////////////////////////////////////////////////
6318 procedure ReadCompressed;
6320 HeaderWidth, HeaderHeight: Integer;
6321 LinePixelsRead, ImgPixelsRead, ImgPixelsToRead: Integer;
6324 CacheSize, CachePos: Integer;
6327 TempBuf: Array [0..15] of Byte;
6329 PixelRepeat: Boolean;
6330 PixelToRead, TempPixels: Integer;
6332 /////////////////////////////////////////////////////////////////
6333 procedure CheckLine;
6335 if LinePixelsRead >= HeaderWidth then begin
6336 LinePixelsRead := 0;
6339 Inc(pData, YStart * LineSize);
6343 /////////////////////////////////////////////////////////////////
6344 procedure CachedRead(out Buffer; Count: Integer);
6348 if (CachePos + Count) > CacheSize then begin
6352 if CacheSize - CachePos > 0 then begin
6353 BytesRead := CacheSize - CachePos;
6354 Move(pByteArray(Cache)^[CachePos], Buffer, BytesRead);
6355 Inc(CachePos, BytesRead);
6359 CacheSize := Min(CACHE_SIZE, aStream.Size - aStream.Position);
6360 aStream.Read(Cache^, CacheSize);
6364 if Count - BytesRead > 0 then begin
6365 Move(pByteArray(Cache)^[CachePos], TByteArray(Buffer)[BytesRead], Count - BytesRead);
6366 Inc(CachePos, Count - BytesRead);
6369 Move(pByteArray(Cache)^[CachePos], Buffer, Count);
6370 Inc(CachePos, Count);
6378 HeaderWidth := Header.Width;
6379 HeaderHeight := Header.Height;
6381 GetMem(Cache, CACHE_SIZE); // 16K Buffer
6383 ImgPixelsToRead := HeaderWidth * HeaderHeight;
6385 LinePixelsRead := 0;
6388 Inc(pData, YStart * LineSize);
6390 // Read until all Pixels
6392 CachedRead(Temp, 1);
6394 PixelRepeat := Temp and $80 > 0;
6395 PixelToRead := (Temp and $7F) + 1;
6397 Inc(ImgPixelsRead, PixelToRead);
6399 if PixelRepeat then begin
6400 // repeat one pixel x times
6401 CachedRead(TempBuf[0], PixelSize);
6404 while PixelToRead > 0 do begin
6407 TempPixels := HeaderWidth - LinePixelsRead;
6408 if PixelToRead < TempPixels then
6409 TempPixels := PixelToRead;
6411 Inc(LinePixelsRead, TempPixels);
6412 Dec(PixelToRead, TempPixels);
6414 while TempPixels > 0 do begin
6417 pData^ := TempBuf[0];
6421 pWord(pData)^ := pWord(@TempBuf[0])^;
6425 pWord(pData)^ := pWord(@TempBuf[0])^;
6427 pData^ := TempBuf[2];
6431 pDWord(pData)^ := pDWord(@TempBuf[0])^;
6440 while PixelToRead > 0 do begin
6442 TempPixels := HeaderWidth - LinePixelsRead;
6443 if PixelToRead < TempPixels then
6444 TempPixels := PixelToRead;
6445 CachedRead(pData^, PixelSize * TempPixels);
6446 Inc(pData, PixelSize * TempPixels);
6447 Inc(LinePixelsRead, TempPixels);
6448 Dec(PixelToRead, TempPixels);
6451 until ImgPixelsRead >= ImgPixelsToRead;
6460 // reading header to test file and set cursor back to begin
6461 StreamPos := aStream.Position;
6462 aStream.Read(Header, SizeOf(Header));
6464 // no colormapped files
6465 if (Header.ColorMapType = 0) then begin
6466 if Header.ImageType in [TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY] then begin
6468 //TODO 8: Format := tfAlpha8;
6469 16: Format := tfLuminance8Alpha8;
6470 24: Format := tfBGR8;
6471 32: Format := tfBGRA8;
6473 raise EglBitmapException.Create('LoadTga - unsupported BitsPerPixel found.');
6477 if Header.ImageID <> 0 then
6478 aStream.Position := aStream.Position + Header.ImageID;
6480 PixelSize := TFormatDescriptor.Get(Format).GetSize(1, 1);
6481 LineSize := Trunc(Header.Width * PixelSize);
6483 GetMem(NewImage, LineSize * Header.Height);
6486 if (Header.ImageDes and $20 > 0) then begin
6488 YEnd := Header.Height -1;
6491 YStart := Header.Height -1;
6497 case Header.ImageType of
6498 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY:
6500 TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY:
6504 SetDataPointer(NewImage, Format, Header.Width, Header.Height);
6511 else aStream.Position := StreamPos;
6513 else aStream.Position := StreamPos;
6516 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6517 procedure TglBitmap.SaveTGA(const aStream: TStream);
6522 FormatDesc: TFormatDescriptor;
6524 procedure ConvertData(pTemp: pByte);
6526 Idx, PixelSize: Integer;
6529 PixelSize := fPixelSize;
6530 for Idx := 1 to Height * Width do begin
6531 Temp := pByteArray(pTemp)^[2];
6532 pByteArray(pTemp)^[2] := pByteArray(pTemp)^[0];
6533 pByteArray(pTemp)^[0] := Temp;
6534 Inc(pTemp, PixelSize);
6539 if not (ftTGA in FormatGetSupportedFiles(Format)) then
6540 raise EglBitmapUnsupportedFormatFormat.Create('SaveTGA - ' + UNSUPPORTED_FORMAT);
6542 FillChar(Header, SizeOf(Header), 0);
6544 //TODO ifAlpha8, ifLuminance8, ifDepth8: begin
6546 Header.ImageType := TGA_UNCOMPRESSED_GRAY;
6549 tfLuminance8Alpha8: begin
6550 Header.ImageType := TGA_UNCOMPRESSED_GRAY;
6553 tfRGB8, tfBGR8: begin
6554 Header.ImageType := TGA_UNCOMPRESSED_RGB;
6557 tfRGBA8, tfBGRA8: begin
6558 Header.ImageType := TGA_UNCOMPRESSED_RGB;
6562 raise EglBitmapUnsupportedFormatFormat.Create('SaveTGA - ' + UNSUPPORTED_FORMAT);
6565 Header.Width := Width;
6566 Header.Height := Height;
6567 Header.ImageDes := $20;
6568 FormatDesc := TFormatDescriptor.Get(Format);
6570 if FormatDesc.HasAlpha then
6571 Header.ImageDes := Header.ImageDes or $08;
6572 aStream.Write(Header, SizeOf(Header));
6574 // convert RGB(A) to BGR(A)
6575 Size := FormatDesc.GetSize(Dimension);
6576 if Format in [tfRGB8, tfRGBA8] then begin
6577 GetMem(pTemp, Size);
6583 if Format in [tfRGB8, tfRGBA8] then begin
6584 Move(Data^, pTemp^, Size);
6589 aStream.Write(pTemp^, Size);
6592 if Format in [tfRGB8, tfRGBA8] then
6597 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6598 //DDS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6599 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6601 DDS_MAGIC = $20534444;
6603 // DDS_header.dwFlags
6604 DDSD_CAPS = $00000001;
6605 DDSD_HEIGHT = $00000002;
6606 DDSD_WIDTH = $00000004;
6607 DDSD_PITCH = $00000008;
6608 DDSD_PIXELFORMAT = $00001000;
6609 DDSD_MIPMAPCOUNT = $00020000;
6610 DDSD_LINEARSIZE = $00080000;
6611 DDSD_DEPTH = $00800000;
6613 // DDS_header.sPixelFormat.dwFlags
6614 DDPF_ALPHAPIXELS = $00000001;
6615 DDPF_FOURCC = $00000004;
6616 DDPF_INDEXED = $00000020;
6617 DDPF_RGB = $00000040;
6619 // DDS_header.sCaps.dwCaps1
6620 DDSCAPS_COMPLEX = $00000008;
6621 DDSCAPS_TEXTURE = $00001000;
6622 DDSCAPS_MIPMAP = $00400000;
6624 // DDS_header.sCaps.dwCaps2
6625 DDSCAPS2_CUBEMAP = $00000200;
6626 DDSCAPS2_CUBEMAP_POSITIVEX = $00000400;
6627 DDSCAPS2_CUBEMAP_NEGATIVEX = $00000800;
6628 DDSCAPS2_CUBEMAP_POSITIVEY = $00001000;
6629 DDSCAPS2_CUBEMAP_NEGATIVEY = $00002000;
6630 DDSCAPS2_CUBEMAP_POSITIVEZ = $00004000;
6631 DDSCAPS2_CUBEMAP_NEGATIVEZ = $00008000;
6632 DDSCAPS2_VOLUME = $00200000;
6634 D3DFMT_DXT1 = $31545844;
6635 D3DFMT_DXT3 = $33545844;
6636 D3DFMT_DXT5 = $35545844;
6639 TDDSPixelFormat = packed record
6643 dwRGBBitCount: Cardinal;
6644 dwRBitMask: Cardinal;
6645 dwGBitMask: Cardinal;
6646 dwBBitMask: Cardinal;
6647 dwABitMask: Cardinal;
6650 TDDSCaps = packed record
6654 dwReserved: Cardinal;
6657 TDDSHeader = packed record
6663 dwPitchOrLinearSize: Cardinal;
6665 dwMipMapCount: Cardinal;
6666 dwReserved: array[0..10] of Cardinal;
6667 PixelFormat: TDDSPixelFormat;
6669 dwReserved2: Cardinal;
6672 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6673 function TglBitmap.LoadDDS(const aStream: TStream): Boolean;
6677 Y, LineSize: Cardinal;
6679 NewImage, pData: pByte;
6680 ddsFormat: TglBitmapFormat;
6682 function RaiseEx : Exception;
6684 result := EglBitmapException.Create('LoadDDS - unsupported Pixelformat found.');
6687 function GetDDSFormat: TglBitmapFormat;
6689 with Header.PixelFormat do begin
6691 if (dwFlags and DDPF_FOURCC) > 0 then begin
6693 case Header.PixelFormat.dwFourCC of
6694 D3DFMT_DXT1: result := ifDXT1;
6695 D3DFMT_DXT3: result := ifDXT3;
6696 D3DFMT_DXT5: result := ifDXT5;
6705 if (dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS)) > 0 then begin
6706 case dwRGBBitCount of
6708 (* TODO if dwFlags and DDPF_ALPHAPIXELS > 0 then
6712 result := tfLuminance8;
6715 if dwFlags and DDPF_ALPHAPIXELS > 0 then begin
6717 case CountSetBits(dwRBitMask) of
6718 5: result := tfRGB5A1;
6719 //TODO 4: result := tfRGBA4;
6721 result := tfLuminance8Alpha8;
6725 //TODO result := ifR5G6B5;
6730 if dwRBitMask > dwBBitMask then
6736 if CountSetBits(dwRBitMask) = 10 then
6737 //TODO result := tfRGB10A2
6741 if dwRBitMask > dwBBitMask then
6758 StreamPos := aStream.Position;
6759 aStream.Read(Header, sizeof(Header));
6761 if ((Header.dwMagic <> DDS_MAGIC) or (Header.dwSize <> 124) or
6762 ((Header.dwFlags and DDSD_PIXELFORMAT) = 0) or ((Header.dwFlags and DDSD_CAPS) = 0)) then begin
6763 aStream.Position := StreamPos;
6767 ddsFormat := GetDDSFormat;
6768 LineSize := Trunc(Header.dwWidth * TFormatDescriptor.Get(ddsFormat).PixelSize);
6769 GetMem(NewImage, Header.dwHeight * LineSize);
6774 if (Header.PixelFormat.dwFlags and DDPF_FOURCC) > 0 then begin
6775 RowSize := Header.dwPitchOrLinearSize div Header.dwWidth;
6776 for Y := 0 to Header.dwHeight -1 do begin
6777 aStream.Read(pData^, RowSize);
6778 Inc(pData, LineSize);
6783 if (Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS)) > 0 then begin
6784 RowSize := Header.dwPitchOrLinearSize;
6786 for Y := 0 to Header.dwHeight -1 do begin
6787 aStream.Read(pData^, RowSize);
6788 Inc(pData, LineSize);
6793 SetDataPointer(NewImage, ddsFormat, Header.dwWidth, Header.dwHeight);
6801 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6802 procedure TglBitmap.SaveDDS(const aStream: TStream);
6805 Pix: TglBitmapPixelData;
6806 FormatDesc: TFormatDescriptor;
6808 //if not FormatIsUncompressed(InternalFormat) then
6809 // raise EglBitmapUnsupportedFormatFormat.Create('SaveDDS - ' + UNSUPPORTED_FORMAT);
6811 (* TODO if Format = tfAlpha8 then
6812 FORMAT_DESCRIPTORS[tfLuminance8].PreparePixel(Pix);
6814 TFormatDescriptor.Get(Format).PreparePixel(Pix);
6817 FillChar(Header, SizeOf(Header), 0);
6818 Header.dwMagic := DDS_MAGIC;
6819 Header.dwSize := 124;
6820 Header.dwFlags := DDSD_PITCH or DDSD_CAPS or DDSD_PIXELFORMAT;
6822 if Width > 0 then begin
6823 Header.dwWidth := Width;
6824 Header.dwFlags := Header.dwFlags or DDSD_WIDTH;
6827 if Height > 0 then begin
6828 Header.dwHeight := Height;
6829 Header.dwFlags := Header.dwFlags or DDSD_HEIGHT;
6832 Header.dwPitchOrLinearSize := fRowSize;
6833 Header.dwMipMapCount := 1;
6836 Header.Caps.dwCaps1 := DDSCAPS_TEXTURE;
6839 Header.PixelFormat.dwSize := Sizeof(Header.PixelFormat);
6840 Header.PixelFormat.dwFlags := DDPF_RGB;
6843 if FORMAT_DESCRIPTORS[Format].HasAlpha and (Format <> tfAlpha8) then
6844 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHAPIXELS;
6847 FormatDesc := TFormatDescriptor.Get(Format);
6848 Header.PixelFormat.dwRGBBitCount := Trunc(FormatDesc.PixelSize * 8);
6849 Header.PixelFormat.dwRBitMask := FormatDesc.RedMask;
6850 Header.PixelFormat.dwGBitMask := FormatDesc.GreenMask;
6851 Header.PixelFormat.dwBBitMask := FormatDesc.BlueMask;
6852 Header.PixelFormat.dwABitMask := FormatDesc.AlphaMask;
6854 aStream.Write(Header, SizeOf(Header));
6855 aStream.Write(Data^, FormatDesc.GetSize(Dimension));
6858 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6859 //TglBitmap2D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6860 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6861 function TglBitmap2D.GetScanline(const aIndex: Integer): Pointer;
6863 if (aIndex >= Low(fLines)) and (aIndex <= High(fLines)) then
6864 result := fLines[aIndex]
6869 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6870 procedure TglBitmap2D.SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
6871 const aWidth: Integer; const aHeight: Integer);
6873 Idx, LineWidth: Integer;
6875 inherited SetDataPointer(aData, aFormat, aWidth, aHeight);
6878 if {FormatIsUncompressed(Format)} true then begin
6880 fGetPixelFunc := GetPixel2DUnmap;
6881 fSetPixelFunc := SetPixel2DUnmap;
6884 if Assigned(Data) then begin
6885 SetLength(fLines, GetHeight);
6886 LineWidth := Trunc(GetWidth * TFormatDescriptor.Get(Format).PixelSize);
6888 for Idx := 0 to GetHeight -1 do begin
6889 fLines[Idx] := Data;
6890 Inc(fLines[Idx], Idx * LineWidth);
6893 else SetLength(fLines, 0);
6896 SetLength(fLines, 0);
6898 fSetPixelFunc := nil;
6902 fGetPixelFunc := GetPixel2DDXT1;
6904 fGetPixelFunc := GetPixel2DDXT3;
6906 fGetPixelFunc := GetPixel2DDXT5;
6908 fGetPixelFunc := nil;
6914 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6915 procedure TglBitmap2D.UploadData(const aTarget: Cardinal; const aBuildWithGlu: Boolean);
6917 FormatDesc: TFormatDescriptor;
6919 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
6922 if Self.InternalFormat in [ifDXT1, ifDXT3, ifDXT5] then
6923 glCompressedTexImage2D(Target, 0, InternalFormat, Width, Height, 0, Trunc(Width * Height * FormatGetSize(Self.InternalFormat)), Data)
6927 FormatDesc := TFormatDescriptor.Get(Format);
6928 if aBuildWithGlu then
6929 gluBuild2DMipmaps(aTarget, FormatDesc.Components, Width, Height,
6930 FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
6932 glTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0,
6933 FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
6936 if (FreeDataAfterGenTexture) then
6940 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6941 procedure TglBitmap2D.AfterConstruction;
6944 Target := GL_TEXTURE_2D;
6947 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6948 procedure TglBitmap2D.GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
6951 Size, w, h: Integer;
6952 FormatDesc: TFormatDescriptor;
6955 if not FormatIsUncompressed(Format) then
6956 raise EglBitmapUnsupportedFormatFormat.Create('TglBitmap2D.GrabScreen - ' + UNSUPPORTED_FORMAT);
6959 w := aRight - aLeft;
6960 h := aBottom - aTop;
6961 FormatDesc := TFormatDescriptor.Get(Format);
6962 Size := FormatDesc.GetSize(w, h);
6965 glPixelStorei(GL_PACK_ALIGNMENT, 1);
6966 glReadPixels(aLeft, aTop, w, h, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
6967 SetDataPointer(Temp, Format, w, h);
6975 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6976 procedure TglBitmap2D.GetDataFromTexture;
6979 TempWidth, TempHeight: Integer;
6980 TempType, TempIntFormat: Cardinal;
6981 IntFormat, f: TglBitmapFormat;
6982 FormatDesc: TFormatDescriptor;
6987 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_WIDTH, @TempWidth);
6988 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT, @TempHeight);
6989 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat);
6991 IntFormat := tfEmpty;
6992 for f := Low(TglBitmapFormat) to High(TglBitmapFormat) do
6993 if (TFormatDescriptor.Get(f).glInternalFormat = TempIntFormat) then begin
6994 IntFormat := FormatDesc.Format;
6998 // Getting data from OpenGL
6999 FormatDesc := TFormatDescriptor.Get(IntFormat);
7000 GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight));
7003 if FormatIsCompressed(IntFormat) and (GL_VERSION_1_3 or GL_ARB_texture_compression) then
7004 glGetCompressedTexImage(Target, 0, Temp)
7007 glGetTexImage(Target, 0, FormatDesc.glInternalFormat, FormatDesc.glDataFormat, Temp);
7008 SetDataPointer(Temp, IntFormat, TempWidth, TempHeight);
7015 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7016 procedure TglBitmap2D.GenTexture(const aTestTextureSize: Boolean);
7018 BuildWithGlu, PotTex, TexRec: Boolean;
7021 if Assigned(Data) then begin
7022 // Check Texture Size
7023 if (aTestTextureSize) then begin
7024 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
7026 if ((Height > TexSize) or (Width > TexSize)) then
7027 raise EglBitmapSizeToLargeException.Create('TglBitmap2D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
7029 PotTex := IsPowerOfTwo(Height) and IsPowerOfTwo(Width);
7030 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and (Target = GL_TEXTURE_RECTANGLE_ARB);
7032 if not (PotTex or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
7033 raise EglBitmapNonPowerOfTwoException.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
7037 SetupParameters(BuildWithGlu);
7038 UploadData(Target, BuildWithGlu);
7039 glAreTexturesResident(1, @fID, @fIsResident);
7043 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7044 function TglBitmap2D.FlipHorz: Boolean;
7047 TempDestData, DestData, SourceData: PByte;
7050 result := inherited FlipHorz;
7051 if Assigned(Data) then begin
7053 ImgSize := Height * fRowSize;
7054 GetMem(DestData, ImgSize);
7056 TempDestData := DestData;
7057 Dec(TempDestData, fRowSize + fPixelSize);
7058 for Row := 0 to Height -1 do begin
7059 Inc(TempDestData, fRowSize * 2);
7060 for Col := 0 to Width -1 do begin
7061 Move(SourceData^, TempDestData^, fPixelSize);
7062 Inc(SourceData, fPixelSize);
7063 Dec(TempDestData, fPixelSize);
7066 SetDataPointer(DestData, Format);
7075 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7076 function TglBitmap2D.FlipVert: Boolean;
7079 TempDestData, DestData, SourceData: PByte;
7081 result := inherited FlipVert;
7082 if Assigned(Data) then begin
7084 GetMem(DestData, Height * fRowSize);
7086 TempDestData := DestData;
7087 Inc(TempDestData, Width * (Height -1) * fPixelSize);
7088 for Row := 0 to Height -1 do begin
7089 Move(SourceData^, TempDestData^, fRowSize);
7090 Dec(TempDestData, fRowSize);
7091 Inc(SourceData, fRowSize);
7093 SetDataPointer(DestData, Format);
7102 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7103 //TglBitmap2D - ToNormalMap///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7104 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7106 TMatrixItem = record
7111 PglBitmapToNormalMapRec = ^TglBitmapToNormalMapRec;
7112 TglBitmapToNormalMapRec = Record
7114 Heights: array of Single;
7115 MatrixU : array of TMatrixItem;
7116 MatrixV : array of TMatrixItem;
7120 ONE_OVER_255 = 1 / 255;
7122 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7123 procedure glBitmapToNormalMapPrepareFunc(var FuncRec: TglBitmapFunctionRec);
7127 with FuncRec do begin
7129 Source.Data.r * LUMINANCE_WEIGHT_R +
7130 Source.Data.g * LUMINANCE_WEIGHT_G +
7131 Source.Data.b * LUMINANCE_WEIGHT_B;
7132 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Val * ONE_OVER_255;
7136 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7137 procedure glBitmapToNormalMapPrepareAlphaFunc(var FuncRec: TglBitmapFunctionRec);
7140 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Source.Data.a * ONE_OVER_255;
7143 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7144 procedure glBitmapToNormalMapFunc (var FuncRec: TglBitmapFunctionRec);
7146 TVec = Array[0..2] of Single;
7153 function GetHeight(X, Y: Integer): Single;
7155 with FuncRec do begin
7156 X := Max(0, Min(Size.X -1, X));
7157 Y := Max(0, Min(Size.Y -1, Y));
7158 result := PglBitmapToNormalMapRec(Args)^.Heights[Y * Size.X + X];
7163 with FuncRec do begin
7164 with PglBitmapToNormalMapRec(Args)^ do begin
7166 for Idx := Low(MatrixU) to High(MatrixU) do
7167 du := du + GetHeight(Position.X + MatrixU[Idx].X, Position.Y + MatrixU[Idx].Y) * MatrixU[Idx].W;
7170 for Idx := Low(MatrixU) to High(MatrixU) do
7171 dv := dv + GetHeight(Position.X + MatrixV[Idx].X, Position.Y + MatrixV[Idx].Y) * MatrixV[Idx].W;
7173 Vec[0] := -du * Scale;
7174 Vec[1] := -dv * Scale;
7179 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
7180 if Len <> 0 then begin
7181 Vec[0] := Vec[0] * Len;
7182 Vec[1] := Vec[1] * Len;
7183 Vec[2] := Vec[2] * Len;
7187 Dest.Data.r := Trunc((Vec[0] + 1) * 127.5);
7188 Dest.Data.g := Trunc((Vec[1] + 1) * 127.5);
7189 Dest.Data.b := Trunc((Vec[2] + 1) * 127.5);
7193 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7194 procedure TglBitmap2D.ToNormalMap(const aFunc: TglBitmapNormalMapFunc; const aScale: Single; const aUseAlpha: Boolean);
7196 Rec: TglBitmapToNormalMapRec;
7198 procedure SetEntry (var Matrix: array of TMatrixItem; Index, X, Y: Integer; W: Single);
7200 if (Index >= Low(Matrix)) and (Index <= High(Matrix)) then begin
7201 Matrix[Index].X := X;
7202 Matrix[Index].Y := Y;
7203 Matrix[Index].W := W;
7209 if not FormatIsUncompressed(InternalFormat) then
7210 raise EglBitmapUnsupportedFormatFormat.Create('TglBitmap2D.ToNormalMap - ' + UNSUPPORTED_FORMAT);
7213 if aScale > 100 then
7215 else if aScale < -100 then
7218 Rec.Scale := aScale;
7220 SetLength(Rec.Heights, Width * Height);
7224 SetLength(Rec.MatrixU, 2);
7225 SetEntry(Rec.MatrixU, 0, -1, 0, -0.5);
7226 SetEntry(Rec.MatrixU, 1, 1, 0, 0.5);
7228 SetLength(Rec.MatrixV, 2);
7229 SetEntry(Rec.MatrixV, 0, 0, 1, 0.5);
7230 SetEntry(Rec.MatrixV, 1, 0, -1, -0.5);
7234 SetLength(Rec.MatrixU, 6);
7235 SetEntry(Rec.MatrixU, 0, -1, 1, -1.0);
7236 SetEntry(Rec.MatrixU, 1, -1, 0, -2.0);
7237 SetEntry(Rec.MatrixU, 2, -1, -1, -1.0);
7238 SetEntry(Rec.MatrixU, 3, 1, 1, 1.0);
7239 SetEntry(Rec.MatrixU, 4, 1, 0, 2.0);
7240 SetEntry(Rec.MatrixU, 5, 1, -1, 1.0);
7242 SetLength(Rec.MatrixV, 6);
7243 SetEntry(Rec.MatrixV, 0, -1, 1, 1.0);
7244 SetEntry(Rec.MatrixV, 1, 0, 1, 2.0);
7245 SetEntry(Rec.MatrixV, 2, 1, 1, 1.0);
7246 SetEntry(Rec.MatrixV, 3, -1, -1, -1.0);
7247 SetEntry(Rec.MatrixV, 4, 0, -1, -2.0);
7248 SetEntry(Rec.MatrixV, 5, 1, -1, -1.0);
7252 SetLength(Rec.MatrixU, 6);
7253 SetEntry(Rec.MatrixU, 0, -1, 1, -1/6);
7254 SetEntry(Rec.MatrixU, 1, -1, 0, -1/6);
7255 SetEntry(Rec.MatrixU, 2, -1, -1, -1/6);
7256 SetEntry(Rec.MatrixU, 3, 1, 1, 1/6);
7257 SetEntry(Rec.MatrixU, 4, 1, 0, 1/6);
7258 SetEntry(Rec.MatrixU, 5, 1, -1, 1/6);
7260 SetLength(Rec.MatrixV, 6);
7261 SetEntry(Rec.MatrixV, 0, -1, 1, 1/6);
7262 SetEntry(Rec.MatrixV, 1, 0, 1, 1/6);
7263 SetEntry(Rec.MatrixV, 2, 1, 1, 1/6);
7264 SetEntry(Rec.MatrixV, 3, -1, -1, -1/6);
7265 SetEntry(Rec.MatrixV, 4, 0, -1, -1/6);
7266 SetEntry(Rec.MatrixV, 5, 1, -1, -1/6);
7270 SetLength(Rec.MatrixU, 20);
7271 SetEntry(Rec.MatrixU, 0, -2, 2, -1 / 16);
7272 SetEntry(Rec.MatrixU, 1, -1, 2, -1 / 10);
7273 SetEntry(Rec.MatrixU, 2, 1, 2, 1 / 10);
7274 SetEntry(Rec.MatrixU, 3, 2, 2, 1 / 16);
7275 SetEntry(Rec.MatrixU, 4, -2, 1, -1 / 10);
7276 SetEntry(Rec.MatrixU, 5, -1, 1, -1 / 8);
7277 SetEntry(Rec.MatrixU, 6, 1, 1, 1 / 8);
7278 SetEntry(Rec.MatrixU, 7, 2, 1, 1 / 10);
7279 SetEntry(Rec.MatrixU, 8, -2, 0, -1 / 2.8);
7280 SetEntry(Rec.MatrixU, 9, -1, 0, -0.5);
7281 SetEntry(Rec.MatrixU, 10, 1, 0, 0.5);
7282 SetEntry(Rec.MatrixU, 11, 2, 0, 1 / 2.8);
7283 SetEntry(Rec.MatrixU, 12, -2, -1, -1 / 10);
7284 SetEntry(Rec.MatrixU, 13, -1, -1, -1 / 8);
7285 SetEntry(Rec.MatrixU, 14, 1, -1, 1 / 8);
7286 SetEntry(Rec.MatrixU, 15, 2, -1, 1 / 10);
7287 SetEntry(Rec.MatrixU, 16, -2, -2, -1 / 16);
7288 SetEntry(Rec.MatrixU, 17, -1, -2, -1 / 10);
7289 SetEntry(Rec.MatrixU, 18, 1, -2, 1 / 10);
7290 SetEntry(Rec.MatrixU, 19, 2, -2, 1 / 16);
7292 SetLength(Rec.MatrixV, 20);
7293 SetEntry(Rec.MatrixV, 0, -2, 2, 1 / 16);
7294 SetEntry(Rec.MatrixV, 1, -1, 2, 1 / 10);
7295 SetEntry(Rec.MatrixV, 2, 0, 2, 0.25);
7296 SetEntry(Rec.MatrixV, 3, 1, 2, 1 / 10);
7297 SetEntry(Rec.MatrixV, 4, 2, 2, 1 / 16);
7298 SetEntry(Rec.MatrixV, 5, -2, 1, 1 / 10);
7299 SetEntry(Rec.MatrixV, 6, -1, 1, 1 / 8);
7300 SetEntry(Rec.MatrixV, 7, 0, 1, 0.5);
7301 SetEntry(Rec.MatrixV, 8, 1, 1, 1 / 8);
7302 SetEntry(Rec.MatrixV, 9, 2, 1, 1 / 16);
7303 SetEntry(Rec.MatrixV, 10, -2, -1, -1 / 16);
7304 SetEntry(Rec.MatrixV, 11, -1, -1, -1 / 8);
7305 SetEntry(Rec.MatrixV, 12, 0, -1, -0.5);
7306 SetEntry(Rec.MatrixV, 13, 1, -1, -1 / 8);
7307 SetEntry(Rec.MatrixV, 14, 2, -1, -1 / 10);
7308 SetEntry(Rec.MatrixV, 15, -2, -2, -1 / 16);
7309 SetEntry(Rec.MatrixV, 16, -1, -2, -1 / 10);
7310 SetEntry(Rec.MatrixV, 17, 0, -2, -0.25);
7311 SetEntry(Rec.MatrixV, 18, 1, -2, -1 / 10);
7312 SetEntry(Rec.MatrixV, 19, 2, -2, -1 / 16);
7317 if aUseAlpha and TFormatDescriptor.Get(Format).HasAlpha then
7318 AddFunc(glBitmapToNormalMapPrepareAlphaFunc, false, PtrInt(@Rec))
7320 AddFunc(glBitmapToNormalMapPrepareFunc, false, PtrInt(@Rec));
7321 AddFunc(glBitmapToNormalMapFunc, false, PtrInt(@Rec));
7323 SetLength(Rec.Heights, 0);
7336 procedure TglBitmap1D.SetDataPointer(Data: pByte; Format: TglBitmapInternalFormat; Width, Height: Integer);
7341 if Height > 1 then begin
7342 // extract first line of the data
7343 Size := FormatGetImageSize(glBitmapPosition(Width), Format);
7344 GetMem(pTemp, Size);
7346 Move(Data^, pTemp^, Size);
7353 inherited SetDataPointer(pTemp, Format, Width);
7355 if FormatIsUncompressed(Format) then begin
7356 fUnmapFunc := FormatGetUnMapFunc(Format);
7357 fGetPixelFunc := GetPixel1DUnmap;
7362 procedure TglBitmap1D.GetPixel1DUnmap(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
7367 Inc(pTemp, Pos.X * fPixelSize);
7369 fUnmapFunc(pTemp, Pixel);
7373 function TglBitmap1D.FlipHorz: Boolean;
7376 pTempDest, pDest, pSource: pByte;
7378 result := inherited FlipHorz;
7380 if Assigned(Data) and FormatIsUncompressed(InternalFormat) then begin
7383 GetMem(pDest, fRowSize);
7387 Inc(pTempDest, fRowSize);
7388 for Col := 0 to Width -1 do begin
7389 Move(pSource^, pTempDest^, fPixelSize);
7391 Inc(pSource, fPixelSize);
7392 Dec(pTempDest, fPixelSize);
7395 SetDataPointer(pDest, InternalFormat);
7405 procedure TglBitmap1D.UploadData (Target, Format, InternalFormat, Typ: Cardinal; BuildWithGlu: Boolean);
7408 if Self.InternalFormat in [ifDXT1, ifDXT3, ifDXT5] then
7409 glCompressedTexImage1D(Target, 0, InternalFormat, Width, 0, Trunc(Width * FormatGetSize(Self.InternalFormat)), Data)
7413 if BuildWithGlu then
7414 gluBuild1DMipmaps(Target, InternalFormat, Width, Format, Typ, Data)
7416 glTexImage1D(Target, 0, InternalFormat, Width, 0, Format, Typ, Data);
7419 if (FreeDataAfterGenTexture) then
7424 procedure TglBitmap1D.GenTexture(TestTextureSize: Boolean);
7426 BuildWithGlu, TexRec: Boolean;
7427 glFormat, glInternalFormat, glType: Cardinal;
7430 if Assigned(Data) then begin
7431 // Check Texture Size
7432 if (TestTextureSize) then begin
7433 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
7435 if (Width > TexSize) then
7436 raise EglBitmapSizeToLargeException.Create('TglBitmap1D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
7438 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and
7439 (Target = GL_TEXTURE_RECTANGLE_ARB);
7441 if not (IsPowerOfTwo (Width) or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
7442 raise EglBitmapNonPowerOfTwoException.Create('TglBitmap1D.GenTexture - Rendercontex dosn''t support non power of two texture.');
7447 SetupParameters(BuildWithGlu);
7448 SelectFormat(InternalFormat, glFormat, glInternalFormat, glType);
7450 UploadData(Target, glFormat, glInternalFormat, glType, BuildWithGlu);
7453 glAreTexturesResident(1, @fID, @fIsResident);
7458 procedure TglBitmap1D.AfterConstruction;
7462 Target := GL_TEXTURE_1D;
7466 { TglBitmapCubeMap }
7468 procedure TglBitmapCubeMap.AfterConstruction;
7472 if not (GL_VERSION_1_3 or GL_ARB_texture_cube_map or GL_EXT_texture_cube_map) then
7473 raise EglBitmapException.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
7475 SetWrap; // set all to GL_CLAMP_TO_EDGE
7476 Target := GL_TEXTURE_CUBE_MAP;
7477 fGenMode := GL_REFLECTION_MAP;
7481 procedure TglBitmapCubeMap.Bind(EnableTexCoordsGen, EnableTextureUnit: Boolean);
7483 inherited Bind (EnableTextureUnit);
7485 if EnableTexCoordsGen then begin
7486 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, fGenMode);
7487 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, fGenMode);
7488 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, fGenMode);
7489 glEnable(GL_TEXTURE_GEN_S);
7490 glEnable(GL_TEXTURE_GEN_T);
7491 glEnable(GL_TEXTURE_GEN_R);
7496 procedure TglBitmapCubeMap.GenerateCubeMap(CubeTarget: Cardinal; TestTextureSize: Boolean);
7498 glFormat, glInternalFormat, glType: Cardinal;
7499 BuildWithGlu: Boolean;
7502 // Check Texture Size
7503 if (TestTextureSize) then begin
7504 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, @TexSize);
7506 if ((Height > TexSize) or (Width > TexSize)) then
7507 raise EglBitmapSizeToLargeException.Create('TglBitmapCubeMap.GenTexture - The size for the Cubemap is to large. It''s may be not conform with the Hardware.');
7509 if not ((IsPowerOfTwo (Height) and IsPowerOfTwo (Width)) or GL_VERSION_2_0 or GL_ARB_texture_non_power_of_two) then
7510 raise EglBitmapNonPowerOfTwoException.Create('TglBitmapCubeMap.GenTexture - Cubemaps dosn''t support non power of two texture.');
7514 if ID = 0 then begin
7516 SetupParameters(BuildWithGlu);
7519 SelectFormat(InternalFormat, glFormat, glInternalFormat, glType);
7521 UploadData (CubeTarget, glFormat, glInternalFormat, glType, BuildWithGlu);
7525 procedure TglBitmapCubeMap.GenTexture(TestTextureSize: Boolean);
7527 Assert(false, 'TglBitmapCubeMap.GenTexture - Don''t call GenTextures directly.');
7531 procedure TglBitmapCubeMap.Unbind(DisableTexCoordsGen,
7532 DisableTextureUnit: Boolean);
7534 inherited Unbind (DisableTextureUnit);
7536 if DisableTexCoordsGen then begin
7537 glDisable(GL_TEXTURE_GEN_S);
7538 glDisable(GL_TEXTURE_GEN_T);
7539 glDisable(GL_TEXTURE_GEN_R);
7544 { TglBitmapNormalMap }
7547 TVec = Array[0..2] of Single;
7548 TglBitmapNormalMapGetVectorFunc = procedure (var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
7550 PglBitmapNormalMapRec = ^TglBitmapNormalMapRec;
7551 TglBitmapNormalMapRec = record
7553 Func: TglBitmapNormalMapGetVectorFunc;
7557 procedure glBitmapNormalMapPosX(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
7560 Vec[1] := - (Position.Y + 0.5 - HalfSize);
7561 Vec[2] := - (Position.X + 0.5 - HalfSize);
7565 procedure glBitmapNormalMapNegX(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
7567 Vec[0] := - HalfSize;
7568 Vec[1] := - (Position.Y + 0.5 - HalfSize);
7569 Vec[2] := Position.X + 0.5 - HalfSize;
7573 procedure glBitmapNormalMapPosY(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
7575 Vec[0] := Position.X + 0.5 - HalfSize;
7577 Vec[2] := Position.Y + 0.5 - HalfSize;
7581 procedure glBitmapNormalMapNegY(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
7583 Vec[0] := Position.X + 0.5 - HalfSize;
7584 Vec[1] := - HalfSize;
7585 Vec[2] := - (Position.Y + 0.5 - HalfSize);
7589 procedure glBitmapNormalMapPosZ(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
7591 Vec[0] := Position.X + 0.5 - HalfSize;
7592 Vec[1] := - (Position.Y + 0.5 - HalfSize);
7597 procedure glBitmapNormalMapNegZ(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
7599 Vec[0] := - (Position.X + 0.5 - HalfSize);
7600 Vec[1] := - (Position.Y + 0.5 - HalfSize);
7601 Vec[2] := - HalfSize;
7605 procedure glBitmapNormalMapFunc(var FuncRec: TglBitmapFunctionRec);
7610 with FuncRec do begin
7611 with PglBitmapNormalMapRec (CustomData)^ do begin
7612 Func(Vec, Position, HalfSize);
7615 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
7616 if Len <> 0 then begin
7617 Vec[0] := Vec[0] * Len;
7618 Vec[1] := Vec[1] * Len;
7619 Vec[2] := Vec[2] * Len;
7622 // Scale Vector and AddVectro
7623 Vec[0] := Vec[0] * 0.5 + 0.5;
7624 Vec[1] := Vec[1] * 0.5 + 0.5;
7625 Vec[2] := Vec[2] * 0.5 + 0.5;
7629 Dest.Red := Round(Vec[0] * 255);
7630 Dest.Green := Round(Vec[1] * 255);
7631 Dest.Blue := Round(Vec[2] * 255);
7636 procedure TglBitmapNormalMap.AfterConstruction;
7640 fGenMode := GL_NORMAL_MAP;
7644 procedure TglBitmapNormalMap.GenerateNormalMap(Size: Integer;
7645 TestTextureSize: Boolean);
7647 Rec: TglBitmapNormalMapRec;
7648 SizeRec: TglBitmapPixelPosition;
7650 Rec.HalfSize := Size div 2;
7652 FreeDataAfterGenTexture := false;
7654 SizeRec.Fields := [ffX, ffY];
7659 Rec.Func := glBitmapNormalMapPosX;
7660 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
7661 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X, TestTextureSize);
7664 Rec.Func := glBitmapNormalMapNegX;
7665 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
7666 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, TestTextureSize);
7669 Rec.Func := glBitmapNormalMapPosY;
7670 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
7671 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, TestTextureSize);
7674 Rec.Func := glBitmapNormalMapNegY;
7675 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
7676 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, TestTextureSize);
7679 Rec.Func := glBitmapNormalMapPosZ;
7680 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
7681 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, TestTextureSize);
7684 Rec.Func := glBitmapNormalMapNegZ;
7685 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
7686 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, TestTextureSize);
7691 glBitmapSetDefaultFormat(tfEmpty);
7692 glBitmapSetDefaultMipmap(mmMipmap);
7693 glBitmapSetDefaultFilter(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
7694 glBitmapSetDefaultWrap (GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
7696 glBitmapSetDefaultFreeDataAfterGenTexture(true);
7697 glBitmapSetDefaultDeleteTextureOnFree (true);
7699 TFormatDescriptor.Init;
7702 TFormatDescriptor.Finalize;