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 TbmpBitfieldFormat = 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 TbmpColorTableEnty = packed record
1438 TbmpColorTable = array of TbmpColorTableEnty;
1439 TbmpColorTableFormat = class(TFormatDescriptor)
1441 fColorTable: TbmpColorTable;
1443 property PixelSize: Single read fPixelSize write fPixelSize;
1444 property ColorTable: TbmpColorTable read fColorTable write fColorTable;
1445 property Range: TglBitmapColorRec read fRange write fRange;
1446 property Shift: TShiftRec read fShift write fShift;
1447 property Format: TglBitmapFormat read fFormat write fFormat;
1449 procedure CreateColorTable;
1451 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1452 procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1453 destructor Destroy; override;
1457 LUMINANCE_WEIGHT_R = 0.30;
1458 LUMINANCE_WEIGHT_G = 0.59;
1459 LUMINANCE_WEIGHT_B = 0.11;
1461 ALPHA_WEIGHT_R = 0.30;
1462 ALPHA_WEIGHT_G = 0.59;
1463 ALPHA_WEIGHT_B = 0.11;
1465 DEPTH_WEIGHT_R = 0.333333333;
1466 DEPTH_WEIGHT_G = 0.333333333;
1467 DEPTH_WEIGHT_B = 0.333333333;
1469 UNSUPPORTED_FORMAT = 'the given format isn''t supported by this function.';
1471 FORMAT_DESCRIPTOR_CLASSES: array[TglBitmapFormat] of TFormatDescriptorClass = (
1484 TfdLuminance4Alpha4,
1485 TfdLuminance6Alpha2,
1486 TfdLuminance8Alpha8,
1487 TfdLuminance12Alpha4,
1488 TfdLuminance12Alpha12,
1489 TfdLuminance16Alpha16,
1530 FormatDescriptorCS: TCriticalSection;
1531 FormatDescriptors: array[TglBitmapFormat] of TFormatDescriptor;
1533 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1534 function glBitmapPosition(X, Y: Integer): TglBitmapPixelPosition;
1536 result.Fields := [];
1539 result.Fields := result.Fields + [ffX];
1541 result.Fields := result.Fields + [ffY];
1543 result.X := Max(0, X);
1544 result.Y := Max(0, Y);
1547 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1548 function glBitmapColorRec(const r, g, b, a: Cardinal): TglBitmapColorRec;
1556 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1557 function glBitmapShiftRec(const r, g, b, a: Byte): TShiftRec;
1565 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1566 function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes;
1568 result := [ftDDS, ftTGA];
1575 tfR3G3B2, tfLuminance8,
1578 tfRGB4, tfRGB5, tfR5G6B5, tfRGB5A1, tfRGBA4,
1579 tfBGR4, tfBGR5, tfB5G6R5, tfBGR5A1, tfBGRA4,
1585 tfRGB10, tfRGB10A2, tfRGBA8,
1586 tfBGR10, tfBGR10A2, tfBGRA8]) then
1587 result := result + [ftBMP];
1589 //TODO Supported File Formats!
1592 {$IFDEF GLB_SUPPORT_PNG_WRITE}
1594 tfAlpha4, tfAlpha8, tfAlpha12, tfAlpha16,
1595 tfLuminance4, tfLuminance8, tfLuminance12, tfLuminance16,
1596 tfuminance4Alpha4, tfLuminance6Alpha2, tfLuminance8Alpha8, tfLuminance12Alpha4, tfLuminance12Alpha12, tfLuminance16Alpha16,
1597 tfR3G3B2, tfRGB4, tfRGB5, tfRGB8, tfRGB10, tfRGB12, tfRGB16,
1598 tfRGBA2, tfRGBA4, tfRGB5A1, tfRGBA8, tfRGB10A2, tfRGBA12, tfRGBA16,
1599 tfDepth16, tfDepth24, tfDepth32]
1601 result := result + [ftPNG];
1604 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
1606 tfAlpha4, tfAlpha8, tfAlpha12, tfAlpha16,
1607 tfLuminance4, tfLuminance8, tfLuminance12, tfLuminance16,
1608 tfR3G3B2, tfRGB4, tfRGB5, tfRGB8, tfRGB10, tfRGB12, tfRGB16,
1609 tfDepth16, tfDepth24, tfDepth32]
1611 result := result + [ftJPEG];
1615 tfAlpha4, tfAlpha8, tfAlpha12, tfAlpha16,
1616 tfLuminance4, tfLuminance8, tfLuminance12, tfLuminance16,
1617 tfuminance4Alpha4, tfLuminance6Alpha2, tfLuminance8Alpha8, tfLuminance12Alpha4, tfLuminance12Alpha12, tfLuminance16Alpha16,
1618 tfR3G3B2, tfRGB4, tfRGB5, tfRGB8, tfRGB10, tfRGB12, tfRGB16,
1619 tfRGBA2, tfRGBA4, tfRGB5A1, tfRGBA8, tfRGB10A2, tfRGBA12, tfRGBA16,
1620 tfDepth16, tfDepth24, tfDepth32]
1622 result := result + [ftDDS, ftTGA, ftBMP];
1626 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1627 function IsPowerOfTwo(aNumber: Integer): Boolean;
1629 while (aNumber and 1) = 0 do
1630 aNumber := aNumber shr 1;
1631 result := aNumber = 1;
1634 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1635 function GetTopMostBit(aBitSet: UInt64): Integer;
1638 while aBitSet > 0 do begin
1640 aBitSet := aBitSet shr 1;
1644 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1645 function CountSetBits(aBitSet: UInt64): Integer;
1648 while aBitSet > 0 do begin
1649 if (aBitSet and 1) = 1 then
1651 aBitSet := aBitSet shr 1;
1655 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1656 function LuminanceWeight(const aPixel: TglBitmapPixelData): Cardinal;
1659 LUMINANCE_WEIGHT_R * aPixel.Data.r +
1660 LUMINANCE_WEIGHT_G * aPixel.Data.g +
1661 LUMINANCE_WEIGHT_B * aPixel.Data.b);
1664 function DepthWeight(const aPixel: TglBitmapPixelData): Cardinal;
1667 DEPTH_WEIGHT_R * aPixel.Data.r +
1668 DEPTH_WEIGHT_G * aPixel.Data.g +
1669 DEPTH_WEIGHT_B * aPixel.Data.b);
1672 //TODO check _ARB functions and constants
1675 {$IFNDEF GLB_NO_NATIVE_GL}
1676 procedure ReadOpenGLExtensions;
1682 MajorVersion, MinorVersion: Integer;
1685 procedure TrimVersionString(Buffer: AnsiString; var Major, Minor: Integer);
1692 Separator := Pos(AnsiString('.'), Buffer);
1694 if (Separator > 1) and (Separator < Length(Buffer)) and
1695 (Buffer[Separator - 1] in ['0'..'9']) and
1696 (Buffer[Separator + 1] in ['0'..'9']) then begin
1699 while (Separator > 0) and (Buffer[Separator] in ['0'..'9']) do
1702 Delete(Buffer, 1, Separator);
1703 Separator := Pos(AnsiString('.'), Buffer) + 1;
1705 while (Separator <= Length(Buffer)) and (AnsiChar(Buffer[Separator]) in ['0'..'9']) do
1708 Delete(Buffer, Separator, 255);
1709 Separator := Pos(AnsiString('.'), Buffer);
1711 Major := StrToInt(Copy(String(Buffer), 1, Separator - 1));
1712 Minor := StrToInt(Copy(String(Buffer), Separator + 1, 1));
1717 function CheckExtension(const Extension: AnsiString): Boolean;
1721 ExtPos := Pos(Extension, Buffer);
1722 result := ExtPos > 0;
1725 result := ((ExtPos + Length(Extension) - 1) = Length(Buffer)) or not (Buffer[ExtPos + Length(Extension)] in ['_', 'A'..'Z', 'a'..'z']);
1729 function glLoad (aFunc: pAnsiChar): pointer;
1732 result := glXGetProcAddress(aFunc);
1734 result := wglGetProcAddress(aFunc);
1741 Context := wglGetCurrentContext;
1743 if Context <> gLastContext then begin
1744 gLastContext := Context;
1748 Buffer := glGetString(GL_VERSION);
1749 TrimVersionString(Buffer, MajorVersion, MinorVersion);
1751 GL_VERSION_1_2 := false;
1752 GL_VERSION_1_3 := false;
1753 GL_VERSION_1_4 := false;
1754 GL_VERSION_2_0 := false;
1756 if MajorVersion = 1 then begin
1757 if MinorVersion >= 1 then begin
1758 if MinorVersion >= 2 then
1759 GL_VERSION_1_2 := true;
1761 if MinorVersion >= 3 then
1762 GL_VERSION_1_3 := true;
1764 if MinorVersion >= 4 then
1765 GL_VERSION_1_4 := true;
1769 if MajorVersion >= 2 then begin
1770 GL_VERSION_1_2 := true;
1771 GL_VERSION_1_3 := true;
1772 GL_VERSION_1_4 := true;
1773 GL_VERSION_2_0 := true;
1777 Buffer := glGetString(GL_EXTENSIONS);
1778 GL_ARB_texture_border_clamp := CheckExtension('GL_ARB_texture_border_clamp');
1779 GL_ARB_texture_cube_map := CheckExtension('GL_ARB_texture_cube_map');
1780 GL_ARB_texture_compression := CheckExtension('GL_ARB_texture_compression');
1781 GL_ARB_texture_non_power_of_two := CheckExtension('GL_ARB_texture_non_power_of_two');
1782 GL_ARB_texture_rectangle := CheckExtension('GL_ARB_texture_rectangle');
1783 GL_ARB_texture_mirrored_repeat := CheckExtension('GL_ARB_texture_mirrored_repeat');
1784 GL_EXT_bgra := CheckExtension('GL_EXT_bgra');
1785 GL_EXT_texture_edge_clamp := CheckExtension('GL_EXT_texture_edge_clamp');
1786 GL_EXT_texture_cube_map := CheckExtension('GL_EXT_texture_cube_map');
1787 GL_EXT_texture_compression_s3tc := CheckExtension('GL_EXT_texture_compression_s3tc');
1788 GL_EXT_texture_filter_anisotropic := CheckExtension('GL_EXT_texture_filter_anisotropic');
1789 GL_EXT_texture_rectangle := CheckExtension('GL_EXT_texture_rectangle');
1790 GL_NV_texture_rectangle := CheckExtension('GL_NV_texture_rectangle');
1791 GL_IBM_texture_mirrored_repeat := CheckExtension('GL_IBM_texture_mirrored_repeat');
1792 GL_SGIS_generate_mipmap := CheckExtension('GL_SGIS_generate_mipmap');
1795 if GL_VERSION_1_3 then begin
1797 glCompressedTexImage1D := glLoad('glCompressedTexImage1D');
1798 glCompressedTexImage2D := glLoad('glCompressedTexImage2D');
1799 glGetCompressedTexImage := glLoad('glGetCompressedTexImage');
1803 // Try loading Extension
1804 glCompressedTexImage1D := glLoad('glCompressedTexImage1DARB');
1805 glCompressedTexImage2D := glLoad('glCompressedTexImage2DARB');
1806 glGetCompressedTexImage := glLoad('glGetCompressedTexImageARB');
1817 function CreateGrayPalette: HPALETTE;
1822 GetMem(Pal, SizeOf(TLogPalette) + (SizeOf(TPaletteEntry) * 256));
1824 Pal.palVersion := $300;
1825 Pal.palNumEntries := 256;
1828 {$DEFINE GLB_TEMPRANGECHECK}
1832 for Idx := 0 to 256 - 1 do begin
1833 Pal.palPalEntry[Idx].peRed := Idx;
1834 Pal.palPalEntry[Idx].peGreen := Idx;
1835 Pal.palPalEntry[Idx].peBlue := Idx;
1836 Pal.palPalEntry[Idx].peFlags := 0;
1839 {$IFDEF GLB_TEMPRANGECHECK}
1840 {$UNDEF GLB_TEMPRANGECHECK}
1844 result := CreatePalette(Pal^);
1851 (* TODO GLB_SDL_IMAGE
1852 {$IFDEF GLB_SDL_IMAGE}
1853 function glBitmapRWseek(context: PSDL_RWops; offset: Integer; whence: Integer): Integer; cdecl;
1855 result := TStream(context^.unknown.data1).Seek(offset, whence);
1858 function glBitmapRWread(context: PSDL_RWops; Ptr: Pointer; size: Integer; maxnum : Integer): Integer; cdecl;
1860 result := TStream(context^.unknown.data1).Read(Ptr^, size * maxnum);
1863 function glBitmapRWwrite(context: PSDL_RWops; Ptr: Pointer; size: Integer; num: Integer): Integer; cdecl;
1865 result := TStream(context^.unknown.data1).Write(Ptr^, size * num);
1868 function glBitmapRWclose(context: PSDL_RWops): Integer; cdecl;
1873 function glBitmapCreateRWops(Stream: TStream): PSDL_RWops;
1875 result := SDL_AllocRW;
1877 if result = nil then
1878 raise EglBitmapException.Create('glBitmapCreateRWops - SDL_AllocRW failed.');
1880 result^.seek := glBitmapRWseek;
1881 result^.read := glBitmapRWread;
1882 result^.write := glBitmapRWwrite;
1883 result^.close := glBitmapRWclose;
1884 result^.unknown.data1 := Stream;
1890 function LoadTexture(Filename: String; var Texture: Cardinal{$IFDEF GLB_DELPHI}; LoadFromRes : Boolean; Instance: Cardinal{$ENDIF}): Boolean;
1892 glBitmap: TglBitmap2D;
1898 if Instance = 0 then
1899 Instance := HInstance;
1901 if (LoadFromRes) then
1902 glBitmap := TglBitmap2D.CreateFromResourceName(Instance, FileName)
1905 glBitmap := TglBitmap2D.Create(FileName);
1908 glBitmap.DeleteTextureOnFree := false;
1909 glBitmap.FreeDataAfterGenTexture := false;
1910 glBitmap.GenTexture(true);
1911 if (glBitmap.ID > 0) then begin
1912 Texture := glBitmap.ID;
1920 function LoadCubeMap(PositiveX, NegativeX, PositiveY, NegativeY, PositiveZ, NegativeZ: String; var Texture: Cardinal{$IFDEF GLB_DELPHI}; LoadFromRes : Boolean; Instance: Cardinal{$ENDIF}): Boolean;
1922 CM: TglBitmapCubeMap;
1927 if Instance = 0 then
1928 Instance := HInstance;
1931 CM := TglBitmapCubeMap.Create;
1933 CM.DeleteTextureOnFree := false;
1937 if (LoadFromRes) then
1938 CM.LoadFromResource(Instance, PositiveX)
1941 CM.LoadFromFile(PositiveX);
1942 CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X);
1945 if (LoadFromRes) then
1946 CM.LoadFromResource(Instance, NegativeX)
1949 CM.LoadFromFile(NegativeX);
1950 CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_X);
1953 if (LoadFromRes) then
1954 CM.LoadFromResource(Instance, PositiveY)
1957 CM.LoadFromFile(PositiveY);
1958 CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Y);
1961 if (LoadFromRes) then
1962 CM.LoadFromResource(Instance, NegativeY)
1965 CM.LoadFromFile(NegativeY);
1966 CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);
1969 if (LoadFromRes) then
1970 CM.LoadFromResource(Instance, PositiveZ)
1973 CM.LoadFromFile(PositiveZ);
1974 CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Z);
1977 if (LoadFromRes) then
1978 CM.LoadFromResource(Instance, NegativeZ)
1981 CM.LoadFromFile(NegativeZ);
1982 CM.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
1991 function LoadNormalMap(Size: Integer; var Texture: Cardinal): Boolean;
1993 NM: TglBitmapNormalMap;
1997 NM := TglBitmapNormalMap.Create;
1999 NM.DeleteTextureOnFree := false;
2000 NM.GenerateNormalMap(Size);
2010 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2011 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
2013 glBitmapDefaultDeleteTextureOnFree := aDeleteTextureOnFree;
2016 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2017 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
2019 glBitmapDefaultFreeDataAfterGenTextures := aFreeData;
2022 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2023 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
2025 glBitmapDefaultMipmap := aValue;
2028 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2029 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
2031 glBitmapDefaultFormat := aFormat;
2034 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2035 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
2037 glBitmapDefaultFilterMin := aMin;
2038 glBitmapDefaultFilterMag := aMag;
2041 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2042 procedure glBitmapSetDefaultWrap(const S: Cardinal = GL_CLAMP_TO_EDGE; const T: Cardinal = GL_CLAMP_TO_EDGE; const R: Cardinal = GL_CLAMP_TO_EDGE);
2044 glBitmapDefaultWrapS := S;
2045 glBitmapDefaultWrapT := T;
2046 glBitmapDefaultWrapR := R;
2049 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2050 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
2052 result := glBitmapDefaultDeleteTextureOnFree;
2055 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2056 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
2058 result := glBitmapDefaultFreeDataAfterGenTextures;
2061 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2062 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
2064 result := glBitmapDefaultMipmap;
2067 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2068 function glBitmapGetDefaultFormat: TglBitmapFormat;
2070 result := glBitmapDefaultFormat;
2073 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2074 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
2076 aMin := glBitmapDefaultFilterMin;
2077 aMag := glBitmapDefaultFilterMag;
2080 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2081 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
2083 S := glBitmapDefaultWrapS;
2084 T := glBitmapDefaultWrapT;
2085 R := glBitmapDefaultWrapR;
2088 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2089 //TglBitmapFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2090 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2091 function TFormatDescriptor.GetRedMask: UInt64;
2093 result := fRange.r shl fShift.r;
2096 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2097 function TFormatDescriptor.GetGreenMask: UInt64;
2099 result := fRange.g shl fShift.g;
2102 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2103 function TFormatDescriptor.GetBlueMask: UInt64;
2105 result := fRange.b shl fShift.b;
2108 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2109 function TFormatDescriptor.GetAlphaMask: UInt64;
2111 result := fRange.a shl fShift.a;
2114 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2115 function TFormatDescriptor.GetComponents: Integer;
2121 if (fRange.arr[i] > 0) then
2125 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2126 function TFormatDescriptor.GetSize(const aSize: TglBitmapPixelPosition): Integer;
2130 if (ffX in aSize.Fields) or (ffY in aSize.Fields) then begin
2131 w := Max(1, aSize.X);
2132 h := Max(1, aSize.Y);
2133 result := GetSize(w, h);
2138 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2139 function TFormatDescriptor.GetSize(const aWidth, aHeight: Integer): Integer;
2142 if (aWidth <= 0) or (aHeight <= 0) then
2144 result := Ceil(aWidth * aHeight * fPixelSize);
2147 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2148 function TFormatDescriptor.CreateMappingData: Pointer;
2153 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2154 procedure TFormatDescriptor.FreeMappingData(var aMappingData: Pointer);
2159 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2160 function TFormatDescriptor.IsEmpty: Boolean;
2162 result := (fFormat = tfEmpty);
2165 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2166 function TFormatDescriptor.HasAlpha: Boolean;
2168 result := (fRange.a > 0);
2171 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2172 function TFormatDescriptor.MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: UInt64): Boolean;
2176 if (aRedMask = 0) and (aGreenMask = 0) and (aBlueMask = 0) and (aAlphaMask = 0) then
2177 raise EglBitmapException.Create('FormatCheckFormat - All Masks are 0');
2179 if (aRedMask <> RedMask) then
2181 if (aGreenMask <> GreenMask) then
2183 if (aBlueMask <> BlueMask) then
2185 if (aAlphaMask <> AlphaMask) then
2190 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2191 procedure TFormatDescriptor.PreparePixel(var aPixel: TglBitmapPixelData);
2193 FillChar(aPixel, SizeOf(aPixel), 0);
2194 aPixel.Data := fRange;
2195 aPixel.Range := fRange;
2196 aPixel.Format := fFormat;
2199 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2200 constructor TFormatDescriptor.Create;
2205 fWithAlpha := tfEmpty;
2206 fWithoutAlpha := tfEmpty;
2210 fglInternalFormat := 0;
2213 FillChar(fRange, 0, SizeOf(fRange));
2214 FillChar(fShift, 0, SizeOf(fShift));
2217 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2218 //TfdAlpha_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2219 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2220 procedure TfdAlpha_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2222 aData^ := aPixel.Data.a;
2226 procedure TfdAlpha_UB1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2231 aPixel.Data.a := aData^;
2235 constructor TfdAlpha_UB1.Create;
2240 fglFormat := GL_ALPHA;
2241 fglDataFormat := GL_UNSIGNED_BYTE;
2244 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2245 //TfdLuminance_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2246 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2247 procedure TfdLuminance_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2249 aData^ := LuminanceWeight(aPixel);
2253 procedure TfdLuminance_UB1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2255 aPixel.Data.r := aData^;
2256 aPixel.Data.g := aData^;
2257 aPixel.Data.b := aData^;
2262 constructor TfdLuminance_UB1.Create;
2269 fglFormat := GL_LUMINANCE;
2270 fglDataFormat := GL_UNSIGNED_BYTE;
2273 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2274 //TfdUniversal_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2275 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2276 procedure TfdUniversal_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2282 if (fRange.arr[i] > 0) then
2283 aData^ := aData^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
2287 procedure TfdUniversal_UB1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2292 aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and fRange.arr[i];
2296 constructor TfdUniversal_UB1.Create;
2302 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2303 //TfdLuminanceAlpha_UB2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2304 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2305 procedure TfdLuminanceAlpha_UB2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2307 inherited Map(aPixel, aData, aMapData);
2308 aData^ := aPixel.Data.a;
2312 procedure TfdLuminanceAlpha_UB2.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2314 inherited Unmap(aData, aPixel, aMapData);
2315 aPixel.Data.a := aData^;
2319 constructor TfdLuminanceAlpha_UB2.Create;
2325 fglFormat := GL_LUMINANCE_ALPHA;
2326 fglDataFormat := GL_UNSIGNED_BYTE;
2329 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2330 //TfdRGB_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2331 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2332 procedure TfdRGB_UB3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2334 aData^ := aPixel.Data.r;
2336 aData^ := aPixel.Data.g;
2338 aData^ := aPixel.Data.b;
2342 procedure TfdRGB_UB3.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2344 aPixel.Data.r := aData^;
2346 aPixel.Data.g := aData^;
2348 aPixel.Data.b := aData^;
2353 constructor TfdRGB_UB3.Create;
2363 fglFormat := GL_RGB;
2364 fglDataFormat := GL_UNSIGNED_BYTE;
2367 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2368 //TfdBGR_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2369 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2370 procedure TfdBGR_UB3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2372 aData^ := aPixel.Data.b;
2374 aData^ := aPixel.Data.g;
2376 aData^ := aPixel.Data.r;
2380 procedure TfdBGR_UB3.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2382 aPixel.Data.b := aData^;
2384 aPixel.Data.g := aData^;
2386 aPixel.Data.r := aData^;
2391 constructor TfdBGR_UB3.Create;
2400 fglFormat := GL_BGR;
2401 fglDataFormat := GL_UNSIGNED_BYTE;
2404 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2405 //TdfRGBA_UB4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2406 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2407 procedure TfdRGBA_UB4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2409 inherited Map(aPixel, aData, aMapData);
2410 aData^ := aPixel.Data.a;
2414 procedure TfdRGBA_UB4.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2416 inherited Unmap(aData, aPixel, aMapData);
2417 aPixel.Data.a := aData^;
2421 constructor TfdRGBA_UB4.Create;
2427 fglFormat := GL_RGBA;
2428 fglDataFormat := GL_UNSIGNED_BYTE;
2431 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2432 //TfdBGRA_UB4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2433 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2434 procedure TfdBGRA_UB4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2436 inherited Map(aPixel, aData, aMapData);
2437 aData^ := aPixel.Data.a;
2441 procedure TfdBGRA_UB4.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2443 inherited Unmap(aData, aPixel, aMapData);
2444 aPixel.Data.a := aData^;
2448 constructor TfdBGRA_UB4.Create;
2454 fglFormat := GL_BGRA;
2455 fglDataFormat := GL_UNSIGNED_BYTE;
2458 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2459 //TfdAlpha_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2460 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2461 procedure TfdAlpha_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2463 PWord(aData)^ := aPixel.Data.a;
2467 procedure TfdAlpha_US1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2472 aPixel.Data.a := PWord(aData)^;
2476 constructor TfdAlpha_US1.Create;
2481 fglFormat := GL_ALPHA;
2482 fglDataFormat := GL_UNSIGNED_SHORT;
2485 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2486 //TfdLuminance_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2487 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2488 procedure TfdLuminance_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2490 PWord(aData)^ := LuminanceWeight(aPixel);
2494 procedure TfdLuminance_US1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2496 aPixel.Data.r := PWord(aData)^;
2497 aPixel.Data.g := PWord(aData)^;
2498 aPixel.Data.b := PWord(aData)^;
2503 constructor TfdLuminance_US1.Create;
2510 fglFormat := GL_LUMINANCE;
2511 fglDataFormat := GL_UNSIGNED_SHORT;
2514 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2515 //TfdUniversal_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2516 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2517 procedure TfdUniversal_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2523 if (fRange.arr[i] > 0) then
2524 PWord(aData)^ := PWord(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
2528 procedure TfdUniversal_US1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2533 aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and fRange.arr[i];
2537 constructor TfdUniversal_US1.Create;
2543 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2544 //TfdDepth_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2545 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2546 procedure TfdDepth_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2548 PWord(aData)^ := DepthWeight(aPixel);
2552 procedure TfdDepth_US1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2554 aPixel.Data.r := PWord(aData)^;
2555 aPixel.Data.g := PWord(aData)^;
2556 aPixel.Data.b := PWord(aData)^;
2561 constructor TfdDepth_US1.Create;
2568 fglFormat := GL_DEPTH_COMPONENT;
2569 fglDataFormat := GL_UNSIGNED_SHORT;
2572 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2573 //TfdLuminanceAlpha_US2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2574 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2575 procedure TfdLuminanceAlpha_US2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2577 inherited Map(aPixel, aData, aMapData);
2578 PWord(aData)^ := aPixel.Data.a;
2582 procedure TfdLuminanceAlpha_US2.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2584 inherited Unmap(aData, aPixel, aMapData);
2585 aPixel.Data.a := PWord(aData)^;
2589 constructor TfdLuminanceAlpha_US2.Create;
2595 fglFormat := GL_LUMINANCE_ALPHA;
2596 fglDataFormat := GL_UNSIGNED_SHORT;
2599 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2600 //TfdRGB_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2601 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2602 procedure TfdRGB_US3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2604 PWord(aData)^ := aPixel.Data.r;
2606 PWord(aData)^ := aPixel.Data.g;
2608 PWord(aData)^ := aPixel.Data.b;
2612 procedure TfdRGB_US3.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2614 aPixel.Data.r := PWord(aData)^;
2616 aPixel.Data.g := PWord(aData)^;
2618 aPixel.Data.b := PWord(aData)^;
2623 constructor TfdRGB_US3.Create;
2633 fglFormat := GL_RGB;
2634 fglDataFormat := GL_UNSIGNED_SHORT;
2637 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2638 //TfdBGR_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2639 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2640 procedure TfdBGR_US3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2642 PWord(aData)^ := aPixel.Data.b;
2644 PWord(aData)^ := aPixel.Data.g;
2646 PWord(aData)^ := aPixel.Data.r;
2650 procedure TfdBGR_US3.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2652 aPixel.Data.b := PWord(aData)^;
2654 aPixel.Data.g := PWord(aData)^;
2656 aPixel.Data.r := PWord(aData)^;
2661 constructor TfdBGR_US3.Create;
2671 fglFormat := GL_BGR;
2672 fglDataFormat := GL_UNSIGNED_SHORT;
2675 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2676 //TfdRGBA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2677 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2678 procedure TfdRGBA_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2680 inherited Map(aPixel, aData, aMapData);
2681 PWord(aData)^ := aPixel.Data.a;
2685 procedure TfdRGBA_US4.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2687 inherited Unmap(aData, aPixel, aMapData);
2688 aPixel.Data.a := PWord(aData)^;
2692 constructor TfdRGBA_US4.Create;
2698 fglFormat := GL_RGBA;
2699 fglDataFormat := GL_UNSIGNED_SHORT;
2702 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2703 //TfdBGRA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2704 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2705 procedure TfdBGRA_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2707 inherited Map(aPixel, aData, aMapData);
2708 PWord(aData)^ := aPixel.Data.a;
2712 procedure TfdBGRA_US4.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2714 inherited Unmap(aData, aPixel, aMapData);
2715 aPixel.Data.a := PWord(aData)^;
2719 constructor TfdBGRA_US4.Create;
2725 fglFormat := GL_BGRA;
2726 fglDataFormat := GL_UNSIGNED_SHORT;
2729 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2730 //TfdUniversal_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2731 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2732 procedure TfdUniversal_UI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2736 PCardinal(aData)^ := 0;
2738 if (fRange.arr[i] > 0) then
2739 PCardinal(aData)^ := PCardinal(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
2743 procedure TfdUniversal_UI1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2748 aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and fRange.arr[i];
2752 constructor TfdUniversal_UI1.Create;
2758 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2759 //TfdDepth_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2760 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2761 procedure TfdDepth_UI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2763 PCardinal(aData)^ := DepthWeight(aPixel);
2767 procedure TfdDepth_UI1.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
2769 aPixel.Data.r := PCardinal(aData)^;
2770 aPixel.Data.g := PCardinal(aData)^;
2771 aPixel.Data.b := PCardinal(aData)^;
2776 constructor TfdDepth_UI1.Create;
2780 fRange.r := $FFFFFFFF;
2781 fRange.g := $FFFFFFFF;
2782 fRange.b := $FFFFFFFF;
2783 fglFormat := GL_DEPTH_COMPONENT;
2784 fglDataFormat := GL_UNSIGNED_INT;
2787 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2788 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2789 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2790 constructor TfdAlpha4.Create;
2793 fFormat := tfAlpha4;
2794 fWithAlpha := tfAlpha4;
2795 fglInternalFormat := GL_ALPHA4;
2798 constructor TfdAlpha8.Create;
2801 fFormat := tfAlpha8;
2802 fWithAlpha := tfAlpha8;
2803 fglInternalFormat := GL_ALPHA8;
2806 constructor TfdAlpha12.Create;
2809 fFormat := tfAlpha12;
2810 fWithAlpha := tfAlpha12;
2811 fglInternalFormat := GL_ALPHA12;
2814 constructor TfdAlpha16.Create;
2817 fFormat := tfAlpha16;
2818 fWithAlpha := tfAlpha16;
2819 fglInternalFormat := GL_ALPHA16;
2822 constructor TfdLuminance4.Create;
2825 fFormat := tfLuminance4;
2826 fWithAlpha := tfLuminance4Alpha4;
2827 fWithoutAlpha := tfLuminance4;
2828 fglInternalFormat := GL_LUMINANCE4;
2831 constructor TfdLuminance8.Create;
2834 fFormat := tfLuminance8;
2835 fWithAlpha := tfLuminance8Alpha8;
2836 fWithoutAlpha := tfLuminance8;
2837 fglInternalFormat := GL_LUMINANCE8;
2840 constructor TfdLuminance12.Create;
2843 fFormat := tfLuminance12;
2844 fWithAlpha := tfLuminance12Alpha12;
2845 fWithoutAlpha := tfLuminance12;
2846 fglInternalFormat := GL_LUMINANCE12;
2849 constructor TfdLuminance16.Create;
2852 fFormat := tfLuminance16;
2853 fWithAlpha := tfLuminance16Alpha16;
2854 fWithoutAlpha := tfLuminance16;
2855 fglInternalFormat := GL_LUMINANCE16;
2858 constructor TfdLuminance4Alpha4.Create;
2861 fFormat := tfLuminance4Alpha4;
2862 fWithAlpha := tfLuminance4Alpha4;
2863 fWithoutAlpha := tfLuminance4;
2864 fglInternalFormat := GL_LUMINANCE4_ALPHA4;
2867 constructor TfdLuminance6Alpha2.Create;
2870 fFormat := tfLuminance6Alpha2;
2871 fWithAlpha := tfLuminance6Alpha2;
2872 fWithoutAlpha := tfLuminance8;
2873 fglInternalFormat := GL_LUMINANCE6_ALPHA2;
2876 constructor TfdLuminance8Alpha8.Create;
2879 fFormat := tfLuminance8Alpha8;
2880 fWithAlpha := tfLuminance8Alpha8;
2881 fWithoutAlpha := tfLuminance8;
2882 fglInternalFormat := GL_LUMINANCE8_ALPHA8;
2885 constructor TfdLuminance12Alpha4.Create;
2888 fFormat := tfLuminance12Alpha4;
2889 fWithAlpha := tfLuminance12Alpha4;
2890 fWithoutAlpha := tfLuminance12;
2891 fglInternalFormat := GL_LUMINANCE12_ALPHA4;
2894 constructor TfdLuminance12Alpha12.Create;
2897 fFormat := tfLuminance12Alpha12;
2898 fWithAlpha := tfLuminance12Alpha12;
2899 fWithoutAlpha := tfLuminance12;
2900 fglInternalFormat := GL_LUMINANCE12_ALPHA12;
2903 constructor TfdLuminance16Alpha16.Create;
2906 fFormat := tfLuminance16Alpha16;
2907 fWithAlpha := tfLuminance16Alpha16;
2908 fWithoutAlpha := tfLuminance16;
2909 fglInternalFormat := GL_LUMINANCE16_ALPHA16;
2912 constructor TfdR3G3B2.Create;
2915 fFormat := tfR3G3B2;
2916 fWithAlpha := tfRGBA2;
2917 fWithoutAlpha := tfR3G3B2;
2924 fglFormat := GL_RGB;
2925 fglInternalFormat := GL_R3_G3_B2;
2926 fglDataFormat := GL_UNSIGNED_BYTE_2_3_3_REV;
2929 constructor TfdRGB4.Create;
2933 fWithAlpha := tfRGBA4;
2934 fWithoutAlpha := tfRGB4;
2941 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
2942 fglInternalFormat := GL_RGB4;
2943 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
2946 constructor TfdR5G6B5.Create;
2949 fFormat := tfR5G6B5;
2950 fWithAlpha := tfRGBA4;
2951 fWithoutAlpha := tfR5G6B5;
2958 fglFormat := GL_RGB;
2959 fglInternalFormat := GL_RGB565;
2960 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5_REV;
2963 constructor TfdRGB5.Create;
2967 fWithAlpha := tfRGB5A1;
2968 fWithoutAlpha := tfRGB5;
2975 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
2976 fglInternalFormat := GL_RGB5;
2977 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
2980 constructor TfdRGB8.Create;
2984 fWithAlpha := tfRGBA8;
2985 fWithoutAlpha := tfRGB8;
2986 fglInternalFormat := GL_RGB8;
2989 constructor TfdRGB10.Create;
2993 fWithAlpha := tfRGB10A2;
2994 fWithoutAlpha := tfRGB10;
3001 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3002 fglInternalFormat := GL_RGB10;
3003 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3006 constructor TfdRGB12.Create;
3010 fWithAlpha := tfRGBA12;
3011 fWithoutAlpha := tfRGB12;
3012 fglInternalFormat := GL_RGB12;
3015 constructor TfdRGB16.Create;
3019 fWithAlpha := tfRGBA16;
3020 fWithoutAlpha := tfRGB16;
3021 fglInternalFormat := GL_RGB16;
3024 constructor TfdRGBA2.Create;
3028 fWithAlpha := tfRGBA2;
3029 fWithoutAlpha := tfR3G3B2;
3030 fglInternalFormat := GL_RGBA2;
3033 constructor TfdRGBA4.Create;
3037 fWithAlpha := tfRGBA4;
3038 fWithoutAlpha := tfRGB4;
3047 fglFormat := GL_RGBA;
3048 fglInternalFormat := GL_RGBA4;
3049 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3052 constructor TfdRGB5A1.Create;
3055 fFormat := tfRGB5A1;
3056 fWithAlpha := tfRGB5A1;
3057 fWithoutAlpha := tfRGB5;
3066 fglFormat := GL_RGBA;
3067 fglInternalFormat := GL_RGB5_A1;
3068 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3071 constructor TfdRGBA8.Create;
3075 fWithAlpha := tfRGBA8;
3076 fWithoutAlpha := tfRGB8;
3077 fglInternalFormat := GL_RGBA8;
3080 constructor TfdRGB10A2.Create;
3083 fFormat := tfRGB10A2;
3084 fWithAlpha := tfRGB10A2;
3085 fWithoutAlpha := tfRGB10;
3094 fglFormat := GL_RGBA;
3095 fglInternalFormat := GL_RGB10_A2;
3096 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3099 constructor TfdRGBA12.Create;
3102 fFormat := tfRGBA12;
3103 fWithAlpha := tfRGBA12;
3104 fWithoutAlpha := tfRGB12;
3105 fglInternalFormat := GL_RGBA12;
3108 constructor TfdRGBA16.Create;
3111 fFormat := tfRGBA16;
3112 fWithAlpha := tfRGBA16;
3113 fWithoutAlpha := tfRGB16;
3114 fglInternalFormat := GL_RGBA16;
3117 constructor TfdBGR4.Create;
3122 fWithAlpha := tfBGRA4;
3123 fWithoutAlpha := tfBGR4;
3132 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3133 fglInternalFormat := GL_RGB4;
3134 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3137 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3138 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3139 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3140 constructor TfdB5G6R5.Create;
3143 fFormat := tfB5G6R5;
3144 fWithAlpha := tfBGRA4;
3145 fWithoutAlpha := tfB5G6R5;
3152 fglFormat := GL_RGB; //B5G6R5 is only possible as R5G6B5 -> use reverted dataformat
3153 fglInternalFormat := GL_RGB8;
3154 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5;
3157 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3158 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3159 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3160 constructor TfdBGR5.Create;
3165 fWithAlpha := tfBGR5A1;
3166 fWithoutAlpha := tfBGR5;
3175 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3176 fglInternalFormat := GL_RGB5;
3177 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3180 constructor TfdBGR8.Create;
3184 fWithAlpha := tfBGRA8;
3185 fWithoutAlpha := tfBGR8;
3186 fglInternalFormat := GL_RGB8;
3189 constructor TfdBGR10.Create;
3193 fWithAlpha := tfBGR10A2;
3194 fWithoutAlpha := tfBGR10;
3203 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3204 fglInternalFormat := GL_RGB10;
3205 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3208 constructor TfdBGR12.Create;
3212 fWithAlpha := tfBGRA12;
3213 fWithoutAlpha := tfBGR12;
3214 fglInternalFormat := GL_RGB12;
3217 constructor TfdBGR16.Create;
3221 fWithAlpha := tfBGRA16;
3222 fWithoutAlpha := tfBGR16;
3223 fglInternalFormat := GL_RGB16;
3226 constructor TfdBGRA2.Create;
3230 fWithAlpha := tfBGRA4;
3231 fWithoutAlpha := tfBGR4;
3232 fglInternalFormat := GL_RGBA2;
3235 constructor TfdBGRA4.Create;
3239 fWithAlpha := tfBGRA4;
3240 fWithoutAlpha := tfBGR4;
3249 fglFormat := GL_BGRA;
3250 fglInternalFormat := GL_RGBA4;
3251 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3254 constructor TfdBGR5A1.Create;
3257 fFormat := tfBGR5A1;
3258 fWithAlpha := tfBGR5A1;
3259 fWithoutAlpha := tfBGR5;
3268 fglFormat := GL_BGRA;
3269 fglInternalFormat := GL_RGB5_A1;
3270 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3273 constructor TfdBGRA8.Create;
3277 fWithAlpha := tfBGRA8;
3278 fWithoutAlpha := tfBGR8;
3279 fglInternalFormat := GL_RGBA8;
3282 constructor TfdBGR10A2.Create;
3285 fFormat := tfBGR10A2;
3286 fWithAlpha := tfBGR10A2;
3287 fWithoutAlpha := tfBGR10;
3296 fglFormat := GL_BGRA;
3297 fglInternalFormat := GL_RGB10_A2;
3298 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3301 constructor TfdBGRA12.Create;
3304 fFormat := tfBGRA12;
3305 fWithAlpha := tfBGRA12;
3306 fWithoutAlpha := tfBGR12;
3307 fglInternalFormat := GL_RGBA12;
3310 constructor TfdBGRA16.Create;
3313 fFormat := tfBGRA16;
3314 fWithAlpha := tfBGRA16;
3315 fWithoutAlpha := tfBGR16;
3316 fglInternalFormat := GL_RGBA16;
3319 constructor TfdDepth16.Create;
3322 fFormat := tfDepth16;
3323 fWithAlpha := tfEmpty;
3324 fWithoutAlpha := tfDepth16;
3325 fglInternalFormat := GL_DEPTH_COMPONENT16;
3328 constructor TfdDepth24.Create;
3331 fFormat := tfDepth24;
3332 fWithAlpha := tfEmpty;
3333 fWithoutAlpha := tfDepth24;
3334 fglInternalFormat := GL_DEPTH_COMPONENT24;
3337 constructor TfdDepth32.Create;
3340 fFormat := tfDepth32;
3341 fWithAlpha := tfEmpty;
3342 fWithoutAlpha := tfDepth32;
3343 fglInternalFormat := GL_DEPTH_COMPONENT32;
3346 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3347 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3348 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3349 class procedure TFormatDescriptor.Init;
3351 if not Assigned(FormatDescriptorCS) then
3352 FormatDescriptorCS := TCriticalSection.Create;
3355 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3356 class function TFormatDescriptor.Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
3358 FormatDescriptorCS.Enter;
3360 result := FormatDescriptors[aFormat];
3361 if not Assigned(result) then begin
3362 result := FORMAT_DESCRIPTOR_CLASSES[aFormat].Create;
3363 FormatDescriptors[aFormat] := result;
3366 FormatDescriptorCS.Leave;
3370 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3371 class function TFormatDescriptor.GetWithAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
3373 result := Get(Get(aFormat).WithAlpha);
3376 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3377 class procedure TFormatDescriptor.Clear;
3381 FormatDescriptorCS.Enter;
3383 for f := low(FormatDescriptors) to high(FormatDescriptors) do
3384 FreeAndNil(FormatDescriptors[f]);
3386 FormatDescriptorCS.Leave;
3390 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3391 class procedure TFormatDescriptor.Finalize;
3394 FreeAndNil(FormatDescriptorCS);
3397 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3398 //TBitfieldFormat/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3399 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3400 procedure TbmpBitfieldFormat.SetRedMask(const aValue: UInt64);
3402 Update(aValue, fRange.r, fShift.r);
3405 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3406 procedure TbmpBitfieldFormat.SetGreenMask(const aValue: UInt64);
3408 Update(aValue, fRange.g, fShift.g);
3411 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3412 procedure TbmpBitfieldFormat.SetBlueMask(const aValue: UInt64);
3414 Update(aValue, fRange.b, fShift.b);
3417 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3418 procedure TbmpBitfieldFormat.SetAlphaMask(const aValue: UInt64);
3420 Update(aValue, fRange.a, fShift.a);
3423 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3424 procedure TbmpBitfieldFormat.Update(aMask: UInt64; out aRange: Cardinal; out
3431 while (aMask > 0) and ((aMask and 1) = 0) do begin
3433 aMask := aMask shr 1;
3436 while (aMask > 0) do begin
3437 aRange := aRange shl 1;
3438 aMask := aMask shr 1;
3442 fPixelSize := Round(GetTopMostBit(RedMask or GreenMask or BlueMask or AlphaMask) / 8);
3445 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3446 procedure TbmpBitfieldFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3454 ((aPixel.Data.r and fRange.r) shl fShift.r) or
3455 ((aPixel.Data.g and fRange.g) shl fShift.g) or
3456 ((aPixel.Data.b and fRange.b) shl fShift.b) or
3457 ((aPixel.Data.a and fRange.a) shl fShift.a);
3458 s := Round(fPixelSize);
3461 2: PWord(aData)^ := data;
3462 4: PCardinal(aData)^ := data;
3463 8: PUInt64(aData)^ := data;
3465 raise EglBitmapException.CreateFmt('invalid pixel size: %.1f', [fPixelSize]);
3470 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3471 procedure TbmpBitfieldFormat.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
3478 s := Round(fPixelSize);
3481 2: data := PWord(aData)^;
3482 4: data := PCardinal(aData)^;
3483 8: data := PUInt64(aData)^;
3485 raise EglBitmapException.CreateFmt('invalid pixel size: %.1f', [fPixelSize]);
3488 aPixel.Data.arr[i] := (data shr fShift.arr[i]) and fRange.arr[i];
3492 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3493 //TColorTableFormat///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3494 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3495 procedure TbmpColorTableFormat.CreateColorTable;
3501 if not (Format in [tfLuminance4, tfLuminance8, tfR3G3B2]) then
3502 raise EglBitmapException.Create(UNSUPPORTED_FORMAT);
3504 if (Format = tfLuminance4) then
3505 SetLength(fColorTable, 16)
3507 SetLength(fColorTable, 256);
3511 for i := 0 to High(fColorTable) do begin
3512 fColorTable[i].r := 16 * i;
3513 fColorTable[i].g := 16 * i;
3514 fColorTable[i].b := 16 * i;
3515 fColorTable[i].a := 0;
3520 for i := 0 to High(fColorTable) do begin
3521 fColorTable[i].r := i;
3522 fColorTable[i].g := i;
3523 fColorTable[i].b := i;
3524 fColorTable[i].a := 0;
3529 for i := 0 to High(fColorTable) do begin
3530 fColorTable[i].r := Round(((i shr Shift.r) and Range.r) / Range.r * 255);
3531 fColorTable[i].g := Round(((i shr Shift.g) and Range.g) / Range.g * 255);
3532 fColorTable[i].b := Round(((i shr Shift.b) and Range.b) / Range.b * 255);
3533 fColorTable[i].a := 0;
3535 s := SysUtils.Format('%.2X%.2X%.2X' + sLineBreak, [fColorTable[i].r, fColorTable[i].g, fColorTable[i].b]);
3536 fs.Write(s[1], Length(s));
3542 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3543 procedure TbmpColorTableFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3547 if not (Format in [tfLuminance4, tfLuminance8, tfR3G3B2]) then
3548 raise EglBitmapException.Create(UNSUPPORTED_FORMAT);
3552 if (aMapData = nil) then
3554 d := LuminanceWeight(aPixel) and Range.r;
3555 aData^ := aData^ or (d shl (4 - PtrInt(aMapData)));
3557 if (PtrInt(aMapData) >= 8) then begin
3564 aData^ := LuminanceWeight(aPixel) and Range.r;
3570 ((aPixel.Data.r and Range.r) shl Shift.r) or
3571 ((aPixel.Data.g and Range.g) shl Shift.g) or
3572 ((aPixel.Data.b and Range.b) shl Shift.b));
3578 procedure TbmpColorTableFormat.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
3587 s := Trunc(fPixelSize);
3588 f := fPixelSize - s;
3589 bits := Round(8 * f);
3591 0: idx := (aData^ shr (8 - bits - PtrInt(aMapData))) and ((1 shl bits) - 1);
3593 2: idx := PWord(aData)^;
3594 4: idx := PCardinal(aData)^;
3595 8: idx := PUInt64(aData)^;
3597 raise EglBitmapException.CreateFmt('invalid pixel size: %.3f', [fPixelSize]);
3599 if (idx >= Length(fColorTable)) then
3600 raise EglBitmapException.CreateFmt('invalid color index: %d', [idx]);
3601 with fColorTable[idx] do begin
3607 inc(aMapData, bits);
3608 if (PtrInt(aMapData) >= 8) then begin
3615 destructor TbmpColorTableFormat.Destroy;
3617 SetLength(fColorTable, 0);
3621 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3622 //TglBitmap - Helper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3623 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3624 procedure glBitmapConvertCopyFunc(var aFuncRec: TglBitmapFunctionRec);
3626 with aFuncRec do begin
3627 if (Source.Range.r > 0) then
3628 Dest.Data.r := Source.Data.r;
3629 if (Source.Range.g > 0) then
3630 Dest.Data.g := Source.Data.g;
3631 if (Source.Range.b > 0) then
3632 Dest.Data.b := Source.Data.b;
3633 if (Source.Range.a > 0) then
3634 Dest.Data.a := Source.Data.a;
3638 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3639 procedure glBitmapConvertCalculateRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
3643 with aFuncRec do begin
3645 if (Source.Range.arr[i] > 0) then
3646 Dest.Data.arr[i] := Round(Dest.Range.arr[i] * Source.Data.arr[i] / Source.Range.arr[i]);
3651 TShiftData = packed record
3653 0: (r, g, b, a: SmallInt);
3654 1: (arr: array[0..3] of SmallInt);
3656 PShiftData = ^TShiftData;
3658 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3659 procedure glBitmapConvertShiftRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
3665 if (Source.Range.arr[i] > 0) then
3666 Dest.Data.arr[i] := Source.Data.arr[i] shr PShiftData(Args)^.arr[i];
3669 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3670 procedure glBitmapInvertFunc(var aFuncRec: TglBitmapFunctionRec);
3672 with aFuncRec do begin
3673 Dest.Data.r := Source.Data.r;
3674 Dest.Data.g := Source.Data.g;
3675 Dest.Data.b := Source.Data.b;
3676 Dest.Data.a := Source.Data.a;
3677 if (Args and $1 > 0) then begin
3678 Dest.Data.r := Dest.Data.r xor Dest.Range.r;
3679 Dest.Data.g := Dest.Data.g xor Dest.Range.g;
3680 Dest.Data.b := Dest.Data.b xor Dest.Range.b;
3682 if (Args and $2 > 0) then begin
3683 Dest.Data.a := Dest.Data.a xor Dest.Range.a;
3688 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3689 procedure glBitmapFillWithColorFunc(var aFuncRec: TglBitmapFunctionRec);
3693 with aFuncRec do begin
3695 Dest.Data.arr[i] := PglBitmapPixelData(Args)^.Data.arr[i];
3699 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3700 procedure glBitmapAlphaFunc(var FuncRec: TglBitmapFunctionRec);
3704 with FuncRec do begin
3705 if (FuncRec.Args = 0) then begin //source has no alpha
3707 Source.Data.r / Source.Range.r * ALPHA_WEIGHT_R +
3708 Source.Data.g / Source.Range.g * ALPHA_WEIGHT_G +
3709 Source.Data.b / Source.Range.b * ALPHA_WEIGHT_B;
3710 Dest.Data.a := Round(Dest.Range.a * Temp);
3712 Dest.Data.a := Round(Source.Data.a / Source.Range.a * Dest.Range.a);
3716 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3717 procedure glBitmapColorKeyAlphaFunc(var FuncRec: TglBitmapFunctionRec);
3719 PglBitmapPixelData = ^TglBitmapPixelData;
3721 with FuncRec do begin
3722 Dest.Data.r := Source.Data.r;
3723 Dest.Data.g := Source.Data.g;
3724 Dest.Data.b := Source.Data.b;
3726 with PglBitmapPixelData(Args)^ do
3727 if ((Dest.Data.r <= Data.r) and (Dest.Data.r >= Range.r) and
3728 (Dest.Data.g <= Data.g) and (Dest.Data.g >= Range.g) and
3729 (Dest.Data.b <= Data.b) and (Dest.Data.b >= Range.b)) then
3732 Dest.Data.a := Dest.Range.a;
3736 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3737 procedure glBitmapValueAlphaFunc(var FuncRec: TglBitmapFunctionRec);
3739 PglBitmapPixelData = ^TglBitmapPixelData;
3741 with FuncRec do begin
3742 Dest.Data.r := Source.Data.r;
3743 Dest.Data.g := Source.Data.g;
3744 Dest.Data.b := Source.Data.b;
3745 Dest.Data.a := PCardinal(Args)^;
3749 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3750 procedure SwapRGB(aData: PByte; aWidth: Integer; const aHasAlpha: Boolean);
3753 TRGBPix = array [0..2] of byte;
3757 while aWidth > 0 do begin
3758 Temp := PRGBPix(aData)^[0];
3759 PRGBPix(aData)^[0] := PRGBPix(aData)^[2];
3760 PRGBPix(aData)^[2] := Temp;
3770 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3771 //TglBitmap - PROTECTED///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3772 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3773 function TglBitmap.GetWidth: Integer;
3775 if (ffX in fDimension.Fields) then
3776 result := fDimension.X
3781 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3782 function TglBitmap.GetHeight: Integer;
3784 if (ffY in fDimension.Fields) then
3785 result := fDimension.Y
3790 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3791 function TglBitmap.GetFileWidth: Integer;
3793 result := Max(1, Width);
3796 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3797 function TglBitmap.GetFileHeight: Integer;
3799 result := Max(1, Height);
3802 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3803 procedure TglBitmap.SetCustomData(const aValue: Pointer);
3805 if fCustomData = aValue then
3807 fCustomData := aValue;
3810 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3811 procedure TglBitmap.SetCustomName(const aValue: String);
3813 if fCustomName = aValue then
3815 fCustomName := aValue;
3818 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3819 procedure TglBitmap.SetCustomNameW(const aValue: WideString);
3821 if fCustomNameW = aValue then
3823 fCustomNameW := aValue;
3826 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3827 procedure TglBitmap.SetDeleteTextureOnFree(const aValue: Boolean);
3829 if fDeleteTextureOnFree = aValue then
3831 fDeleteTextureOnFree := aValue;
3834 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3835 procedure TglBitmap.SetFormat(const aValue: TglBitmapFormat);
3837 if fFormat = aValue then
3839 if TFormatDescriptor.Get(Format).PixelSize <> TFormatDescriptor.Get(aValue).PixelSize then
3840 raise EglBitmapUnsupportedFormatFormat.Create('SetInternalFormat - ' + UNSUPPORTED_FORMAT);
3841 SetDataPointer(Data, aValue, Width, Height);
3844 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3845 procedure TglBitmap.SetFreeDataAfterGenTexture(const aValue: Boolean);
3847 if fFreeDataAfterGenTexture = aValue then
3849 fFreeDataAfterGenTexture := aValue;
3852 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3853 procedure TglBitmap.SetID(const aValue: Cardinal);
3855 if fID = aValue then
3860 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3861 procedure TglBitmap.SetMipMap(const aValue: TglBitmapMipMap);
3863 if fMipMap = aValue then
3868 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3869 procedure TglBitmap.SetTarget(const aValue: Cardinal);
3871 if fTarget = aValue then
3876 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3877 procedure TglBitmap.SetAnisotropic(const aValue: Integer);
3879 MaxAnisotropic: Integer;
3881 fAnisotropic := aValue;
3882 if (ID > 0) then begin
3883 if GL_EXT_texture_filter_anisotropic then begin
3884 if fAnisotropic > 0 then begin
3886 glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @MaxAnisotropic);
3887 if aValue > MaxAnisotropic then
3888 fAnisotropic := MaxAnisotropic;
3889 glTexParameteri(Target, GL_TEXTURE_MAX_ANISOTROPY_EXT, fAnisotropic);
3897 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3898 procedure TglBitmap.CreateID;
3901 glDeleteTextures(1, @fID);
3902 glGenTextures(1, @fID);
3906 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3907 procedure TglBitmap.SetupParameters(var aBuildWithGlu: Boolean);
3909 // Set Up Parameters
3910 SetWrap(fWrapS, fWrapT, fWrapR);
3911 SetFilter(fFilterMin, fFilterMag);
3912 SetAnisotropic(fAnisotropic);
3913 SetBorderColor(fBorderColor[0], fBorderColor[1], fBorderColor[2], fBorderColor[3]);
3915 // Mip Maps Generation Mode
3916 aBuildWithGlu := false;
3917 if (MipMap = mmMipmap) then begin
3918 if (GL_VERSION_1_4 or GL_SGIS_generate_mipmap) then
3919 glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE)
3921 aBuildWithGlu := true;
3922 end else if (MipMap = mmMipmapGlu) then
3923 aBuildWithGlu := true;
3926 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3927 procedure TglBitmap.SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
3928 const aWidth: Integer; const aHeight: Integer);
3932 if (Data <> aData) then begin
3933 if (Assigned(Data)) then
3938 FillChar(fDimension, SizeOf(fDimension), 0);
3939 if not Assigned(fData) then begin
3944 if aWidth <> -1 then begin
3945 fDimension.Fields := fDimension.Fields + [ffX];
3946 fDimension.X := aWidth;
3949 if aHeight <> -1 then begin
3950 fDimension.Fields := fDimension.Fields + [ffY];
3951 fDimension.Y := aHeight;
3954 s := TFormatDescriptor.Get(aFormat).PixelSize;
3956 fPixelSize := Ceil(s);
3957 fRowSize := Ceil(s * aWidth);
3961 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3962 function TglBitmap.FlipHorz: Boolean;
3967 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3968 function TglBitmap.FlipVert: Boolean;
3973 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3974 //TglBitmap - PUBLIC//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3975 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3976 procedure TglBitmap.AfterConstruction;
3978 inherited AfterConstruction;
3982 fIsResident := false;
3984 fFormat := glBitmapGetDefaultFormat;
3985 fMipMap := glBitmapDefaultMipmap;
3986 fFreeDataAfterGenTexture := glBitmapGetDefaultFreeDataAfterGenTexture;
3987 fDeleteTextureOnFree := glBitmapGetDefaultDeleteTextureOnFree;
3989 glBitmapGetDefaultFilter (fFilterMin, fFilterMag);
3990 glBitmapGetDefaultTextureWrap(fWrapS, fWrapT, fWrapR);
3993 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3994 procedure TglBitmap.BeforeDestruction;
3996 SetDataPointer(nil, tfEmpty);
3997 if (fID > 0) and fDeleteTextureOnFree then
3998 glDeleteTextures(1, @fID);
3999 inherited BeforeDestruction;
4002 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4003 procedure TglBitmap.LoadFromFile(const aFilename: String);
4007 fFilename := aFilename;
4008 fs := TFileStream.Create(fFilename, fmOpenRead);
4017 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4018 procedure TglBitmap.LoadFromStream(const aStream: TStream);
4020 {$IFDEF GLB_SUPPORT_PNG_READ}
4021 if not LoadPNG(aStream) then
4023 {$IFDEF GLB_SUPPORT_JPEG_READ}
4024 if not LoadJPEG(aStream) then
4026 if not LoadDDS(aStream) then
4027 if not LoadTGA(aStream) then
4028 if not LoadBMP(aStream) then
4029 raise EglBitmapException.Create('LoadFromStream - Couldn''t load Stream. It''s possible to be an unknow Streamtype.');
4032 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4033 procedure TglBitmap.LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
4034 const aFormat: TglBitmapFormat; const aArgs: PtrInt);
4039 size := TFormatDescriptor.Get(aFormat).GetSize(aSize);
4040 GetMem(tmpData, size);
4042 FillChar(tmpData^, size, #$FF);
4043 SetDataPointer(tmpData, aFormat, aSize.X, aSize.Y);
4048 AddFunc(Self, aFunc, false, Format, aArgs);
4052 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4053 procedure TglBitmap.LoadFromResource(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil);
4055 rs: TResourceStream;
4060 if not Assigned(ResType) then begin
4061 TempPos := Pos('.', Resource);
4062 ResTypeStr := UpperCase(Copy(Resource, TempPos + 1, Length(Resource) - TempPos));
4063 Resource := UpperCase(Copy(Resource, 0, TempPos -1));
4064 TempResType := PChar(ResTypeStr);
4066 TempResType := ResType
4068 rs := TResourceStream.Create(Instance, Resource, TempResType);
4076 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4077 procedure TglBitmap.LoadFromResourceID(const sInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
4079 rs: TResourceStream;
4081 rs := TResourceStream.CreateFromID(Instance, ResourceID, ResType);
4090 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4091 procedure TglBitmap.SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
4095 fs := TFileStream.Create(aFileName, fmCreate);
4098 SaveToStream(fs, aFileType);
4104 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4105 procedure TglBitmap.SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType);
4108 {$IFDEF GLB_SUPPORT_PNG_WRITE}
4109 ftPNG: SavePng(aStream);
4111 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
4112 ftJPEG: SaveJPEG(aStream);
4114 ftDDS: SaveDDS(aStream);
4115 ftTGA: SaveTGA(aStream);
4116 ftBMP: SaveBMP(aStream);
4120 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4121 function TglBitmap.AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: PtrInt): Boolean;
4123 result := AddFunc(Self, aFunc, aCreateTemp, Format, aArgs);
4126 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4127 function TglBitmap.AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
4128 const aFormat: TglBitmapFormat; const aArgs: PtrInt): Boolean;
4130 DestData, TmpData, SourceData: pByte;
4131 TempHeight, TempWidth: Integer;
4132 SourceFD, DestFD: TFormatDescriptor;
4133 SourceMD, DestMD: Pointer;
4135 FuncRec: TglBitmapFunctionRec;
4137 Assert(Assigned(Data));
4138 Assert(Assigned(aSource));
4139 Assert(Assigned(aSource.Data));
4142 if Assigned(aSource.Data) and ((aSource.Height > 0) or (aSource.Width > 0)) then begin
4143 SourceFD := TFormatDescriptor.Get(aSource.Format);
4144 DestFD := TFormatDescriptor.Get(aFormat);
4146 // inkompatible Formats so CreateTemp
4147 if (SourceFD.PixelSize <> DestFD.PixelSize) then
4148 aCreateTemp := true;
4151 TempHeight := Max(1, aSource.Height);
4152 TempWidth := Max(1, aSource.Width);
4154 FuncRec.Sender := Self;
4155 FuncRec.Args := aArgs;
4158 if aCreateTemp then begin
4159 GetMem(TmpData, TFormatDescriptor.Get(aFormat).GetSize(TempWidth, TempHeight));
4160 DestData := TmpData;
4165 SourceFD.PreparePixel(FuncRec.Source);
4166 DestFD.PreparePixel (FuncRec.Dest);
4168 SourceMD := SourceFD.CreateMappingData;
4169 DestMD := DestFD.CreateMappingData;
4171 FuncRec.Size := aSource.Dimension;
4172 FuncRec.Position.Fields := FuncRec.Size.Fields;
4175 SourceData := aSource.Data;
4176 FuncRec.Position.Y := 0;
4177 while FuncRec.Position.Y < TempHeight do begin
4178 FuncRec.Position.X := 0;
4179 while FuncRec.Position.X < TempWidth do begin
4180 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
4182 DestFD.Map(FuncRec.Dest, DestData, DestMD);
4183 inc(FuncRec.Position.X);
4185 inc(FuncRec.Position.Y);
4188 // Updating Image or InternalFormat
4190 SetDataPointer(TmpData, aFormat, aSource.Width, aSource.Height)
4191 else if (aFormat <> fFormat) then
4196 SourceFD.FreeMappingData(SourceMD);
4197 DestFD.FreeMappingData(DestMD);
4208 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4209 function TglBitmap.AssignToSurface(out aSurface: PSDL_Surface): Boolean;
4211 Row, RowSize: Integer;
4212 SourceData, TmpData: PByte;
4214 Pix: TglBitmapPixelData;
4215 FormatDesc: TglBitmapFormatDescriptor;
4217 function GetRowPointer(Row: Integer): pByte;
4219 result := Surface.pixels;
4220 Inc(result, Row * RowSize);
4227 if not FormatIsUncompressed(InternalFormat) then
4228 raise EglBitmapUnsupportedInternalFormat.Create('AssignToSurface - ' + UNSUPPORTED_INTERNAL_FORMAT);
4231 FormatDesc := FORMAT_DESCRIPTORS[Format];
4232 if Assigned(Data) then begin
4233 case Trunc(FormatDesc.GetSize) of
4239 raise EglBitmapException.Create('AssignToSurface - ' + UNSUPPORTED_INTERNAL_FORMAT);
4241 FormatDesc.PreparePixel(Pix);
4242 with Pix.PixelDesc do
4243 Surface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, TempDepth,
4244 RedRange shl RedShift, GreenRange shl GreenShift, BlueRange shl BlueShift, AlphaRange shl AlphaShift);
4247 RowSize := Ceil(FileWidth * FormatDesc.GetSize);
4249 for Row := 0 to FileHeight -1 do begin
4250 TmpData := GetRowPointer(Row);
4251 if Assigned(TmpData) then begin
4252 Move(SourceData^, TmpData^, RowSize);
4253 inc(SourceData, RowSize);
4260 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4261 function TglBitmap.AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
4263 pSource, pData, pTempData: PByte;
4264 Row, RowSize, TempWidth, TempHeight: Integer;
4265 IntFormat, f: TglBitmapInternalFormat;
4266 FormatDesc: TglBitmapFormatDescriptor;
4268 function GetRowPointer(Row: Integer): pByte;
4270 result := Surface^.pixels;
4271 Inc(result, Row * RowSize);
4276 if (Assigned(Surface)) then begin
4277 with Surface^.format^ do begin
4278 IntFormat := tfEmpty;
4279 for f := Low(f) to High(f) do begin
4280 if FORMAT_DESCRIPTORS[f].MaskMatch(RMask, GMask, BMask, AMask) then begin
4285 if (IntFormat = tfEmpty) then
4286 raise EglBitmapException.Create('AssignFromSurface - Invalid Pixelformat.');
4289 FormatDesc := FORMAT_DESCRIPTORS[IntFormat];
4290 TempWidth := Surface^.w;
4291 TempHeight := Surface^.h;
4292 RowSize := Trunc(TempWidth * FormatDesc.GetSize);
4293 GetMem(pData, TempHeight * RowSize);
4296 for Row := 0 to TempHeight -1 do begin
4297 pSource := GetRowPointer(Row);
4298 if (Assigned(pSource)) then begin
4299 Move(pSource^, pTempData^, RowSize);
4300 Inc(pTempData, RowSize);
4303 SetDataPointer(pData, IntFormat, TempWidth, TempHeight);
4312 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4313 function TglBitmap.AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
4315 Row, Col, AlphaInterleave: Integer;
4316 pSource, pDest: PByte;
4318 function GetRowPointer(Row: Integer): pByte;
4320 result := aSurface.pixels;
4321 Inc(result, Row * Width);
4326 if Assigned(Data) then begin
4327 if Format in [tfAlpha8, tfLuminance8Alpha8, tfBGRA8, tfRGBA8] then begin
4328 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, 8, $FF, $FF, $FF, 0);
4330 AlphaInterleave := 0;
4333 AlphaInterleave := 1;
4335 AlphaInterleave := 3;
4339 for Row := 0 to Height -1 do begin
4340 pDest := GetRowPointer(Row);
4341 if Assigned(pDest) then begin
4342 for Col := 0 to Width -1 do begin
4343 Inc(pSource, AlphaInterleave);
4355 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4356 function TglBitmap.AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
4360 bmp := TglBitmap2D.Create;
4362 bmp.AssignFromSurface(Surface);
4363 result := AddAlphaFromGlBitmap(bmp, Func, CustomData);
4371 //TODO rework & test
4372 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4373 function TglBitmap.AssignToBitmap(const aBitmap: TBitmap): Boolean;
4376 pSource, pData: PByte;
4379 if Assigned(Data) then begin
4380 if Assigned(aBitmap) then begin
4381 aBitmap.Width := Width;
4382 aBitmap.Height := Height;
4385 tfAlpha8, ifLuminance, ifDepth8:
4387 Bitmap.PixelFormat := pf8bit;
4388 Bitmap.Palette := CreateGrayPalette;
4391 Bitmap.PixelFormat := pf15bit;
4393 Bitmap.PixelFormat := pf16bit;
4395 Bitmap.PixelFormat := pf24bit;
4397 Bitmap.PixelFormat := pf32bit;
4399 raise EglBitmapException.Create('AssignToBitmap - Invalid Pixelformat.');
4403 for Row := 0 to FileHeight -1 do begin
4404 pData := Bitmap.Scanline[Row];
4406 Move(pSource^, pData^, fRowSize);
4407 Inc(pSource, fRowSize);
4409 // swap RGB(A) to BGR(A)
4410 if InternalFormat in [ifRGB8, ifRGBA8] then
4411 SwapRGB(pData, FileWidth, InternalFormat = ifRGBA8);
4419 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4420 function TglBitmap.AssignFromBitmap(const aBitmap: TBitmap): Boolean;
4422 pSource, pData, pTempData: PByte;
4423 Row, RowSize, TempWidth, TempHeight: Integer;
4424 IntFormat: TglBitmapInternalFormat;
4428 if (Assigned(Bitmap)) then begin
4429 case Bitmap.PixelFormat of
4431 IntFormat := ifLuminance;
4433 IntFormat := ifRGB5A1;
4435 IntFormat := ifR5G6B5;
4437 IntFormat := ifBGR8;
4439 IntFormat := ifBGRA8;
4441 raise EglBitmapException.Create('AssignFromBitmap - Invalid Pixelformat.');
4444 TempWidth := Bitmap.Width;
4445 TempHeight := Bitmap.Height;
4447 RowSize := Trunc(TempWidth * FormatGetSize(IntFormat));
4449 GetMem(pData, TempHeight * RowSize);
4453 for Row := 0 to TempHeight -1 do begin
4454 pSource := Bitmap.Scanline[Row];
4456 if (Assigned(pSource)) then begin
4457 Move(pSource^, pTempData^, RowSize);
4458 Inc(pTempData, RowSize);
4462 SetDataPointer(pData, IntFormat, TempWidth, TempHeight);
4472 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4473 function TglBitmap.AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
4475 Row, Col, AlphaInterleave: Integer;
4476 pSource, pDest: PByte;
4480 if Assigned(Data) then begin
4481 if InternalFormat in [ifAlpha, ifLuminanceAlpha, ifRGBA8, ifBGRA8] then begin
4482 if Assigned(Bitmap) then begin
4483 Bitmap.PixelFormat := pf8bit;
4484 Bitmap.Palette := CreateGrayPalette;
4485 Bitmap.Width := Width;
4486 Bitmap.Height := Height;
4488 case InternalFormat of
4490 AlphaInterleave := 1;
4492 AlphaInterleave := 3;
4494 AlphaInterleave := 0;
4500 for Row := 0 to Height -1 do begin
4501 pDest := Bitmap.Scanline[Row];
4503 if Assigned(pDest) then begin
4504 for Col := 0 to Width -1 do begin
4505 Inc(pSource, AlphaInterleave);
4519 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4520 function TglBitmap.AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
4524 tex := TglBitmap2D.Create;
4526 tex.AssignFromBitmap(Bitmap);
4527 result := AddAlphaFromglBitmap(tex, Func, CustomData);
4533 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4534 function TglBitmap.AddAlphaFromResource(const aInstance: Cardinal; const aResource: String; const aResType: PChar;
4535 const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
4537 RS: TResourceStream;
4542 if Assigned(ResType) then
4543 TempResType := ResType
4546 TempPos := Pos('.', Resource);
4547 ResTypeStr := UpperCase(Copy(Resource, TempPos + 1, Length(Resource) - TempPos));
4548 Resource := UpperCase(Copy(Resource, 0, TempPos -1));
4549 TempResType := PChar(ResTypeStr);
4552 RS := TResourceStream.Create(Instance, Resource, TempResType);
4554 result := AddAlphaFromStream(RS, Func, CustomData);
4560 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4561 function TglBitmap.AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
4562 const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
4564 RS: TResourceStream;
4566 RS := TResourceStream.CreateFromID(Instance, ResourceID, ResType);
4568 result := AddAlphaFromStream(RS, Func, CustomData);
4575 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4576 function TglBitmap.AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
4579 if not FormatIsUncompressed(InternalFormat) then
4580 raise EglBitmapUnsupportedFormatFormat.Create('AddAlphaFromFunc - ' + UNSUPPORTED_FORMAT);
4582 result := AddFunc(Self, aFunc, false, TFormatDescriptor.Get(Format).WithAlpha, aArgs);
4585 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4586 function TglBitmap.AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
4590 FS := TFileStream.Create(FileName, fmOpenRead);
4592 result := AddAlphaFromStream(FS, aFunc, aArgs);
4598 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4599 function TglBitmap.AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
4603 tex := TglBitmap2D.Create(aStream);
4605 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
4611 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4612 function TglBitmap.AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction; const aArgs: PtrInt): Boolean;
4614 DestData, DestData2, SourceData: pByte;
4615 TempHeight, TempWidth: Integer;
4616 SourceFD, DestFD: TFormatDescriptor;
4617 SourceMD, DestMD, DestMD2: Pointer;
4619 FuncRec: TglBitmapFunctionRec;
4623 Assert(Assigned(Data));
4624 Assert(Assigned(aBitmap));
4625 Assert(Assigned(aBitmap.Data));
4627 if ((aBitmap.Width = Width) and (aBitmap.Height = Height)) then begin
4628 result := ConvertTo(TFormatDescriptor.Get(Format).WithAlpha);
4629 if not Assigned(aFunc) then
4630 aFunc := glBitmapAlphaFunc;
4632 SourceFD := TFormatDescriptor.Get(aBitmap.Format);
4633 DestFD := TFormatDescriptor.Get(Format);
4636 TempHeight := aBitmap.FileHeight;
4637 TempWidth := aBitmap.FileWidth;
4639 FuncRec.Sender := Self;
4640 FuncRec.Args := aArgs;
4641 FuncRec.Size := Dimension;
4642 FuncRec.Position.Fields := FuncRec.Size.Fields;
4643 FuncRec.Args := PtrInt(SourceFD.HasAlpha) and 1;
4647 SourceData := aBitmap.Data;
4650 SourceFD.PreparePixel(FuncRec.Source);
4651 DestFD.PreparePixel (FuncRec.Dest);
4653 SourceMD := SourceFD.CreateMappingData;
4654 DestMD := DestFD.CreateMappingData;
4655 DestMD2 := DestFD.CreateMappingData;
4657 FuncRec.Position.Y := 0;
4658 while FuncRec.Position.Y < TempHeight do begin
4659 FuncRec.Position.X := 0;
4660 while FuncRec.Position.X < TempWidth do begin
4661 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
4662 DestFD.Unmap (DestData, FuncRec.Dest, DestMD);
4664 DestFD.Map(FuncRec.Dest, DestData2, DestMD2);
4665 inc(FuncRec.Position.X);
4667 inc(FuncRec.Position.Y);
4670 SourceFD.FreeMappingData(SourceMD);
4671 DestFD.FreeMappingData(DestMD);
4672 DestFD.FreeMappingData(DestMD2);
4677 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4678 function TglBitmap.AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte): Boolean;
4680 result := AddAlphaFromColorKeyFloat(aRed / $FF, aGreen / $FF, aBlue / $FF, aDeviation / $FF);
4683 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4684 function TglBitmap.AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal): Boolean;
4686 PixelData: TglBitmapPixelData;
4688 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
4689 result := AddAlphaFromColorKeyFloat(
4690 aRed / PixelData.Range.r,
4691 aGreen / PixelData.Range.g,
4692 aBlue / PixelData.Range.b,
4693 aDeviation / Max(PixelData.Range.r, Max(PixelData.Range.g, PixelData.Range.b)));
4696 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4697 function TglBitmap.AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single): Boolean;
4699 values: array[0..2] of Single;
4702 PixelData: TglBitmapPixelData;
4704 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
4705 with PixelData do begin
4707 values[1] := aGreen;
4710 for i := 0 to 2 do begin
4711 tmp := Trunc(Range.arr[i] * aDeviation);
4712 Data.arr[i] := Min(Range.arr[i], Trunc(Range.arr[i] * values[i] + tmp));
4713 Range.arr[i] := Max(0, Trunc(Range.arr[i] * values[i] - tmp));
4718 result := AddAlphaFromFunc(glBitmapColorKeyAlphaFunc, PtrInt(@PixelData));
4721 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4722 function TglBitmap.AddAlphaFromValue(const aAlpha: Byte): Boolean;
4724 result := AddAlphaFromValueFloat(aAlpha / $FF);
4727 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4728 function TglBitmap.AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
4730 PixelData: TglBitmapPixelData;
4732 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
4733 result := AddAlphaFromValueFloat(aAlpha / PixelData.Range.a);
4736 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4737 function TglBitmap.AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
4739 PixelData: TglBitmapPixelData;
4741 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
4743 Data.a := Min(Range.a, Max(0, Round(Range.a * aAlpha)));
4744 result := AddAlphaFromFunc(glBitmapValueAlphaFunc, PtrInt(@PixelData.Data.a));
4747 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4748 function TglBitmap.RemoveAlpha: Boolean;
4750 FormatDesc: TFormatDescriptor;
4753 FormatDesc := TFormatDescriptor.Get(Format);
4754 if Assigned(Data) then begin
4755 if not ({FormatDesc.IsUncompressed or }FormatDesc.HasAlpha) then
4756 raise EglBitmapUnsupportedFormatFormat.Create('RemoveAlpha - ' + UNSUPPORTED_FORMAT);
4757 result := ConvertTo(FormatDesc.WithoutAlpha);
4761 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4762 function TglBitmap.Clone: TglBitmap;
4769 Temp := (ClassType.Create as TglBitmap);
4771 // copy texture data if assigned
4772 if Assigned(Data) then begin
4773 Size := TFormatDescriptor.Get(Format).GetSize(fDimension);
4774 GetMem(TempPtr, Size);
4776 Move(Data^, TempPtr^, Size);
4777 Temp.SetDataPointer(TempPtr, Format, Width, Height);
4783 Temp.SetDataPointer(nil, Format, Width, Height);
4787 Temp.fTarget := Target;
4788 Temp.fFormat := Format;
4789 Temp.fMipMap := MipMap;
4790 Temp.fAnisotropic := Anisotropic;
4791 Temp.fBorderColor := fBorderColor;
4792 Temp.fDeleteTextureOnFree := DeleteTextureOnFree;
4793 Temp.fFreeDataAfterGenTexture := FreeDataAfterGenTexture;
4794 Temp.fFilterMin := fFilterMin;
4795 Temp.fFilterMag := fFilterMag;
4796 Temp.fWrapS := fWrapS;
4797 Temp.fWrapT := fWrapT;
4798 Temp.fWrapR := fWrapR;
4799 Temp.fFilename := fFilename;
4800 Temp.fCustomName := fCustomName;
4801 Temp.fCustomNameW := fCustomNameW;
4802 Temp.fCustomData := fCustomData;
4811 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4812 function TglBitmap.ConvertTo(const aFormat: TglBitmapFormat): Boolean;
4814 SourceFD, DestFD: TFormatDescriptor;
4815 SourcePD, DestPD: TglBitmapPixelData;
4816 ShiftData: TShiftData;
4818 function CanCopyDirect: Boolean;
4821 ((SourcePD.Range.r = DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
4822 ((SourcePD.Range.g = DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
4823 ((SourcePD.Range.b = DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
4824 ((SourcePD.Range.a = DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
4827 function CanShift: Boolean;
4830 ((SourcePD.Range.r >= DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
4831 ((SourcePD.Range.g >= DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
4832 ((SourcePD.Range.b >= DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
4833 ((SourcePD.Range.a >= DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
4836 function GetShift(aSource, aDest: Cardinal) : ShortInt;
4839 while (aSource > aDest) and (aSource > 0) do begin
4841 aSource := aSource shr 1;
4846 if (aFormat <> fFormat) and (aFormat <> tfEmpty) then begin
4847 SourceFD := TFormatDescriptor.Get(Format);
4848 DestFD := TFormatDescriptor.Get(aFormat);
4850 SourceFD.PreparePixel(SourcePD);
4851 DestFD.PreparePixel (DestPD);
4853 if CanCopyDirect then
4854 result := AddFunc(Self, glBitmapConvertCopyFunc, false, aFormat)
4855 else if CanShift then begin
4856 ShiftData.r := GetShift(SourcePD.Range.r, DestPD.Range.r);
4857 ShiftData.g := GetShift(SourcePD.Range.g, DestPD.Range.g);
4858 ShiftData.b := GetShift(SourcePD.Range.b, DestPD.Range.b);
4859 ShiftData.a := GetShift(SourcePD.Range.a, DestPD.Range.a);
4860 result := AddFunc(Self, glBitmapConvertShiftRGBAFunc, false, aFormat, PtrInt(@ShiftData));
4862 result := AddFunc(Self, glBitmapConvertCalculateRGBAFunc, false, aFormat);
4867 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4868 procedure TglBitmap.Invert(const aUseRGB: Boolean; const aUseAlpha: Boolean);
4870 if aUseRGB or aUseAlpha then
4871 AddFunc(glBitmapInvertFunc, false, ((PtrInt(aUseAlpha) and 1) shl 1) or (PtrInt(aUseRGB) and 1));
4874 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4875 procedure TglBitmap.SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
4877 fBorderColor[0] := aRed;
4878 fBorderColor[1] := aGreen;
4879 fBorderColor[2] := aBlue;
4880 fBorderColor[3] := aAlpha;
4881 if (ID > 0) then begin
4883 glTexParameterfv(Target, GL_TEXTURE_BORDER_COLOR, @fBorderColor[0]);
4887 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4888 procedure TglBitmap.FreeData;
4890 SetDataPointer(nil, tfEmpty);
4893 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4894 procedure TglBitmap.FillWithColor(const aRed, aGreen, aBlue: Byte;
4895 const aAlpha: Byte);
4897 FillWithColorFloat(aRed/$FF, aGreen/$FF, aBlue/$FF, aAlpha/$FF);
4900 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4901 procedure TglBitmap.FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal);
4903 PixelData: TglBitmapPixelData;
4905 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
4907 aRed / PixelData.Range.r,
4908 aGreen / PixelData.Range.g,
4909 aBlue / PixelData.Range.b,
4910 aAlpha / PixelData.Range.a);
4913 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4914 procedure TglBitmap.FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single);
4916 PixelData: TglBitmapPixelData;
4918 TFormatDescriptor.Get(Format).PreparePixel(PixelData);
4919 with PixelData do begin
4920 Data.r := Max(0, Min(Range.r, Trunc(Range.r * aRed)));
4921 Data.g := Max(0, Min(Range.g, Trunc(Range.g * aGreen)));
4922 Data.b := Max(0, Min(Range.b, Trunc(Range.b * aBlue)));
4923 Data.a := Max(0, Min(Range.a, Trunc(Range.a * aAlpha)));
4925 AddFunc(glBitmapFillWithColorFunc, false, PtrInt(@PixelData));
4928 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4929 procedure TglBitmap.SetFilter(const aMin, aMag: Cardinal);
4934 fFilterMin := GL_NEAREST;
4936 fFilterMin := GL_LINEAR;
4937 GL_NEAREST_MIPMAP_NEAREST:
4938 fFilterMin := GL_NEAREST_MIPMAP_NEAREST;
4939 GL_LINEAR_MIPMAP_NEAREST:
4940 fFilterMin := GL_LINEAR_MIPMAP_NEAREST;
4941 GL_NEAREST_MIPMAP_LINEAR:
4942 fFilterMin := GL_NEAREST_MIPMAP_LINEAR;
4943 GL_LINEAR_MIPMAP_LINEAR:
4944 fFilterMin := GL_LINEAR_MIPMAP_LINEAR;
4946 raise EglBitmapException.Create('SetFilter - Unknow MIN filter.');
4952 fFilterMag := GL_NEAREST;
4954 fFilterMag := GL_LINEAR;
4956 raise EglBitmapException.Create('SetFilter - Unknow MAG filter.');
4960 if (ID > 0) then begin
4962 glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, fFilterMag);
4964 if (MipMap = mmNone) or (Target = GL_TEXTURE_RECTANGLE) then begin
4966 GL_NEAREST, GL_LINEAR:
4967 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
4968 GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR:
4969 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4970 GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR:
4971 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4974 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
4978 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4979 procedure TglBitmap.SetWrap(const S: Cardinal; const T: Cardinal; const R: Cardinal);
4981 procedure CheckAndSetWrap(const aValue: Cardinal; var aTarget: Cardinal);
4985 aTarget := GL_CLAMP;
4988 aTarget := GL_REPEAT;
4990 GL_CLAMP_TO_EDGE: begin
4991 if GL_VERSION_1_2 or GL_EXT_texture_edge_clamp then
4992 aTarget := GL_CLAMP_TO_EDGE
4994 aTarget := GL_CLAMP;
4997 GL_CLAMP_TO_BORDER: begin
4998 if GL_VERSION_1_3 or GL_ARB_texture_border_clamp then
4999 aTarget := GL_CLAMP_TO_BORDER
5001 aTarget := GL_CLAMP;
5004 GL_MIRRORED_REPEAT: begin
5005 if GL_VERSION_1_4 or GL_ARB_texture_mirrored_repeat or GL_IBM_texture_mirrored_repeat then
5006 aTarget := GL_MIRRORED_REPEAT
5008 raise EglBitmapException.Create('SetWrap - Unsupported Texturewrap GL_MIRRORED_REPEAT (S).');
5011 raise EglBitmapException.Create('SetWrap - Unknow Texturewrap (S).');
5016 CheckAndSetWrap(S, fWrapS);
5017 CheckAndSetWrap(T, fWrapT);
5018 CheckAndSetWrap(R, fWrapR);
5020 if (ID > 0) then begin
5022 glTexParameteri(Target, GL_TEXTURE_WRAP_S, fWrapS);
5023 glTexParameteri(Target, GL_TEXTURE_WRAP_T, fWrapT);
5024 glTexParameteri(Target, GL_TEXTURE_WRAP_R, fWrapR);
5028 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5029 procedure TglBitmap.GetPixel(const aPos: TglBitmapPixelPosition; var aPixel: TglBitmapPixelData);
5032 if Assigned (fGetPixelFunc) then
5033 fGetPixelFunc(aPos, aPixel);
5037 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5038 procedure TglBitmap.SetPixel(const aPos: TglBitmapPixelPosition; const aPixel: TglBitmapPixelData);
5041 if Assigned (fSetPixelFunc) then
5042 fSetPixelFuc(aPos, aPixel);
5046 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5047 procedure TglBitmap.Bind(const aEnableTextureUnit: Boolean);
5049 if aEnableTextureUnit then
5052 glBindTexture(Target, ID);
5055 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5056 procedure TglBitmap.Unbind(const aDisableTextureUnit: Boolean);
5058 if aDisableTextureUnit then
5060 glBindTexture(Target, 0);
5063 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5064 constructor TglBitmap.Create;
5066 {$IFNDEF GLB_NO_NATIVE_GL}
5067 ReadOpenGLExtensions;
5069 if (ClassType = TglBitmap) then
5070 raise EglBitmapException.Create('Don''t create TglBitmap directly. Use one of the deviated classes (TglBitmap2D) instead.');
5074 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5075 constructor TglBitmap.Create(const aFileName: String);
5078 LoadFromFile(FileName);
5081 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5082 constructor TglBitmap.Create(const aStream: TStream);
5085 LoadFromStream(aStream);
5088 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5089 constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat);
5095 TFormatDescriptor.Get(aFormat).GetSize(aSize);
5096 GetMem(Image, ImageSize);
5098 FillChar(Image^, ImageSize, #$FF);
5099 SetDataPointer(Image, aFormat, aSize.X, aSize.Y);
5106 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5107 constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat;
5108 const aFunc: TglBitmapFunction; const aArgs: PtrInt);
5111 LoadFromFunc(aSize, aFunc, aFormat, aArgs);
5115 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5116 constructor TglBitmap.Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar);
5119 LoadFromResource(aInstance, aResource, aResType);
5122 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5123 constructor TglBitmap.Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
5126 LoadFromResourceID(aInstance, aResourceID, aResType);
5130 {$IFDEF GLB_SUPPORT_PNG_READ}
5131 {$IF DEFINED(GLB_SDL_IMAGE)}
5132 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5133 //PNG/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5134 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5135 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
5137 Surface: PSDL_Surface;
5141 RWops := glBitmapCreateRWops(aStream);
5143 if IMG_isPNG(RWops) > 0 then begin
5144 Surface := IMG_LoadPNG_RW(RWops);
5146 AssignFromSurface(Surface);
5149 SDL_FreeSurface(Surface);
5157 {$ELSEIF DEFINED(GLB_LIB_PNG)}
5158 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5159 procedure glBitmap_libPNG_read_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
5161 TStream(png_get_io_ptr(png)).Read(buffer^, size);
5164 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5165 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
5168 signature: array [0..7] of byte;
5170 png_info: png_infop;
5172 TempHeight, TempWidth: Integer;
5173 Format: TglBitmapInternalFormat;
5176 png_rows: array of pByte;
5177 Row, LineSize: Integer;
5181 if not init_libPNG then
5182 raise Exception.Create('LoadPNG - unable to initialize libPNG.');
5186 StreamPos := Stream.Position;
5187 Stream.Read(signature, 8);
5188 Stream.Position := StreamPos;
5190 if png_check_sig(@signature, 8) <> 0 then begin
5192 png := png_create_read_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
5194 raise EglBitmapException.Create('LoadPng - couldn''t create read struct.');
5197 png_info := png_create_info_struct(png);
5198 if png_info = nil then begin
5199 png_destroy_read_struct(@png, nil, nil);
5200 raise EglBitmapException.Create('LoadPng - couldn''t create info struct.');
5203 // set read callback
5204 png_set_read_fn(png, stream, glBitmap_libPNG_read_func);
5206 // read informations
5207 png_read_info(png, png_info);
5210 TempHeight := png_get_image_height(png, png_info);
5211 TempWidth := png_get_image_width(png, png_info);
5214 case png_get_color_type(png, png_info) of
5215 PNG_COLOR_TYPE_GRAY:
5216 Format := tfLuminance8;
5217 PNG_COLOR_TYPE_GRAY_ALPHA:
5218 Format := tfLuminance8Alpha8;
5221 PNG_COLOR_TYPE_RGB_ALPHA:
5224 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
5227 // cut upper 8 bit from 16 bit formats
5228 if png_get_bit_depth(png, png_info) > 8 then
5229 png_set_strip_16(png);
5231 // expand bitdepth smaller than 8
5232 if png_get_bit_depth(png, png_info) < 8 then
5233 png_set_expand(png);
5235 // allocating mem for scanlines
5236 LineSize := png_get_rowbytes(png, png_info);
5237 GetMem(png_data, TempHeight * LineSize);
5239 SetLength(png_rows, TempHeight);
5240 for Row := Low(png_rows) to High(png_rows) do begin
5241 png_rows[Row] := png_data;
5242 Inc(png_rows[Row], Row * LineSize);
5245 // read complete image into scanlines
5246 png_read_image(png, @png_rows[0]);
5249 png_read_end(png, png_info);
5251 // destroy read struct
5252 png_destroy_read_struct(@png, @png_info, nil);
5254 SetLength(png_rows, 0);
5257 SetDataPointer(png_data, Format, TempWidth, TempHeight);
5270 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
5271 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5272 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
5276 Header: Array[0..7] of Byte;
5277 Row, Col, PixSize, LineSize: Integer;
5278 NewImage, pSource, pDest, pAlpha: pByte;
5279 Format: TglBitmapInternalFormat;
5282 PngHeader: Array[0..7] of Byte = (#137, #80, #78, #71, #13, #10, #26, #10);
5287 StreamPos := Stream.Position;
5288 Stream.Read(Header[0], SizeOf(Header));
5289 Stream.Position := StreamPos;
5291 {Test if the header matches}
5292 if Header = PngHeader then begin
5293 Png := TPNGObject.Create;
5295 Png.LoadFromStream(Stream);
5297 case Png.Header.ColorType of
5299 Format := ifLuminance;
5300 COLOR_GRAYSCALEALPHA:
5301 Format := ifLuminanceAlpha;
5307 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
5310 PixSize := Trunc(FormatGetSize(Format));
5311 LineSize := Integer(Png.Header.Width) * PixSize;
5313 GetMem(NewImage, LineSize * Integer(Png.Header.Height));
5317 case Png.Header.ColorType of
5318 COLOR_RGB, COLOR_GRAYSCALE:
5320 for Row := 0 to Png.Height -1 do begin
5321 Move (Png.Scanline[Row]^, pDest^, LineSize);
5322 Inc(pDest, LineSize);
5325 COLOR_RGBALPHA, COLOR_GRAYSCALEALPHA:
5327 PixSize := PixSize -1;
5329 for Row := 0 to Png.Height -1 do begin
5330 pSource := Png.Scanline[Row];
5331 pAlpha := pByte(Png.AlphaScanline[Row]);
5333 for Col := 0 to Png.Width -1 do begin
5334 Move (pSource^, pDest^, PixSize);
5335 Inc(pSource, PixSize);
5336 Inc(pDest, PixSize);
5345 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
5348 SetDataPointer(NewImage, Format, Png.Header.Width, Png.Header.Height);
5363 {$IFDEF GLB_SUPPORT_PNG_WRITE}
5364 {$IFDEF GLB_LIB_PNG}
5365 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5366 procedure glBitmap_libPNG_write_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
5368 TStream(png_get_io_ptr(png)).Write(buffer^, size);
5372 {$IF DEFINED(GLB_LIB_PNG)}
5373 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5374 procedure TglBitmap.SavePNG(const aStream: TStream);
5377 png_info: png_infop;
5378 png_rows: array of pByte;
5383 if not (ftPNG in FormatGetSupportedFiles (InternalFormat)) then
5384 raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
5386 if not init_libPNG then
5387 raise Exception.Create('SavePNG - unable to initialize libPNG.');
5390 case FInternalFormat of
5391 ifAlpha, ifLuminance, ifDepth8:
5392 ColorType := PNG_COLOR_TYPE_GRAY;
5394 ColorType := PNG_COLOR_TYPE_GRAY_ALPHA;
5396 ColorType := PNG_COLOR_TYPE_RGB;
5398 ColorType := PNG_COLOR_TYPE_RGBA;
5400 raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
5402 LineSize := Trunc(FormatGetSize(FInternalFormat) * Width);
5404 // creating array for scanline
5405 SetLength(png_rows, Height);
5407 for Row := 0 to Height - 1 do begin
5408 png_rows[Row] := Data;
5409 Inc(png_rows[Row], Row * LineSize)
5413 png := png_create_write_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
5415 raise EglBitmapException.Create('SavePng - couldn''t create write struct.');
5418 png_info := png_create_info_struct(png);
5419 if png_info = nil then begin
5420 png_destroy_write_struct(@png, nil);
5421 raise EglBitmapException.Create('SavePng - couldn''t create info struct.');
5424 // set read callback
5425 png_set_write_fn(png, stream, glBitmap_libPNG_write_func, nil);
5428 png_set_compression_level(png, 6);
5430 if InternalFormat in [ifBGR8, ifBGRA8] then
5433 png_set_IHDR(png, png_info, Width, Height, 8, ColorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
5434 png_write_info(png, png_info);
5435 png_write_image(png, @png_rows[0]);
5436 png_write_end(png, png_info);
5437 png_destroy_write_struct(@png, @png_info);
5439 SetLength(png_rows, 0);
5446 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
5447 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5448 procedure TglBitmap.SavePNG(const aStream: TStream);
5452 pSource, pDest: pByte;
5453 X, Y, PixSize: Integer;
5454 ColorType: Cardinal;
5460 if not (ftPNG in FormatGetSupportedFiles (InternalFormat)) then
5461 raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
5463 case FInternalFormat of
5464 ifAlpha, ifLuminance, ifDepth8: begin
5465 ColorType := COLOR_GRAYSCALE;
5469 ifLuminanceAlpha: begin
5470 ColorType := COLOR_GRAYSCALEALPHA;
5474 ifBGR8, ifRGB8: begin
5475 ColorType := COLOR_RGB;
5479 ifBGRA8, ifRGBA8: begin
5480 ColorType := COLOR_RGBALPHA;
5485 raise EglBitmapUnsupportedInternalFormat.Create('SavePng - ' + UNSUPPORTED_INTERNAL_FORMAT);
5488 Png := TPNGObject.CreateBlank(ColorType, 8, Width, Height);
5492 for Y := 0 to Height -1 do begin
5493 pDest := png.ScanLine[Y];
5494 for X := 0 to Width -1 do begin
5495 Move(pSource^, pDest^, PixSize);
5496 Inc(pDest, PixSize);
5497 Inc(pSource, PixSize);
5499 png.AlphaScanline[Y]^[X] := pSource^;
5504 // convert RGB line to BGR
5505 if InternalFormat in [ifRGB8, ifRGBA8] then begin
5506 pTemp := png.ScanLine[Y];
5507 for X := 0 to Width -1 do begin
5508 Temp := pByteArray(pTemp)^[0];
5509 pByteArray(pTemp)^[0] := pByteArray(pTemp)^[2];
5510 pByteArray(pTemp)^[2] := Temp;
5517 Png.CompressionLevel := 6;
5518 Png.SaveToStream(Stream);
5526 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5527 //JPEG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5528 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5529 {$IFDEF GLB_LIB_JPEG}
5531 glBitmap_libJPEG_source_mgr_ptr = ^glBitmap_libJPEG_source_mgr;
5532 glBitmap_libJPEG_source_mgr = record
5533 pub: jpeg_source_mgr;
5536 SrcBuffer: array [1..4096] of byte;
5539 glBitmap_libJPEG_dest_mgr_ptr = ^glBitmap_libJPEG_dest_mgr;
5540 glBitmap_libJPEG_dest_mgr = record
5541 pub: jpeg_destination_mgr;
5543 DestStream: TStream;
5544 DestBuffer: array [1..4096] of byte;
5547 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5549 procedure glBitmap_libJPEG_error_exit(cinfo: j_common_ptr); cdecl;
5553 SetLength(Msg, 256);
5554 cinfo^.err^.format_message(cinfo, pChar(Msg));
5555 Writeln('ERROR [' + IntToStr(cinfo^.err^.msg_code) + '] ' + Msg);
5556 cinfo^.global_state := 0;
5561 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5563 procedure glBitmap_libJPEG_output_message(cinfo: j_common_ptr); cdecl;
5567 SetLength(Msg, 256);
5568 cinfo^.err^.format_message(cinfo, pChar(Msg));
5569 Writeln('OUTPUT [' + IntToStr(cinfo^.err^.msg_code) + '] ' + Msg);
5570 cinfo^.global_state := 0;
5574 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5576 procedure glBitmap_libJPEG_init_source(cinfo: j_decompress_ptr); cdecl;
5581 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5582 function glBitmap_libJPEG_fill_input_buffer(cinfo: j_decompress_ptr): boolean; cdecl;
5584 src: glBitmap_libJPEG_source_mgr_ptr;
5587 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
5589 bytes := src^.SrcStream.Read(src^.SrcBuffer[1], 4096);
5590 if (bytes <= 0) then begin
5591 src^.SrcBuffer[1] := $FF;
5592 src^.SrcBuffer[2] := JPEG_EOI;
5596 src^.pub.next_input_byte := @(src^.SrcBuffer[1]);
5597 src^.pub.bytes_in_buffer := bytes;
5602 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5603 procedure glBitmap_libJPEG_skip_input_data(cinfo: j_decompress_ptr; num_bytes: Longint); cdecl;
5605 src: glBitmap_libJPEG_source_mgr_ptr;
5607 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
5609 if num_bytes > 0 then begin
5610 // wanted byte isn't in buffer so set stream position and read buffer
5611 if num_bytes > src^.pub.bytes_in_buffer then begin
5612 src^.SrcStream.Position := src^.SrcStream.Position + num_bytes - src^.pub.bytes_in_buffer;
5613 src^.pub.fill_input_buffer(cinfo);
5615 // wanted byte is in buffer so only skip
5616 inc(src^.pub.next_input_byte, num_bytes);
5617 dec(src^.pub.bytes_in_buffer, num_bytes);
5622 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5624 procedure glBitmap_libJPEG_term_source(cinfo: j_decompress_ptr); cdecl;
5629 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5631 procedure glBitmap_libJPEG_init_destination(cinfo: j_compress_ptr); cdecl;
5636 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5637 function glBitmap_libJPEG_empty_output_buffer(cinfo: j_compress_ptr): boolean; cdecl;
5639 dest: glBitmap_libJPEG_dest_mgr_ptr;
5641 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
5643 if dest^.pub.free_in_buffer < Cardinal(Length(dest^.DestBuffer)) then begin
5644 // write complete buffer
5645 dest^.DestStream.Write(dest^.DestBuffer[1], SizeOf(dest^.DestBuffer));
5648 dest^.pub.next_output_byte := @dest^.DestBuffer[1];
5649 dest^.pub.free_in_buffer := Length(dest^.DestBuffer);
5655 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5656 procedure glBitmap_libJPEG_term_destination(cinfo: j_compress_ptr); cdecl;
5659 dest: glBitmap_libJPEG_dest_mgr_ptr;
5661 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
5663 for Idx := Low(dest^.DestBuffer) to High(dest^.DestBuffer) do begin
5664 // check for endblock
5665 if (Idx < High(dest^.DestBuffer)) and (dest^.DestBuffer[Idx] = $FF) and (dest^.DestBuffer[Idx +1] = JPEG_EOI) then begin
5667 dest^.DestStream.Write(dest^.DestBuffer[Idx], 2);
5672 dest^.DestStream.Write(dest^.DestBuffer[Idx], 1);
5677 {$IFDEF GLB_SUPPORT_JPEG_READ}
5678 {$IF DEFINED(GLB_SDL_IMAGE)}
5679 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5680 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
5682 Surface: PSDL_Surface;
5687 RWops := glBitmapCreateRWops(Stream);
5689 if IMG_isJPG(RWops) > 0 then begin
5690 Surface := IMG_LoadJPG_RW(RWops);
5692 AssignFromSurface(Surface);
5695 SDL_FreeSurface(Surface);
5703 {$ELSEIF DEFINED(GLB_LIB_JPEG)}
5704 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5705 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
5708 Temp: array[0..1]of Byte;
5710 jpeg: jpeg_decompress_struct;
5711 jpeg_err: jpeg_error_mgr;
5713 IntFormat: TglBitmapInternalFormat;
5715 TempHeight, TempWidth: Integer;
5722 if not init_libJPEG then
5723 raise Exception.Create('LoadJPG - unable to initialize libJPEG.');
5726 // reading first two bytes to test file and set cursor back to begin
5727 StreamPos := Stream.Position;
5728 Stream.Read(Temp[0], 2);
5729 Stream.Position := StreamPos;
5731 // if Bitmap then read file.
5732 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
5733 FillChar(jpeg, SizeOf(jpeg_decompress_struct), $00);
5734 FillChar(jpeg_err, SizeOf(jpeg_error_mgr), $00);
5737 jpeg.err := jpeg_std_error(@jpeg_err);
5738 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
5739 jpeg_err.output_message := glBitmap_libJPEG_output_message;
5741 // decompression struct
5742 jpeg_create_decompress(@jpeg);
5744 // allocation space for streaming methods
5745 jpeg.src := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_source_mgr));
5747 // seeting up custom functions
5748 with glBitmap_libJPEG_source_mgr_ptr(jpeg.src)^ do begin
5749 pub.init_source := glBitmap_libJPEG_init_source;
5750 pub.fill_input_buffer := glBitmap_libJPEG_fill_input_buffer;
5751 pub.skip_input_data := glBitmap_libJPEG_skip_input_data;
5752 pub.resync_to_restart := jpeg_resync_to_restart; // use default method
5753 pub.term_source := glBitmap_libJPEG_term_source;
5755 pub.bytes_in_buffer := 0; // forces fill_input_buffer on first read
5756 pub.next_input_byte := nil; // until buffer loaded
5758 SrcStream := Stream;
5761 // set global decoding state
5762 jpeg.global_state := DSTATE_START;
5764 // read header of jpeg
5765 jpeg_read_header(@jpeg, false);
5767 // setting output parameter
5768 case jpeg.jpeg_color_space of
5771 jpeg.out_color_space := JCS_GRAYSCALE;
5772 IntFormat := ifLuminance;
5775 jpeg.out_color_space := JCS_RGB;
5776 IntFormat := ifRGB8;
5780 jpeg_start_decompress(@jpeg);
5782 TempHeight := jpeg.output_height;
5783 TempWidth := jpeg.output_width;
5785 // creating new image
5786 GetMem(pImage, FormatGetImageSize(glBitmapPosition(TempWidth, TempHeight), IntFormat));
5790 for Row := 0 to TempHeight -1 do begin
5791 jpeg_read_scanlines(@jpeg, @pTemp, 1);
5792 Inc(pTemp, Trunc(FormatGetSize(IntFormat) * TempWidth));
5795 // finish decompression
5796 jpeg_finish_decompress(@jpeg);
5798 // destroy decompression
5799 jpeg_destroy_decompress(@jpeg);
5801 SetDataPointer(pImage, IntFormat, TempWidth, TempHeight);
5814 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
5815 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5816 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
5821 Temp: array[0..1]of Byte;
5825 // reading first two bytes to test file and set cursor back to begin
5826 StreamPos := Stream.Position;
5827 Stream.Read(Temp[0], 2);
5828 Stream.Position := StreamPos;
5830 // if Bitmap then read file.
5831 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
5832 bmp := TBitmap.Create;
5834 jpg := TJPEGImage.Create;
5836 jpg.LoadFromStream(Stream);
5838 result := AssignFromBitmap(bmp);
5850 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
5851 {$IF DEFEFINED(GLB_LIB_JPEG)}
5852 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5853 procedure TglBitmap.SaveJPEG(Stream: TStream);
5855 jpeg: jpeg_compress_struct;
5856 jpeg_err: jpeg_error_mgr;
5858 pTemp, pTemp2: pByte;
5860 procedure CopyRow(pDest, pSource: pByte);
5864 for X := 0 to Width - 1 do begin
5865 pByteArray(pDest)^[0] := pByteArray(pSource)^[2];
5866 pByteArray(pDest)^[1] := pByteArray(pSource)^[1];
5867 pByteArray(pDest)^[2] := pByteArray(pSource)^[0];
5874 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
5875 raise EglBitmapUnsupportedInternalFormat.Create('SaveJpg - ' + UNSUPPORTED_INTERNAL_FORMAT);
5877 if not init_libJPEG then
5878 raise Exception.Create('SaveJPG - unable to initialize libJPEG.');
5881 FillChar(jpeg, SizeOf(jpeg_compress_struct), $00);
5882 FillChar(jpeg_err, SizeOf(jpeg_error_mgr), $00);
5885 jpeg.err := jpeg_std_error(@jpeg_err);
5886 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
5887 jpeg_err.output_message := glBitmap_libJPEG_output_message;
5889 // compression struct
5890 jpeg_create_compress(@jpeg);
5892 // allocation space for streaming methods
5893 jpeg.dest := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_dest_mgr));
5895 // seeting up custom functions
5896 with glBitmap_libJPEG_dest_mgr_ptr(jpeg.dest)^ do begin
5897 pub.init_destination := glBitmap_libJPEG_init_destination;
5898 pub.empty_output_buffer := glBitmap_libJPEG_empty_output_buffer;
5899 pub.term_destination := glBitmap_libJPEG_term_destination;
5901 pub.next_output_byte := @DestBuffer[1];
5902 pub.free_in_buffer := Length(DestBuffer);
5904 DestStream := Stream;
5907 // very important state
5908 jpeg.global_state := CSTATE_START;
5909 jpeg.image_width := Width;
5910 jpeg.image_height := Height;
5911 case InternalFormat of
5912 ifAlpha, ifLuminance, ifDepth8: begin
5913 jpeg.input_components := 1;
5914 jpeg.in_color_space := JCS_GRAYSCALE;
5916 ifRGB8, ifBGR8: begin
5917 jpeg.input_components := 3;
5918 jpeg.in_color_space := JCS_RGB;
5922 jpeg_set_defaults(@jpeg);
5923 jpeg_set_quality(@jpeg, 95, true);
5924 jpeg_start_compress(@jpeg, true);
5927 if InternalFormat = ifBGR8 then
5928 GetMem(pTemp2, fRowSize)
5933 for Row := 0 to jpeg.image_height -1 do begin
5935 if InternalFormat = ifBGR8 then
5936 CopyRow(pTemp2, pTemp)
5941 jpeg_write_scanlines(@jpeg, @pTemp2, 1);
5942 inc(pTemp, fRowSize);
5946 if InternalFormat = ifBGR8 then
5949 jpeg_finish_compress(@jpeg);
5950 jpeg_destroy_compress(@jpeg);
5956 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
5957 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5958 procedure TglBitmap.SaveJPEG(Stream: TStream);
5963 if not (ftJPEG in FormatGetSupportedFiles (InternalFormat)) then
5964 raise EglBitmapUnsupportedInternalFormat.Create('SaveJpg - ' + UNSUPPORTED_INTERNAL_FORMAT);
5966 Bmp := TBitmap.Create;
5968 Jpg := TJPEGImage.Create;
5970 AssignToBitmap(Bmp);
5971 if FInternalFormat in [ifAlpha, ifLuminance, ifDepth8] then begin
5972 Jpg.Grayscale := true;
5973 Jpg.PixelFormat := jf8Bit;
5976 Jpg.SaveToStream(Stream);
5987 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5988 //BMP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5989 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5996 BMP_COMP_BITFIELDS = 3;
5999 TBMPHeader = packed record
6004 bfOffBits: Cardinal;
6007 TBMPInfo = packed record
6013 biCompression: Cardinal;
6014 biSizeImage: Cardinal;
6015 biXPelsPerMeter: Longint;
6016 biYPelsPerMeter: Longint;
6017 biClrUsed: Cardinal;
6018 biClrImportant: Cardinal;
6021 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6022 function TglBitmap.LoadBMP(const aStream: TStream): Boolean;
6024 //////////////////////////////////////////////////////////////////////////////////////////////////
6025 function ReadInfo(var aInfo: TBMPInfo; var aMask: TglBitmapColorRec): TglBitmapFormat;
6028 aStream.Read(aInfo, SizeOf(aInfo));
6029 FillChar(aMask, SizeOf(aMask), 0);
6032 case aInfo.biCompression of
6034 BMP_COMP_RLE8: begin
6035 raise EglBitmapException.Create('RLE compression is not supported');
6037 BMP_COMP_BITFIELDS: begin
6038 if (aInfo.biBitCount = 16) or (aInfo.biBitCount = 32) then begin
6039 aStream.Read(aMask.r, SizeOf(aMask.r));
6040 aStream.Read(aMask.g, SizeOf(aMask.g));
6041 aStream.Read(aMask.b, SizeOf(aMask.b));
6042 aStream.Read(aMask.a, SizeOf(aMask.a));
6044 raise EglBitmapException.Create('Bitfields are only supported for 16bit and 32bit formats');
6048 //get suitable format
6049 case aInfo.biBitCount of
6050 8: result := tfLuminance8;
6051 16: result := tfBGR5;
6052 24: result := tfBGR8;
6053 32: result := tfBGRA8;
6057 function ReadColorTable(var aFormat: TglBitmapFormat; const aInfo: TBMPInfo): TbmpColorTableFormat;
6060 ColorTable: TbmpColorTable;
6063 if (aInfo.biBitCount >= 16) then
6065 aFormat := tfLuminance8;
6066 c := aInfo.biClrUsed;
6068 c := 1 shl aInfo.biBitCount;
6069 SetLength(ColorTable, c);
6070 for i := 0 to c-1 do begin
6071 aStream.Read(ColorTable[i], SizeOf(TbmpColorTableEnty));
6072 if (ColorTable[i].r <> ColorTable[i].g) or (ColorTable[i].g <> ColorTable[i].b) then
6076 result := TbmpColorTableFormat.Create;
6077 result.PixelSize := aInfo.biBitCount / 8;
6078 result.ColorTable := ColorTable;
6079 result.Range := glBitmapColorRec($FF, $FF, $FF, $00);
6082 //////////////////////////////////////////////////////////////////////////////////////////////////
6083 function CheckBitfields(var aFormat: TglBitmapFormat; const aMask: TglBitmapColorRec;
6084 const aInfo: TBMPInfo): TbmpBitfieldFormat;
6086 TmpFormat: TglBitmapFormat;
6087 FormatDesc: TFormatDescriptor;
6090 if (aMask.r <> 0) or (aMask.g <> 0) or (aMask.b <> 0) or (aMask.a <> 0) then begin
6091 for TmpFormat := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
6092 FormatDesc := TFormatDescriptor.Get(TmpFormat);
6093 if FormatDesc.MaskMatch(aMask.r, aMask.g, aMask.b, aMask.a) then begin
6094 aFormat := FormatDesc.Format;
6099 if (aMask.a = 0) and TFormatDescriptor.Get(aFormat).HasAlpha then
6100 aFormat := TFormatDescriptor.Get(aFormat).WithoutAlpha;
6101 if (aMask.a <> 0) and not TFormatDescriptor.Get(aFormat).HasAlpha then
6102 aFormat := TFormatDescriptor.Get(aFormat).WithAlpha;
6104 result := TbmpBitfieldFormat.Create;
6105 result.PixelSize := aInfo.biBitCount / 8;
6106 result.RedMask := aMask.r;
6107 result.GreenMask := aMask.g;
6108 result.BlueMask := aMask.b;
6109 result.AlphaMask := aMask.a;
6116 ImageSize, rbLineSize, wbLineSize, Padding, i: Integer;
6117 PaddingBuff: Cardinal;
6118 LineBuf, ImageData, TmpData: PByte;
6119 SourceMD, DestMD: Pointer;
6120 BmpFormat: TglBitmapFormat;
6121 ColorTable: TbmpColorTable;
6124 Mask: TglBitmapColorRec;
6129 SpecialFormat: TFormatDescriptor;
6130 FormatDesc: TFormatDescriptor;
6132 //////////////////////////////////////////////////////////////////////////////////////////////////
6133 procedure SpecialFormatReadLine(aData: PByte; aLineBuf: PByte);
6136 Pixel: TglBitmapPixelData;
6138 aStream.Read(aLineBuf^, rbLineSize);
6139 SpecialFormat.PreparePixel(Pixel);
6140 for i := 0 to Info.biWidth-1 do begin
6141 SpecialFormat.Unmap(aLineBuf, Pixel, SourceMD);
6142 with FormatDesc do begin
6143 //TODO: use convert function
6145 if (SpecialFormat.Range.arr[j] <> Range.arr[j]) then begin
6146 if (SpecialFormat.Range.arr[j] > 0) then
6147 Pixel.Data.arr[j] := Round(Pixel.Data.arr[j] / SpecialFormat.Range.arr[j] * Range.arr[j])
6149 Pixel.Data.arr[j] := 0;
6152 FormatDesc.Map(Pixel, aData, DestMD);
6158 BmpFormat := tfEmpty;
6159 SpecialFormat := nil;
6165 StartPos := aStream.Position;
6166 aStream.Read(Header, SizeOf(Header));
6168 if Header.bfType = BMP_MAGIC then begin
6170 BmpFormat := ReadInfo(Info, Mask);
6171 SpecialFormat := ReadColorTable(BmpFormat, Info);
6172 if not Assigned(SpecialFormat) then
6173 SpecialFormat := CheckBitfields(BmpFormat, Mask, Info);
6174 aStream.Position := StartPos + Header.bfOffBits;
6176 if (BmpFormat <> tfEmpty) then begin
6177 FormatDesc := TFormatDescriptor.Get(BmpFormat);
6178 rbLineSize := Round(Info.biWidth * Info.biBitCount / 8); //ReadBuffer LineSize
6179 wbLineSize := Trunc(Info.biWidth * FormatDesc.PixelSize);
6180 Padding := (((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3) - rbLineSize;
6183 DestMD := FormatDesc.CreateMappingData;
6184 ImageSize := FormatDesc.GetSize(Info.biWidth, abs(Info.biHeight));
6185 GetMem(ImageData, ImageSize);
6186 if Assigned(SpecialFormat) then begin
6187 GetMem(LineBuf, rbLineSize); //tmp Memory for converting Bitfields
6188 SourceMD := SpecialFormat.CreateMappingData;
6193 FillChar(ImageData^, ImageSize, $FF);
6194 TmpData := ImageData;
6195 if (Info.biHeight > 0) then
6196 Inc(TmpData, wbLineSize * (Info.biHeight-1));
6197 for i := 0 to Abs(Info.biHeight)-1 do begin
6198 if Assigned(SpecialFormat) then
6199 SpecialFormatReadLine(TmpData, LineBuf) //if is special format read and convert data
6201 aStream.Read(TmpData^, wbLineSize); //else only read data
6202 if (Info.biHeight > 0) then
6203 dec(TmpData, wbLineSize)
6205 inc(TmpData, wbLineSize);
6206 aStream.Read(PaddingBuff, Padding);
6208 SetDataPointer(ImageData, BmpFormat, Info.biWidth, abs(Info.biHeight));
6211 if Assigned(LineBuf) then
6213 if Assigned(SourceMD) then
6214 SpecialFormat.FreeMappingData(SourceMD);
6215 FormatDesc.FreeMappingData(DestMD);
6222 raise EglBitmapException.Create('LoadBMP - No suitable format found');
6224 aStream.Position := StartPos;
6228 FreeAndNil(SpecialFormat);
6231 else aStream.Position := StartPos;
6234 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6235 procedure TglBitmap.SaveBMP(const aStream: TStream);
6239 Converter: TbmpColorTableFormat;
6240 FormatDesc: TFormatDescriptor;
6241 SourceFD, DestFD: Pointer;
6242 pData, srcData, dstData, ConvertBuffer: pByte;
6244 Pixel: TglBitmapPixelData;
6245 PixelFormat: TglBitmapPixelData;
6246 ImageSize, wbLineSize, rbLineSize, Padding, LineIdx, PixelIdx, i: Integer;
6247 RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
6249 PaddingBuff: Cardinal;
6251 function GetLineWidth : Integer;
6253 result := ((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3;
6257 if not (ftBMP in FormatGetSupportedFiles(Format)) then
6258 raise EglBitmapUnsupportedFormatFormat.Create('SaveBMP - ' + UNSUPPORTED_FORMAT);
6261 FormatDesc := TFormatDescriptor.Get(Format);
6262 ImageSize := FormatDesc.GetSize(Dimension);
6264 FillChar(Header, SizeOf(Header), 0);
6265 Header.bfType := BMP_MAGIC;
6266 Header.bfSize := SizeOf(Header) + SizeOf(Info) + ImageSize;
6267 Header.bfReserved1 := 0;
6268 Header.bfReserved2 := 0;
6269 Header.bfOffBits := SizeOf(Header) + SizeOf(Info);
6271 FillChar(Info, SizeOf(Info), 0);
6272 Info.biSize := SizeOf(Info);
6273 Info.biWidth := Width;
6274 Info.biHeight := Height;
6276 Info.biCompression := BMP_COMP_RGB;
6277 Info.biSizeImage := ImageSize;
6282 Info.biBitCount := 4;
6283 Header.bfSize := Header.bfSize + 16 * SizeOf(Cardinal);
6284 Header.bfOffBits := Header.bfOffBits + 16 * SizeOf(Cardinal); //16 ColorTable entries
6285 Converter := TbmpColorTableFormat.Create;
6286 Converter.PixelSize := 0.5;
6287 Converter.Format := Format;
6288 Converter.Range := glBitmapColorRec($F, $F, $F, $0);
6289 Converter.CreateColorTable;
6292 tfR3G3B2, tfLuminance8: begin
6293 Info.biBitCount := 8;
6294 Header.bfSize := Header.bfSize + 256 * SizeOf(Cardinal);
6295 Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal); //256 ColorTable entries
6296 Converter := TbmpColorTableFormat.Create;
6297 Converter.PixelSize := 1;
6298 Converter.Format := Format;
6299 if (Format = tfR3G3B2) then begin
6300 Converter.Range := glBitmapColorRec($7, $7, $3, $0);
6301 Converter.Shift := glBitmapShiftRec(0, 3, 6, 0);
6303 Converter.Range := glBitmapColorRec($FF, $FF, $FF, $0);
6304 Converter.CreateColorTable;
6307 tfRGB4, tfRGB5, tfR5G6B5, tfRGB5A1, tfRGBA4,
6308 tfBGR4, tfBGR5, tfB5G6R5, tfBGR5A1, tfBGRA4: begin
6309 Info.biBitCount := 16;
6310 Info.biCompression := BMP_COMP_BITFIELDS;
6313 tfBGR8, tfRGB8: begin
6314 Info.biBitCount := 24;
6317 tfRGB10, tfRGB10A2, tfRGBA8,
6318 tfBGR10, tfBGR10A2, tfBGRA8: begin
6319 Info.biBitCount := 32;
6320 Info.biCompression := BMP_COMP_BITFIELDS;
6323 raise EglBitmapUnsupportedFormatFormat.Create('SaveBMP - ' + UNSUPPORTED_FORMAT);
6325 Info.biXPelsPerMeter := 2835;
6326 Info.biYPelsPerMeter := 2835;
6329 if Info.biCompression = BMP_COMP_BITFIELDS then begin
6330 Header.bfSize := Header.bfSize + 4 * SizeOf(Cardinal);
6331 Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal);
6333 RedMask := FormatDesc.RedMask;
6334 GreenMask := FormatDesc.GreenMask;
6335 BlueMask := FormatDesc.BlueMask;
6336 AlphaMask := FormatDesc.AlphaMask;
6340 aStream.Write(Header, SizeOf(Header));
6341 aStream.Write(Info, SizeOf(Info));
6344 if Assigned(Converter) then
6345 aStream.Write(Converter.ColorTable[0].b,
6346 SizeOf(TbmpColorTableEnty) * Length(Converter.ColorTable));
6349 if Info.biCompression = BMP_COMP_BITFIELDS then begin
6350 aStream.Write(RedMask, SizeOf(Cardinal));
6351 aStream.Write(GreenMask, SizeOf(Cardinal));
6352 aStream.Write(BlueMask, SizeOf(Cardinal));
6353 aStream.Write(AlphaMask, SizeOf(Cardinal));
6357 rbLineSize := Round(Info.biWidth * FormatDesc.PixelSize);
6358 wbLineSize := Round(Info.biWidth * Info.biBitCount / 8);
6359 Padding := GetLineWidth - wbLineSize;
6363 inc(pData, (Height-1) * rbLineSize);
6365 // prepare row buffer. But only for RGB because RGBA supports color masks
6366 // so it's possible to change color within the image.
6367 if Assigned(Converter) then begin
6368 FormatDesc.PreparePixel(Pixel);
6369 GetMem(ConvertBuffer, wbLineSize);
6370 SourceFD := FormatDesc.CreateMappingData;
6371 DestFD := Converter.CreateMappingData;
6373 ConvertBuffer := nil;
6376 for LineIdx := 0 to Height - 1 do begin
6378 if Assigned(Converter) then begin
6380 dstData := ConvertBuffer;
6381 for PixelIdx := 0 to Info.biWidth-1 do begin
6382 FormatDesc.Unmap(srcData, Pixel, SourceFD);
6383 with FormatDesc do begin
6384 //TODO use convert function
6386 if (Converter.Range.arr[i] <> Range.arr[i]) then begin
6387 if (Range.arr[i] > 0) then
6388 Pixel.Data.arr[i] := Round(Pixel.Data.arr[i] / Range.arr[i] * Converter.Range.arr[i])
6390 Pixel.Data.arr[i] := 0;
6393 Converter.Map(Pixel, dstData, DestFD);
6395 aStream.Write(ConvertBuffer^, wbLineSize);
6397 aStream.Write(pData^, rbLineSize);
6399 dec(pData, rbLineSize);
6400 if (Padding > 0) then
6401 aStream.Write(PaddingBuff, Padding);
6404 // destroy row buffer
6405 if Assigned(ConvertBuffer) then begin
6406 FormatDesc.FreeMappingData(SourceFD);
6407 Converter.FreeMappingData(DestFD);
6408 FreeMem(ConvertBuffer);
6412 if Assigned(Converter) then
6417 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6418 //TGA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6419 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6421 TTGAHeader = packed record
6425 ColorMapSpec: Array[0..4] of Byte;
6435 TGA_UNCOMPRESSED_RGB = 2;
6436 TGA_UNCOMPRESSED_GRAY = 3;
6437 TGA_COMPRESSED_RGB = 10;
6438 TGA_COMPRESSED_GRAY = 11;
6440 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6441 function TglBitmap.LoadTGA(const aStream: TStream): Boolean;
6444 NewImage, pData: PByte;
6446 PixelSize, LineSize, YStart, YEnd, YInc: Integer;
6447 Format: TglBitmapFormat;
6452 ////////////////////////////////////////////////////////////////////////////////////////
6453 procedure ReadUncompressed;
6457 RowSize := Header.Width * PixelSize;
6458 // copy line by line
6459 while YStart <> YEnd + YInc do begin
6461 Inc(pData, YStart * LineSize);
6462 aStream.Read(pData^, RowSize);
6467 ////////////////////////////////////////////////////////////////////////////////////////
6468 procedure ReadCompressed;
6470 HeaderWidth, HeaderHeight: Integer;
6471 LinePixelsRead, ImgPixelsRead, ImgPixelsToRead: Integer;
6474 CacheSize, CachePos: Integer;
6477 TempBuf: Array [0..15] of Byte;
6479 PixelRepeat: Boolean;
6480 PixelToRead, TempPixels: Integer;
6482 /////////////////////////////////////////////////////////////////
6483 procedure CheckLine;
6485 if LinePixelsRead >= HeaderWidth then begin
6486 LinePixelsRead := 0;
6489 Inc(pData, YStart * LineSize);
6493 /////////////////////////////////////////////////////////////////
6494 procedure CachedRead(out Buffer; Count: Integer);
6498 if (CachePos + Count) > CacheSize then begin
6502 if CacheSize - CachePos > 0 then begin
6503 BytesRead := CacheSize - CachePos;
6504 Move(pByteArray(Cache)^[CachePos], Buffer, BytesRead);
6505 Inc(CachePos, BytesRead);
6509 CacheSize := Min(CACHE_SIZE, aStream.Size - aStream.Position);
6510 aStream.Read(Cache^, CacheSize);
6514 if Count - BytesRead > 0 then begin
6515 Move(pByteArray(Cache)^[CachePos], TByteArray(Buffer)[BytesRead], Count - BytesRead);
6516 Inc(CachePos, Count - BytesRead);
6519 Move(pByteArray(Cache)^[CachePos], Buffer, Count);
6520 Inc(CachePos, Count);
6528 HeaderWidth := Header.Width;
6529 HeaderHeight := Header.Height;
6531 GetMem(Cache, CACHE_SIZE); // 16K Buffer
6533 ImgPixelsToRead := HeaderWidth * HeaderHeight;
6535 LinePixelsRead := 0;
6538 Inc(pData, YStart * LineSize);
6540 // Read until all Pixels
6542 CachedRead(Temp, 1);
6544 PixelRepeat := Temp and $80 > 0;
6545 PixelToRead := (Temp and $7F) + 1;
6547 Inc(ImgPixelsRead, PixelToRead);
6549 if PixelRepeat then begin
6550 // repeat one pixel x times
6551 CachedRead(TempBuf[0], PixelSize);
6554 while PixelToRead > 0 do begin
6557 TempPixels := HeaderWidth - LinePixelsRead;
6558 if PixelToRead < TempPixels then
6559 TempPixels := PixelToRead;
6561 Inc(LinePixelsRead, TempPixels);
6562 Dec(PixelToRead, TempPixels);
6564 while TempPixels > 0 do begin
6567 pData^ := TempBuf[0];
6571 pWord(pData)^ := pWord(@TempBuf[0])^;
6575 pWord(pData)^ := pWord(@TempBuf[0])^;
6577 pData^ := TempBuf[2];
6581 pDWord(pData)^ := pDWord(@TempBuf[0])^;
6590 while PixelToRead > 0 do begin
6592 TempPixels := HeaderWidth - LinePixelsRead;
6593 if PixelToRead < TempPixels then
6594 TempPixels := PixelToRead;
6595 CachedRead(pData^, PixelSize * TempPixels);
6596 Inc(pData, PixelSize * TempPixels);
6597 Inc(LinePixelsRead, TempPixels);
6598 Dec(PixelToRead, TempPixels);
6601 until ImgPixelsRead >= ImgPixelsToRead;
6610 // reading header to test file and set cursor back to begin
6611 StreamPos := aStream.Position;
6612 aStream.Read(Header, SizeOf(Header));
6614 // no colormapped files
6615 if (Header.ColorMapType = 0) then begin
6616 if Header.ImageType in [TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY] then begin
6618 //TODO 8: Format := tfAlpha8;
6619 16: Format := tfLuminance8Alpha8;
6620 24: Format := tfBGR8;
6621 32: Format := tfBGRA8;
6623 raise EglBitmapException.Create('LoadTga - unsupported BitsPerPixel found.');
6627 if Header.ImageID <> 0 then
6628 aStream.Position := aStream.Position + Header.ImageID;
6630 PixelSize := TFormatDescriptor.Get(Format).GetSize(1, 1);
6631 LineSize := Trunc(Header.Width * PixelSize);
6633 GetMem(NewImage, LineSize * Header.Height);
6636 if (Header.ImageDes and $20 > 0) then begin
6638 YEnd := Header.Height -1;
6641 YStart := Header.Height -1;
6647 case Header.ImageType of
6648 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY:
6650 TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY:
6654 SetDataPointer(NewImage, Format, Header.Width, Header.Height);
6661 else aStream.Position := StreamPos;
6663 else aStream.Position := StreamPos;
6666 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6667 procedure TglBitmap.SaveTGA(const aStream: TStream);
6672 FormatDesc: TFormatDescriptor;
6674 procedure ConvertData(pTemp: pByte);
6676 Idx, PixelSize: Integer;
6679 PixelSize := fPixelSize;
6680 for Idx := 1 to Height * Width do begin
6681 Temp := pByteArray(pTemp)^[2];
6682 pByteArray(pTemp)^[2] := pByteArray(pTemp)^[0];
6683 pByteArray(pTemp)^[0] := Temp;
6684 Inc(pTemp, PixelSize);
6689 if not (ftTGA in FormatGetSupportedFiles(Format)) then
6690 raise EglBitmapUnsupportedFormatFormat.Create('SaveTGA - ' + UNSUPPORTED_FORMAT);
6692 FillChar(Header, SizeOf(Header), 0);
6694 //TODO ifAlpha8, ifLuminance8, ifDepth8: begin
6696 Header.ImageType := TGA_UNCOMPRESSED_GRAY;
6699 tfLuminance8Alpha8: begin
6700 Header.ImageType := TGA_UNCOMPRESSED_GRAY;
6703 tfRGB8, tfBGR8: begin
6704 Header.ImageType := TGA_UNCOMPRESSED_RGB;
6707 tfRGBA8, tfBGRA8: begin
6708 Header.ImageType := TGA_UNCOMPRESSED_RGB;
6712 raise EglBitmapUnsupportedFormatFormat.Create('SaveTGA - ' + UNSUPPORTED_FORMAT);
6715 Header.Width := Width;
6716 Header.Height := Height;
6717 Header.ImageDes := $20;
6718 FormatDesc := TFormatDescriptor.Get(Format);
6720 if FormatDesc.HasAlpha then
6721 Header.ImageDes := Header.ImageDes or $08;
6722 aStream.Write(Header, SizeOf(Header));
6724 // convert RGB(A) to BGR(A)
6725 Size := FormatDesc.GetSize(Dimension);
6726 if Format in [tfRGB8, tfRGBA8] then begin
6727 GetMem(pTemp, Size);
6733 if Format in [tfRGB8, tfRGBA8] then begin
6734 Move(Data^, pTemp^, Size);
6739 aStream.Write(pTemp^, Size);
6742 if Format in [tfRGB8, tfRGBA8] then
6747 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6748 //DDS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6749 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6751 DDS_MAGIC = $20534444;
6753 // DDS_header.dwFlags
6754 DDSD_CAPS = $00000001;
6755 DDSD_HEIGHT = $00000002;
6756 DDSD_WIDTH = $00000004;
6757 DDSD_PITCH = $00000008;
6758 DDSD_PIXELFORMAT = $00001000;
6759 DDSD_MIPMAPCOUNT = $00020000;
6760 DDSD_LINEARSIZE = $00080000;
6761 DDSD_DEPTH = $00800000;
6763 // DDS_header.sPixelFormat.dwFlags
6764 DDPF_ALPHAPIXELS = $00000001;
6765 DDPF_FOURCC = $00000004;
6766 DDPF_INDEXED = $00000020;
6767 DDPF_RGB = $00000040;
6769 // DDS_header.sCaps.dwCaps1
6770 DDSCAPS_COMPLEX = $00000008;
6771 DDSCAPS_TEXTURE = $00001000;
6772 DDSCAPS_MIPMAP = $00400000;
6774 // DDS_header.sCaps.dwCaps2
6775 DDSCAPS2_CUBEMAP = $00000200;
6776 DDSCAPS2_CUBEMAP_POSITIVEX = $00000400;
6777 DDSCAPS2_CUBEMAP_NEGATIVEX = $00000800;
6778 DDSCAPS2_CUBEMAP_POSITIVEY = $00001000;
6779 DDSCAPS2_CUBEMAP_NEGATIVEY = $00002000;
6780 DDSCAPS2_CUBEMAP_POSITIVEZ = $00004000;
6781 DDSCAPS2_CUBEMAP_NEGATIVEZ = $00008000;
6782 DDSCAPS2_VOLUME = $00200000;
6784 D3DFMT_DXT1 = $31545844;
6785 D3DFMT_DXT3 = $33545844;
6786 D3DFMT_DXT5 = $35545844;
6789 TDDSPixelFormat = packed record
6793 dwRGBBitCount: Cardinal;
6794 dwRBitMask: Cardinal;
6795 dwGBitMask: Cardinal;
6796 dwBBitMask: Cardinal;
6797 dwABitMask: Cardinal;
6800 TDDSCaps = packed record
6804 dwReserved: Cardinal;
6807 TDDSHeader = packed record
6813 dwPitchOrLinearSize: Cardinal;
6815 dwMipMapCount: Cardinal;
6816 dwReserved: array[0..10] of Cardinal;
6817 PixelFormat: TDDSPixelFormat;
6819 dwReserved2: Cardinal;
6822 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6823 function TglBitmap.LoadDDS(const aStream: TStream): Boolean;
6827 Y, LineSize: Cardinal;
6829 NewImage, pData: pByte;
6830 ddsFormat: TglBitmapFormat;
6832 function RaiseEx : Exception;
6834 result := EglBitmapException.Create('LoadDDS - unsupported Pixelformat found.');
6837 function GetDDSFormat: TglBitmapFormat;
6839 with Header.PixelFormat do begin
6841 if (dwFlags and DDPF_FOURCC) > 0 then begin
6843 case Header.PixelFormat.dwFourCC of
6844 D3DFMT_DXT1: result := ifDXT1;
6845 D3DFMT_DXT3: result := ifDXT3;
6846 D3DFMT_DXT5: result := ifDXT5;
6855 if (dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS)) > 0 then begin
6856 case dwRGBBitCount of
6858 (* TODO if dwFlags and DDPF_ALPHAPIXELS > 0 then
6862 result := tfLuminance8;
6865 if dwFlags and DDPF_ALPHAPIXELS > 0 then begin
6867 case CountSetBits(dwRBitMask) of
6868 5: result := tfRGB5A1;
6869 //TODO 4: result := tfRGBA4;
6871 result := tfLuminance8Alpha8;
6875 //TODO result := ifR5G6B5;
6880 if dwRBitMask > dwBBitMask then
6886 if CountSetBits(dwRBitMask) = 10 then
6887 //TODO result := tfRGB10A2
6891 if dwRBitMask > dwBBitMask then
6908 StreamPos := aStream.Position;
6909 aStream.Read(Header, sizeof(Header));
6911 if ((Header.dwMagic <> DDS_MAGIC) or (Header.dwSize <> 124) or
6912 ((Header.dwFlags and DDSD_PIXELFORMAT) = 0) or ((Header.dwFlags and DDSD_CAPS) = 0)) then begin
6913 aStream.Position := StreamPos;
6917 ddsFormat := GetDDSFormat;
6918 LineSize := Trunc(Header.dwWidth * TFormatDescriptor.Get(ddsFormat).PixelSize);
6919 GetMem(NewImage, Header.dwHeight * LineSize);
6924 if (Header.PixelFormat.dwFlags and DDPF_FOURCC) > 0 then begin
6925 RowSize := Header.dwPitchOrLinearSize div Header.dwWidth;
6926 for Y := 0 to Header.dwHeight -1 do begin
6927 aStream.Read(pData^, RowSize);
6928 Inc(pData, LineSize);
6933 if (Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS)) > 0 then begin
6934 RowSize := Header.dwPitchOrLinearSize;
6936 for Y := 0 to Header.dwHeight -1 do begin
6937 aStream.Read(pData^, RowSize);
6938 Inc(pData, LineSize);
6943 SetDataPointer(NewImage, ddsFormat, Header.dwWidth, Header.dwHeight);
6951 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6952 procedure TglBitmap.SaveDDS(const aStream: TStream);
6955 Pix: TglBitmapPixelData;
6956 FormatDesc: TFormatDescriptor;
6958 //if not FormatIsUncompressed(InternalFormat) then
6959 // raise EglBitmapUnsupportedFormatFormat.Create('SaveDDS - ' + UNSUPPORTED_FORMAT);
6961 (* TODO if Format = tfAlpha8 then
6962 FORMAT_DESCRIPTORS[tfLuminance8].PreparePixel(Pix);
6964 TFormatDescriptor.Get(Format).PreparePixel(Pix);
6967 FillChar(Header, SizeOf(Header), 0);
6968 Header.dwMagic := DDS_MAGIC;
6969 Header.dwSize := 124;
6970 Header.dwFlags := DDSD_PITCH or DDSD_CAPS or DDSD_PIXELFORMAT;
6972 if Width > 0 then begin
6973 Header.dwWidth := Width;
6974 Header.dwFlags := Header.dwFlags or DDSD_WIDTH;
6977 if Height > 0 then begin
6978 Header.dwHeight := Height;
6979 Header.dwFlags := Header.dwFlags or DDSD_HEIGHT;
6982 Header.dwPitchOrLinearSize := fRowSize;
6983 Header.dwMipMapCount := 1;
6986 Header.Caps.dwCaps1 := DDSCAPS_TEXTURE;
6989 Header.PixelFormat.dwSize := Sizeof(Header.PixelFormat);
6990 Header.PixelFormat.dwFlags := DDPF_RGB;
6993 if FORMAT_DESCRIPTORS[Format].HasAlpha and (Format <> tfAlpha8) then
6994 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHAPIXELS;
6997 FormatDesc := TFormatDescriptor.Get(Format);
6998 Header.PixelFormat.dwRGBBitCount := Trunc(FormatDesc.PixelSize * 8);
6999 Header.PixelFormat.dwRBitMask := FormatDesc.RedMask;
7000 Header.PixelFormat.dwGBitMask := FormatDesc.GreenMask;
7001 Header.PixelFormat.dwBBitMask := FormatDesc.BlueMask;
7002 Header.PixelFormat.dwABitMask := FormatDesc.AlphaMask;
7004 aStream.Write(Header, SizeOf(Header));
7005 aStream.Write(Data^, FormatDesc.GetSize(Dimension));
7008 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7009 //TglBitmap2D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7010 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7011 function TglBitmap2D.GetScanline(const aIndex: Integer): Pointer;
7013 if (aIndex >= Low(fLines)) and (aIndex <= High(fLines)) then
7014 result := fLines[aIndex]
7019 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7020 procedure TglBitmap2D.SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
7021 const aWidth: Integer; const aHeight: Integer);
7023 Idx, LineWidth: Integer;
7025 inherited SetDataPointer(aData, aFormat, aWidth, aHeight);
7028 if {FormatIsUncompressed(Format)} true then begin
7030 fGetPixelFunc := GetPixel2DUnmap;
7031 fSetPixelFunc := SetPixel2DUnmap;
7034 if Assigned(Data) then begin
7035 SetLength(fLines, GetHeight);
7036 LineWidth := Trunc(GetWidth * TFormatDescriptor.Get(Format).PixelSize);
7038 for Idx := 0 to GetHeight -1 do begin
7039 fLines[Idx] := Data;
7040 Inc(fLines[Idx], Idx * LineWidth);
7043 else SetLength(fLines, 0);
7046 SetLength(fLines, 0);
7048 fSetPixelFunc := nil;
7052 fGetPixelFunc := GetPixel2DDXT1;
7054 fGetPixelFunc := GetPixel2DDXT3;
7056 fGetPixelFunc := GetPixel2DDXT5;
7058 fGetPixelFunc := nil;
7064 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7065 procedure TglBitmap2D.UploadData(const aTarget: Cardinal; const aBuildWithGlu: Boolean);
7067 FormatDesc: TFormatDescriptor;
7069 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
7072 if Self.InternalFormat in [ifDXT1, ifDXT3, ifDXT5] then
7073 glCompressedTexImage2D(Target, 0, InternalFormat, Width, Height, 0, Trunc(Width * Height * FormatGetSize(Self.InternalFormat)), Data)
7077 FormatDesc := TFormatDescriptor.Get(Format);
7078 if aBuildWithGlu then
7079 gluBuild2DMipmaps(aTarget, FormatDesc.Components, Width, Height,
7080 FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
7082 glTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0,
7083 FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
7086 if (FreeDataAfterGenTexture) then
7090 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7091 procedure TglBitmap2D.AfterConstruction;
7094 Target := GL_TEXTURE_2D;
7097 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7098 procedure TglBitmap2D.GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
7101 Size, w, h: Integer;
7102 FormatDesc: TFormatDescriptor;
7105 if not FormatIsUncompressed(Format) then
7106 raise EglBitmapUnsupportedFormatFormat.Create('TglBitmap2D.GrabScreen - ' + UNSUPPORTED_FORMAT);
7109 w := aRight - aLeft;
7110 h := aBottom - aTop;
7111 FormatDesc := TFormatDescriptor.Get(Format);
7112 Size := FormatDesc.GetSize(w, h);
7115 glPixelStorei(GL_PACK_ALIGNMENT, 1);
7116 glReadPixels(aLeft, aTop, w, h, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
7117 SetDataPointer(Temp, Format, w, h);
7125 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7126 procedure TglBitmap2D.GetDataFromTexture;
7129 TempWidth, TempHeight: Integer;
7130 TempType, TempIntFormat: Cardinal;
7131 IntFormat, f: TglBitmapFormat;
7132 FormatDesc: TFormatDescriptor;
7137 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_WIDTH, @TempWidth);
7138 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT, @TempHeight);
7139 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat);
7141 IntFormat := tfEmpty;
7142 for f := Low(TglBitmapFormat) to High(TglBitmapFormat) do
7143 if (TFormatDescriptor.Get(f).glInternalFormat = TempIntFormat) then begin
7144 IntFormat := FormatDesc.Format;
7148 // Getting data from OpenGL
7149 FormatDesc := TFormatDescriptor.Get(IntFormat);
7150 GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight));
7153 if FormatIsCompressed(IntFormat) and (GL_VERSION_1_3 or GL_ARB_texture_compression) then
7154 glGetCompressedTexImage(Target, 0, Temp)
7157 glGetTexImage(Target, 0, FormatDesc.glInternalFormat, FormatDesc.glDataFormat, Temp);
7158 SetDataPointer(Temp, IntFormat, TempWidth, TempHeight);
7165 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7166 procedure TglBitmap2D.GenTexture(const aTestTextureSize: Boolean);
7168 BuildWithGlu, PotTex, TexRec: Boolean;
7171 if Assigned(Data) then begin
7172 // Check Texture Size
7173 if (aTestTextureSize) then begin
7174 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
7176 if ((Height > TexSize) or (Width > TexSize)) then
7177 raise EglBitmapSizeToLargeException.Create('TglBitmap2D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
7179 PotTex := IsPowerOfTwo(Height) and IsPowerOfTwo(Width);
7180 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and (Target = GL_TEXTURE_RECTANGLE_ARB);
7182 if not (PotTex or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
7183 raise EglBitmapNonPowerOfTwoException.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
7187 SetupParameters(BuildWithGlu);
7188 UploadData(Target, BuildWithGlu);
7189 glAreTexturesResident(1, @fID, @fIsResident);
7193 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7194 function TglBitmap2D.FlipHorz: Boolean;
7197 TempDestData, DestData, SourceData: PByte;
7200 result := inherited FlipHorz;
7201 if Assigned(Data) then begin
7203 ImgSize := Height * fRowSize;
7204 GetMem(DestData, ImgSize);
7206 TempDestData := DestData;
7207 Dec(TempDestData, fRowSize + fPixelSize);
7208 for Row := 0 to Height -1 do begin
7209 Inc(TempDestData, fRowSize * 2);
7210 for Col := 0 to Width -1 do begin
7211 Move(SourceData^, TempDestData^, fPixelSize);
7212 Inc(SourceData, fPixelSize);
7213 Dec(TempDestData, fPixelSize);
7216 SetDataPointer(DestData, Format);
7225 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7226 function TglBitmap2D.FlipVert: Boolean;
7229 TempDestData, DestData, SourceData: PByte;
7231 result := inherited FlipVert;
7232 if Assigned(Data) then begin
7234 GetMem(DestData, Height * fRowSize);
7236 TempDestData := DestData;
7237 Inc(TempDestData, Width * (Height -1) * fPixelSize);
7238 for Row := 0 to Height -1 do begin
7239 Move(SourceData^, TempDestData^, fRowSize);
7240 Dec(TempDestData, fRowSize);
7241 Inc(SourceData, fRowSize);
7243 SetDataPointer(DestData, Format);
7252 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7253 //TglBitmap2D - ToNormalMap///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7254 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7256 TMatrixItem = record
7261 PglBitmapToNormalMapRec = ^TglBitmapToNormalMapRec;
7262 TglBitmapToNormalMapRec = Record
7264 Heights: array of Single;
7265 MatrixU : array of TMatrixItem;
7266 MatrixV : array of TMatrixItem;
7270 ONE_OVER_255 = 1 / 255;
7272 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7273 procedure glBitmapToNormalMapPrepareFunc(var FuncRec: TglBitmapFunctionRec);
7277 with FuncRec do begin
7279 Source.Data.r * LUMINANCE_WEIGHT_R +
7280 Source.Data.g * LUMINANCE_WEIGHT_G +
7281 Source.Data.b * LUMINANCE_WEIGHT_B;
7282 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Val * ONE_OVER_255;
7286 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7287 procedure glBitmapToNormalMapPrepareAlphaFunc(var FuncRec: TglBitmapFunctionRec);
7290 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Source.Data.a * ONE_OVER_255;
7293 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7294 procedure glBitmapToNormalMapFunc (var FuncRec: TglBitmapFunctionRec);
7296 TVec = Array[0..2] of Single;
7303 function GetHeight(X, Y: Integer): Single;
7305 with FuncRec do begin
7306 X := Max(0, Min(Size.X -1, X));
7307 Y := Max(0, Min(Size.Y -1, Y));
7308 result := PglBitmapToNormalMapRec(Args)^.Heights[Y * Size.X + X];
7313 with FuncRec do begin
7314 with PglBitmapToNormalMapRec(Args)^ do begin
7316 for Idx := Low(MatrixU) to High(MatrixU) do
7317 du := du + GetHeight(Position.X + MatrixU[Idx].X, Position.Y + MatrixU[Idx].Y) * MatrixU[Idx].W;
7320 for Idx := Low(MatrixU) to High(MatrixU) do
7321 dv := dv + GetHeight(Position.X + MatrixV[Idx].X, Position.Y + MatrixV[Idx].Y) * MatrixV[Idx].W;
7323 Vec[0] := -du * Scale;
7324 Vec[1] := -dv * Scale;
7329 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
7330 if Len <> 0 then begin
7331 Vec[0] := Vec[0] * Len;
7332 Vec[1] := Vec[1] * Len;
7333 Vec[2] := Vec[2] * Len;
7337 Dest.Data.r := Trunc((Vec[0] + 1) * 127.5);
7338 Dest.Data.g := Trunc((Vec[1] + 1) * 127.5);
7339 Dest.Data.b := Trunc((Vec[2] + 1) * 127.5);
7343 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7344 procedure TglBitmap2D.ToNormalMap(const aFunc: TglBitmapNormalMapFunc; const aScale: Single; const aUseAlpha: Boolean);
7346 Rec: TglBitmapToNormalMapRec;
7348 procedure SetEntry (var Matrix: array of TMatrixItem; Index, X, Y: Integer; W: Single);
7350 if (Index >= Low(Matrix)) and (Index <= High(Matrix)) then begin
7351 Matrix[Index].X := X;
7352 Matrix[Index].Y := Y;
7353 Matrix[Index].W := W;
7359 if not FormatIsUncompressed(InternalFormat) then
7360 raise EglBitmapUnsupportedFormatFormat.Create('TglBitmap2D.ToNormalMap - ' + UNSUPPORTED_FORMAT);
7363 if aScale > 100 then
7365 else if aScale < -100 then
7368 Rec.Scale := aScale;
7370 SetLength(Rec.Heights, Width * Height);
7374 SetLength(Rec.MatrixU, 2);
7375 SetEntry(Rec.MatrixU, 0, -1, 0, -0.5);
7376 SetEntry(Rec.MatrixU, 1, 1, 0, 0.5);
7378 SetLength(Rec.MatrixV, 2);
7379 SetEntry(Rec.MatrixV, 0, 0, 1, 0.5);
7380 SetEntry(Rec.MatrixV, 1, 0, -1, -0.5);
7384 SetLength(Rec.MatrixU, 6);
7385 SetEntry(Rec.MatrixU, 0, -1, 1, -1.0);
7386 SetEntry(Rec.MatrixU, 1, -1, 0, -2.0);
7387 SetEntry(Rec.MatrixU, 2, -1, -1, -1.0);
7388 SetEntry(Rec.MatrixU, 3, 1, 1, 1.0);
7389 SetEntry(Rec.MatrixU, 4, 1, 0, 2.0);
7390 SetEntry(Rec.MatrixU, 5, 1, -1, 1.0);
7392 SetLength(Rec.MatrixV, 6);
7393 SetEntry(Rec.MatrixV, 0, -1, 1, 1.0);
7394 SetEntry(Rec.MatrixV, 1, 0, 1, 2.0);
7395 SetEntry(Rec.MatrixV, 2, 1, 1, 1.0);
7396 SetEntry(Rec.MatrixV, 3, -1, -1, -1.0);
7397 SetEntry(Rec.MatrixV, 4, 0, -1, -2.0);
7398 SetEntry(Rec.MatrixV, 5, 1, -1, -1.0);
7402 SetLength(Rec.MatrixU, 6);
7403 SetEntry(Rec.MatrixU, 0, -1, 1, -1/6);
7404 SetEntry(Rec.MatrixU, 1, -1, 0, -1/6);
7405 SetEntry(Rec.MatrixU, 2, -1, -1, -1/6);
7406 SetEntry(Rec.MatrixU, 3, 1, 1, 1/6);
7407 SetEntry(Rec.MatrixU, 4, 1, 0, 1/6);
7408 SetEntry(Rec.MatrixU, 5, 1, -1, 1/6);
7410 SetLength(Rec.MatrixV, 6);
7411 SetEntry(Rec.MatrixV, 0, -1, 1, 1/6);
7412 SetEntry(Rec.MatrixV, 1, 0, 1, 1/6);
7413 SetEntry(Rec.MatrixV, 2, 1, 1, 1/6);
7414 SetEntry(Rec.MatrixV, 3, -1, -1, -1/6);
7415 SetEntry(Rec.MatrixV, 4, 0, -1, -1/6);
7416 SetEntry(Rec.MatrixV, 5, 1, -1, -1/6);
7420 SetLength(Rec.MatrixU, 20);
7421 SetEntry(Rec.MatrixU, 0, -2, 2, -1 / 16);
7422 SetEntry(Rec.MatrixU, 1, -1, 2, -1 / 10);
7423 SetEntry(Rec.MatrixU, 2, 1, 2, 1 / 10);
7424 SetEntry(Rec.MatrixU, 3, 2, 2, 1 / 16);
7425 SetEntry(Rec.MatrixU, 4, -2, 1, -1 / 10);
7426 SetEntry(Rec.MatrixU, 5, -1, 1, -1 / 8);
7427 SetEntry(Rec.MatrixU, 6, 1, 1, 1 / 8);
7428 SetEntry(Rec.MatrixU, 7, 2, 1, 1 / 10);
7429 SetEntry(Rec.MatrixU, 8, -2, 0, -1 / 2.8);
7430 SetEntry(Rec.MatrixU, 9, -1, 0, -0.5);
7431 SetEntry(Rec.MatrixU, 10, 1, 0, 0.5);
7432 SetEntry(Rec.MatrixU, 11, 2, 0, 1 / 2.8);
7433 SetEntry(Rec.MatrixU, 12, -2, -1, -1 / 10);
7434 SetEntry(Rec.MatrixU, 13, -1, -1, -1 / 8);
7435 SetEntry(Rec.MatrixU, 14, 1, -1, 1 / 8);
7436 SetEntry(Rec.MatrixU, 15, 2, -1, 1 / 10);
7437 SetEntry(Rec.MatrixU, 16, -2, -2, -1 / 16);
7438 SetEntry(Rec.MatrixU, 17, -1, -2, -1 / 10);
7439 SetEntry(Rec.MatrixU, 18, 1, -2, 1 / 10);
7440 SetEntry(Rec.MatrixU, 19, 2, -2, 1 / 16);
7442 SetLength(Rec.MatrixV, 20);
7443 SetEntry(Rec.MatrixV, 0, -2, 2, 1 / 16);
7444 SetEntry(Rec.MatrixV, 1, -1, 2, 1 / 10);
7445 SetEntry(Rec.MatrixV, 2, 0, 2, 0.25);
7446 SetEntry(Rec.MatrixV, 3, 1, 2, 1 / 10);
7447 SetEntry(Rec.MatrixV, 4, 2, 2, 1 / 16);
7448 SetEntry(Rec.MatrixV, 5, -2, 1, 1 / 10);
7449 SetEntry(Rec.MatrixV, 6, -1, 1, 1 / 8);
7450 SetEntry(Rec.MatrixV, 7, 0, 1, 0.5);
7451 SetEntry(Rec.MatrixV, 8, 1, 1, 1 / 8);
7452 SetEntry(Rec.MatrixV, 9, 2, 1, 1 / 16);
7453 SetEntry(Rec.MatrixV, 10, -2, -1, -1 / 16);
7454 SetEntry(Rec.MatrixV, 11, -1, -1, -1 / 8);
7455 SetEntry(Rec.MatrixV, 12, 0, -1, -0.5);
7456 SetEntry(Rec.MatrixV, 13, 1, -1, -1 / 8);
7457 SetEntry(Rec.MatrixV, 14, 2, -1, -1 / 10);
7458 SetEntry(Rec.MatrixV, 15, -2, -2, -1 / 16);
7459 SetEntry(Rec.MatrixV, 16, -1, -2, -1 / 10);
7460 SetEntry(Rec.MatrixV, 17, 0, -2, -0.25);
7461 SetEntry(Rec.MatrixV, 18, 1, -2, -1 / 10);
7462 SetEntry(Rec.MatrixV, 19, 2, -2, -1 / 16);
7467 if aUseAlpha and TFormatDescriptor.Get(Format).HasAlpha then
7468 AddFunc(glBitmapToNormalMapPrepareAlphaFunc, false, PtrInt(@Rec))
7470 AddFunc(glBitmapToNormalMapPrepareFunc, false, PtrInt(@Rec));
7471 AddFunc(glBitmapToNormalMapFunc, false, PtrInt(@Rec));
7473 SetLength(Rec.Heights, 0);
7486 procedure TglBitmap1D.SetDataPointer(Data: pByte; Format: TglBitmapInternalFormat; Width, Height: Integer);
7491 if Height > 1 then begin
7492 // extract first line of the data
7493 Size := FormatGetImageSize(glBitmapPosition(Width), Format);
7494 GetMem(pTemp, Size);
7496 Move(Data^, pTemp^, Size);
7503 inherited SetDataPointer(pTemp, Format, Width);
7505 if FormatIsUncompressed(Format) then begin
7506 fUnmapFunc := FormatGetUnMapFunc(Format);
7507 fGetPixelFunc := GetPixel1DUnmap;
7512 procedure TglBitmap1D.GetPixel1DUnmap(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
7517 Inc(pTemp, Pos.X * fPixelSize);
7519 fUnmapFunc(pTemp, Pixel);
7523 function TglBitmap1D.FlipHorz: Boolean;
7526 pTempDest, pDest, pSource: pByte;
7528 result := inherited FlipHorz;
7530 if Assigned(Data) and FormatIsUncompressed(InternalFormat) then begin
7533 GetMem(pDest, fRowSize);
7537 Inc(pTempDest, fRowSize);
7538 for Col := 0 to Width -1 do begin
7539 Move(pSource^, pTempDest^, fPixelSize);
7541 Inc(pSource, fPixelSize);
7542 Dec(pTempDest, fPixelSize);
7545 SetDataPointer(pDest, InternalFormat);
7555 procedure TglBitmap1D.UploadData (Target, Format, InternalFormat, Typ: Cardinal; BuildWithGlu: Boolean);
7558 if Self.InternalFormat in [ifDXT1, ifDXT3, ifDXT5] then
7559 glCompressedTexImage1D(Target, 0, InternalFormat, Width, 0, Trunc(Width * FormatGetSize(Self.InternalFormat)), Data)
7563 if BuildWithGlu then
7564 gluBuild1DMipmaps(Target, InternalFormat, Width, Format, Typ, Data)
7566 glTexImage1D(Target, 0, InternalFormat, Width, 0, Format, Typ, Data);
7569 if (FreeDataAfterGenTexture) then
7574 procedure TglBitmap1D.GenTexture(TestTextureSize: Boolean);
7576 BuildWithGlu, TexRec: Boolean;
7577 glFormat, glInternalFormat, glType: Cardinal;
7580 if Assigned(Data) then begin
7581 // Check Texture Size
7582 if (TestTextureSize) then begin
7583 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
7585 if (Width > TexSize) then
7586 raise EglBitmapSizeToLargeException.Create('TglBitmap1D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
7588 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and
7589 (Target = GL_TEXTURE_RECTANGLE_ARB);
7591 if not (IsPowerOfTwo (Width) or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
7592 raise EglBitmapNonPowerOfTwoException.Create('TglBitmap1D.GenTexture - Rendercontex dosn''t support non power of two texture.');
7597 SetupParameters(BuildWithGlu);
7598 SelectFormat(InternalFormat, glFormat, glInternalFormat, glType);
7600 UploadData(Target, glFormat, glInternalFormat, glType, BuildWithGlu);
7603 glAreTexturesResident(1, @fID, @fIsResident);
7608 procedure TglBitmap1D.AfterConstruction;
7612 Target := GL_TEXTURE_1D;
7616 { TglBitmapCubeMap }
7618 procedure TglBitmapCubeMap.AfterConstruction;
7622 if not (GL_VERSION_1_3 or GL_ARB_texture_cube_map or GL_EXT_texture_cube_map) then
7623 raise EglBitmapException.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
7625 SetWrap; // set all to GL_CLAMP_TO_EDGE
7626 Target := GL_TEXTURE_CUBE_MAP;
7627 fGenMode := GL_REFLECTION_MAP;
7631 procedure TglBitmapCubeMap.Bind(EnableTexCoordsGen, EnableTextureUnit: Boolean);
7633 inherited Bind (EnableTextureUnit);
7635 if EnableTexCoordsGen then begin
7636 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, fGenMode);
7637 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, fGenMode);
7638 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, fGenMode);
7639 glEnable(GL_TEXTURE_GEN_S);
7640 glEnable(GL_TEXTURE_GEN_T);
7641 glEnable(GL_TEXTURE_GEN_R);
7646 procedure TglBitmapCubeMap.GenerateCubeMap(CubeTarget: Cardinal; TestTextureSize: Boolean);
7648 glFormat, glInternalFormat, glType: Cardinal;
7649 BuildWithGlu: Boolean;
7652 // Check Texture Size
7653 if (TestTextureSize) then begin
7654 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, @TexSize);
7656 if ((Height > TexSize) or (Width > TexSize)) then
7657 raise EglBitmapSizeToLargeException.Create('TglBitmapCubeMap.GenTexture - The size for the Cubemap is to large. It''s may be not conform with the Hardware.');
7659 if not ((IsPowerOfTwo (Height) and IsPowerOfTwo (Width)) or GL_VERSION_2_0 or GL_ARB_texture_non_power_of_two) then
7660 raise EglBitmapNonPowerOfTwoException.Create('TglBitmapCubeMap.GenTexture - Cubemaps dosn''t support non power of two texture.');
7664 if ID = 0 then begin
7666 SetupParameters(BuildWithGlu);
7669 SelectFormat(InternalFormat, glFormat, glInternalFormat, glType);
7671 UploadData (CubeTarget, glFormat, glInternalFormat, glType, BuildWithGlu);
7675 procedure TglBitmapCubeMap.GenTexture(TestTextureSize: Boolean);
7677 Assert(false, 'TglBitmapCubeMap.GenTexture - Don''t call GenTextures directly.');
7681 procedure TglBitmapCubeMap.Unbind(DisableTexCoordsGen,
7682 DisableTextureUnit: Boolean);
7684 inherited Unbind (DisableTextureUnit);
7686 if DisableTexCoordsGen then begin
7687 glDisable(GL_TEXTURE_GEN_S);
7688 glDisable(GL_TEXTURE_GEN_T);
7689 glDisable(GL_TEXTURE_GEN_R);
7694 { TglBitmapNormalMap }
7697 TVec = Array[0..2] of Single;
7698 TglBitmapNormalMapGetVectorFunc = procedure (var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
7700 PglBitmapNormalMapRec = ^TglBitmapNormalMapRec;
7701 TglBitmapNormalMapRec = record
7703 Func: TglBitmapNormalMapGetVectorFunc;
7707 procedure glBitmapNormalMapPosX(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
7710 Vec[1] := - (Position.Y + 0.5 - HalfSize);
7711 Vec[2] := - (Position.X + 0.5 - HalfSize);
7715 procedure glBitmapNormalMapNegX(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
7717 Vec[0] := - HalfSize;
7718 Vec[1] := - (Position.Y + 0.5 - HalfSize);
7719 Vec[2] := Position.X + 0.5 - HalfSize;
7723 procedure glBitmapNormalMapPosY(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
7725 Vec[0] := Position.X + 0.5 - HalfSize;
7727 Vec[2] := Position.Y + 0.5 - HalfSize;
7731 procedure glBitmapNormalMapNegY(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
7733 Vec[0] := Position.X + 0.5 - HalfSize;
7734 Vec[1] := - HalfSize;
7735 Vec[2] := - (Position.Y + 0.5 - HalfSize);
7739 procedure glBitmapNormalMapPosZ(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
7741 Vec[0] := Position.X + 0.5 - HalfSize;
7742 Vec[1] := - (Position.Y + 0.5 - HalfSize);
7747 procedure glBitmapNormalMapNegZ(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
7749 Vec[0] := - (Position.X + 0.5 - HalfSize);
7750 Vec[1] := - (Position.Y + 0.5 - HalfSize);
7751 Vec[2] := - HalfSize;
7755 procedure glBitmapNormalMapFunc(var FuncRec: TglBitmapFunctionRec);
7760 with FuncRec do begin
7761 with PglBitmapNormalMapRec (CustomData)^ do begin
7762 Func(Vec, Position, HalfSize);
7765 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
7766 if Len <> 0 then begin
7767 Vec[0] := Vec[0] * Len;
7768 Vec[1] := Vec[1] * Len;
7769 Vec[2] := Vec[2] * Len;
7772 // Scale Vector and AddVectro
7773 Vec[0] := Vec[0] * 0.5 + 0.5;
7774 Vec[1] := Vec[1] * 0.5 + 0.5;
7775 Vec[2] := Vec[2] * 0.5 + 0.5;
7779 Dest.Red := Round(Vec[0] * 255);
7780 Dest.Green := Round(Vec[1] * 255);
7781 Dest.Blue := Round(Vec[2] * 255);
7786 procedure TglBitmapNormalMap.AfterConstruction;
7790 fGenMode := GL_NORMAL_MAP;
7794 procedure TglBitmapNormalMap.GenerateNormalMap(Size: Integer;
7795 TestTextureSize: Boolean);
7797 Rec: TglBitmapNormalMapRec;
7798 SizeRec: TglBitmapPixelPosition;
7800 Rec.HalfSize := Size div 2;
7802 FreeDataAfterGenTexture := false;
7804 SizeRec.Fields := [ffX, ffY];
7809 Rec.Func := glBitmapNormalMapPosX;
7810 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
7811 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X, TestTextureSize);
7814 Rec.Func := glBitmapNormalMapNegX;
7815 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
7816 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, TestTextureSize);
7819 Rec.Func := glBitmapNormalMapPosY;
7820 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
7821 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, TestTextureSize);
7824 Rec.Func := glBitmapNormalMapNegY;
7825 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
7826 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, TestTextureSize);
7829 Rec.Func := glBitmapNormalMapPosZ;
7830 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
7831 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, TestTextureSize);
7834 Rec.Func := glBitmapNormalMapNegZ;
7835 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
7836 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, TestTextureSize);
7841 glBitmapSetDefaultFormat(tfEmpty);
7842 glBitmapSetDefaultMipmap(mmMipmap);
7843 glBitmapSetDefaultFilter(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
7844 glBitmapSetDefaultWrap (GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
7846 glBitmapSetDefaultFreeDataAfterGenTexture(true);
7847 glBitmapSetDefaultDeleteTextureOnFree (true);
7849 TFormatDescriptor.Init;
7852 TFormatDescriptor.Finalize;