1 {***********************************************************
2 glBitmap by Steffen Xonna aka Lossy eX (2003-2008)
3 http://www.opengl24.de/index.php?cat=header&file=glbitmap
5 modified by Delphi OpenGL Community (http://delphigl.com/) (2013)
7 ------------------------------------------------------------
8 The contents of this file are used with permission, subject to
9 the Mozilla Public License Version 1.1 (the "License"); you may
10 not use this file except in compliance with the License. You may
11 obtain a copy of the License at
12 http://www.mozilla.org/MPL/MPL-1.1.html
13 ------------------------------------------------------------
15 ------------------------------------------------------------
18 - refactoring of the complete library
20 - The define GLB_DELPHI dosn't check versions anymore. If you say you are using delphi
21 then it's your problem if that isn't true. This prevents the unit for incompatibility
22 with newer versions of Delphi.
23 - Problems with D2009+ resolved (Thanks noeska and all i forgot)
24 - GetPixel isn't set if you are loading textures inside the constructor (Thanks Wilson)
26 - AddAlphaFromglBitmap used the custom pointer instead the imagedatapointer (Thanks Wilson)
27 - Additional Datapointer for functioninterface now has the name CustomData
29 - AssigneAlphaToBitmap overwrites his own palette (Thanks Wilson)
30 - If you load an texture from an file the property Filename will be set to the name of the file
31 - Three new properties to attach custom data to the Texture objects
32 - CustomName (free for use string)
33 - CustomNameW (free for use widestring)
34 - CustomDataPointer (free for use pointer to attach other objects or complex structures)
36 - RLE TGAs loaded much faster
38 - fixed some problem with reading RLE TGAs.
40 - function clone now only copys data if it's assigned and now it also copies the ID
41 - it seems that lazarus dont like comments in comments.
43 - It's possible to set the id of the texture
44 - define GLB_NO_NATIVE_GL deactivated by default
46 - Now supports the following libraries
50 - Linux compatibillity via free pascal compatibility (delphi sources optional)
51 - BMPs now loaded manuel
53 - Property DataPtr now has the name Data
54 - Functions are more flexible between RGB(A) and BGR(A). RGB can be saved as Bitmap and will be saved as BGR
55 - Unused Depth removed
56 - Function FreeData to freeing image data added
58 - ImageID flag of TGAs was ignored. (Thanks Zwoetzen)
60 - Function SetBorderColor implemented (only used by opengl if wrap is set to GL_CLAMP_TO_BORDER)
61 - Function AddAlphaFromValue implemented to use an fixed Value as Alphachannel
62 - Function ReadOpenGLExtension is now only intern
64 - pngimage now disabled by default like all other versions.
66 - Setting up an anisotropic filter of 0 isnt allowed by nvidia (Thanks Ogridi)
68 - Fixed some Problem with Delphi 5
69 - Now uses the newest version of pngimage. Makes saving pngs much easier.
71 - Property IsCompressed and Size removed. Not really supported by Spec (Thanks Ogridi)
73 - Internal Format ifDepth8 added
74 - function GrabScreen now supports all uncompressed formats
76 - AddAlphaFromglBitmap implemented
78 - LoadFromResource and LoadFromResourceId now needs an Instance and an ResourceType (for ID)
80 - Width, Height and Depth internal changed to TglBitmapPixelPosition.
81 property Width, Height, Depth are still existing and new property Dimension are avail
83 - Added native OpenGL Support. Breaking the dglOpenGL "barrier".
85 - Added function GrabScreen to class TglBitmap2D
87 - Added support to Save images
88 - Added function Clone to Clone Instance
90 - Functions now works with Cardinals for each channel. Up to 32 Bits per channel.
92 - Several speed optimizations
94 - Internal structure change. Loading of TGA, PNG and DDS improved.
95 Data, format and size will now set directly with SetDataPtr.
96 - AddFunc now works with all Types of Images and Formats
97 - Some Funtions moved to Baseclass TglBitmap
99 - Added Support to decompress DXT3 and DXT5 compressed Images.
100 - Added Mapping to convert data from one format into an other.
102 - Added method ConvertTo in Class TglBitmap2D. Method allows to convert every
103 supported Input format (supported by GetPixel) into any uncompresed Format
104 - Added Support to decompress DXT1 compressed Images.
105 - SwapColors replaced by ConvertTo
107 - Added Support for compressed DDSs
108 - Added new internal formats (DXT1, DXT3, DXT5)
110 - Parameter Components renamed to InternalFormat
112 - Some AllocMem replaced with GetMem (little speed change)
113 - better exception handling. Better protection from memory leaks.
115 - Added support for Direct Draw Surfaces (.DDS) (uncompressed images only)
116 - Added new internal formats (RGB8, RGBA8, RGBA4, RGB5A1, RGB10A2, R5G6B5)
118 - Added support for Grayscale textures
119 - Added internal formats (Alpha, Luminance, LuminanceAlpha, BGR8, BGRA8)
121 - Added support for GL_VERSION_2_0
122 - Added support for GL_EXT_texture_filter_anisotropic
124 - Function FillWithColor fills the Image with one Color
125 - Function LoadNormalMap added
127 - ToNormalMap allows to Create an NormalMap from the Alphachannel
128 - ToNormalMap now supports Sobel (nmSobel) function.
130 - support for RLE Compressed RGB TGAs added
132 - Class TglBitmapNormalMap added to support Normalmap generation
133 - Added function ToNormalMap in class TglBitmap2D to genereate normal maps from textures.
134 3 Filters are supported. (4 Samples, 3x3 and 5x5)
136 - Method LoadCubeMapClass removed
137 - LoadCubeMap returnvalue is now the Texture paramter. Such as LoadTextures
138 - virtual abstract method GenTexture in class TglBitmap now is protected
140 - now support DescriptionFlag in LoadTga. Allows vertical flipped images to be loaded as normal
142 - little enhancement for IsPowerOfTwo
143 - TglBitmap1D.GenTexture now tests NPOT Textures
145 - some little name changes. All properties or function with Texture in name are
146 now without texture in name. We have allways texture so we dosn't name it.
148 - GenTexture now tests if texture is NPOT and NPOT-Texture are supported or
149 TextureTarget is GL_TEXTURE_RECTANGLE. Else it raised an exception.
151 - added support for GL_ARB_texture_rectangle, GL_EXT_texture_rectangle and GL_NV_texture_rectangle
153 - Function Unbind added
154 - call of SetFilter or SetTextureWrap if TextureID exists results in setting properties to opengl texture.
156 - class TglBitmapCubeMap added (allows to Create Cubemaps)
158 - Added Support for PNG Images. (http://pngdelphi.sourceforge.net/)
159 To Enable png's use the define pngimage
161 - New Functioninterface added
162 - Function GetPixel added
164 - Property BuildMipMaps renamed to MipMap
166 - property Name removed.
167 - BuildMipMaps is now a set of 3 values. None, GluBuildMipmaps and SGIS_generate_mipmap
169 - property name added. Only used in glForms!
171 - property FreeDataAfterGenTexture is now available as default (default = true)
172 - BuildMipmaps now implemented in TglBitmap1D (i've forgotten it)
173 - function MoveMemory replaced with function Move (little speed change)
174 - several calculations stored in variables (little speed change)
176 - property BuildMipsMaps added (default = true)
177 if BuildMipMaps isn't set GenTextures uses glTexImage[12]D else it use gluBuild[12]dMipmaps
178 - property FreeDataAfterGenTexture added (default = true)
179 if FreeDataAfterGenTexture is set the texturedata were deleted after the texture was generated.
180 - parameter DisableOtherTextureUnits of Bind removed
181 - parameter FreeDataAfterGeneration of GenTextures removed
183 - TglBitmap dosn't delete data if class was destroyed (fixed)
185 - Bind now enables TextureUnits (by params)
186 - GenTextures can leave data (by param)
187 - LoadTextures now optimal
189 - Performance optimization in AddFunc
190 - procedure Bind moved to subclasses
191 - Added new Class TglBitmap1D to support real OpenGL 1D Textures
193 - Texturefilter and texturewrap now also as defaults
194 Minfilter = GL_LINEAR_MIPMAP_LINEAR
195 Magfilter = GL_LINEAR
196 Wrap(str) = GL_CLAMP_TO_EDGE
197 - Added new format tfCompressed to create a compressed texture.
198 - propertys IsCompressed, TextureSize and IsResident added
199 IsCompressed and TextureSize only contains data from level 0
201 - Added function AddFunc to add PerPixelEffects to Image
202 - LoadFromFunc now based on AddFunc
203 - Invert now based on AddFunc
204 - SwapColors now based on AddFunc
206 - Added function FlipHorz
208 - Added function LaodFromFunc to create images with function
209 - Added function FlipVert
210 - Added internal format RGB(A) if GL_EXT_bgra or OpenGL 1.2 isn't supported
212 - Added Alphafunctions to calculate alpha per function
213 - Added Alpha from ColorKey using alphafunctions
215 - First full functionally Version of glBitmap
216 - Support for 24Bit and 32Bit TGA Pictures added
218 - begin of programming
219 ***********************************************************}
222 // Please uncomment the defines below to configure the glBitmap to your preferences.
223 // If you have configured the unit you can uncomment the warning above.
224 {.$MESSAGE error 'Hey. I''m the glBitmap.pas and i need to be configured. My master tell me your preferences! ;)'}
226 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
227 // Preferences ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
228 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
229 // enable OpenGL ES support
230 {.$DEFINE OPENGL_ES_1_1}
231 {.$DEFINE OPENGL_ES_2_0}
232 {.$DEFINE OPENGL_ES_3_0}
233 {.$DEFINE OPENGL_ES_EXT}
235 // activate to enable build-in OpenGL support with statically linked methods
236 // use dglOpenGL.pas if not enabled
237 {.$DEFINE GLB_NATIVE_OGL_STATIC}
239 // activate to enable build-in OpenGL support with dynamically linked methods
240 // use dglOpenGL.pas if not enabled
241 {.$DEFINE GLB_NATIVE_OGL_DYNAMIC}
244 // activate to enable the support for SDL_surfaces
247 // activate to enable the support for Delphi (including support for Delphi's (not Lazarus') TBitmap)
248 {.$DEFINE GLB_DELPHI}
250 // activate to enable the support for TLazIntfImage from Lazarus
251 {$DEFINE GLB_LAZARUS}
255 // activate to enable the support of SDL_image to load files. (READ ONLY)
256 // If you enable SDL_image all other libraries will be ignored!
257 {.$DEFINE GLB_SDL_IMAGE}
261 // activate to enable Lazarus TPortableNetworkGraphic support
262 // if you enable this pngImage and libPNG will be ignored
263 {$DEFINE GLB_LAZ_PNG}
265 // activate to enable png support with the unit pngimage -> http://pngdelphi.sourceforge.net/
266 // if you enable pngimage the libPNG will be ignored
267 {.$DEFINE GLB_PNGIMAGE}
269 // activate to use the libPNG -> http://www.libpng.org/
270 // You will need an aditional header -> http://www.opengl24.de/index.php?cat=header&file=libpng
271 {.$DEFINE GLB_LIB_PNG}
275 // activate to enable Lazarus TJPEGImage support
276 // if you enable this delphi jpegs and libJPEG will be ignored
277 {$DEFINE GLB_LAZ_JPEG}
279 // if you enable delphi jpegs the libJPEG will be ignored
280 {.$DEFINE GLB_DELPHI_JPEG}
282 // activate to use the libJPEG -> http://www.ijg.org/
283 // You will need an aditional header -> http://www.opengl24.de/index.php?cat=header&file=libjpeg
284 {.$DEFINE GLB_LIB_JPEG}
287 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
288 // PRIVATE: do not change anything! //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
289 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
305 {$IF DEFINED(WIN32) or DEFINED(WIN64) or DEFINED(WINDOWS)}
307 {$ELSEIF DEFINED(LINUX)}
312 {$IF DEFINED(OPENGL_ES_EXT)} {$DEFINE OPENGL_ES_1_1} {$IFEND}
313 {$IF DEFINED(OPENGL_ES_3_0)} {$DEFINE OPENGL_ES_2_0} {$IFEND}
314 {$IF DEFINED(OPENGL_ES_2_0)} {$DEFINE OPENGL_ES_1_1} {$IFEND}
315 {$IF DEFINED(OPENGL_ES_1_1)} {$DEFINE OPENGL_ES} {$IFEND}
317 // native OpenGL Support
318 {$IF DEFINED(GLB_NATIVE_OGL_STATIC) OR DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
320 {$ERROR 'native OpenGL is not supported yet for OpenGL ES, please use dglOpenGLES.pas instead'}
322 {$DEFINE GLB_NATIVE_OGL}
326 // checking define combinations
328 {$IFDEF GLB_SDL_IMAGE}
330 {$MESSAGE warn 'SDL_image won''t work without SDL. SDL will be activated.'}
335 {$MESSAGE warn 'The Lazarus TPortableNetworkGraphics will be ignored because you are using SDL_image.'}
339 {$IFDEF GLB_PNGIMAGE}
340 {$MESSAGE warn 'The unit pngimage will be ignored because you are using SDL_image.'}
341 {$undef GLB_PNGIMAGE}
344 {$IFDEF GLB_LAZ_JPEG}
345 {$MESSAGE warn 'The Lazarus TJPEGImage will be ignored because you are using SDL_image.'}
346 {$undef GLB_LAZ_JPEG}
349 {$IFDEF GLB_DELPHI_JPEG}
350 {$MESSAGE warn 'The unit JPEG will be ignored because you are using SDL_image.'}
351 {$undef GLB_DELPHI_JPEG}
355 {$MESSAGE warn 'The library libPNG will be ignored because you are using SDL_image.'}
359 {$IFDEF GLB_LIB_JPEG}
360 {$MESSAGE warn 'The library libJPEG will be ignored because you are using SDL_image.'}
361 {$undef GLB_LIB_JPEG}
364 {$DEFINE GLB_SUPPORT_PNG_READ}
365 {$DEFINE GLB_SUPPORT_JPEG_READ}
368 // Lazarus TPortableNetworkGraphic
370 {$IFNDEF GLB_LAZARUS}
371 {$MESSAGE warn 'Lazarus TPortableNetworkGraphic won''t work without Lazarus. Lazarus will be activated.'}
372 {$DEFINE GLB_LAZARUS}
375 {$IFDEF GLB_PNGIMAGE}
376 {$MESSAGE warn 'The pngimage will be ignored if you are using Lazarus TPortableNetworkGraphic.'}
377 {$undef GLB_PNGIMAGE}
381 {$MESSAGE warn 'The library libPNG will be ignored if you are using Lazarus TPortableNetworkGraphic.'}
385 {$DEFINE GLB_SUPPORT_PNG_READ}
386 {$DEFINE GLB_SUPPORT_PNG_WRITE}
390 {$IFDEF GLB_PNGIMAGE}
392 {$MESSAGE warn 'The library libPNG will be ignored if you are using pngimage.'}
396 {$DEFINE GLB_SUPPORT_PNG_READ}
397 {$DEFINE GLB_SUPPORT_PNG_WRITE}
402 {$DEFINE GLB_SUPPORT_PNG_READ}
403 {$DEFINE GLB_SUPPORT_PNG_WRITE}
406 // Lazarus TJPEGImage
407 {$IFDEF GLB_LAZ_JPEG}
408 {$IFNDEF GLB_LAZARUS}
409 {$MESSAGE warn 'Lazarus TJPEGImage won''t work without Lazarus. Lazarus will be activated.'}
410 {$DEFINE GLB_LAZARUS}
413 {$IFDEF GLB_DELPHI_JPEG}
414 {$MESSAGE warn 'The Delphi JPEGImage will be ignored if you are using the Lazarus TJPEGImage.'}
415 {$undef GLB_DELPHI_JPEG}
418 {$IFDEF GLB_LIB_JPEG}
419 {$MESSAGE warn 'The library libJPEG will be ignored if you are using the Lazarus TJPEGImage.'}
420 {$undef GLB_LIB_JPEG}
423 {$DEFINE GLB_SUPPORT_JPEG_READ}
424 {$DEFINE GLB_SUPPORT_JPEG_WRITE}
428 {$IFDEF GLB_DELPHI_JPEG}
429 {$IFDEF GLB_LIB_JPEG}
430 {$MESSAGE warn 'The library libJPEG will be ignored if you are using the unit JPEG.'}
431 {$undef GLB_LIB_JPEG}
434 {$DEFINE GLB_SUPPORT_JPEG_READ}
435 {$DEFINE GLB_SUPPORT_JPEG_WRITE}
439 {$IFDEF GLB_LIB_JPEG}
440 {$DEFINE GLB_SUPPORT_JPEG_READ}
441 {$DEFINE GLB_SUPPORT_JPEG_WRITE}
445 {$IF DEFINED(GLB_NATIVE_OGL_STATIC) AND DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
446 {$MESSAGE warn 'GLB_NATIVE_OGL_STATIC will be ignored because you enabled GLB_NATIVE_OGL_DYNAMIC'}
460 {$IFNDEF GLB_NATIVE_OGL}
461 {$IFDEF OPENGL_ES} dglOpenGLES,
462 {$ELSE} dglOpenGL, {$ENDIF}
464 {$IF DEFINED(GLB_WIN) AND
465 (DEFINED(GLB_NATIVE_OGL) OR
466 DEFINED(GLB_DELPHI))} windows, {$IFEND}
468 {$IFDEF GLB_SDL} SDL, {$ENDIF}
469 {$IFDEF GLB_LAZARUS} IntfGraphics, GraphType, Graphics, {$ENDIF}
470 {$IFDEF GLB_DELPHI} Dialogs, Graphics, Types, {$ENDIF}
472 {$IFDEF GLB_SDL_IMAGE} SDL_image, {$ENDIF}
473 {$IFDEF GLB_PNGIMAGE} pngimage, {$ENDIF}
474 {$IFDEF GLB_LIB_PNG} libPNG, {$ENDIF}
475 {$IFDEF GLB_DELPHI_JPEG} JPEG, {$ENDIF}
476 {$IFDEF GLB_LIB_JPEG} libJPEG, {$ENDIF}
480 {$IFDEF GLB_NATIVE_OGL}
489 GL_EXTENSIONS = $1F03;
491 GL_TEXTURE_1D = $0DE0;
492 GL_TEXTURE_2D = $0DE1;
493 GL_TEXTURE_RECTANGLE = $84F5;
495 GL_NORMAL_MAP = $8511;
496 GL_TEXTURE_CUBE_MAP = $8513;
497 GL_REFLECTION_MAP = $8512;
498 GL_TEXTURE_CUBE_MAP_POSITIVE_X = $8515;
499 GL_TEXTURE_CUBE_MAP_NEGATIVE_X = $8516;
500 GL_TEXTURE_CUBE_MAP_POSITIVE_Y = $8517;
501 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y = $8518;
502 GL_TEXTURE_CUBE_MAP_POSITIVE_Z = $8519;
503 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z = $851A;
505 GL_TEXTURE_WIDTH = $1000;
506 GL_TEXTURE_HEIGHT = $1001;
507 GL_TEXTURE_INTERNAL_FORMAT = $1003;
508 GL_TEXTURE_SWIZZLE_RGBA = $8E46;
515 GL_TEXTURE_GEN_S = $0C60;
516 GL_TEXTURE_GEN_T = $0C61;
517 GL_TEXTURE_GEN_R = $0C62;
518 GL_TEXTURE_GEN_Q = $0C63;
530 GL_LUMINANCE = $1909;
531 GL_LUMINANCE4 = $803F;
532 GL_LUMINANCE8 = $8040;
533 GL_LUMINANCE12 = $8041;
534 GL_LUMINANCE16 = $8042;
536 GL_LUMINANCE_ALPHA = $190A;
537 GL_LUMINANCE4_ALPHA4 = $8043;
538 GL_LUMINANCE6_ALPHA2 = $8044;
539 GL_LUMINANCE8_ALPHA8 = $8045;
540 GL_LUMINANCE12_ALPHA4 = $8046;
541 GL_LUMINANCE12_ALPHA12 = $8047;
542 GL_LUMINANCE16_ALPHA16 = $8048;
565 GL_DEPTH_COMPONENT = $1902;
566 GL_DEPTH_COMPONENT16 = $81A5;
567 GL_DEPTH_COMPONENT24 = $81A6;
568 GL_DEPTH_COMPONENT32 = $81A7;
570 GL_COMPRESSED_RGB = $84ED;
571 GL_COMPRESSED_RGBA = $84EE;
572 GL_COMPRESSED_RGB_S3TC_DXT1_EXT = $83F0;
573 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = $83F1;
574 GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = $83F2;
575 GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = $83F3;
577 GL_UNSIGNED_BYTE = $1401;
578 GL_UNSIGNED_BYTE_3_3_2 = $8032;
579 GL_UNSIGNED_BYTE_2_3_3_REV = $8362;
581 GL_UNSIGNED_SHORT = $1403;
582 GL_UNSIGNED_SHORT_5_6_5 = $8363;
583 GL_UNSIGNED_SHORT_4_4_4_4 = $8033;
584 GL_UNSIGNED_SHORT_5_5_5_1 = $8034;
585 GL_UNSIGNED_SHORT_5_6_5_REV = $8364;
586 GL_UNSIGNED_SHORT_4_4_4_4_REV = $8365;
587 GL_UNSIGNED_SHORT_1_5_5_5_REV = $8366;
589 GL_UNSIGNED_INT = $1405;
590 GL_UNSIGNED_INT_8_8_8_8 = $8035;
591 GL_UNSIGNED_INT_10_10_10_2 = $8036;
592 GL_UNSIGNED_INT_8_8_8_8_REV = $8367;
593 GL_UNSIGNED_INT_2_10_10_10_REV = $8368;
596 GL_TEXTURE_MAG_FILTER = $2800;
597 GL_TEXTURE_MIN_FILTER = $2801;
599 GL_NEAREST_MIPMAP_NEAREST = $2700;
600 GL_NEAREST_MIPMAP_LINEAR = $2702;
602 GL_LINEAR_MIPMAP_NEAREST = $2701;
603 GL_LINEAR_MIPMAP_LINEAR = $2703;
606 GL_TEXTURE_WRAP_S = $2802;
607 GL_TEXTURE_WRAP_T = $2803;
608 GL_TEXTURE_WRAP_R = $8072;
611 GL_CLAMP_TO_EDGE = $812F;
612 GL_CLAMP_TO_BORDER = $812D;
613 GL_MIRRORED_REPEAT = $8370;
616 GL_GENERATE_MIPMAP = $8191;
617 GL_TEXTURE_BORDER_COLOR = $1004;
618 GL_MAX_TEXTURE_SIZE = $0D33;
619 GL_PACK_ALIGNMENT = $0D05;
620 GL_UNPACK_ALIGNMENT = $0CF5;
622 GL_TEXTURE_MAX_ANISOTROPY_EXT = $84FE;
623 GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = $84FF;
624 GL_MAX_CUBE_MAP_TEXTURE_SIZE = $851C;
625 GL_TEXTURE_GEN_MODE = $2500;
627 {$IF DEFINED(GLB_WIN)}
628 libglu = 'glu32.dll';
629 libopengl = 'opengl32.dll';
630 {$ELSEIF DEFINED(GLB_LINUX)}
631 libglu = 'libGLU.so.1';
632 libopengl = 'libGL.so.1';
636 GLboolean = BYTEBOOL;
644 PGLboolean = ^GLboolean;
649 TglCompressedTexImage1D = procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
650 TglCompressedTexImage2D = procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; height: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
651 TglGetCompressedTexImage = procedure(target: GLenum; level: GLint; img: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
653 {$IF DEFINED(GLB_WIN)}
654 TwglGetProcAddress = function (ProcName: PAnsiChar): Pointer; stdcall;
655 {$ELSEIF DEFINED(GLB_LINUX)}
656 TglXGetProcAddress = function(ProcName: PAnsiChar): Pointer; cdecl;
657 TglXGetProcAddressARB = function(const name: PAnsiChar): pointer; cdecl;
660 {$IF DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
661 TglEnable = procedure(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
662 TglDisable = procedure(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
664 TglGetString = function(name: GLenum): PAnsiChar; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
665 TglGetIntegerv = procedure(pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
667 TglTexParameteri = procedure(target: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
668 TglTexParameteriv = procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
669 TglTexParameterfv = procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
670 TglGetTexParameteriv = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
671 TglGetTexParameterfv = procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
672 TglGetTexLevelParameteriv = procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
673 TglGetTexLevelParameterfv = procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
675 TglTexGeni = procedure(coord: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
676 TglGenTextures = procedure(n: GLsizei; textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
677 TglBindTexture = procedure(target: GLenum; texture: GLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
678 TglDeleteTextures = procedure(n: GLsizei; const textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
680 TglAreTexturesResident = function(n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
681 TglReadPixels = procedure(x: GLint; y: GLint; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
682 TglPixelStorei = procedure(pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
684 TglTexImage1D = procedure(target: GLenum; level: GLint; internalformat: GLint; width: GLsizei; border: GLint; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
685 TglTexImage2D = procedure(target: GLenum; level: GLint; internalformat: GLint; width: GLsizei; height: GLsizei; border: GLint; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
686 TglGetTexImage = procedure(target: GLenum; level: GLint; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
688 TgluBuild1DMipmaps = function(target: GLEnum; components, width: GLint; format, atype: GLEnum; const data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
689 TgluBuild2DMipmaps = function(target: GLEnum; components, width, height: GLint; format, atype: GLEnum; const Data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
691 {$ELSEIF DEFINED(GLB_NATIVE_OGL_STATIC)}
692 procedure glEnable(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
693 procedure glDisable(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
695 function glGetString(name: GLenum): PAnsiChar; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
696 procedure glGetIntegerv(pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
698 procedure glTexParameteri(target: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
699 procedure glTexParameteriv(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
700 procedure glTexParameterfv(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
701 procedure glGetTexParameteriv(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
702 procedure glGetTexParameterfv(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
703 procedure glGetTexLevelParameteriv(target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
704 procedure glGetTexLevelParameterfv(target: GLenum; level: GLint; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
706 procedure glTexGeni(coord: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
707 procedure glGenTextures(n: GLsizei; textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
708 procedure glBindTexture(target: GLenum; texture: GLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
709 procedure glDeleteTextures(n: GLsizei; const textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
711 function glAreTexturesResident(n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
712 procedure glReadPixels(x: GLint; y: GLint; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
713 procedure glPixelStorei(pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
715 procedure glTexImage1D(target: GLenum; level: GLint; internalformat: GLint; width: GLsizei; border: GLint; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
716 procedure glTexImage2D(target: GLenum; level: GLint; internalformat: GLint; width: GLsizei; height: GLsizei; border: GLint; format: GLenum; _type: GLenum; const pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
717 procedure glGetTexImage(target: GLenum; level: GLint; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
719 function gluBuild1DMipmaps(target: GLEnum; components, width: GLint; format, atype: GLEnum; const data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libglu;
720 function gluBuild2DMipmaps(target: GLEnum; components, width, height: GLint; format, atype: GLEnum; const Data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libglu;
730 GL_SGIS_generate_mipmap,
732 GL_ARB_texture_border_clamp,
733 GL_ARB_texture_mirrored_repeat,
734 GL_ARB_texture_rectangle,
735 GL_ARB_texture_non_power_of_two,
736 GL_ARB_texture_swizzle,
737 GL_ARB_texture_cube_map,
739 GL_IBM_texture_mirrored_repeat,
741 GL_NV_texture_rectangle,
743 GL_EXT_texture_edge_clamp,
744 GL_EXT_texture_rectangle,
745 GL_EXT_texture_swizzle,
746 GL_EXT_texture_cube_map,
747 GL_EXT_texture_filter_anisotropic: Boolean;
749 glCompressedTexImage1D: TglCompressedTexImage1D;
750 glCompressedTexImage2D: TglCompressedTexImage2D;
751 glGetCompressedTexImage: TglGetCompressedTexImage;
753 {$IF DEFINED(GLB_WIN)}
754 wglGetProcAddress: TwglGetProcAddress;
755 {$ELSEIF DEFINED(GLB_LINUX)}
756 glXGetProcAddress: TglXGetProcAddress;
757 glXGetProcAddressARB: TglXGetProcAddress;
760 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
762 glDisable: TglDisable;
764 glGetString: TglGetString;
765 glGetIntegerv: TglGetIntegerv;
767 glTexParameteri: TglTexParameteri;
768 glTexParameteriv: TglTexParameteriv;
769 glTexParameterfv: TglTexParameterfv;
770 glGetTexParameteriv: TglGetTexParameteriv;
771 glGetTexParameterfv: TglGetTexParameterfv;
772 glGetTexLevelParameteriv: TglGetTexLevelParameteriv;
773 glGetTexLevelParameterfv: TglGetTexLevelParameterfv;
775 glTexGeni: TglTexGeni;
776 glGenTextures: TglGenTextures;
777 glBindTexture: TglBindTexture;
778 glDeleteTextures: TglDeleteTextures;
780 glAreTexturesResident: TglAreTexturesResident;
781 glReadPixels: TglReadPixels;
782 glPixelStorei: TglPixelStorei;
784 glTexImage1D: TglTexImage1D;
785 glTexImage2D: TglTexImage2D;
786 glGetTexImage: TglGetTexImage;
788 gluBuild1DMipmaps: TgluBuild1DMipmaps;
789 gluBuild2DMipmaps: TgluBuild2DMipmaps;
794 ////////////////////////////////////////////////////////////////////////////////////////////////////
795 // the name of formats is composed of the following constituents:
796 // - multiple chanals:
797 // - channel (e.g. R, G, B, A or Alpha, Luminance or X (reserved)
798 // - width of the chanel in bit (4, 8, 16, ...)
799 // - data type (e.g. ub, us, ui)
800 // - number of data types
803 QWord = System.UInt64;
811 tfEmpty = 0, //must be smallest value!
813 tfAlpha4ub1, // 1 x unsigned byte
814 tfAlpha8ub1, // 1 x unsigned byte
815 tfAlpha16us1, // 1 x unsigned short
817 tfLuminance4ub1, // 1 x unsigned byte
818 tfLuminance8ub1, // 1 x unsigned byte
819 tfLuminance16us1, // 1 x unsigned short
821 tfLuminance4Alpha4ub2, // 1 x unsigned byte (lum), 1 x unsigned byte (alpha)
822 tfLuminance6Alpha2ub2, // 1 x unsigned byte (lum), 1 x unsigned byte (alpha)
823 tfLuminance8Alpha8ub2, // 1 x unsigned byte (lum), 1 x unsigned byte (alpha)
824 tfLuminance12Alpha4us2, // 1 x unsigned short (lum), 1 x unsigned short (alpha)
825 tfLuminance16Alpha16us2, // 1 x unsigned short (lum), 1 x unsigned short (alpha)
827 tfR3G3B2ub1, // 1 x unsigned byte (3bit red, 3bit green, 2bit blue)
828 tfRGBX4us1, // 1 x unsigned short (4bit red, 4bit green, 4bit blue, 4bit reserverd)
829 tfXRGB4us1, // 1 x unsigned short (4bit reserved, 4bit red, 4bit green, 4bit blue)
830 tfR5G6B5us1, // 1 x unsigned short (5bit red, 6bit green, 5bit blue)
831 tfRGB5X1us1, // 1 x unsigned short (5bit red, 5bit green, 5bit blue, 1bit reserved)
832 tfX1RGB5us1, // 1 x unsigned short (1bit reserved, 5bit red, 5bit green, 5bit blue)
833 tfRGB8ub3, // 1 x unsigned byte (red), 1 x unsigned byte (green), 1 x unsigned byte (blue)
834 tfRGBX8ui1, // 1 x unsigned int (8bit red, 8bit green, 8bit blue, 8bit reserved)
835 tfXRGB8ui1, // 1 x unsigned int (8bit reserved, 8bit red, 8bit green, 8bit blue)
836 tfRGB10X2ui1, // 1 x unsigned int (10bit red, 10bit green, 10bit blue, 2bit reserved)
837 tfX2RGB10ui1, // 1 x unsigned int (2bit reserved, 10bit red, 10bit green, 10bit blue)
838 tfRGB16us3, // 1 x unsigned short (red), 1 x unsigned short (green), 1 x unsigned short (blue)
840 tfRGBA4us1, // 1 x unsigned short (4bit red, 4bit green, 4bit blue, 4bit alpha)
841 tfARGB4us1, // 1 x unsigned short (4bit alpha, 4bit red, 4bit green, 4bit blue)
842 tfRGB5A1us1, // 1 x unsigned short (5bit red, 5bit green, 5bit blue, 1bit alpha)
843 tfA1RGB5us1, // 1 x unsigned short (1bit alpha, 5bit red, 5bit green, 5bit blue)
844 tfRGBA8ui1, // 1 x unsigned int (8bit red, 8bit green, 8bit blue, 8 bit alpha)
845 tfARGB8ui1, // 1 x unsigned int (8 bit alpha, 8bit red, 8bit green, 8bit blue)
846 tfRGBA8ub4, // 1 x unsigned byte (red), 1 x unsigned byte (green), 1 x unsigned byte (blue), 1 x unsigned byte (alpha)
847 tfRGB10A2ui1, // 1 x unsigned int (10bit red, 10bit green, 10bit blue, 2bit alpha)
848 tfA2RGB10ui1, // 1 x unsigned int (2bit alpha, 10bit red, 10bit green, 10bit blue)
849 tfRGBA16us4, // 1 x unsigned short (red), 1 x unsigned short (green), 1 x unsigned short (blue), 1 x unsigned short (alpha)
851 tfBGRX4us1, // 1 x unsigned short (4bit blue, 4bit green, 4bit red, 4bit reserved)
852 tfXBGR4us1, // 1 x unsigned short (4bit reserved, 4bit blue, 4bit green, 4bit red)
853 tfB5G6R5us1, // 1 x unsigned short (5bit blue, 6bit green, 5bit red)
854 tfBGR5X1us1, // 1 x unsigned short (5bit blue, 5bit green, 5bit red, 1bit reserved)
855 tfX1BGR5us1, // 1 x unsigned short (1bit reserved, 5bit blue, 5bit green, 5bit red)
856 tfBGR8ub3, // 1 x unsigned byte (blue), 1 x unsigned byte (green), 1 x unsigned byte (red)
857 tfBGRX8ui1, // 1 x unsigned int (8bit blue, 8bit green, 8bit red, 8bit reserved)
858 tfXBGR8ui1, // 1 x unsigned int (8bit reserved, 8bit blue, 8bit green, 8bit red)
859 tfBGR10X2ui1, // 1 x unsigned int (10bit blue, 10bit green, 10bit red, 2bit reserved)
860 tfX2BGR10ui1, // 1 x unsigned int (2bit reserved, 10bit blue, 10bit green, 10bit red)
861 tfBGR16us3, // 1 x unsigned short (blue), 1 x unsigned short (green), 1 x unsigned short (red)
863 tfBGRA4us1, // 1 x unsigned short (4bit blue, 4bit green, 4bit red, 4bit alpha)
864 tfABGR4us1, // 1 x unsigned short (4bit alpha, 4bit blue, 4bit green, 4bit red)
865 tfBGR5A1us1, // 1 x unsigned short (5bit blue, 5bit green, 5bit red, 1bit alpha)
866 tfA1BGR5us1, // 1 x unsigned short (1bit alpha, 5bit blue, 5bit green, 5bit red)
867 tfBGRA8ui1, // 1 x unsigned int (8bit blue, 8bit green, 8bit red, 8bit alpha)
868 tfABGR8ui1, // 1 x unsigned int (8bit alpha, 8bit blue, 8bit green, 8bit red)
869 tfBGRA8ub4, // 1 x unsigned byte (blue), 1 x unsigned byte (green), 1 x unsigned byte (red), 1 x unsigned byte (alpha)
870 tfBGR10A2ui1, // 1 x unsigned int (10bit blue, 10bit green, 10bit red, 2bit alpha)
871 tfA2BGR10ui1, // 1 x unsigned int (2bit alpha, 10bit blue, 10bit green, 10bit red)
872 tfBGRA16us4, // 1 x unsigned short (blue), 1 x unsigned short (green), 1 x unsigned short (red), 1 x unsigned short (alpha)
874 tfDepth16us1, // 1 x unsigned short (depth)
875 tfDepth24ui1, // 1 x unsigned int (depth)
876 tfDepth32ui1, // 1 x unsigned int (depth)
883 TglBitmapFileType = (
884 {$IFDEF GLB_SUPPORT_PNG_WRITE} ftPNG, {$ENDIF}
885 {$IFDEF GLB_SUPPORT_JPEG_WRITE}ftJPEG, {$ENDIF}
890 TglBitmapFileTypes = set of TglBitmapFileType;
897 TglBitmapNormalMapFunc = (
903 ////////////////////////////////////////////////////////////////////////////////////////////////////
904 EglBitmap = class(Exception);
905 EglBitmapNotSupported = class(Exception);
906 EglBitmapSizeToLarge = class(EglBitmap);
907 EglBitmapNonPowerOfTwo = class(EglBitmap);
908 EglBitmapUnsupportedFormat = class(EglBitmap)
910 constructor Create(const aFormat: TglBitmapFormat); overload;
911 constructor Create(const aMsg: String; const aFormat: TglBitmapFormat); overload;
914 ////////////////////////////////////////////////////////////////////////////////////////////////////
915 TglBitmapRec4ui = packed record
917 0: (r, g, b, a: Cardinal);
918 1: (arr: array[0..3] of Cardinal);
921 TglBitmapRec4ub = packed record
923 0: (r, g, b, a: Byte);
924 1: (arr: array[0..3] of Byte);
927 TglBitmapRec4ul = packed record
929 0: (r, g, b, a: QWord);
930 1: (arr: array[0..3] of QWord);
933 TglBitmapFormatDescriptor = class(TObject)
936 fBytesPerPixel: Single;
937 fChannelCount: Integer;
938 fMask: TglBitmapRec4ul;
939 fRange: TglBitmapRec4ui;
941 function GetHasRed: Boolean;
942 function GetHasGreen: Boolean;
943 function GetHasBlue: Boolean;
944 function GetHasAlpha: Boolean;
945 function GetHasColor: Boolean;
946 function GetIsGrayscale: Boolean;
948 fFormat: TglBitmapFormat;
949 fWithAlpha: TglBitmapFormat;
950 fWithoutAlpha: TglBitmapFormat;
951 fOpenGLFormat: TglBitmapFormat;
952 fRGBInverted: TglBitmapFormat;
953 fUncompressed: TglBitmapFormat;
955 fBitsPerPixel: Integer;
956 fIsCompressed: Boolean;
958 fPrecision: TglBitmapRec4ub;
959 fShift: TglBitmapRec4ub;
962 fglInternalFormat: GLenum;
963 fglDataFormat: GLenum;
965 procedure SetValues; virtual;
966 procedure CalcValues;
968 property Format: TglBitmapFormat read fFormat;
969 property ChannelCount: Integer read fChannelCount;
970 property IsCompressed: Boolean read fIsCompressed;
971 property BitsPerPixel: Integer read fBitsPerPixel;
972 property BytesPerPixel: Single read fBytesPerPixel;
974 property Precision: TglBitmapRec4ub read fPrecision;
975 property Shift: TglBitmapRec4ub read fShift;
976 property Range: TglBitmapRec4ui read fRange;
977 property Mask: TglBitmapRec4ul read fMask;
979 property RGBInverted: TglBitmapFormat read fRGBInverted;
980 property WithAlpha: TglBitmapFormat read fWithAlpha;
981 property WithoutAlpha: TglBitmapFormat read fWithAlpha;
982 property OpenGLFormat: TglBitmapFormat read fOpenGLFormat;
983 property Uncompressed: TglBitmapFormat read fUncompressed;
985 property glFormat: GLenum read fglFormat;
986 property glInternalFormat: GLenum read fglInternalFormat;
987 property glDataFormat: GLenum read fglDataFormat;
989 property HasRed: Boolean read GetHasRed;
990 property HasGreen: Boolean read GetHasGreen;
991 property HasBlue: Boolean read GetHasBlue;
992 property HasAlpha: Boolean read GetHasAlpha;
993 property HasColor: Boolean read GetHasColor;
994 property IsGrayscale: Boolean read GetIsGrayscale;
998 class function GetByFormat(const aInternalFormat: GLenum): TglBitmapFormatDescriptor;
1001 ////////////////////////////////////////////////////////////////////////////////////////////////////
1002 TglBitmapPixelData = packed record
1003 Data: TglBitmapRec4ui;
1004 Range: TglBitmapRec4ui;
1005 Format: TglBitmapFormat;
1007 PglBitmapPixelData = ^TglBitmapPixelData;
1009 TglBitmapPixelPositionFields = set of (ffX, ffY);
1010 TglBitmapPixelPosition = record
1011 Fields : TglBitmapPixelPositionFields;
1016 ////////////////////////////////////////////////////////////////////////////////////////////////////
1018 TglBitmapFunctionRec = record
1020 Size: TglBitmapPixelPosition;
1021 Position: TglBitmapPixelPosition;
1022 Source: TglBitmapPixelData;
1023 Dest: TglBitmapPixelData;
1026 TglBitmapFunction = procedure(var FuncRec: TglBitmapFunctionRec);
1028 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1031 function GetFormatDesc: TglBitmapFormatDescriptor;
1035 fAnisotropic: Integer;
1036 fDeleteTextureOnFree: Boolean;
1037 fFreeDataOnDestroy: Boolean;
1038 fFreeDataAfterGenTexture: Boolean;
1041 fIsResident: GLboolean;
1043 fBorderColor: array[0..3] of Single;
1045 fDimension: TglBitmapPixelPosition;
1046 fMipMap: TglBitmapMipMap;
1047 fFormat: TglBitmapFormat;
1050 fPixelSize: Integer;
1062 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
1064 fSwizzle: array[0..3] of GLenum;
1069 fCustomName: String;
1070 fCustomNameW: WideString;
1071 fCustomData: Pointer;
1074 function GetWidth: Integer; virtual;
1075 function GetHeight: Integer; virtual;
1077 function GetFileWidth: Integer; virtual;
1078 function GetFileHeight: Integer; virtual;
1081 procedure SetCustomData(const aValue: Pointer);
1082 procedure SetCustomName(const aValue: String);
1083 procedure SetCustomNameW(const aValue: WideString);
1084 procedure SetFreeDataOnDestroy(const aValue: Boolean);
1085 procedure SetDeleteTextureOnFree(const aValue: Boolean);
1086 procedure SetFormat(const aValue: TglBitmapFormat);
1087 procedure SetFreeDataAfterGenTexture(const aValue: Boolean);
1088 procedure SetID(const aValue: Cardinal);
1089 procedure SetMipMap(const aValue: TglBitmapMipMap);
1090 procedure SetTarget(const aValue: Cardinal);
1091 procedure SetAnisotropic(const aValue: Integer);
1094 procedure SetupParameters({$IFNDEF OPENGL_ES}out aBuildWithGlu: Boolean{$ENDIF});
1095 procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
1096 const aWidth: Integer = -1; const aHeight: Integer = -1); virtual; //be careful, aData could be freed by this method
1097 procedure GenTexture(const aTestTextureSize: Boolean = true); virtual; abstract;
1099 function FlipHorz: Boolean; virtual;
1100 function FlipVert: Boolean; virtual;
1102 property Width: Integer read GetWidth;
1103 property Height: Integer read GetHeight;
1105 property FileWidth: Integer read GetFileWidth;
1106 property FileHeight: Integer read GetFileHeight;
1109 property ID: Cardinal read fID write SetID;
1110 property Target: Cardinal read fTarget write SetTarget;
1111 property Format: TglBitmapFormat read fFormat write SetFormat;
1112 property MipMap: TglBitmapMipMap read fMipMap write SetMipMap;
1113 property Anisotropic: Integer read fAnisotropic write SetAnisotropic;
1115 property FormatDesc: TglBitmapFormatDescriptor read GetFormatDesc;
1117 property Filename: String read fFilename;
1118 property CustomName: String read fCustomName write SetCustomName;
1119 property CustomNameW: WideString read fCustomNameW write SetCustomNameW;
1120 property CustomData: Pointer read fCustomData write SetCustomData;
1122 property DeleteTextureOnFree: Boolean read fDeleteTextureOnFree write SetDeleteTextureOnFree;
1123 property FreeDataOnDestroy: Boolean read fFreeDataOnDestroy write SetFreeDataOnDestroy;
1124 property FreeDataAfterGenTexture: Boolean read fFreeDataAfterGenTexture write SetFreeDataAfterGenTexture;
1126 property Dimension: TglBitmapPixelPosition read fDimension;
1127 property Data: PByte read fData;
1129 property IsResident: GLboolean read fIsResident;
1132 procedure AfterConstruction; override;
1133 procedure BeforeDestruction; override;
1135 procedure PrepareResType(var aResource: String; var aResType: PChar);
1138 procedure LoadFromFile(const aFilename: String);
1139 procedure LoadFromStream(const aStream: TStream); virtual;
1140 procedure LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
1141 const aFormat: TglBitmapFormat; const aArgs: Pointer = nil);
1142 procedure LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil);
1143 procedure LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
1146 procedure SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
1147 procedure SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType); virtual;
1150 function AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer = nil): Boolean; overload;
1151 function AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
1152 const aFormat: TglBitmapFormat; const aArgs: Pointer = nil): Boolean; overload;
1156 function AssignToSurface(out aSurface: PSDL_Surface): Boolean;
1157 function AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
1158 function AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
1159 function AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil;
1160 const aArgs: Pointer = nil): Boolean;
1164 function AssignToBitmap(const aBitmap: TBitmap): Boolean;
1165 function AssignFromBitmap(const aBitmap: TBitmap): Boolean;
1166 function AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
1167 function AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction = nil;
1168 const aArgs: Pointer = nil): Boolean;
1171 {$IFDEF GLB_LAZARUS}
1172 function AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
1173 function AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
1174 function AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
1175 function AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction = nil;
1176 const aArgs: Pointer = nil): Boolean;
1179 function AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil;
1180 const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1181 function AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
1182 const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1184 function AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer = nil): Boolean; virtual;
1185 function AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1186 function AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1187 function AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1189 function AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte = 0): Boolean;
1190 function AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal = 0): Boolean;
1191 function AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single = 0): Boolean;
1193 function AddAlphaFromValue(const aAlpha: Byte): Boolean;
1194 function AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
1195 function AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
1197 function RemoveAlpha: Boolean; virtual;
1200 function Clone: TglBitmap;
1201 function ConvertTo(const aFormat: TglBitmapFormat): Boolean; virtual;
1202 procedure Invert(const aUseRGB: Boolean = true; const aUseAlpha: Boolean = false);
1204 procedure SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
1209 procedure FillWithColor(const aRed, aGreen, aBlue: Byte; const aAlpha: Byte = 255);
1210 procedure FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal = $FFFFFFFF);
1211 procedure FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha : Single = 1);
1214 procedure SetFilter(const aMin, aMag: GLenum);
1216 const S: GLenum = GL_CLAMP_TO_EDGE;
1217 const T: GLenum = GL_CLAMP_TO_EDGE;
1218 const R: GLenum = GL_CLAMP_TO_EDGE);
1219 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
1220 procedure SetSwizzle(const r, g, b, a: GLenum);
1223 procedure Bind(const aEnableTextureUnit: Boolean = true); virtual;
1224 procedure Unbind(const aDisableTextureUnit: Boolean = true); virtual;
1227 constructor Create; overload;
1228 constructor Create(const aFileName: String); overload;
1229 constructor Create(const aStream: TStream); overload;
1230 constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; aData: PByte = nil); overload;
1231 constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer = nil); overload;
1232 constructor Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil); overload;
1233 constructor Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar); overload;
1235 {$IFDEF GLB_SUPPORT_PNG_READ} function LoadPNG(const aStream: TStream): Boolean; virtual; {$ENDIF}
1236 {$ifdef GLB_SUPPORT_PNG_WRITE} procedure SavePNG(const aStream: TStream); virtual; {$ENDIF}
1238 {$IFDEF GLB_SUPPORT_JPEG_READ} function LoadJPEG(const aStream: TStream): Boolean; virtual; {$ENDIF}
1239 {$IFDEF GLB_SUPPORT_JPEG_WRITE} procedure SaveJPEG(const aStream: TStream); virtual; {$ENDIF}
1241 function LoadRAW(const aStream: TStream): Boolean;
1242 procedure SaveRAW(const aStream: TStream);
1244 function LoadBMP(const aStream: TStream): Boolean;
1245 procedure SaveBMP(const aStream: TStream);
1247 function LoadTGA(const aStream: TStream): Boolean;
1248 procedure SaveTGA(const aStream: TStream);
1250 function LoadDDS(const aStream: TStream): Boolean;
1251 procedure SaveDDS(const aStream: TStream);
1254 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1256 TglBitmap1D = class(TglBitmap)
1258 procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
1259 const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
1260 procedure UploadData(const aBuildWithGlu: Boolean);
1263 procedure AfterConstruction; override;
1264 function FlipHorz: Boolean; override;
1265 procedure GenTexture(const aTestTextureSize: Boolean = true); override;
1269 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1270 TglBitmap2D = class(TglBitmap)
1272 fLines: array of PByte;
1273 function GetScanline(const aIndex: Integer): Pointer;
1274 procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
1275 const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
1276 procedure UploadData(const aTarget: GLenum{$IFNDEF OPENGL_ES}; const aBuildWithGlu: Boolean{$ENDIF});
1280 property Scanline[const aIndex: Integer]: Pointer read GetScanline;
1282 procedure AfterConstruction; override;
1284 procedure GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
1286 procedure GetDataFromTexture;
1288 procedure GenTexture(const aTestTextureSize: Boolean = true); override;
1290 function FlipHorz: Boolean; override;
1291 function FlipVert: Boolean; override;
1293 procedure ToNormalMap(const aFunc: TglBitmapNormalMapFunc = nm3x3;
1294 const aScale: Single = 2; const aUseAlpha: Boolean = false);
1297 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1298 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
1299 TglBitmapCubeMap = class(TglBitmap2D)
1304 procedure GenTexture(const aTestTextureSize: Boolean = true); reintroduce;
1306 procedure AfterConstruction; override;
1307 procedure GenerateCubeMap(const aCubeTarget: Cardinal; const aTestTextureSize: Boolean = true);
1308 procedure Bind({$IFNDEF OPENGL_ES}const aEnableTexCoordsGen: Boolean = true;{$ENDIF} const aEnableTextureUnit: Boolean = true); reintroduce; virtual;
1309 procedure Unbind({$IFNDEF OPENGL_ES}const aDisableTexCoordsGen: Boolean = true;{$ENDIF} const aDisableTextureUnit: Boolean = true); reintroduce; virtual;
1313 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
1314 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1315 TglBitmapNormalMap = class(TglBitmapCubeMap)
1317 procedure AfterConstruction; override;
1318 procedure GenerateNormalMap(const aSize: Integer = 32; const aTestTextureSize: Boolean = true);
1322 TglcBitmapFormat = TglBitmapFormat;
1323 TglcBitmap2D = TglBitmap2D;
1324 {$IF NOT DEFINED(OPENGL_ES)}
1325 TglcBitmap1D = TglBitmap1D;
1326 TglcBitmapCubeMap = TglBitmapCubeMap;
1327 TglcBitmapNormalMap = TglBitmapNormalMap;
1328 {$ELSEIF DEFINED(OPENGL_ES_2_0)}
1329 TglcBitmapCubeMap = TglBitmapCubeMap;
1330 TglcBitmapNormalMap = TglBitmapNormalMap;
1334 NULL_SIZE: TglBitmapPixelPosition = (Fields: []; X: 0; Y: 0);
1336 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
1337 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
1338 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
1339 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
1340 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
1341 procedure glBitmapSetDefaultWrap(
1342 const S: Cardinal = GL_CLAMP_TO_EDGE;
1343 const T: Cardinal = GL_CLAMP_TO_EDGE;
1344 const R: Cardinal = GL_CLAMP_TO_EDGE);
1346 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
1347 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
1348 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
1349 function glBitmapGetDefaultFormat: TglBitmapFormat;
1350 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
1351 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
1353 function glBitmapPosition(X: Integer = -1; Y: Integer = -1): TglBitmapPixelPosition;
1354 function glBitmapRec4ub(const r, g, b, a: Byte): TglBitmapRec4ub;
1355 function glBitmapRec4ui(const r, g, b, a: Cardinal): TglBitmapRec4ui;
1356 function glBitmapRec4ul(const r, g, b, a: QWord): TglBitmapRec4ul;
1357 function glBitmapRec4ubCompare(const r1, r2: TglBitmapRec4ub): Boolean;
1358 function glBitmapRec4uiCompare(const r1, r2: TglBitmapRec4ui): Boolean;
1360 function glBitmapCreateTestTexture(const aFormat: TglBitmapFormat): TglBitmap2D;
1363 glBitmapDefaultDeleteTextureOnFree: Boolean;
1364 glBitmapDefaultFreeDataAfterGenTextures: Boolean;
1365 glBitmapDefaultFormat: TglBitmapFormat;
1366 glBitmapDefaultMipmap: TglBitmapMipMap;
1367 glBitmapDefaultFilterMin: Cardinal;
1368 glBitmapDefaultFilterMag: Cardinal;
1369 glBitmapDefaultWrapS: Cardinal;
1370 glBitmapDefaultWrapT: Cardinal;
1371 glBitmapDefaultWrapR: Cardinal;
1372 glDefaultSwizzle: array[0..3] of GLenum;
1375 function CreateGrayPalette: HPALETTE;
1381 Math, syncobjs, typinfo
1382 {$IF DEFINED(GLB_SUPPORT_JPEG_READ) AND DEFINED(GLB_LAZ_JPEG)}, FPReadJPEG{$IFEND};
1384 ////////////////////////////////////////////////////////////////////////////////////////////////////
1386 TFormatDescriptor = class(TglBitmapFormatDescriptor)
1388 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); virtual; abstract;
1389 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); virtual; abstract;
1391 function GetSize(const aSize: TglBitmapPixelPosition): Integer; overload; virtual;
1392 function GetSize(const aWidth, aHeight: Integer): Integer; overload; virtual;
1394 function CreateMappingData: Pointer; virtual;
1395 procedure FreeMappingData(var aMappingData: Pointer); virtual;
1397 function IsEmpty: Boolean; virtual;
1398 function MaskMatch(const aMask: TglBitmapRec4ul): Boolean; virtual;
1400 procedure PreparePixel(out aPixel: TglBitmapPixelData); virtual;
1402 constructor Create; virtual;
1404 class procedure Init;
1405 class function Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
1406 class function GetAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
1407 class function GetFromMask(const aMask: TglBitmapRec4ul; const aBitCount: Integer = 0): TFormatDescriptor;
1408 class function GetFromPrecShift(const aPrec, aShift: TglBitmapRec4ub; const aBitCount: Integer): TFormatDescriptor;
1409 class procedure Clear;
1410 class procedure Finalize;
1412 TFormatDescriptorClass = class of TFormatDescriptor;
1414 TfdEmpty = class(TFormatDescriptor);
1416 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1417 TfdAlphaUB1 = class(TFormatDescriptor) //1* unsigned byte
1418 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1419 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1422 TfdLuminanceUB1 = class(TFormatDescriptor) //1* unsigned byte
1423 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1424 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1427 TfdUniversalUB1 = class(TFormatDescriptor) //1* unsigned byte
1428 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1429 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1432 TfdLuminanceAlphaUB2 = class(TfdLuminanceUB1) //2* unsigned byte
1433 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1434 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1437 TfdRGBub3 = class(TFormatDescriptor) //3* unsigned byte
1438 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1439 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1442 TfdBGRub3 = class(TFormatDescriptor) //3* unsigned byte (inverse)
1443 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1444 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1447 TfdRGBAub4 = class(TfdRGBub3) //3* unsigned byte
1448 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1449 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1452 TfdBGRAub4 = class(TfdBGRub3) //3* unsigned byte (inverse)
1453 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1454 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1457 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1458 TfdAlphaUS1 = class(TFormatDescriptor) //1* unsigned short
1459 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1460 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1463 TfdLuminanceUS1 = class(TFormatDescriptor) //1* unsigned short
1464 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1465 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1468 TfdUniversalUS1 = class(TFormatDescriptor) //1* unsigned short
1469 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1470 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1473 TfdDepthUS1 = class(TFormatDescriptor) //1* unsigned short
1474 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1475 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1478 TfdLuminanceAlphaUS2 = class(TfdLuminanceUS1) //2* unsigned short
1479 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1480 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1483 TfdRGBus3 = class(TFormatDescriptor) //3* unsigned short
1484 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1485 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1488 TfdBGRus3 = class(TFormatDescriptor) //3* unsigned short (inverse)
1489 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1490 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1493 TfdRGBAus4 = class(TfdRGBus3) //4* unsigned short
1494 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1495 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1498 TfdARGBus4 = class(TfdRGBus3) //4* unsigned short
1499 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1500 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1503 TfdBGRAus4 = class(TfdBGRus3) //4* unsigned short (inverse)
1504 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1505 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1508 TfdABGRus4 = class(TfdBGRus3) //4* unsigned short (inverse)
1509 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1510 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1513 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1514 TfdUniversalUI1 = class(TFormatDescriptor) //1* unsigned int
1515 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1516 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1519 TfdDepthUI1 = class(TFormatDescriptor) //1* unsigned int
1520 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1521 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1524 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1525 TfdAlpha4ub1 = class(TfdAlphaUB1)
1526 procedure SetValues; override;
1529 TfdAlpha8ub1 = class(TfdAlphaUB1)
1530 procedure SetValues; override;
1533 TfdAlpha16us1 = class(TfdAlphaUS1)
1534 procedure SetValues; override;
1537 TfdLuminance4ub1 = class(TfdLuminanceUB1)
1538 procedure SetValues; override;
1541 TfdLuminance8ub1 = class(TfdLuminanceUB1)
1542 procedure SetValues; override;
1545 TfdLuminance16us1 = class(TfdLuminanceUS1)
1546 procedure SetValues; override;
1549 TfdLuminance4Alpha4ub2 = class(TfdLuminanceAlphaUB2)
1550 procedure SetValues; override;
1553 TfdLuminance6Alpha2ub2 = class(TfdLuminanceAlphaUB2)
1554 procedure SetValues; override;
1557 TfdLuminance8Alpha8ub2 = class(TfdLuminanceAlphaUB2)
1558 procedure SetValues; override;
1561 TfdLuminance12Alpha4us2 = class(TfdLuminanceAlphaUS2)
1562 procedure SetValues; override;
1565 TfdLuminance16Alpha16us2 = class(TfdLuminanceAlphaUS2)
1566 procedure SetValues; override;
1569 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1570 TfdR3G3B2ub1 = class(TfdUniversalUB1)
1571 procedure SetValues; override;
1574 TfdRGBX4us1 = class(TfdUniversalUS1)
1575 procedure SetValues; override;
1578 TfdXRGB4us1 = class(TfdUniversalUS1)
1579 procedure SetValues; override;
1582 TfdR5G6B5us1 = class(TfdUniversalUS1)
1583 procedure SetValues; override;
1586 TfdRGB5X1us1 = class(TfdUniversalUS1)
1587 procedure SetValues; override;
1590 TfdX1RGB5us1 = class(TfdUniversalUS1)
1591 procedure SetValues; override;
1594 TfdRGB8ub3 = class(TfdRGBub3)
1595 procedure SetValues; override;
1598 TfdRGBX8ui1 = class(TfdUniversalUI1)
1599 procedure SetValues; override;
1602 TfdXRGB8ui1 = class(TfdUniversalUI1)
1603 procedure SetValues; override;
1606 TfdRGB10X2ui1 = class(TfdUniversalUI1)
1607 procedure SetValues; override;
1610 TfdX2RGB10ui1 = class(TfdUniversalUI1)
1611 procedure SetValues; override;
1614 TfdRGB16us3 = class(TfdRGBus3)
1615 procedure SetValues; override;
1618 TfdRGBA4us1 = class(TfdUniversalUS1)
1619 procedure SetValues; override;
1622 TfdARGB4us1 = class(TfdUniversalUS1)
1623 procedure SetValues; override;
1626 TfdRGB5A1us1 = class(TfdUniversalUS1)
1627 procedure SetValues; override;
1630 TfdA1RGB5us1 = class(TfdUniversalUS1)
1631 procedure SetValues; override;
1634 TfdRGBA8ui1 = class(TfdUniversalUI1)
1635 procedure SetValues; override;
1638 TfdARGB8ui1 = class(TfdUniversalUI1)
1639 procedure SetValues; override;
1642 TfdRGBA8ub4 = class(TfdRGBAub4)
1643 procedure SetValues; override;
1646 TfdRGB10A2ui1 = class(TfdUniversalUI1)
1647 procedure SetValues; override;
1650 TfdA2RGB10ui1 = class(TfdUniversalUI1)
1651 procedure SetValues; override;
1654 TfdRGBA16us4 = class(TfdRGBAus4)
1655 procedure SetValues; override;
1658 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1659 TfdBGRX4us1 = class(TfdUniversalUS1)
1660 procedure SetValues; override;
1663 TfdXBGR4us1 = class(TfdUniversalUS1)
1664 procedure SetValues; override;
1667 TfdB5G6R5us1 = class(TfdUniversalUS1)
1668 procedure SetValues; override;
1671 TfdBGR5X1us1 = class(TfdUniversalUS1)
1672 procedure SetValues; override;
1675 TfdX1BGR5us1 = class(TfdUniversalUS1)
1676 procedure SetValues; override;
1679 TfdBGR8ub3 = class(TfdBGRub3)
1680 procedure SetValues; override;
1683 TfdBGRX8ui1 = class(TfdUniversalUI1)
1684 procedure SetValues; override;
1687 TfdXBGR8ui1 = class(TfdUniversalUI1)
1688 procedure SetValues; override;
1691 TfdBGR10X2ui1 = class(TfdUniversalUI1)
1692 procedure SetValues; override;
1695 TfdX2BGR10ui1 = class(TfdUniversalUI1)
1696 procedure SetValues; override;
1699 TfdBGR16us3 = class(TfdBGRus3)
1700 procedure SetValues; override;
1703 TfdBGRA4us1 = class(TfdUniversalUS1)
1704 procedure SetValues; override;
1707 TfdABGR4us1 = class(TfdUniversalUS1)
1708 procedure SetValues; override;
1711 TfdBGR5A1us1 = class(TfdUniversalUS1)
1712 procedure SetValues; override;
1715 TfdA1BGR5us1 = class(TfdUniversalUS1)
1716 procedure SetValues; override;
1719 TfdBGRA8ui1 = class(TfdUniversalUI1)
1720 procedure SetValues; override;
1723 TfdABGR8ui1 = class(TfdUniversalUI1)
1724 procedure SetValues; override;
1727 TfdBGRA8ub4 = class(TfdBGRAub4)
1728 procedure SetValues; override;
1731 TfdBGR10A2ui1 = class(TfdUniversalUI1)
1732 procedure SetValues; override;
1735 TfdA2BGR10ui1 = class(TfdUniversalUI1)
1736 procedure SetValues; override;
1739 TfdBGRA16us4 = class(TfdBGRAus4)
1740 procedure SetValues; override;
1743 TfdDepth16us1 = class(TfdDepthUS1)
1744 procedure SetValues; override;
1747 TfdDepth24ui1 = class(TfdDepthUI1)
1748 procedure SetValues; override;
1751 TfdDepth32ui1 = class(TfdDepthUI1)
1752 procedure SetValues; override;
1755 TfdS3tcDtx1RGBA = class(TFormatDescriptor)
1756 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1757 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1758 procedure SetValues; override;
1761 TfdS3tcDtx3RGBA = class(TFormatDescriptor)
1762 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1763 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1764 procedure SetValues; override;
1767 TfdS3tcDtx5RGBA = class(TFormatDescriptor)
1768 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1769 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1770 procedure SetValues; override;
1773 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1774 TbmpBitfieldFormat = class(TFormatDescriptor)
1776 procedure SetCustomValues(const aBPP: Integer; aMask: TglBitmapRec4ul); overload;
1777 procedure SetCustomValues(const aBBP: Integer; const aPrec, aShift: TglBitmapRec4ub); overload;
1778 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1779 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1782 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1783 TbmpColorTableEnty = packed record
1786 TbmpColorTable = array of TbmpColorTableEnty;
1787 TbmpColorTableFormat = class(TFormatDescriptor)
1789 fBitsPerPixel: Integer;
1790 fColorTable: TbmpColorTable;
1792 procedure SetValues; override;
1794 property ColorTable: TbmpColorTable read fColorTable write fColorTable;
1795 property BitsPerPixel: Integer read fBitsPerPixel write fBitsPerPixel;
1797 procedure SetCustomValues(const aFormat: TglBitmapFormat; const aBPP: Integer; const aPrec, aShift: TglBitmapRec4ub); overload;
1798 procedure CalcValues;
1799 procedure CreateColorTable;
1801 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1802 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1803 destructor Destroy; override;
1807 LUMINANCE_WEIGHT_R = 0.30;
1808 LUMINANCE_WEIGHT_G = 0.59;
1809 LUMINANCE_WEIGHT_B = 0.11;
1811 ALPHA_WEIGHT_R = 0.30;
1812 ALPHA_WEIGHT_G = 0.59;
1813 ALPHA_WEIGHT_B = 0.11;
1815 DEPTH_WEIGHT_R = 0.333333333;
1816 DEPTH_WEIGHT_G = 0.333333333;
1817 DEPTH_WEIGHT_B = 0.333333333;
1819 FORMAT_DESCRIPTOR_CLASSES: array[TglBitmapFormat] of TFormatDescriptorClass = (
1830 TfdLuminance4Alpha4ub2,
1831 TfdLuminance6Alpha2ub2,
1832 TfdLuminance8Alpha8ub2,
1833 TfdLuminance12Alpha4us2,
1834 TfdLuminance16Alpha16us2,
1893 FormatDescriptorCS: TCriticalSection;
1894 FormatDescriptors: array[TglBitmapFormat] of TFormatDescriptor;
1896 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1897 constructor EglBitmapUnsupportedFormat.Create(const aFormat: TglBitmapFormat);
1899 inherited Create('unsupported format: ' + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
1902 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1903 constructor EglBitmapUnsupportedFormat.Create(const aMsg: String; const aFormat: TglBitmapFormat);
1905 inherited Create(aMsg + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
1908 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1909 function glBitmapPosition(X: Integer; Y: Integer): TglBitmapPixelPosition;
1911 result.Fields := [];
1914 result.Fields := result.Fields + [ffX];
1916 result.Fields := result.Fields + [ffY];
1918 result.X := Max(0, X);
1919 result.Y := Max(0, Y);
1922 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1923 function glBitmapRec4ub(const r, g, b, a: Byte): TglBitmapRec4ub;
1931 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1932 function glBitmapRec4ui(const r, g, b, a: Cardinal): TglBitmapRec4ui;
1940 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1941 function glBitmapRec4ul(const r, g, b, a: QWord): TglBitmapRec4ul;
1949 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1950 function glBitmapRec4ubCompare(const r1, r2: TglBitmapRec4ub): Boolean;
1955 for i := 0 to high(r1.arr) do
1956 if (r1.arr[i] <> r2.arr[i]) then
1961 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1962 function glBitmapRec4uiCompare(const r1, r2: TglBitmapRec4ui): Boolean;
1967 for i := 0 to high(r1.arr) do
1968 if (r1.arr[i] <> r2.arr[i]) then
1973 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1974 function glBitmapCreateTestTexture(const aFormat: TglBitmapFormat): TglBitmap2D;
1976 desc: TFormatDescriptor;
1980 px: TglBitmapPixelData;
1983 desc := TFormatDescriptor.Get(aFormat);
1984 if (desc.IsCompressed) or (desc.glFormat = 0) then
1987 p := GetMemory(ceil(25 * desc.BytesPerPixel)); // 5 x 5 pixel
1988 md := desc.CreateMappingData;
1991 desc.PreparePixel(px);
1993 for x := 0 to 4 do begin
1994 px.Data := glBitmapRec4ui(0, 0, 0, 0);
1995 for i := 0 to 3 do begin
1996 if ((y < 3) and (y = i)) or
1997 ((y = 3) and (i < 3)) or
1998 ((y = 4) and (i = 3))
2000 px.Data.arr[i] := Trunc(px.Range.arr[i] / 4 * x)
2001 else if ((y < 4) and (i = 3)) or
2002 ((y = 4) and (i < 3))
2004 px.Data.arr[i] := px.Range.arr[i]
2006 px.Data.arr[i] := 0; //px.Range.arr[i];
2008 desc.Map(px, tmp, md);
2011 desc.FreeMappingData(md);
2014 result := TglBitmap2D.Create(glBitmapPosition(5, 5), aFormat, p);
2015 result.FreeDataOnDestroy := true;
2016 result.FreeDataAfterGenTexture := false;
2017 result.SetFilter(GL_NEAREST, GL_NEAREST);
2020 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2021 function glBitmapShiftRec(const r, g, b, a: Byte): TglBitmapRec4ub;
2029 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2030 function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes;
2036 tfAlpha4ub1, tfAlpha8ub1,
2037 tfLuminance4ub1, tfLuminance8ub1, tfR3G3B2ub1,
2040 tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
2041 tfRGBX4us1, tfXRGB4us1, tfRGB5X1us1, tfX1RGB5us1, tfR5G6B5us1, tfRGB5A1us1, tfA1RGB5us1, tfRGBA4us1, tfARGB4us1,
2042 tfBGRX4us1, tfXBGR4us1, tfBGR5X1us1, tfX1BGR5us1, tfB5G6R5us1, tfBGR5A1us1, tfA1BGR5us1, tfBGRA4us1, tfABGR4us1,
2045 tfBGR8ub3, tfRGB8ub3,
2048 tfRGBX8ui1, tfXRGB8ui1, tfRGB10X2ui1, tfX2RGB10ui1, tfRGBA8ui1, tfARGB8ui1, tfRGBA8ub4, tfRGB10A2ui1, tfA2RGB10ui1,
2049 tfBGRX8ui1, tfXBGR8ui1, tfBGR10X2ui1, tfX2BGR10ui1, tfBGRA8ui1, tfABGR8ui1, tfBGRA8ub4, tfBGR10A2ui1, tfA2BGR10ui1])
2051 result := result + [ ftBMP ];
2055 tfAlpha4ub1, tfAlpha8ub1, tfLuminance4ub1, tfLuminance8ub1,
2058 tfAlpha16us1, tfLuminance16us1,
2059 tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
2060 tfX1RGB5us1, tfARGB4us1, tfA1RGB5us1, tfDepth16us1,
2066 tfX2RGB10ui1, tfARGB8ui1, tfBGRA8ub4, tfA2RGB10ui1,
2067 tfDepth24ui1, tfDepth32ui1])
2069 result := result + [ftTGA];
2071 if not (aFormat in [tfEmpty, tfRGB16us3, tfBGR16us3]) then
2072 result := result + [ftDDS];
2074 {$IFDEF GLB_SUPPORT_PNG_WRITE}
2076 tfAlpha8ub1, tfLuminance8ub1, tfLuminance8Alpha8ub2,
2077 tfRGB8ub3, tfRGBA8ui1,
2078 tfBGR8ub3, tfBGRA8ui1] then
2079 result := result + [ftPNG];
2082 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
2083 if aFormat in [tfAlpha8ub1, tfLuminance8ub1, tfRGB8ub3, tfBGR8ub3] then
2084 result := result + [ftJPEG];
2088 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2089 function IsPowerOfTwo(aNumber: Integer): Boolean;
2091 while (aNumber and 1) = 0 do
2092 aNumber := aNumber shr 1;
2093 result := aNumber = 1;
2096 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2097 function GetTopMostBit(aBitSet: QWord): Integer;
2100 while aBitSet > 0 do begin
2102 aBitSet := aBitSet shr 1;
2106 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2107 function CountSetBits(aBitSet: QWord): Integer;
2110 while aBitSet > 0 do begin
2111 if (aBitSet and 1) = 1 then
2113 aBitSet := aBitSet shr 1;
2117 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2118 function LuminanceWeight(const aPixel: TglBitmapPixelData): Cardinal;
2121 LUMINANCE_WEIGHT_R * aPixel.Data.r +
2122 LUMINANCE_WEIGHT_G * aPixel.Data.g +
2123 LUMINANCE_WEIGHT_B * aPixel.Data.b);
2126 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2127 function DepthWeight(const aPixel: TglBitmapPixelData): Cardinal;
2130 DEPTH_WEIGHT_R * aPixel.Data.r +
2131 DEPTH_WEIGHT_G * aPixel.Data.g +
2132 DEPTH_WEIGHT_B * aPixel.Data.b);
2135 {$IFDEF GLB_NATIVE_OGL}
2136 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2137 //OpenGLInitialization///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2138 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2140 GL_LibHandle: Pointer = nil;
2142 function glbGetProcAddress(aProcName: PAnsiChar; aLibHandle: Pointer = nil; const aRaiseOnErr: Boolean = true): Pointer;
2144 if not Assigned(aLibHandle) then
2145 aLibHandle := GL_LibHandle;
2147 {$IF DEFINED(GLB_WIN)}
2148 result := GetProcAddress({%H-}HMODULE(aLibHandle), aProcName);
2149 if Assigned(result) then
2152 if Assigned(wglGetProcAddress) then
2153 result := wglGetProcAddress(aProcName);
2154 {$ELSEIF DEFINED(GLB_LINUX)}
2155 if Assigned(glXGetProcAddress) then begin
2156 result := glXGetProcAddress(aProcName);
2157 if Assigned(result) then
2161 if Assigned(glXGetProcAddressARB) then begin
2162 result := glXGetProcAddressARB(aProcName);
2163 if Assigned(result) then
2167 result := dlsym(aLibHandle, aProcName);
2169 if not Assigned(result) and aRaiseOnErr then
2170 raise EglBitmap.Create('unable to load procedure form library: ' + aProcName);
2173 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
2175 GLU_LibHandle: Pointer = nil;
2176 OpenGLInitialized: Boolean;
2177 InitOpenGLCS: TCriticalSection;
2179 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2180 procedure glbInitOpenGL;
2182 ////////////////////////////////////////////////////////////////////////////////
2183 function glbLoadLibrary(const aName: PChar): Pointer;
2185 {$IF DEFINED(GLB_WIN)}
2186 result := {%H-}Pointer(LoadLibrary(aName));
2187 {$ELSEIF DEFINED(GLB_LINUX)}
2188 result := dlopen(Name, RTLD_LAZY);
2194 ////////////////////////////////////////////////////////////////////////////////
2195 function glbFreeLibrary(const aLibHandle: Pointer): Boolean;
2198 if not Assigned(aLibHandle) then
2201 {$IF DEFINED(GLB_WIN)}
2202 Result := FreeLibrary({%H-}HINST(aLibHandle));
2203 {$ELSEIF DEFINED(GLB_LINUX)}
2204 Result := dlclose(aLibHandle) = 0;
2209 if Assigned(GL_LibHandle) then
2210 glbFreeLibrary(GL_LibHandle);
2212 if Assigned(GLU_LibHandle) then
2213 glbFreeLibrary(GLU_LibHandle);
2215 GL_LibHandle := glbLoadLibrary(libopengl);
2216 if not Assigned(GL_LibHandle) then
2217 raise EglBitmap.Create('unable to load library: ' + libopengl);
2219 GLU_LibHandle := glbLoadLibrary(libglu);
2220 if not Assigned(GLU_LibHandle) then
2221 raise EglBitmap.Create('unable to load library: ' + libglu);
2223 {$IF DEFINED(GLB_WIN)}
2224 wglGetProcAddress := glbGetProcAddress('wglGetProcAddress');
2225 {$ELSEIF DEFINED(GLB_LINUX)}
2226 glXGetProcAddress := glbGetProcAddress('glXGetProcAddress');
2227 glXGetProcAddressARB := glbGetProcAddress('glXGetProcAddressARB');
2230 glEnable := glbGetProcAddress('glEnable');
2231 glDisable := glbGetProcAddress('glDisable');
2232 glGetString := glbGetProcAddress('glGetString');
2233 glGetIntegerv := glbGetProcAddress('glGetIntegerv');
2234 glTexParameteri := glbGetProcAddress('glTexParameteri');
2235 glTexParameteriv := glbGetProcAddress('glTexParameteriv');
2236 glTexParameterfv := glbGetProcAddress('glTexParameterfv');
2237 glGetTexParameteriv := glbGetProcAddress('glGetTexParameteriv');
2238 glGetTexParameterfv := glbGetProcAddress('glGetTexParameterfv');
2239 glGetTexLevelParameteriv := glbGetProcAddress('glGetTexLevelParameteriv');
2240 glGetTexLevelParameterfv := glbGetProcAddress('glGetTexLevelParameterfv');
2241 glTexGeni := glbGetProcAddress('glTexGeni');
2242 glGenTextures := glbGetProcAddress('glGenTextures');
2243 glBindTexture := glbGetProcAddress('glBindTexture');
2244 glDeleteTextures := glbGetProcAddress('glDeleteTextures');
2245 glAreTexturesResident := glbGetProcAddress('glAreTexturesResident');
2246 glReadPixels := glbGetProcAddress('glReadPixels');
2247 glPixelStorei := glbGetProcAddress('glPixelStorei');
2248 glTexImage1D := glbGetProcAddress('glTexImage1D');
2249 glTexImage2D := glbGetProcAddress('glTexImage2D');
2250 glGetTexImage := glbGetProcAddress('glGetTexImage');
2252 gluBuild1DMipmaps := glbGetProcAddress('gluBuild1DMipmaps', GLU_LibHandle);
2253 gluBuild2DMipmaps := glbGetProcAddress('gluBuild2DMipmaps', GLU_LibHandle);
2257 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2258 procedure glbReadOpenGLExtensions;
2261 MajorVersion, MinorVersion: Integer;
2263 ///////////////////////////////////////////////////////////////////////////////////////////
2264 procedure TrimVersionString(aBuffer: AnsiString; out aMajor, aMinor: Integer);
2271 Separator := Pos(AnsiString('.'), aBuffer);
2272 if (Separator > 1) and (Separator < Length(aBuffer)) and
2273 (aBuffer[Separator - 1] in ['0'..'9']) and
2274 (aBuffer[Separator + 1] in ['0'..'9']) then begin
2277 while (Separator > 0) and (aBuffer[Separator] in ['0'..'9']) do
2280 Delete(aBuffer, 1, Separator);
2281 Separator := Pos(AnsiString('.'), aBuffer) + 1;
2283 while (Separator <= Length(aBuffer)) and (AnsiChar(aBuffer[Separator]) in ['0'..'9']) do
2286 Delete(aBuffer, Separator, 255);
2287 Separator := Pos(AnsiString('.'), aBuffer);
2289 aMajor := StrToInt(Copy(String(aBuffer), 1, Separator - 1));
2290 aMinor := StrToInt(Copy(String(aBuffer), Separator + 1, 1));
2294 ///////////////////////////////////////////////////////////////////////////////////////////
2295 function CheckExtension(const Extension: AnsiString): Boolean;
2299 ExtPos := Pos(Extension, Buffer);
2300 result := ExtPos > 0;
2302 result := ((ExtPos + Length(Extension) - 1) = Length(Buffer)) or not (Buffer[ExtPos + Length(Extension)] in ['_', 'A'..'Z', 'a'..'z']);
2305 ///////////////////////////////////////////////////////////////////////////////////////////
2306 function CheckVersion(const aMajor, aMinor: Integer): Boolean;
2308 result := (MajorVersion > aMajor) or ((MajorVersion = aMajor) and (MinorVersion >= aMinor));
2312 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
2315 if not OpenGLInitialized then begin
2317 OpenGLInitialized := true;
2325 Buffer := glGetString(GL_VERSION);
2326 TrimVersionString(Buffer, MajorVersion, MinorVersion);
2328 GL_VERSION_1_2 := CheckVersion(1, 2);
2329 GL_VERSION_1_3 := CheckVersion(1, 3);
2330 GL_VERSION_1_4 := CheckVersion(1, 4);
2331 GL_VERSION_2_0 := CheckVersion(2, 0);
2332 GL_VERSION_3_3 := CheckVersion(3, 3);
2335 Buffer := glGetString(GL_EXTENSIONS);
2336 GL_ARB_texture_border_clamp := CheckExtension('GL_ARB_texture_border_clamp');
2337 GL_ARB_texture_non_power_of_two := CheckExtension('GL_ARB_texture_non_power_of_two');
2338 GL_ARB_texture_swizzle := CheckExtension('GL_ARB_texture_swizzle');
2339 GL_ARB_texture_cube_map := CheckExtension('GL_ARB_texture_cube_map');
2340 GL_ARB_texture_rectangle := CheckExtension('GL_ARB_texture_rectangle');
2341 GL_ARB_texture_mirrored_repeat := CheckExtension('GL_ARB_texture_mirrored_repeat');
2342 GL_EXT_texture_edge_clamp := CheckExtension('GL_EXT_texture_edge_clamp');
2343 GL_EXT_texture_filter_anisotropic := CheckExtension('GL_EXT_texture_filter_anisotropic');
2344 GL_EXT_texture_rectangle := CheckExtension('GL_EXT_texture_rectangle');
2345 GL_EXT_texture_swizzle := CheckExtension('GL_EXT_texture_swizzle');
2346 GL_EXT_texture_cube_map := CheckExtension('GL_EXT_texture_cube_map');
2347 GL_NV_texture_rectangle := CheckExtension('GL_NV_texture_rectangle');
2348 GL_IBM_texture_mirrored_repeat := CheckExtension('GL_IBM_texture_mirrored_repeat');
2349 GL_SGIS_generate_mipmap := CheckExtension('GL_SGIS_generate_mipmap');
2351 if GL_VERSION_1_3 then begin
2352 glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1D');
2353 glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2D');
2354 glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImage');
2356 glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1DARB', nil, false);
2357 glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2DARB', nil, false);
2358 glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImageARB', nil, false);
2363 {$IFDEF GLB_SDL_IMAGE}
2364 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2365 // SDL Image Helper /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2366 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2367 function glBitmapRWseek(context: PSDL_RWops; offset: Integer; whence: Integer): Integer; cdecl;
2369 result := TStream(context^.unknown.data1).Seek(offset, whence);
2372 function glBitmapRWread(context: PSDL_RWops; Ptr: Pointer; size: Integer; maxnum : Integer): Integer; cdecl;
2374 result := TStream(context^.unknown.data1).Read(Ptr^, size * maxnum);
2377 function glBitmapRWwrite(context: PSDL_RWops; Ptr: Pointer; size: Integer; num: Integer): Integer; cdecl;
2379 result := TStream(context^.unknown.data1).Write(Ptr^, size * num);
2382 function glBitmapRWclose(context: PSDL_RWops): Integer; cdecl;
2387 function glBitmapCreateRWops(Stream: TStream): PSDL_RWops;
2389 result := SDL_AllocRW;
2391 if result = nil then
2392 raise EglBitmap.Create('glBitmapCreateRWops - SDL_AllocRW failed.');
2394 result^.seek := glBitmapRWseek;
2395 result^.read := glBitmapRWread;
2396 result^.write := glBitmapRWwrite;
2397 result^.close := glBitmapRWclose;
2398 result^.unknown.data1 := Stream;
2402 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2403 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
2405 glBitmapDefaultDeleteTextureOnFree := aDeleteTextureOnFree;
2408 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2409 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
2411 glBitmapDefaultFreeDataAfterGenTextures := aFreeData;
2414 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2415 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
2417 glBitmapDefaultMipmap := aValue;
2420 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2421 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
2423 glBitmapDefaultFormat := aFormat;
2426 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2427 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
2429 glBitmapDefaultFilterMin := aMin;
2430 glBitmapDefaultFilterMag := aMag;
2433 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2434 procedure glBitmapSetDefaultWrap(const S: Cardinal = GL_CLAMP_TO_EDGE; const T: Cardinal = GL_CLAMP_TO_EDGE; const R: Cardinal = GL_CLAMP_TO_EDGE);
2436 glBitmapDefaultWrapS := S;
2437 glBitmapDefaultWrapT := T;
2438 glBitmapDefaultWrapR := R;
2441 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2442 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
2443 procedure glBitmapSetDefaultSwizzle(const r: GLenum = GL_RED; g: GLenum = GL_GREEN; b: GLenum = GL_BLUE; a: GLenum = GL_ALPHA);
2445 glDefaultSwizzle[0] := r;
2446 glDefaultSwizzle[1] := g;
2447 glDefaultSwizzle[2] := b;
2448 glDefaultSwizzle[3] := a;
2452 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2453 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
2455 result := glBitmapDefaultDeleteTextureOnFree;
2458 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2459 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
2461 result := glBitmapDefaultFreeDataAfterGenTextures;
2464 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2465 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
2467 result := glBitmapDefaultMipmap;
2470 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2471 function glBitmapGetDefaultFormat: TglBitmapFormat;
2473 result := glBitmapDefaultFormat;
2476 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2477 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
2479 aMin := glBitmapDefaultFilterMin;
2480 aMag := glBitmapDefaultFilterMag;
2483 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2484 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
2486 S := glBitmapDefaultWrapS;
2487 T := glBitmapDefaultWrapT;
2488 R := glBitmapDefaultWrapR;
2492 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2493 procedure glBitmapGetDefaultSwizzle(var r, g, b, a: GLenum);
2495 r := glDefaultSwizzle[0];
2496 g := glDefaultSwizzle[1];
2497 b := glDefaultSwizzle[2];
2498 a := glDefaultSwizzle[3];
2502 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2503 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2504 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2505 function TFormatDescriptor.GetSize(const aSize: TglBitmapPixelPosition): Integer;
2509 if (ffX in aSize.Fields) or (ffY in aSize.Fields) then begin
2510 w := Max(1, aSize.X);
2511 h := Max(1, aSize.Y);
2512 result := GetSize(w, h);
2517 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2518 function TFormatDescriptor.GetSize(const aWidth, aHeight: Integer): Integer;
2521 if (aWidth <= 0) or (aHeight <= 0) then
2523 result := Ceil(aWidth * aHeight * BytesPerPixel);
2526 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2527 function TFormatDescriptor.CreateMappingData: Pointer;
2532 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2533 procedure TFormatDescriptor.FreeMappingData(var aMappingData: Pointer);
2538 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2539 function TFormatDescriptor.IsEmpty: Boolean;
2541 result := (fFormat = tfEmpty);
2544 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2545 function TFormatDescriptor.MaskMatch(const aMask: TglBitmapRec4ul): Boolean;
2551 if (aMask.r = 0) and (aMask.g = 0) and (aMask.b = 0) and (aMask.a = 0) then
2552 raise EglBitmap.Create('FormatCheckFormat - All Masks are 0');
2555 if (aMask.arr[i] <> m.arr[i]) then
2560 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2561 procedure TFormatDescriptor.PreparePixel(out aPixel: TglBitmapPixelData);
2563 FillChar(aPixel{%H-}, SizeOf(aPixel), 0);
2564 aPixel.Data := Range;
2565 aPixel.Format := fFormat;
2566 aPixel.Range := Range;
2569 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2570 constructor TFormatDescriptor.Create;
2575 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2576 //TfdAlpha_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2577 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2578 procedure TfdAlphaUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2580 aData^ := aPixel.Data.a;
2584 procedure TfdAlphaUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2589 aPixel.Data.a := aData^;
2593 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2594 //TfdLuminance_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2595 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2596 procedure TfdLuminanceUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2598 aData^ := LuminanceWeight(aPixel);
2602 procedure TfdLuminanceUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2604 aPixel.Data.r := aData^;
2605 aPixel.Data.g := aData^;
2606 aPixel.Data.b := aData^;
2611 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2612 //TfdUniversal_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2613 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2614 procedure TfdUniversalUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2620 if (Range.arr[i] > 0) then
2621 aData^ := aData^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
2625 procedure TfdUniversalUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2630 aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and Range.arr[i];
2634 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2635 //TfdLuminanceAlpha_UB2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2636 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2637 procedure TfdLuminanceAlphaUB2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2639 inherited Map(aPixel, aData, aMapData);
2640 aData^ := aPixel.Data.a;
2644 procedure TfdLuminanceAlphaUB2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2646 inherited Unmap(aData, aPixel, aMapData);
2647 aPixel.Data.a := aData^;
2651 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2652 //TfdRGB_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2653 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2654 procedure TfdRGBub3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2656 aData^ := aPixel.Data.r;
2658 aData^ := aPixel.Data.g;
2660 aData^ := aPixel.Data.b;
2664 procedure TfdRGBub3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2666 aPixel.Data.r := aData^;
2668 aPixel.Data.g := aData^;
2670 aPixel.Data.b := aData^;
2675 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2676 //TfdBGR_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2677 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2678 procedure TfdBGRub3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2680 aData^ := aPixel.Data.b;
2682 aData^ := aPixel.Data.g;
2684 aData^ := aPixel.Data.r;
2688 procedure TfdBGRub3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2690 aPixel.Data.b := aData^;
2692 aPixel.Data.g := aData^;
2694 aPixel.Data.r := aData^;
2699 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2700 //TfdRGBA_UB4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2701 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2702 procedure TfdRGBAub4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2704 inherited Map(aPixel, aData, aMapData);
2705 aData^ := aPixel.Data.a;
2709 procedure TfdRGBAub4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2711 inherited Unmap(aData, aPixel, aMapData);
2712 aPixel.Data.a := aData^;
2716 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2717 //TfdBGRA_UB4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2718 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2719 procedure TfdBGRAub4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2721 inherited Map(aPixel, aData, aMapData);
2722 aData^ := aPixel.Data.a;
2726 procedure TfdBGRAub4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2728 inherited Unmap(aData, aPixel, aMapData);
2729 aPixel.Data.a := aData^;
2733 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2734 //TfdAlpha_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2735 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2736 procedure TfdAlphaUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2738 PWord(aData)^ := aPixel.Data.a;
2742 procedure TfdAlphaUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2747 aPixel.Data.a := PWord(aData)^;
2751 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2752 //TfdLuminance_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2753 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2754 procedure TfdLuminanceUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2756 PWord(aData)^ := LuminanceWeight(aPixel);
2760 procedure TfdLuminanceUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2762 aPixel.Data.r := PWord(aData)^;
2763 aPixel.Data.g := PWord(aData)^;
2764 aPixel.Data.b := PWord(aData)^;
2769 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2770 //TfdUniversal_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2771 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2772 procedure TfdUniversalUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2778 if (Range.arr[i] > 0) then
2779 PWord(aData)^ := PWord(aData)^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
2783 procedure TfdUniversalUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2788 aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and Range.arr[i];
2792 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2793 //TfdDepth_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2794 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2795 procedure TfdDepthUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2797 PWord(aData)^ := DepthWeight(aPixel);
2801 procedure TfdDepthUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2803 aPixel.Data.r := PWord(aData)^;
2804 aPixel.Data.g := PWord(aData)^;
2805 aPixel.Data.b := PWord(aData)^;
2806 aPixel.Data.a := PWord(aData)^;;
2810 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2811 //TfdLuminanceAlpha_US2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2812 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2813 procedure TfdLuminanceAlphaUS2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2815 inherited Map(aPixel, aData, aMapData);
2816 PWord(aData)^ := aPixel.Data.a;
2820 procedure TfdLuminanceAlphaUS2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2822 inherited Unmap(aData, aPixel, aMapData);
2823 aPixel.Data.a := PWord(aData)^;
2827 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2828 //TfdRGB_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2829 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2830 procedure TfdRGBus3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2832 PWord(aData)^ := aPixel.Data.r;
2834 PWord(aData)^ := aPixel.Data.g;
2836 PWord(aData)^ := aPixel.Data.b;
2840 procedure TfdRGBus3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2842 aPixel.Data.r := PWord(aData)^;
2844 aPixel.Data.g := PWord(aData)^;
2846 aPixel.Data.b := PWord(aData)^;
2851 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2852 //TfdBGR_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2853 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2854 procedure TfdBGRus3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2856 PWord(aData)^ := aPixel.Data.b;
2858 PWord(aData)^ := aPixel.Data.g;
2860 PWord(aData)^ := aPixel.Data.r;
2864 procedure TfdBGRus3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2866 aPixel.Data.b := PWord(aData)^;
2868 aPixel.Data.g := PWord(aData)^;
2870 aPixel.Data.r := PWord(aData)^;
2875 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2876 //TfdRGBA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2877 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2878 procedure TfdRGBAus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2880 inherited Map(aPixel, aData, aMapData);
2881 PWord(aData)^ := aPixel.Data.a;
2885 procedure TfdRGBAus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2887 inherited Unmap(aData, aPixel, aMapData);
2888 aPixel.Data.a := PWord(aData)^;
2892 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2893 //TfdARGB_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2894 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2895 procedure TfdARGBus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2897 PWord(aData)^ := aPixel.Data.a;
2899 inherited Map(aPixel, aData, aMapData);
2902 procedure TfdARGBus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2904 aPixel.Data.a := PWord(aData)^;
2906 inherited Unmap(aData, aPixel, aMapData);
2909 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2910 //TfdBGRA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2911 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2912 procedure TfdBGRAus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2914 inherited Map(aPixel, aData, aMapData);
2915 PWord(aData)^ := aPixel.Data.a;
2919 procedure TfdBGRAus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2921 inherited Unmap(aData, aPixel, aMapData);
2922 aPixel.Data.a := PWord(aData)^;
2926 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2927 //TfdABGR_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2928 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2929 procedure TfdABGRus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2931 PWord(aData)^ := aPixel.Data.a;
2933 inherited Map(aPixel, aData, aMapData);
2936 procedure TfdABGRus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2938 aPixel.Data.a := PWord(aData)^;
2940 inherited Unmap(aData, aPixel, aMapData);
2943 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2944 //TfdUniversal_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2945 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2946 procedure TfdUniversalUI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2950 PCardinal(aData)^ := 0;
2952 if (Range.arr[i] > 0) then
2953 PCardinal(aData)^ := PCardinal(aData)^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
2957 procedure TfdUniversalUI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2962 aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and Range.arr[i];
2966 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2967 //TfdDepth_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2968 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2969 procedure TfdDepthUI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2971 PCardinal(aData)^ := DepthWeight(aPixel);
2975 procedure TfdDepthUI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2977 aPixel.Data.r := PCardinal(aData)^;
2978 aPixel.Data.g := PCardinal(aData)^;
2979 aPixel.Data.b := PCardinal(aData)^;
2980 aPixel.Data.a := PCardinal(aData)^;
2984 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2985 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2986 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2987 procedure TfdAlpha4ub1.SetValues;
2989 inherited SetValues;
2991 fFormat := tfAlpha4ub1;
2992 fWithAlpha := tfAlpha4ub1;
2993 fPrecision := glBitmapRec4ub(0, 0, 0, 8);
2994 fShift := glBitmapRec4ub(0, 0, 0, 0);
2996 fOpenGLFormat := tfAlpha4ub1;
2997 fglFormat := GL_ALPHA;
2998 fglInternalFormat := GL_ALPHA4;
2999 fglDataFormat := GL_UNSIGNED_BYTE;
3001 fOpenGLFormat := tfAlpha8ub1;
3005 procedure TfdAlpha8ub1.SetValues;
3007 inherited SetValues;
3009 fFormat := tfAlpha8ub1;
3010 fWithAlpha := tfAlpha8ub1;
3011 fPrecision := glBitmapRec4ub(0, 0, 0, 8);
3012 fShift := glBitmapRec4ub(0, 0, 0, 0);
3013 fOpenGLFormat := tfAlpha8ub1;
3014 fglFormat := GL_ALPHA;
3015 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_ALPHA8{$ELSE}GL_ALPHA{$ENDIF};
3016 fglDataFormat := GL_UNSIGNED_BYTE;
3019 procedure TfdAlpha16us1.SetValues;
3021 inherited SetValues;
3022 fBitsPerPixel := 16;
3023 fFormat := tfAlpha16us1;
3024 fWithAlpha := tfAlpha16us1;
3025 fPrecision := glBitmapRec4ub(0, 0, 0, 16);
3026 fShift := glBitmapRec4ub(0, 0, 0, 0);
3028 fOpenGLFormat := tfAlpha16us1;
3029 fglFormat := GL_ALPHA;
3030 fglInternalFormat := GL_ALPHA16;
3031 fglDataFormat := GL_UNSIGNED_SHORT;
3033 fOpenGLFormat := tfAlpha8ub1;
3037 procedure TfdLuminance4ub1.SetValues;
3039 inherited SetValues;
3041 fFormat := tfLuminance4ub1;
3042 fWithAlpha := tfLuminance4Alpha4ub2;
3043 fWithoutAlpha := tfLuminance4ub1;
3044 fPrecision := glBitmapRec4ub(8, 8, 8, 0);
3045 fShift := glBitmapRec4ub(0, 0, 0, 0);
3047 fOpenGLFormat := tfLuminance4ub1;
3048 fglFormat := GL_LUMINANCE;
3049 fglInternalFormat := GL_LUMINANCE4;
3050 fglDataFormat := GL_UNSIGNED_BYTE;
3052 fOpenGLFormat := tfLuminance8ub1;
3056 procedure TfdLuminance8ub1.SetValues;
3058 inherited SetValues;
3060 fFormat := tfLuminance8ub1;
3061 fWithAlpha := tfLuminance8Alpha8ub2;
3062 fWithoutAlpha := tfLuminance8ub1;
3063 fOpenGLFormat := tfLuminance8ub1;
3064 fPrecision := glBitmapRec4ub(8, 8, 8, 0);
3065 fShift := glBitmapRec4ub(0, 0, 0, 0);
3066 fglFormat := GL_LUMINANCE;
3067 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_LUMINANCE8{$ELSE}GL_LUMINANCE{$ENDIF};
3068 fglDataFormat := GL_UNSIGNED_BYTE;
3071 procedure TfdLuminance16us1.SetValues;
3073 inherited SetValues;
3074 fBitsPerPixel := 16;
3075 fFormat := tfLuminance16us1;
3076 fWithAlpha := tfLuminance16Alpha16us2;
3077 fWithoutAlpha := tfLuminance16us1;
3078 fPrecision := glBitmapRec4ub(16, 16, 16, 0);
3079 fShift := glBitmapRec4ub( 0, 0, 0, 0);
3081 fOpenGLFormat := tfLuminance16us1;
3082 fglFormat := GL_LUMINANCE;
3083 fglInternalFormat := GL_LUMINANCE16;
3084 fglDataFormat := GL_UNSIGNED_SHORT;
3086 fOpenGLFormat := tfLuminance8ub1;
3090 procedure TfdLuminance4Alpha4ub2.SetValues;
3092 inherited SetValues;
3093 fBitsPerPixel := 16;
3094 fFormat := tfLuminance4Alpha4ub2;
3095 fWithAlpha := tfLuminance4Alpha4ub2;
3096 fWithoutAlpha := tfLuminance4ub1;
3097 fPrecision := glBitmapRec4ub(8, 8, 8, 8);
3098 fShift := glBitmapRec4ub(0, 0, 0, 8);
3100 fOpenGLFormat := tfLuminance4Alpha4ub2;
3101 fglFormat := GL_LUMINANCE_ALPHA;
3102 fglInternalFormat := GL_LUMINANCE4_ALPHA4;
3103 fglDataFormat := GL_UNSIGNED_BYTE;
3105 fOpenGLFormat := tfLuminance8Alpha8ub2;
3109 procedure TfdLuminance6Alpha2ub2.SetValues;
3111 inherited SetValues;
3112 fBitsPerPixel := 16;
3113 fFormat := tfLuminance6Alpha2ub2;
3114 fWithAlpha := tfLuminance6Alpha2ub2;
3115 fWithoutAlpha := tfLuminance8ub1;
3116 fPrecision := glBitmapRec4ub(8, 8, 8, 8);
3117 fShift := glBitmapRec4ub(0, 0, 0, 8);
3119 fOpenGLFormat := tfLuminance6Alpha2ub2;
3120 fglFormat := GL_LUMINANCE_ALPHA;
3121 fglInternalFormat := GL_LUMINANCE6_ALPHA2;
3122 fglDataFormat := GL_UNSIGNED_BYTE;
3124 fOpenGLFormat := tfLuminance8Alpha8ub2;
3128 procedure TfdLuminance8Alpha8ub2.SetValues;
3130 inherited SetValues;
3131 fBitsPerPixel := 16;
3132 fFormat := tfLuminance8Alpha8ub2;
3133 fWithAlpha := tfLuminance8Alpha8ub2;
3134 fWithoutAlpha := tfLuminance8ub1;
3135 fOpenGLFormat := tfLuminance8Alpha8ub2;
3136 fPrecision := glBitmapRec4ub(8, 8, 8, 8);
3137 fShift := glBitmapRec4ub(0, 0, 0, 8);
3138 fglFormat := GL_LUMINANCE_ALPHA;
3139 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_LUMINANCE8_ALPHA8{$ELSE}GL_LUMINANCE_ALPHA{$ENDIF};
3140 fglDataFormat := GL_UNSIGNED_BYTE;
3143 procedure TfdLuminance12Alpha4us2.SetValues;
3145 inherited SetValues;
3146 fBitsPerPixel := 32;
3147 fFormat := tfLuminance12Alpha4us2;
3148 fWithAlpha := tfLuminance12Alpha4us2;
3149 fWithoutAlpha := tfLuminance16us1;
3150 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3151 fShift := glBitmapRec4ub( 0, 0, 0, 16);
3153 fOpenGLFormat := tfLuminance12Alpha4us2;
3154 fglFormat := GL_LUMINANCE_ALPHA;
3155 fglInternalFormat := GL_LUMINANCE12_ALPHA4;
3156 fglDataFormat := GL_UNSIGNED_SHORT;
3158 fOpenGLFormat := tfLuminance8Alpha8ub2;
3162 procedure TfdLuminance16Alpha16us2.SetValues;
3164 inherited SetValues;
3165 fBitsPerPixel := 32;
3166 fFormat := tfLuminance16Alpha16us2;
3167 fWithAlpha := tfLuminance16Alpha16us2;
3168 fWithoutAlpha := tfLuminance16us1;
3169 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3170 fShift := glBitmapRec4ub( 0, 0, 0, 16);
3172 fOpenGLFormat := tfLuminance16Alpha16us2;
3173 fglFormat := GL_LUMINANCE_ALPHA;
3174 fglInternalFormat := GL_LUMINANCE16_ALPHA16;
3175 fglDataFormat := GL_UNSIGNED_SHORT;
3177 fOpenGLFormat := tfLuminance8Alpha8ub2;
3181 procedure TfdR3G3B2ub1.SetValues;
3183 inherited SetValues;
3185 fFormat := tfR3G3B2ub1;
3186 fWithAlpha := tfRGBA4us1;
3187 fWithoutAlpha := tfR3G3B2ub1;
3188 fRGBInverted := tfEmpty;
3189 fPrecision := glBitmapRec4ub(3, 3, 2, 0);
3190 fShift := glBitmapRec4ub(5, 2, 0, 0);
3192 fOpenGLFormat := tfR3G3B2ub1;
3193 fglFormat := GL_RGB;
3194 fglInternalFormat := GL_R3_G3_B2;
3195 fglDataFormat := GL_UNSIGNED_BYTE_3_3_2;
3197 fOpenGLFormat := tfR5G6B5us1;
3201 procedure TfdRGBX4us1.SetValues;
3203 inherited SetValues;
3204 fBitsPerPixel := 16;
3205 fFormat := tfRGBX4us1;
3206 fWithAlpha := tfRGBA4us1;
3207 fWithoutAlpha := tfRGBX4us1;
3208 fRGBInverted := tfBGRX4us1;
3209 fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
3210 fShift := glBitmapRec4ub(12, 8, 4, 0);
3212 fOpenGLFormat := tfRGBX4us1;
3213 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3214 fglInternalFormat := GL_RGB4;
3215 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3217 fOpenGLFormat := tfR5G6B5us1;
3221 procedure TfdXRGB4us1.SetValues;
3223 inherited SetValues;
3224 fBitsPerPixel := 16;
3225 fFormat := tfXRGB4us1;
3226 fWithAlpha := tfARGB4us1;
3227 fWithoutAlpha := tfXRGB4us1;
3228 fRGBInverted := tfXBGR4us1;
3229 fPrecision := glBitmapRec4ub(4, 4, 4, 0);
3230 fShift := glBitmapRec4ub(8, 4, 0, 0);
3232 fOpenGLFormat := tfXRGB4us1;
3233 fglFormat := GL_BGRA;
3234 fglInternalFormat := GL_RGB4;
3235 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3237 fOpenGLFormat := tfR5G6B5us1;
3241 procedure TfdR5G6B5us1.SetValues;
3243 inherited SetValues;
3244 fBitsPerPixel := 16;
3245 fFormat := tfR5G6B5us1;
3246 fWithAlpha := tfRGB5A1us1;
3247 fWithoutAlpha := tfR5G6B5us1;
3248 fRGBInverted := tfB5G6R5us1;
3249 fPrecision := glBitmapRec4ub( 5, 6, 5, 0);
3250 fShift := glBitmapRec4ub(11, 5, 0, 0);
3251 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
3252 fOpenGLFormat := tfR5G6B5us1;
3253 fglFormat := GL_RGB;
3254 fglInternalFormat := GL_RGB565;
3255 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5;
3257 fOpenGLFormat := tfRGB8ub3;
3261 procedure TfdRGB5X1us1.SetValues;
3263 inherited SetValues;
3264 fBitsPerPixel := 16;
3265 fFormat := tfRGB5X1us1;
3266 fWithAlpha := tfRGB5A1us1;
3267 fWithoutAlpha := tfRGB5X1us1;
3268 fRGBInverted := tfBGR5X1us1;
3269 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
3270 fShift := glBitmapRec4ub(11, 6, 1, 0);
3272 fOpenGLFormat := tfRGB5X1us1;
3273 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3274 fglInternalFormat := GL_RGB5;
3275 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3277 fOpenGLFormat := tfR5G6B5us1;
3281 procedure TfdX1RGB5us1.SetValues;
3283 inherited SetValues;
3284 fBitsPerPixel := 16;
3285 fFormat := tfX1RGB5us1;
3286 fWithAlpha := tfA1RGB5us1;
3287 fWithoutAlpha := tfX1RGB5us1;
3288 fRGBInverted := tfX1BGR5us1;
3289 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
3290 fShift := glBitmapRec4ub(10, 5, 0, 0);
3292 fOpenGLFormat := tfX1RGB5us1;
3293 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3294 fglInternalFormat := GL_RGB5;
3295 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3297 fOpenGLFormat := tfR5G6B5us1;
3301 procedure TfdRGB8ub3.SetValues;
3303 inherited SetValues;
3304 fBitsPerPixel := 24;
3305 fFormat := tfRGB8ub3;
3306 fWithAlpha := tfRGBA8ub4;
3307 fWithoutAlpha := tfRGB8ub3;
3308 fRGBInverted := tfBGR8ub3;
3309 fPrecision := glBitmapRec4ub(8, 8, 8, 0);
3310 fShift := glBitmapRec4ub(0, 8, 16, 0);
3311 fOpenGLFormat := tfRGB8ub3;
3312 fglFormat := GL_RGB;
3313 fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}GL_RGB8{$ELSE}GL_RGB{$IFEND};
3314 fglDataFormat := GL_UNSIGNED_BYTE;
3317 procedure TfdRGBX8ui1.SetValues;
3319 inherited SetValues;
3320 fBitsPerPixel := 32;
3321 fFormat := tfRGBX8ui1;
3322 fWithAlpha := tfRGBA8ui1;
3323 fWithoutAlpha := tfRGBX8ui1;
3324 fRGBInverted := tfBGRX8ui1;
3325 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3326 fShift := glBitmapRec4ub(24, 16, 8, 0);
3328 fOpenGLFormat := tfRGBX8ui1;
3329 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3330 fglInternalFormat := GL_RGB8;
3331 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3333 fOpenGLFormat := tfRGB8ub3;
3337 procedure TfdXRGB8ui1.SetValues;
3339 inherited SetValues;
3340 fBitsPerPixel := 32;
3341 fFormat := tfXRGB8ui1;
3342 fWithAlpha := tfXRGB8ui1;
3343 fWithoutAlpha := tfXRGB8ui1;
3344 fOpenGLFormat := tfXRGB8ui1;
3345 fRGBInverted := tfXBGR8ui1;
3346 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3347 fShift := glBitmapRec4ub(16, 8, 0, 0);
3349 fOpenGLFormat := tfXRGB8ui1;
3350 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3351 fglInternalFormat := GL_RGB8;
3352 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3354 fOpenGLFormat := tfRGB8ub3;
3358 procedure TfdRGB10X2ui1.SetValues;
3360 inherited SetValues;
3361 fBitsPerPixel := 32;
3362 fFormat := tfRGB10X2ui1;
3363 fWithAlpha := tfRGB10A2ui1;
3364 fWithoutAlpha := tfRGB10X2ui1;
3365 fRGBInverted := tfBGR10X2ui1;
3366 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3367 fShift := glBitmapRec4ub(22, 12, 2, 0);
3369 fOpenGLFormat := tfRGB10X2ui1;
3370 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3371 fglInternalFormat := GL_RGB10;
3372 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3374 fOpenGLFormat := tfRGB16us3;
3378 procedure TfdX2RGB10ui1.SetValues;
3380 inherited SetValues;
3381 fBitsPerPixel := 32;
3382 fFormat := tfX2RGB10ui1;
3383 fWithAlpha := tfA2RGB10ui1;
3384 fWithoutAlpha := tfX2RGB10ui1;
3385 fRGBInverted := tfX2BGR10ui1;
3386 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3387 fShift := glBitmapRec4ub(20, 10, 0, 0);
3389 fOpenGLFormat := tfX2RGB10ui1;
3390 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3391 fglInternalFormat := GL_RGB10;
3392 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3394 fOpenGLFormat := tfRGB16us3;
3398 procedure TfdRGB16us3.SetValues;
3400 inherited SetValues;
3401 fBitsPerPixel := 48;
3402 fFormat := tfRGB16us3;
3403 fWithAlpha := tfRGBA16us4;
3404 fWithoutAlpha := tfRGB16us3;
3405 fRGBInverted := tfBGR16us3;
3406 fPrecision := glBitmapRec4ub(16, 16, 16, 0);
3407 fShift := glBitmapRec4ub( 0, 16, 32, 0);
3408 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
3409 fOpenGLFormat := tfRGB16us3;
3410 fglFormat := GL_RGB;
3411 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_RGB16{$ELSE}GL_RGB16UI{$ENDIF};
3412 fglDataFormat := GL_UNSIGNED_SHORT;
3414 fOpenGLFormat := tfRGB8ub3;
3418 procedure TfdRGBA4us1.SetValues;
3420 inherited SetValues;
3421 fBitsPerPixel := 16;
3422 fFormat := tfRGBA4us1;
3423 fWithAlpha := tfRGBA4us1;
3424 fWithoutAlpha := tfRGBX4us1;
3425 fOpenGLFormat := tfRGBA4us1;
3426 fRGBInverted := tfBGRA4us1;
3427 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3428 fShift := glBitmapRec4ub(12, 8, 4, 0);
3429 fglFormat := GL_RGBA;
3430 fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}GL_RGBA8{$ELSE}GL_RGBA{$IFEND};
3431 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3434 procedure TfdARGB4us1.SetValues;
3436 inherited SetValues;
3437 fBitsPerPixel := 16;
3438 fFormat := tfARGB4us1;
3439 fWithAlpha := tfARGB4us1;
3440 fWithoutAlpha := tfXRGB4us1;
3441 fRGBInverted := tfABGR4us1;
3442 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3443 fShift := glBitmapRec4ub( 8, 4, 0, 12);
3445 fOpenGLFormat := tfARGB4us1;
3446 fglFormat := GL_BGRA;
3447 fglInternalFormat := GL_RGBA4;
3448 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3450 fOpenGLFormat := tfRGBA4us1;
3454 procedure TfdRGB5A1us1.SetValues;
3456 inherited SetValues;
3457 fBitsPerPixel := 16;
3458 fFormat := tfRGB5A1us1;
3459 fWithAlpha := tfRGB5A1us1;
3460 fWithoutAlpha := tfRGB5X1us1;
3461 fOpenGLFormat := tfRGB5A1us1;
3462 fRGBInverted := tfBGR5A1us1;
3463 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3464 fShift := glBitmapRec4ub(11, 6, 1, 0);
3465 fglFormat := GL_RGBA;
3466 fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}GL_RGB5_A1{$ELSE}GL_RGBA{$IFEND};
3467 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3470 procedure TfdA1RGB5us1.SetValues;
3472 inherited SetValues;
3473 fBitsPerPixel := 16;
3474 fFormat := tfA1RGB5us1;
3475 fWithAlpha := tfA1RGB5us1;
3476 fWithoutAlpha := tfX1RGB5us1;
3477 fRGBInverted := tfA1BGR5us1;
3478 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3479 fShift := glBitmapRec4ub(10, 5, 0, 15);
3481 fOpenGLFormat := tfA1RGB5us1;
3482 fglFormat := GL_BGRA;
3483 fglInternalFormat := GL_RGB5_A1;
3484 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3486 fOpenGLFormat := tfRGB5A1us1;
3490 procedure TfdRGBA8ui1.SetValues;
3492 inherited SetValues;
3493 fBitsPerPixel := 32;
3494 fFormat := tfRGBA8ui1;
3495 fWithAlpha := tfRGBA8ui1;
3496 fWithoutAlpha := tfRGBX8ui1;
3497 fRGBInverted := tfBGRA8ui1;
3498 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3499 fShift := glBitmapRec4ub(24, 16, 8, 0);
3501 fOpenGLFormat := tfRGBA8ui1;
3502 fglFormat := GL_RGBA;
3503 fglInternalFormat := GL_RGBA8;
3504 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3506 fOpenGLFormat := tfRGBA8ub4;
3510 procedure TfdARGB8ui1.SetValues;
3512 inherited SetValues;
3513 fBitsPerPixel := 32;
3514 fFormat := tfARGB8ui1;
3515 fWithAlpha := tfARGB8ui1;
3516 fWithoutAlpha := tfXRGB8ui1;
3517 fRGBInverted := tfABGR8ui1;
3518 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3519 fShift := glBitmapRec4ub(16, 8, 0, 24);
3521 fOpenGLFormat := tfARGB8ui1;
3522 fglFormat := GL_BGRA;
3523 fglInternalFormat := GL_RGBA8;
3524 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3526 fOpenGLFormat := tfRGBA8ub4;
3530 procedure TfdRGBA8ub4.SetValues;
3532 inherited SetValues;
3533 fBitsPerPixel := 32;
3534 fFormat := tfRGBA8ub4;
3535 fWithAlpha := tfRGBA8ub4;
3536 fWithoutAlpha := tfRGB8ub3;
3537 fOpenGLFormat := tfRGBA8ub4;
3538 fRGBInverted := tfBGRA8ub4;
3539 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3540 fShift := glBitmapRec4ub( 0, 8, 16, 24);
3541 fglFormat := GL_RGBA;
3542 fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}GL_RGBA8{$ELSE}GL_RGBA{$IFEND};
3543 fglDataFormat := GL_UNSIGNED_BYTE;
3546 procedure TfdRGB10A2ui1.SetValues;
3548 inherited SetValues;
3549 fBitsPerPixel := 32;
3550 fFormat := tfRGB10A2ui1;
3551 fWithAlpha := tfRGB10A2ui1;
3552 fWithoutAlpha := tfRGB10X2ui1;
3553 fRGBInverted := tfBGR10A2ui1;
3554 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3555 fShift := glBitmapRec4ub(22, 12, 2, 0);
3557 fOpenGLFormat := tfRGB10A2ui1;
3558 fglFormat := GL_RGBA;
3559 fglInternalFormat := GL_RGB10_A2;
3560 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3562 fOpenGLFormat := tfA2RGB10ui1;
3566 procedure TfdA2RGB10ui1.SetValues;
3568 inherited SetValues;
3569 fBitsPerPixel := 32;
3570 fFormat := tfA2RGB10ui1;
3571 fWithAlpha := tfA2RGB10ui1;
3572 fWithoutAlpha := tfX2RGB10ui1;
3573 fRGBInverted := tfA2BGR10ui1;
3574 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3575 fShift := glBitmapRec4ub(20, 10, 0, 30);
3576 {$IF NOT DEFINED(OPENGL_ES)}
3577 fOpenGLFormat := tfA2RGB10ui1;
3578 fglFormat := GL_BGRA;
3579 fglInternalFormat := GL_RGB10_A2;
3580 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3581 {$ELSEIF DEFINED(OPENGL_ES_3_0)}
3582 fOpenGLFormat := tfA2RGB10ui1;
3583 fglFormat := GL_RGBA;
3584 fglInternalFormat := GL_RGB10_A2;
3585 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3587 fOpenGLFormat := tfRGBA8ui1;
3591 procedure TfdRGBA16us4.SetValues;
3593 inherited SetValues;
3594 fBitsPerPixel := 64;
3595 fFormat := tfRGBA16us4;
3596 fWithAlpha := tfRGBA16us4;
3597 fWithoutAlpha := tfRGB16us3;
3598 fRGBInverted := tfBGRA16us4;
3599 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3600 fShift := glBitmapRec4ub( 0, 16, 32, 48);
3601 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
3602 fOpenGLFormat := tfRGBA16us4;
3603 fglFormat := GL_RGBA;
3604 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_RGBA16{$ELSE}GL_RGBA16UI{$ENDIF};
3605 fglDataFormat := GL_UNSIGNED_SHORT;
3607 fOpenGLFormat := tfRGBA8ub4;
3611 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3612 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3613 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3614 procedure TfdBGRX4us1.SetValues;
3616 inherited SetValues;
3617 fBitsPerPixel := 16;
3618 fFormat := tfBGRX4us1;
3619 fWithAlpha := tfBGRA4us1;
3620 fWithoutAlpha := tfBGRX4us1;
3621 fRGBInverted := tfRGBX4us1;
3622 fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
3623 fShift := glBitmapRec4ub( 4, 8, 12, 0);
3625 fOpenGLFormat := tfBGRX4us1;
3626 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3627 fglInternalFormat := GL_RGB4;
3628 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3630 fOpenGLFormat := tfR5G6B5us1;
3634 procedure TfdXBGR4us1.SetValues;
3636 inherited SetValues;
3637 fBitsPerPixel := 16;
3638 fFormat := tfXBGR4us1;
3639 fWithAlpha := tfABGR4us1;
3640 fWithoutAlpha := tfXBGR4us1;
3641 fRGBInverted := tfXRGB4us1;
3642 fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
3643 fShift := glBitmapRec4ub( 0, 4, 8, 0);
3645 fOpenGLFormat := tfXBGR4us1;
3646 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3647 fglInternalFormat := GL_RGB4;
3648 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3650 fOpenGLFormat := tfR5G6B5us1;
3654 procedure TfdB5G6R5us1.SetValues;
3656 inherited SetValues;
3657 fBitsPerPixel := 16;
3658 fFormat := tfB5G6R5us1;
3659 fWithAlpha := tfBGR5A1us1;
3660 fWithoutAlpha := tfB5G6R5us1;
3661 fRGBInverted := tfR5G6B5us1;
3662 fPrecision := glBitmapRec4ub( 5, 6, 5, 0);
3663 fShift := glBitmapRec4ub( 0, 5, 11, 0);
3665 fOpenGLFormat := tfB5G6R5us1;
3666 fglFormat := GL_RGB;
3667 fglInternalFormat := GL_RGB565;
3668 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5_REV;
3670 fOpenGLFormat := tfR5G6B5us1;
3674 procedure TfdBGR5X1us1.SetValues;
3676 inherited SetValues;
3677 fBitsPerPixel := 16;
3678 fFormat := tfBGR5X1us1;
3679 fWithAlpha := tfBGR5A1us1;
3680 fWithoutAlpha := tfBGR5X1us1;
3681 fRGBInverted := tfRGB5X1us1;
3682 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
3683 fShift := glBitmapRec4ub( 1, 6, 11, 0);
3685 fOpenGLFormat := tfBGR5X1us1;
3686 fglFormat := GL_BGRA;
3687 fglInternalFormat := GL_RGB5;
3688 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3690 fOpenGLFormat := tfR5G6B5us1;
3694 procedure TfdX1BGR5us1.SetValues;
3696 inherited SetValues;
3697 fBitsPerPixel := 16;
3698 fFormat := tfX1BGR5us1;
3699 fWithAlpha := tfA1BGR5us1;
3700 fWithoutAlpha := tfX1BGR5us1;
3701 fRGBInverted := tfX1RGB5us1;
3702 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
3703 fShift := glBitmapRec4ub( 0, 5, 10, 0);
3705 fOpenGLFormat := tfX1BGR5us1;
3706 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3707 fglInternalFormat := GL_RGB5;
3708 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3710 fOpenGLFormat := tfR5G6B5us1;
3714 procedure TfdBGR8ub3.SetValues;
3716 inherited SetValues;
3717 fBitsPerPixel := 24;
3718 fFormat := tfBGR8ub3;
3719 fWithAlpha := tfBGRA8ub4;
3720 fWithoutAlpha := tfBGR8ub3;
3721 fRGBInverted := tfRGB8ub3;
3722 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3723 fShift := glBitmapRec4ub(16, 8, 0, 0);
3725 fOpenGLFormat := tfBGR8ub3;
3726 fglFormat := GL_BGR;
3727 fglInternalFormat := GL_RGB8;
3728 fglDataFormat := GL_UNSIGNED_BYTE;
3730 fOpenGLFormat := tfRGB8ub3;
3734 procedure TfdBGRX8ui1.SetValues;
3736 inherited SetValues;
3737 fBitsPerPixel := 32;
3738 fFormat := tfBGRX8ui1;
3739 fWithAlpha := tfBGRA8ui1;
3740 fWithoutAlpha := tfBGRX8ui1;
3741 fRGBInverted := tfRGBX8ui1;
3742 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3743 fShift := glBitmapRec4ub( 8, 16, 24, 0);
3745 fOpenGLFormat := tfBGRX8ui1;
3746 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3747 fglInternalFormat := GL_RGB8;
3748 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3750 fOpenGLFormat := tfRGB8ub3;
3754 procedure TfdXBGR8ui1.SetValues;
3756 inherited SetValues;
3757 fBitsPerPixel := 32;
3758 fFormat := tfXBGR8ui1;
3759 fWithAlpha := tfABGR8ui1;
3760 fWithoutAlpha := tfXBGR8ui1;
3761 fRGBInverted := tfXRGB8ui1;
3762 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3763 fShift := glBitmapRec4ub( 0, 8, 16, 0);
3765 fOpenGLFormat := tfXBGR8ui1;
3766 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3767 fglInternalFormat := GL_RGB8;
3768 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3770 fOpenGLFormat := tfRGB8ub3;
3774 procedure TfdBGR10X2ui1.SetValues;
3776 inherited SetValues;
3777 fBitsPerPixel := 32;
3778 fFormat := tfBGR10X2ui1;
3779 fWithAlpha := tfBGR10A2ui1;
3780 fWithoutAlpha := tfBGR10X2ui1;
3781 fRGBInverted := tfRGB10X2ui1;
3782 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3783 fShift := glBitmapRec4ub( 2, 12, 22, 0);
3785 fOpenGLFormat := tfBGR10X2ui1;
3786 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3787 fglInternalFormat := GL_RGB10;
3788 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3790 fOpenGLFormat := tfRGB16us3;
3794 procedure TfdX2BGR10ui1.SetValues;
3796 inherited SetValues;
3797 fBitsPerPixel := 32;
3798 fFormat := tfX2BGR10ui1;
3799 fWithAlpha := tfA2BGR10ui1;
3800 fWithoutAlpha := tfX2BGR10ui1;
3801 fRGBInverted := tfX2RGB10ui1;
3802 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3803 fShift := glBitmapRec4ub( 0, 10, 20, 0);
3805 fOpenGLFormat := tfX2BGR10ui1;
3806 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3807 fglInternalFormat := GL_RGB10;
3808 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3810 fOpenGLFormat := tfRGB16us3;
3814 procedure TfdBGR16us3.SetValues;
3816 inherited SetValues;
3817 fBitsPerPixel := 48;
3818 fFormat := tfBGR16us3;
3819 fWithAlpha := tfBGRA16us4;
3820 fWithoutAlpha := tfBGR16us3;
3821 fRGBInverted := tfRGB16us3;
3822 fPrecision := glBitmapRec4ub(16, 16, 16, 0);
3823 fShift := glBitmapRec4ub(32, 16, 0, 0);
3825 fOpenGLFormat := tfBGR16us3;
3826 fglFormat := GL_BGR;
3827 fglInternalFormat := GL_RGB16;
3828 fglDataFormat := GL_UNSIGNED_SHORT;
3830 fOpenGLFormat := tfRGB16us3;
3834 procedure TfdBGRA4us1.SetValues;
3836 inherited SetValues;
3837 fBitsPerPixel := 16;
3838 fFormat := tfBGRA4us1;
3839 fWithAlpha := tfBGRA4us1;
3840 fWithoutAlpha := tfBGRX4us1;
3841 fRGBInverted := tfRGBA4us1;
3842 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3843 fShift := glBitmapRec4ub( 4, 8, 12, 0);
3845 fOpenGLFormat := tfBGRA4us1;
3846 fglFormat := GL_BGRA;
3847 fglInternalFormat := GL_RGBA4;
3848 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3850 fOpenGLFormat := tfRGBA4us1;
3854 procedure TfdABGR4us1.SetValues;
3856 inherited SetValues;
3857 fBitsPerPixel := 16;
3858 fFormat := tfABGR4us1;
3859 fWithAlpha := tfABGR4us1;
3860 fWithoutAlpha := tfXBGR4us1;
3861 fRGBInverted := tfARGB4us1;
3862 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3863 fShift := glBitmapRec4ub( 0, 4, 8, 12);
3865 fOpenGLFormat := tfABGR4us1;
3866 fglFormat := GL_RGBA;
3867 fglInternalFormat := GL_RGBA4;
3868 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3870 fOpenGLFormat := tfRGBA4us1;
3874 procedure TfdBGR5A1us1.SetValues;
3876 inherited SetValues;
3877 fBitsPerPixel := 16;
3878 fFormat := tfBGR5A1us1;
3879 fWithAlpha := tfBGR5A1us1;
3880 fWithoutAlpha := tfBGR5X1us1;
3881 fRGBInverted := tfRGB5A1us1;
3882 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3883 fShift := glBitmapRec4ub( 1, 6, 11, 0);
3885 fOpenGLFormat := tfBGR5A1us1;
3886 fglFormat := GL_BGRA;
3887 fglInternalFormat := GL_RGB5_A1;
3888 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3890 fOpenGLFormat := tfRGB5A1us1;
3894 procedure TfdA1BGR5us1.SetValues;
3896 inherited SetValues;
3897 fBitsPerPixel := 16;
3898 fFormat := tfA1BGR5us1;
3899 fWithAlpha := tfA1BGR5us1;
3900 fWithoutAlpha := tfX1BGR5us1;
3901 fRGBInverted := tfA1RGB5us1;
3902 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3903 fShift := glBitmapRec4ub( 0, 5, 10, 15);
3905 fOpenGLFormat := tfA1BGR5us1;
3906 fglFormat := GL_RGBA;
3907 fglInternalFormat := GL_RGB5_A1;
3908 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3910 fOpenGLFormat := tfRGB5A1us1;
3914 procedure TfdBGRA8ui1.SetValues;
3916 inherited SetValues;
3917 fBitsPerPixel := 32;
3918 fFormat := tfBGRA8ui1;
3919 fWithAlpha := tfBGRA8ui1;
3920 fWithoutAlpha := tfBGRX8ui1;
3921 fRGBInverted := tfRGBA8ui1;
3922 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3923 fShift := glBitmapRec4ub( 8, 16, 24, 0);
3925 fOpenGLFormat := tfBGRA8ui1;
3926 fglFormat := GL_BGRA;
3927 fglInternalFormat := GL_RGBA8;
3928 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3930 fOpenGLFormat := tfRGBA8ub4;
3934 procedure TfdABGR8ui1.SetValues;
3936 inherited SetValues;
3937 fBitsPerPixel := 32;
3938 fFormat := tfABGR8ui1;
3939 fWithAlpha := tfABGR8ui1;
3940 fWithoutAlpha := tfXBGR8ui1;
3941 fRGBInverted := tfARGB8ui1;
3942 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3943 fShift := glBitmapRec4ub( 0, 8, 16, 24);
3945 fOpenGLFormat := tfABGR8ui1;
3946 fglFormat := GL_RGBA;
3947 fglInternalFormat := GL_RGBA8;
3948 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3950 fOpenGLFormat := tfRGBA8ub4
3954 procedure TfdBGRA8ub4.SetValues;
3956 inherited SetValues;
3957 fBitsPerPixel := 32;
3958 fFormat := tfBGRA8ub4;
3959 fWithAlpha := tfBGRA8ub4;
3960 fWithoutAlpha := tfBGR8ub3;
3961 fRGBInverted := tfRGBA8ub4;
3962 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3963 fShift := glBitmapRec4ub(16, 8, 0, 24);
3965 fOpenGLFormat := tfBGRA8ub4;
3966 fglFormat := GL_BGRA;
3967 fglInternalFormat := GL_RGBA8;
3968 fglDataFormat := GL_UNSIGNED_BYTE;
3970 fOpenGLFormat := tfRGBA8ub4;
3974 procedure TfdBGR10A2ui1.SetValues;
3976 inherited SetValues;
3977 fBitsPerPixel := 32;
3978 fFormat := tfBGR10A2ui1;
3979 fWithAlpha := tfBGR10A2ui1;
3980 fWithoutAlpha := tfBGR10X2ui1;
3981 fRGBInverted := tfRGB10A2ui1;
3982 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3983 fShift := glBitmapRec4ub( 2, 12, 22, 0);
3985 fOpenGLFormat := tfBGR10A2ui1;
3986 fglFormat := GL_BGRA;
3987 fglInternalFormat := GL_RGB10_A2;
3988 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3990 fOpenGLFormat := tfA2RGB10ui1;
3994 procedure TfdA2BGR10ui1.SetValues;
3996 inherited SetValues;
3997 fBitsPerPixel := 32;
3998 fFormat := tfA2BGR10ui1;
3999 fWithAlpha := tfA2BGR10ui1;
4000 fWithoutAlpha := tfX2BGR10ui1;
4001 fRGBInverted := tfA2RGB10ui1;
4002 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
4003 fShift := glBitmapRec4ub( 0, 10, 20, 30);
4005 fOpenGLFormat := tfA2BGR10ui1;
4006 fglFormat := GL_RGBA;
4007 fglInternalFormat := GL_RGB10_A2;
4008 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
4010 fOpenGLFormat := tfA2RGB10ui1;
4014 procedure TfdBGRA16us4.SetValues;
4016 inherited SetValues;
4017 fBitsPerPixel := 64;
4018 fFormat := tfBGRA16us4;
4019 fWithAlpha := tfBGRA16us4;
4020 fWithoutAlpha := tfBGR16us3;
4021 fRGBInverted := tfRGBA16us4;
4022 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
4023 fShift := glBitmapRec4ub(32, 16, 0, 48);
4025 fOpenGLFormat := tfBGRA16us4;
4026 fglFormat := GL_BGRA;
4027 fglInternalFormat := GL_RGBA16;
4028 fglDataFormat := GL_UNSIGNED_SHORT;
4030 fOpenGLFormat := tfRGBA16us4;
4034 procedure TfdDepth16us1.SetValues;
4036 inherited SetValues;
4037 fBitsPerPixel := 16;
4038 fFormat := tfDepth16us1;
4039 fWithoutAlpha := tfDepth16us1;
4040 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
4041 fShift := glBitmapRec4ub( 0, 0, 0, 0);
4042 {$IF NOT DEFINED (OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
4043 fOpenGLFormat := tfDepth16us1;
4044 fglFormat := GL_DEPTH_COMPONENT;
4045 fglInternalFormat := GL_DEPTH_COMPONENT16;
4046 fglDataFormat := GL_UNSIGNED_SHORT;
4050 procedure TfdDepth24ui1.SetValues;
4052 inherited SetValues;
4053 fBitsPerPixel := 32;
4054 fFormat := tfDepth24ui1;
4055 fWithoutAlpha := tfDepth24ui1;
4056 fOpenGLFormat := tfDepth24ui1;
4057 fPrecision := glBitmapRec4ub(32, 32, 32, 32);
4058 fShift := glBitmapRec4ub( 0, 0, 0, 0);
4059 {$IF NOT DEFINED (OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
4060 fOpenGLFormat := tfDepth24ui1;
4061 fglFormat := GL_DEPTH_COMPONENT;
4062 fglInternalFormat := GL_DEPTH_COMPONENT24;
4063 fglDataFormat := GL_UNSIGNED_INT;
4067 procedure TfdDepth32ui1.SetValues;
4069 inherited SetValues;
4070 fBitsPerPixel := 32;
4071 fFormat := tfDepth32ui1;
4072 fWithoutAlpha := tfDepth32ui1;
4073 fPrecision := glBitmapRec4ub(32, 32, 32, 32);
4074 fShift := glBitmapRec4ub( 0, 0, 0, 0);
4075 {$IF NOT DEFINED(OPENGL_ES)}
4076 fOpenGLFormat := tfDepth32ui1;
4077 fglFormat := GL_DEPTH_COMPONENT;
4078 fglInternalFormat := GL_DEPTH_COMPONENT32;
4079 fglDataFormat := GL_UNSIGNED_INT;
4080 {$ELSEIF DEFINED(OPENGL_ES_3_0)}
4081 fOpenGLFormat := tfDepth24ui1;
4082 {$ELSEIF DEFINED(OPENGL_ES_2_0)}
4083 fOpenGLFormat := tfDepth16us1;
4087 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4088 //TfdS3tcDtx1RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4089 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4090 procedure TfdS3tcDtx1RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4092 raise EglBitmap.Create('mapping for compressed formats is not supported');
4095 procedure TfdS3tcDtx1RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4097 raise EglBitmap.Create('mapping for compressed formats is not supported');
4100 procedure TfdS3tcDtx1RGBA.SetValues;
4102 inherited SetValues;
4103 fFormat := tfS3tcDtx1RGBA;
4104 fWithAlpha := tfS3tcDtx1RGBA;
4105 fUncompressed := tfRGB5A1us1;
4107 fIsCompressed := true;
4109 fOpenGLFormat := tfS3tcDtx1RGBA;
4110 fglFormat := GL_COMPRESSED_RGBA;
4111 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
4112 fglDataFormat := GL_UNSIGNED_BYTE;
4114 fOpenGLFormat := fUncompressed;
4118 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4119 //TfdS3tcDtx3RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4120 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4121 procedure TfdS3tcDtx3RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4123 raise EglBitmap.Create('mapping for compressed formats is not supported');
4126 procedure TfdS3tcDtx3RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4128 raise EglBitmap.Create('mapping for compressed formats is not supported');
4131 procedure TfdS3tcDtx3RGBA.SetValues;
4133 inherited SetValues;
4134 fFormat := tfS3tcDtx3RGBA;
4135 fWithAlpha := tfS3tcDtx3RGBA;
4136 fUncompressed := tfRGBA8ub4;
4138 fIsCompressed := true;
4140 fOpenGLFormat := tfS3tcDtx3RGBA;
4141 fglFormat := GL_COMPRESSED_RGBA;
4142 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
4143 fglDataFormat := GL_UNSIGNED_BYTE;
4145 fOpenGLFormat := fUncompressed;
4149 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4150 //TfdS3tcDtx5RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4151 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4152 procedure TfdS3tcDtx5RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4154 raise EglBitmap.Create('mapping for compressed formats is not supported');
4157 procedure TfdS3tcDtx5RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4159 raise EglBitmap.Create('mapping for compressed formats is not supported');
4162 procedure TfdS3tcDtx5RGBA.SetValues;
4164 inherited SetValues;
4165 fFormat := tfS3tcDtx3RGBA;
4166 fWithAlpha := tfS3tcDtx3RGBA;
4167 fUncompressed := tfRGBA8ub4;
4169 fIsCompressed := true;
4171 fOpenGLFormat := tfS3tcDtx3RGBA;
4172 fglFormat := GL_COMPRESSED_RGBA;
4173 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
4174 fglDataFormat := GL_UNSIGNED_BYTE;
4176 fOpenGLFormat := fUncompressed;
4180 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4181 //TglBitmapFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4182 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4183 function TglBitmapFormatDescriptor.GetHasRed: Boolean;
4185 result := (fPrecision.r > 0);
4188 function TglBitmapFormatDescriptor.GetHasGreen: Boolean;
4190 result := (fPrecision.g > 0);
4193 function TglBitmapFormatDescriptor.GetHasBlue: Boolean;
4195 result := (fPrecision.b > 0);
4198 function TglBitmapFormatDescriptor.GetHasAlpha: Boolean;
4200 result := (fPrecision.a > 0);
4203 function TglBitmapFormatDescriptor.GetHasColor: Boolean;
4205 result := HasRed or HasGreen or HasBlue;
4208 function TglBitmapFormatDescriptor.GetIsGrayscale: Boolean;
4210 result := (Mask.r = Mask.g) and (Mask.g = Mask.b) and (Mask.r > 0);
4213 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4214 procedure TglBitmapFormatDescriptor.SetValues;
4217 fWithAlpha := tfEmpty;
4218 fWithoutAlpha := tfEmpty;
4219 fOpenGLFormat := tfEmpty;
4220 fRGBInverted := tfEmpty;
4221 fUncompressed := tfEmpty;
4224 fIsCompressed := false;
4227 fglInternalFormat := 0;
4230 FillChar(fPrecision, 0, SizeOf(fPrecision));
4231 FillChar(fShift, 0, SizeOf(fShift));
4234 procedure TglBitmapFormatDescriptor.CalcValues;
4238 fBytesPerPixel := fBitsPerPixel / 8;
4240 for i := 0 to 3 do begin
4241 if (fPrecision.arr[i] > 0) then
4243 fRange.arr[i] := (1 shl fPrecision.arr[i]) - 1;
4244 fMask.arr[i] := fRange.arr[i] shl fShift.arr[i];
4248 constructor TglBitmapFormatDescriptor.Create;
4255 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4256 class function TglBitmapFormatDescriptor.GetByFormat(const aInternalFormat: GLenum): TglBitmapFormatDescriptor;
4260 for f := Low(TglBitmapFormat) to High(TglBitmapFormat) do begin
4261 result := TFormatDescriptor.Get(f);
4262 if (result.glInternalFormat = aInternalFormat) then
4265 result := TFormatDescriptor.Get(tfEmpty);
4268 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4269 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4270 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4271 class procedure TFormatDescriptor.Init;
4273 if not Assigned(FormatDescriptorCS) then
4274 FormatDescriptorCS := TCriticalSection.Create;
4277 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4278 class function TFormatDescriptor.Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
4280 FormatDescriptorCS.Enter;
4282 result := FormatDescriptors[aFormat];
4283 if not Assigned(result) then begin
4284 result := FORMAT_DESCRIPTOR_CLASSES[aFormat].Create;
4285 FormatDescriptors[aFormat] := result;
4288 FormatDescriptorCS.Leave;
4292 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4293 class function TFormatDescriptor.GetAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
4295 result := Get(Get(aFormat).WithAlpha);
4298 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4299 class function TFormatDescriptor.GetFromMask(const aMask: TglBitmapRec4ul; const aBitCount: Integer): TFormatDescriptor;
4301 ft: TglBitmapFormat;
4303 // find matching format with OpenGL support
4304 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
4306 if (result.MaskMatch(aMask)) and
4307 (result.glFormat <> 0) and
4308 (result.glInternalFormat <> 0) and
4309 ((aBitCount = 0) or (aBitCount = result.BitsPerPixel))
4314 // find matching format without OpenGL Support
4315 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
4317 if result.MaskMatch(aMask) and ((aBitCount = 0) or (aBitCount = result.BitsPerPixel)) then
4321 result := TFormatDescriptor.Get(tfEmpty);
4324 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4325 class function TFormatDescriptor.GetFromPrecShift(const aPrec, aShift: TglBitmapRec4ub; const aBitCount: Integer): TFormatDescriptor;
4327 ft: TglBitmapFormat;
4329 // find matching format with OpenGL support
4330 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
4332 if glBitmapRec4ubCompare(result.Shift, aShift) and
4333 glBitmapRec4ubCompare(result.Precision, aPrec) and
4334 (result.glFormat <> 0) and
4335 (result.glInternalFormat <> 0) and
4336 ((aBitCount = 0) or (aBitCount = result.BitsPerPixel))
4341 // find matching format without OpenGL Support
4342 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
4344 if glBitmapRec4ubCompare(result.Shift, aShift) and
4345 glBitmapRec4ubCompare(result.Precision, aPrec) and
4346 ((aBitCount = 0) or (aBitCount = result.BitsPerPixel)) then
4350 result := TFormatDescriptor.Get(tfEmpty);
4353 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4354 class procedure TFormatDescriptor.Clear;
4358 FormatDescriptorCS.Enter;
4360 for f := low(FormatDescriptors) to high(FormatDescriptors) do
4361 FreeAndNil(FormatDescriptors[f]);
4363 FormatDescriptorCS.Leave;
4367 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4368 class procedure TFormatDescriptor.Finalize;
4371 FreeAndNil(FormatDescriptorCS);
4374 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4375 //TBitfieldFormat/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4376 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4377 procedure TbmpBitfieldFormat.SetCustomValues(const aBPP: Integer; aMask: TglBitmapRec4ul);
4381 for i := 0 to 3 do begin
4383 while (aMask.arr[i] > 0) and (aMask.arr[i] and 1 > 0) do begin
4384 aMask.arr[i] := aMask.arr[i] shr 1;
4387 fPrecision.arr[i] := CountSetBits(aMask.arr[i]);
4392 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4393 procedure TbmpBitfieldFormat.SetCustomValues(const aBBP: Integer; const aPrec, aShift: TglBitmapRec4ub);
4395 fBitsPerPixel := aBBP;
4396 fPrecision := aPrec;
4401 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4402 procedure TbmpBitfieldFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4407 ((aPixel.Data.r and Range.r) shl Shift.r) or
4408 ((aPixel.Data.g and Range.g) shl Shift.g) or
4409 ((aPixel.Data.b and Range.b) shl Shift.b) or
4410 ((aPixel.Data.a and Range.a) shl Shift.a);
4411 case BitsPerPixel of
4413 16: PWord(aData)^ := data;
4414 32: PCardinal(aData)^ := data;
4415 64: PQWord(aData)^ := data;
4417 raise EglBitmap.CreateFmt('invalid pixel size: %d', [BitsPerPixel]);
4419 inc(aData, Round(BytesPerPixel));
4422 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4423 procedure TbmpBitfieldFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4428 case BitsPerPixel of
4430 16: data := PWord(aData)^;
4431 32: data := PCardinal(aData)^;
4432 64: data := PQWord(aData)^;
4434 raise EglBitmap.CreateFmt('invalid pixel size: %d', [BitsPerPixel]);
4437 aPixel.Data.arr[i] := (data shr fShift.arr[i]) and Range.arr[i];
4438 inc(aData, Round(BytesPerPixel));
4441 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4442 //TColorTableFormat///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4443 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4444 procedure TbmpColorTableFormat.SetValues;
4446 inherited SetValues;
4447 fShift := glBitmapRec4ub(8, 8, 8, 0);
4450 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4451 procedure TbmpColorTableFormat.SetCustomValues(const aFormat: TglBitmapFormat; const aBPP: Integer; const aPrec, aShift: TglBitmapRec4ub);
4454 fBitsPerPixel := aBPP;
4455 fPrecision := aPrec;
4460 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4461 procedure TbmpColorTableFormat.CalcValues;
4463 inherited CalcValues;
4466 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4467 procedure TbmpColorTableFormat.CreateColorTable;
4471 SetLength(fColorTable, 256);
4472 if not HasColor then begin
4474 for i := 0 to High(fColorTable) do begin
4475 fColorTable[i].r := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
4476 fColorTable[i].g := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
4477 fColorTable[i].b := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
4478 fColorTable[i].a := 0;
4482 for i := 0 to High(fColorTable) do begin
4483 fColorTable[i].r := Round(((i shr Shift.r) and Range.r) / Range.r * 255);
4484 fColorTable[i].g := Round(((i shr Shift.g) and Range.g) / Range.g * 255);
4485 fColorTable[i].b := Round(((i shr Shift.b) and Range.b) / Range.b * 255);
4486 fColorTable[i].a := 0;
4491 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4492 procedure TbmpColorTableFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4494 if (BitsPerPixel <> 8) then
4495 raise EglBitmapUnsupportedFormat.Create('color table are only supported for 8bit formats');
4496 if not HasColor then
4498 aData^ := aPixel.Data.a
4502 ((aPixel.Data.r and Range.r) shl Shift.r) or
4503 ((aPixel.Data.g and Range.g) shl Shift.g) or
4504 ((aPixel.Data.b and Range.b) shl Shift.b));
4508 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4509 procedure TbmpColorTableFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4511 if (BitsPerPixel <> 8) then
4512 raise EglBitmapUnsupportedFormat.Create('color table are only supported for 8bit formats');
4513 with fColorTable[aData^] do begin
4522 destructor TbmpColorTableFormat.Destroy;
4524 SetLength(fColorTable, 0);
4528 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4529 //TglBitmap - Helper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4530 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4531 procedure glBitmapConvertPixel(var aPixel: TglBitmapPixelData; const aSourceFD, aDestFD: TFormatDescriptor);
4535 for i := 0 to 3 do begin
4536 if (aSourceFD.Range.arr[i] <> aDestFD.Range.arr[i]) then begin
4537 if (aSourceFD.Range.arr[i] > 0) then
4538 aPixel.Data.arr[i] := Round(aPixel.Data.arr[i] / aSourceFD.Range.arr[i] * aDestFD.Range.arr[i])
4540 aPixel.Data.arr[i] := 0;
4545 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4546 procedure glBitmapConvertCopyFunc(var aFuncRec: TglBitmapFunctionRec);
4548 with aFuncRec do begin
4549 if (Source.Range.r > 0) then
4550 Dest.Data.r := Source.Data.r;
4551 if (Source.Range.g > 0) then
4552 Dest.Data.g := Source.Data.g;
4553 if (Source.Range.b > 0) then
4554 Dest.Data.b := Source.Data.b;
4555 if (Source.Range.a > 0) then
4556 Dest.Data.a := Source.Data.a;
4560 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4561 procedure glBitmapConvertCalculateRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
4565 with aFuncRec do begin
4567 if (Source.Range.arr[i] > 0) then
4568 Dest.Data.arr[i] := Round(Dest.Range.arr[i] * Source.Data.arr[i] / Source.Range.arr[i]);
4573 TShiftData = packed record
4575 0: (r, g, b, a: SmallInt);
4576 1: (arr: array[0..3] of SmallInt);
4578 PShiftData = ^TShiftData;
4580 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4581 procedure glBitmapConvertShiftRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
4587 if (Source.Range.arr[i] > 0) then
4588 Dest.Data.arr[i] := Source.Data.arr[i] shr PShiftData(Args)^.arr[i];
4591 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4592 procedure glBitmapInvertFunc(var aFuncRec: TglBitmapFunctionRec);
4594 with aFuncRec do begin
4595 Dest.Data := Source.Data;
4596 if ({%H-}PtrUInt(Args) and $1 > 0) then begin
4597 Dest.Data.r := Dest.Data.r xor Dest.Range.r;
4598 Dest.Data.g := Dest.Data.g xor Dest.Range.g;
4599 Dest.Data.b := Dest.Data.b xor Dest.Range.b;
4601 if ({%H-}PtrUInt(Args) and $2 > 0) then begin
4602 Dest.Data.a := Dest.Data.a xor Dest.Range.a;
4607 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4608 procedure glBitmapFillWithColorFunc(var aFuncRec: TglBitmapFunctionRec);
4612 with aFuncRec do begin
4614 Dest.Data.arr[i] := PglBitmapPixelData(Args)^.Data.arr[i];
4618 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4619 procedure glBitmapAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4623 with FuncRec do begin
4624 if (FuncRec.Args = nil) then begin //source has no alpha
4626 Source.Data.r / Source.Range.r * ALPHA_WEIGHT_R +
4627 Source.Data.g / Source.Range.g * ALPHA_WEIGHT_G +
4628 Source.Data.b / Source.Range.b * ALPHA_WEIGHT_B;
4629 Dest.Data.a := Round(Dest.Range.a * Temp);
4631 Dest.Data.a := Round(Source.Data.a / Source.Range.a * Dest.Range.a);
4635 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4636 procedure glBitmapColorKeyAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4638 PglBitmapPixelData = ^TglBitmapPixelData;
4640 with FuncRec do begin
4641 Dest.Data.r := Source.Data.r;
4642 Dest.Data.g := Source.Data.g;
4643 Dest.Data.b := Source.Data.b;
4645 with PglBitmapPixelData(Args)^ do
4646 if ((Dest.Data.r <= Data.r) and (Dest.Data.r >= Range.r) and
4647 (Dest.Data.g <= Data.g) and (Dest.Data.g >= Range.g) and
4648 (Dest.Data.b <= Data.b) and (Dest.Data.b >= Range.b)) then
4651 Dest.Data.a := Dest.Range.a;
4655 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4656 procedure glBitmapValueAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4658 with FuncRec do begin
4659 Dest.Data.r := Source.Data.r;
4660 Dest.Data.g := Source.Data.g;
4661 Dest.Data.b := Source.Data.b;
4662 Dest.Data.a := PCardinal(Args)^;
4666 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4667 procedure SwapRGB(aData: PByte; aWidth: Integer; const aHasAlpha: Boolean);
4670 TRGBPix = array [0..2] of byte;
4674 while aWidth > 0 do begin
4675 Temp := PRGBPix(aData)^[0];
4676 PRGBPix(aData)^[0] := PRGBPix(aData)^[2];
4677 PRGBPix(aData)^[2] := Temp;
4687 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4688 //TglBitmap - PROTECTED///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4689 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4690 function TglBitmap.GetFormatDesc: TglBitmapFormatDescriptor;
4692 result := TFormatDescriptor.Get(Format);
4695 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4696 function TglBitmap.GetWidth: Integer;
4698 if (ffX in fDimension.Fields) then
4699 result := fDimension.X
4704 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4705 function TglBitmap.GetHeight: Integer;
4707 if (ffY in fDimension.Fields) then
4708 result := fDimension.Y
4713 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4714 function TglBitmap.GetFileWidth: Integer;
4716 result := Max(1, Width);
4719 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4720 function TglBitmap.GetFileHeight: Integer;
4722 result := Max(1, Height);
4725 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4726 procedure TglBitmap.SetCustomData(const aValue: Pointer);
4728 if fCustomData = aValue then
4730 fCustomData := aValue;
4733 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4734 procedure TglBitmap.SetCustomName(const aValue: String);
4736 if fCustomName = aValue then
4738 fCustomName := aValue;
4741 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4742 procedure TglBitmap.SetCustomNameW(const aValue: WideString);
4744 if fCustomNameW = aValue then
4746 fCustomNameW := aValue;
4749 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4750 procedure TglBitmap.SetFreeDataOnDestroy(const aValue: Boolean);
4752 if fFreeDataOnDestroy = aValue then
4754 fFreeDataOnDestroy := aValue;
4757 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4758 procedure TglBitmap.SetDeleteTextureOnFree(const aValue: Boolean);
4760 if fDeleteTextureOnFree = aValue then
4762 fDeleteTextureOnFree := aValue;
4765 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4766 procedure TglBitmap.SetFormat(const aValue: TglBitmapFormat);
4768 if fFormat = aValue then
4770 if TFormatDescriptor.Get(Format).BitsPerPixel <> TFormatDescriptor.Get(aValue).BitsPerPixel then
4771 raise EglBitmapUnsupportedFormat.Create(Format);
4772 SetDataPointer(fData, aValue, Width, Height); //be careful, Data could be freed by this method
4775 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4776 procedure TglBitmap.SetFreeDataAfterGenTexture(const aValue: Boolean);
4778 if fFreeDataAfterGenTexture = aValue then
4780 fFreeDataAfterGenTexture := aValue;
4783 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4784 procedure TglBitmap.SetID(const aValue: Cardinal);
4786 if fID = aValue then
4791 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4792 procedure TglBitmap.SetMipMap(const aValue: TglBitmapMipMap);
4794 if fMipMap = aValue then
4799 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4800 procedure TglBitmap.SetTarget(const aValue: Cardinal);
4802 if fTarget = aValue then
4807 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4808 procedure TglBitmap.SetAnisotropic(const aValue: Integer);
4809 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_EXT)}
4811 MaxAnisotropic: Integer;
4814 fAnisotropic := aValue;
4815 if (ID > 0) then begin
4816 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_EXT)}
4817 if GL_EXT_texture_filter_anisotropic then begin
4818 if fAnisotropic > 0 then begin
4820 glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @MaxAnisotropic);
4821 if aValue > MaxAnisotropic then
4822 fAnisotropic := MaxAnisotropic;
4823 glTexParameteri(Target, GL_TEXTURE_MAX_ANISOTROPY_EXT, fAnisotropic);
4834 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4835 procedure TglBitmap.CreateID;
4838 glDeleteTextures(1, @fID);
4839 glGenTextures(1, @fID);
4843 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4844 procedure TglBitmap.SetupParameters({$IFNDEF OPENGL_ES}out aBuildWithGlu: Boolean{$ENDIF});
4846 // Set Up Parameters
4847 SetWrap(fWrapS, fWrapT, fWrapR);
4848 SetFilter(fFilterMin, fFilterMag);
4849 SetAnisotropic(fAnisotropic);
4852 SetBorderColor(fBorderColor[0], fBorderColor[1], fBorderColor[2], fBorderColor[3]);
4853 if (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
4854 SetSwizzle(fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
4858 // Mip Maps Generation Mode
4859 aBuildWithGlu := false;
4860 if (MipMap = mmMipmap) then begin
4861 if (GL_VERSION_1_4 or GL_SGIS_generate_mipmap) then
4862 glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE)
4864 aBuildWithGlu := true;
4865 end else if (MipMap = mmMipmapGlu) then
4866 aBuildWithGlu := true;
4868 if (MipMap = mmMipmap) then
4869 glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE);
4873 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4874 procedure TglBitmap.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
4875 const aWidth: Integer; const aHeight: Integer);
4879 if (Data <> aData) then begin
4880 if (Assigned(Data)) then
4885 if not Assigned(fData) then begin
4889 FillChar(fDimension, SizeOf(fDimension), 0);
4890 if aWidth <> -1 then begin
4891 fDimension.Fields := fDimension.Fields + [ffX];
4892 fDimension.X := aWidth;
4895 if aHeight <> -1 then begin
4896 fDimension.Fields := fDimension.Fields + [ffY];
4897 fDimension.Y := aHeight;
4900 s := TFormatDescriptor.Get(aFormat).BytesPerPixel;
4902 fPixelSize := Ceil(s);
4903 fRowSize := Ceil(s * aWidth);
4907 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4908 function TglBitmap.FlipHorz: Boolean;
4913 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4914 function TglBitmap.FlipVert: Boolean;
4919 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4920 //TglBitmap - PUBLIC//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4921 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4922 procedure TglBitmap.AfterConstruction;
4924 inherited AfterConstruction;
4929 fIsResident := false;
4932 fMipMap := glBitmapDefaultMipmap;
4933 fFreeDataAfterGenTexture := glBitmapGetDefaultFreeDataAfterGenTexture;
4934 fDeleteTextureOnFree := glBitmapGetDefaultDeleteTextureOnFree;
4936 glBitmapGetDefaultFilter (fFilterMin, fFilterMag);
4937 glBitmapGetDefaultTextureWrap(fWrapS, fWrapT, fWrapR);
4939 glBitmapGetDefaultSwizzle (fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
4943 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4944 procedure TglBitmap.BeforeDestruction;
4948 if fFreeDataOnDestroy then begin
4950 SetDataPointer(NewData, tfEmpty); //be careful, Data could be freed by this method
4952 if (fID > 0) and fDeleteTextureOnFree then
4953 glDeleteTextures(1, @fID);
4954 inherited BeforeDestruction;
4957 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4958 procedure TglBitmap.PrepareResType(var aResource: String; var aResType: PChar);
4962 if not Assigned(aResType) then begin
4963 TempPos := Pos('.', aResource);
4964 aResType := PChar(UpperCase(Copy(aResource, TempPos + 1, Length(aResource) - TempPos)));
4965 aResource := UpperCase(Copy(aResource, 0, TempPos -1));
4969 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4970 procedure TglBitmap.LoadFromFile(const aFilename: String);
4974 if not FileExists(aFilename) then
4975 raise EglBitmap.Create('file does not exist: ' + aFilename);
4976 fFilename := aFilename;
4977 fs := TFileStream.Create(fFilename, fmOpenRead);
4986 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4987 procedure TglBitmap.LoadFromStream(const aStream: TStream);
4989 {$IFDEF GLB_SUPPORT_PNG_READ}
4990 if not LoadPNG(aStream) then
4992 {$IFDEF GLB_SUPPORT_JPEG_READ}
4993 if not LoadJPEG(aStream) then
4995 if not LoadDDS(aStream) then
4996 if not LoadTGA(aStream) then
4997 if not LoadBMP(aStream) then
4998 if not LoadRAW(aStream) then
4999 raise EglBitmap.Create('LoadFromStream - Couldn''t load Stream. It''s possible to be an unknow Streamtype.');
5002 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5003 procedure TglBitmap.LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
5004 const aFormat: TglBitmapFormat; const aArgs: Pointer);
5009 size := TFormatDescriptor.Get(aFormat).GetSize(aSize);
5010 GetMem(tmpData, size);
5012 FillChar(tmpData^, size, #$FF);
5013 SetDataPointer(tmpData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
5015 if Assigned(tmpData) then
5019 AddFunc(Self, aFunc, false, aFormat, aArgs);
5022 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5023 procedure TglBitmap.LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar);
5025 rs: TResourceStream;
5027 PrepareResType(aResource, aResType);
5028 rs := TResourceStream.Create(aInstance, aResource, aResType);
5036 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5037 procedure TglBitmap.LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
5039 rs: TResourceStream;
5041 rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
5049 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5050 procedure TglBitmap.SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
5054 fs := TFileStream.Create(aFileName, fmCreate);
5057 SaveToStream(fs, aFileType);
5063 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5064 procedure TglBitmap.SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType);
5067 {$IFDEF GLB_SUPPORT_PNG_WRITE}
5068 ftPNG: SavePNG(aStream);
5070 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
5071 ftJPEG: SaveJPEG(aStream);
5073 ftDDS: SaveDDS(aStream);
5074 ftTGA: SaveTGA(aStream);
5075 ftBMP: SaveBMP(aStream);
5076 ftRAW: SaveRAW(aStream);
5080 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5081 function TglBitmap.AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer): Boolean;
5083 result := AddFunc(Self, aFunc, aCreateTemp, Format, aArgs);
5086 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5087 function TglBitmap.AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
5088 const aFormat: TglBitmapFormat; const aArgs: Pointer): Boolean;
5090 DestData, TmpData, SourceData: pByte;
5091 TempHeight, TempWidth: Integer;
5092 SourceFD, DestFD: TFormatDescriptor;
5093 SourceMD, DestMD: Pointer;
5095 FuncRec: TglBitmapFunctionRec;
5097 Assert(Assigned(Data));
5098 Assert(Assigned(aSource));
5099 Assert(Assigned(aSource.Data));
5102 if Assigned(aSource.Data) and ((aSource.Height > 0) or (aSource.Width > 0)) then begin
5103 SourceFD := TFormatDescriptor.Get(aSource.Format);
5104 DestFD := TFormatDescriptor.Get(aFormat);
5106 if (SourceFD.IsCompressed) then
5107 raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', SourceFD.Format);
5108 if (DestFD.IsCompressed) then
5109 raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', DestFD.Format);
5111 // inkompatible Formats so CreateTemp
5112 if (SourceFD.BitsPerPixel <> DestFD.BitsPerPixel) then
5113 aCreateTemp := true;
5116 TempHeight := Max(1, aSource.Height);
5117 TempWidth := Max(1, aSource.Width);
5119 FuncRec.Sender := Self;
5120 FuncRec.Args := aArgs;
5123 if aCreateTemp then begin
5124 GetMem(TmpData, DestFD.GetSize(TempWidth, TempHeight));
5125 DestData := TmpData;
5130 SourceFD.PreparePixel(FuncRec.Source);
5131 DestFD.PreparePixel (FuncRec.Dest);
5133 SourceMD := SourceFD.CreateMappingData;
5134 DestMD := DestFD.CreateMappingData;
5136 FuncRec.Size := aSource.Dimension;
5137 FuncRec.Position.Fields := FuncRec.Size.Fields;
5140 SourceData := aSource.Data;
5141 FuncRec.Position.Y := 0;
5142 while FuncRec.Position.Y < TempHeight do begin
5143 FuncRec.Position.X := 0;
5144 while FuncRec.Position.X < TempWidth do begin
5145 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
5147 DestFD.Map(FuncRec.Dest, DestData, DestMD);
5148 inc(FuncRec.Position.X);
5150 inc(FuncRec.Position.Y);
5153 // Updating Image or InternalFormat
5155 SetDataPointer(TmpData, aFormat, aSource.Width, aSource.Height) //be careful, Data could be freed by this method
5156 else if (aFormat <> fFormat) then
5161 SourceFD.FreeMappingData(SourceMD);
5162 DestFD.FreeMappingData(DestMD);
5165 if aCreateTemp and Assigned(TmpData) then
5173 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5174 function TglBitmap.AssignToSurface(out aSurface: PSDL_Surface): Boolean;
5176 Row, RowSize: Integer;
5177 SourceData, TmpData: PByte;
5179 FormatDesc: TFormatDescriptor;
5181 function GetRowPointer(Row: Integer): pByte;
5183 result := aSurface.pixels;
5184 Inc(result, Row * RowSize);
5190 FormatDesc := TFormatDescriptor.Get(Format);
5191 if FormatDesc.IsCompressed then
5192 raise EglBitmapUnsupportedFormat.Create(Format);
5194 if Assigned(Data) then begin
5195 case Trunc(FormatDesc.PixelSize) of
5201 raise EglBitmapUnsupportedFormat.Create(Format);
5204 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, TempDepth,
5205 FormatDesc.RedMask, FormatDesc.GreenMask, FormatDesc.BlueMask, FormatDesc.AlphaMask);
5207 RowSize := FormatDesc.GetSize(FileWidth, 1);
5209 for Row := 0 to FileHeight-1 do begin
5210 TmpData := GetRowPointer(Row);
5211 if Assigned(TmpData) then begin
5212 Move(SourceData^, TmpData^, RowSize);
5213 inc(SourceData, RowSize);
5220 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5221 function TglBitmap.AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
5223 pSource, pData, pTempData: PByte;
5224 Row, RowSize, TempWidth, TempHeight: Integer;
5225 IntFormat: TglBitmapFormat;
5226 fd: TFormatDescriptor;
5227 Mask: TglBitmapMask;
5229 function GetRowPointer(Row: Integer): pByte;
5231 result := aSurface^.pixels;
5232 Inc(result, Row * RowSize);
5237 if (Assigned(aSurface)) then begin
5238 with aSurface^.format^ do begin
5243 IntFormat := TFormatDescriptor.GetFromMask(Mask).Format;
5244 if (IntFormat = tfEmpty) then
5245 raise EglBitmap.Create('AssignFromSurface - Invalid Pixelformat.');
5248 fd := TFormatDescriptor.Get(IntFormat);
5249 TempWidth := aSurface^.w;
5250 TempHeight := aSurface^.h;
5251 RowSize := fd.GetSize(TempWidth, 1);
5252 GetMem(pData, TempHeight * RowSize);
5255 for Row := 0 to TempHeight -1 do begin
5256 pSource := GetRowPointer(Row);
5257 if (Assigned(pSource)) then begin
5258 Move(pSource^, pTempData^, RowSize);
5259 Inc(pTempData, RowSize);
5262 SetDataPointer(pData, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
5265 if Assigned(pData) then
5272 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5273 function TglBitmap.AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
5275 Row, Col, AlphaInterleave: Integer;
5276 pSource, pDest: PByte;
5278 function GetRowPointer(Row: Integer): pByte;
5280 result := aSurface.pixels;
5281 Inc(result, Row * Width);
5286 if Assigned(Data) then begin
5287 if Format in [tfAlpha8ub1, tfLuminance8Alpha8ub2, tfBGRA8ub4, tfRGBA8ub4] then begin
5288 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, 8, $FF, $FF, $FF, 0);
5290 AlphaInterleave := 0;
5292 tfLuminance8Alpha8ub2:
5293 AlphaInterleave := 1;
5294 tfBGRA8ub4, tfRGBA8ub4:
5295 AlphaInterleave := 3;
5299 for Row := 0 to Height -1 do begin
5300 pDest := GetRowPointer(Row);
5301 if Assigned(pDest) then begin
5302 for Col := 0 to Width -1 do begin
5303 Inc(pSource, AlphaInterleave);
5315 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5316 function TglBitmap.AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
5320 bmp := TglBitmap2D.Create;
5322 bmp.AssignFromSurface(aSurface);
5323 result := AddAlphaFromGlBitmap(bmp, aFunc, aArgs);
5331 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5332 function CreateGrayPalette: HPALETTE;
5337 GetMem(Pal, SizeOf(TLogPalette) + (SizeOf(TPaletteEntry) * 256));
5339 Pal.palVersion := $300;
5340 Pal.palNumEntries := 256;
5342 for Idx := 0 to Pal.palNumEntries - 1 do begin
5343 Pal.palPalEntry[Idx].peRed := Idx;
5344 Pal.palPalEntry[Idx].peGreen := Idx;
5345 Pal.palPalEntry[Idx].peBlue := Idx;
5346 Pal.palPalEntry[Idx].peFlags := 0;
5348 Result := CreatePalette(Pal^);
5352 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5353 function TglBitmap.AssignToBitmap(const aBitmap: TBitmap): Boolean;
5356 pSource, pData: PByte;
5359 if Assigned(Data) then begin
5360 if Assigned(aBitmap) then begin
5361 aBitmap.Width := Width;
5362 aBitmap.Height := Height;
5365 tfAlpha8ub1, tfLuminance8ub1: begin
5366 aBitmap.PixelFormat := pf8bit;
5367 aBitmap.Palette := CreateGrayPalette;
5370 aBitmap.PixelFormat := pf15bit;
5372 aBitmap.PixelFormat := pf16bit;
5373 tfRGB8ub3, tfBGR8ub3:
5374 aBitmap.PixelFormat := pf24bit;
5375 tfRGBA8ub4, tfBGRA8ub4:
5376 aBitmap.PixelFormat := pf32bit;
5378 raise EglBitmap.Create('AssignToBitmap - Invalid Pixelformat.');
5382 for Row := 0 to FileHeight -1 do begin
5383 pData := aBitmap.Scanline[Row];
5384 Move(pSource^, pData^, fRowSize);
5385 Inc(pSource, fRowSize);
5386 if (Format in [tfRGB8ub3, tfRGBA8ub4]) then // swap RGB(A) to BGR(A)
5387 SwapRGB(pData, FileWidth, Format = tfRGBA8ub4);
5394 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5395 function TglBitmap.AssignFromBitmap(const aBitmap: TBitmap): Boolean;
5397 pSource, pData, pTempData: PByte;
5398 Row, RowSize, TempWidth, TempHeight: Integer;
5399 IntFormat: TglBitmapFormat;
5403 if (Assigned(aBitmap)) then begin
5404 case aBitmap.PixelFormat of
5406 IntFormat := tfLuminance8ub1;
5408 IntFormat := tfRGB5A1us1;
5410 IntFormat := tfR5G6B5us1;
5412 IntFormat := tfBGR8ub3;
5414 IntFormat := tfBGRA8ub4;
5416 raise EglBitmap.Create('AssignFromBitmap - Invalid Pixelformat.');
5419 TempWidth := aBitmap.Width;
5420 TempHeight := aBitmap.Height;
5421 RowSize := TFormatDescriptor.Get(IntFormat).GetSize(TempWidth, 1);
5422 GetMem(pData, TempHeight * RowSize);
5425 for Row := 0 to TempHeight -1 do begin
5426 pSource := aBitmap.Scanline[Row];
5427 if (Assigned(pSource)) then begin
5428 Move(pSource^, pTempData^, RowSize);
5429 Inc(pTempData, RowSize);
5432 SetDataPointer(pData, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
5435 if Assigned(pData) then
5442 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5443 function TglBitmap.AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
5445 Row, Col, AlphaInterleave: Integer;
5446 pSource, pDest: PByte;
5450 if Assigned(Data) then begin
5451 if (Format in [tfAlpha8ub1, tfLuminance8Alpha8ub2, tfRGBA8ub4, tfBGRA8ub4]) then begin
5452 if Assigned(aBitmap) then begin
5453 aBitmap.PixelFormat := pf8bit;
5454 aBitmap.Palette := CreateGrayPalette;
5455 aBitmap.Width := Width;
5456 aBitmap.Height := Height;
5459 tfLuminance8Alpha8ub2:
5460 AlphaInterleave := 1;
5461 tfRGBA8ub4, tfBGRA8ub4:
5462 AlphaInterleave := 3;
5464 AlphaInterleave := 0;
5470 for Row := 0 to Height -1 do begin
5471 pDest := aBitmap.Scanline[Row];
5472 if Assigned(pDest) then begin
5473 for Col := 0 to Width -1 do begin
5474 Inc(pSource, AlphaInterleave);
5487 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5488 function TglBitmap.AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5492 tex := TglBitmap2D.Create;
5494 tex.AssignFromBitmap(ABitmap);
5495 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
5502 {$IFDEF GLB_LAZARUS}
5503 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5504 function TglBitmap.AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
5506 rid: TRawImageDescription;
5507 FormatDesc: TFormatDescriptor;
5509 if not Assigned(Data) then
5510 raise EglBitmap.Create('no pixel data assigned. load data before save');
5513 if not Assigned(aImage) or (Format = tfEmpty) then
5515 FormatDesc := TFormatDescriptor.Get(Format);
5516 if FormatDesc.IsCompressed then
5519 FillChar(rid{%H-}, SizeOf(rid), 0);
5520 if FormatDesc.IsGrayscale then
5521 rid.Format := ricfGray
5523 rid.Format := ricfRGBA;
5526 rid.Height := Height;
5527 rid.Depth := FormatDesc.BitsPerPixel;
5528 rid.BitOrder := riboBitsInOrder;
5529 rid.ByteOrder := riboLSBFirst;
5530 rid.LineOrder := riloTopToBottom;
5531 rid.LineEnd := rileTight;
5532 rid.BitsPerPixel := FormatDesc.BitsPerPixel;
5533 rid.RedPrec := CountSetBits(FormatDesc.Range.r);
5534 rid.GreenPrec := CountSetBits(FormatDesc.Range.g);
5535 rid.BluePrec := CountSetBits(FormatDesc.Range.b);
5536 rid.AlphaPrec := CountSetBits(FormatDesc.Range.a);
5537 rid.RedShift := FormatDesc.Shift.r;
5538 rid.GreenShift := FormatDesc.Shift.g;
5539 rid.BlueShift := FormatDesc.Shift.b;
5540 rid.AlphaShift := FormatDesc.Shift.a;
5542 rid.MaskBitsPerPixel := 0;
5543 rid.PaletteColorCount := 0;
5545 aImage.DataDescription := rid;
5548 if not Assigned(aImage.PixelData) then
5549 raise EglBitmap.Create('error while creating LazIntfImage');
5550 Move(Data^, aImage.PixelData^, FormatDesc.GetSize(Dimension));
5555 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5556 function TglBitmap.AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
5559 FormatDesc: TFormatDescriptor;
5563 Mask: TglBitmapRec4ul;
5565 procedure CopyConvert;
5567 bfFormat: TbmpBitfieldFormat;
5568 pSourceLine, pDestLine: PByte;
5569 pSourceMD, pDestMD: Pointer;
5570 Shift, Prec: TglBitmapRec4ub;
5572 pixel: TglBitmapPixelData;
5574 bfFormat := TbmpBitfieldFormat.Create;
5575 with aImage.DataDescription do begin
5577 Prec.g := GreenPrec;
5579 Prec.a := AlphaPrec;
5580 Shift.r := RedShift;
5581 Shift.g := GreenShift;
5582 Shift.b := BlueShift;
5583 Shift.a := AlphaShift;
5584 bfFormat.SetCustomValues(BitsPerPixel, Prec, Shift);
5586 pSourceMD := bfFormat.CreateMappingData;
5587 pDestMD := FormatDesc.CreateMappingData;
5589 for y := 0 to aImage.Height-1 do begin
5590 pSourceLine := aImage.PixelData + y {%H-}* aImage.DataDescription.BytesPerLine;
5591 pDestLine := ImageData + y * Round(FormatDesc.BytesPerPixel * aImage.Width);
5592 for x := 0 to aImage.Width-1 do begin
5593 bfFormat.Unmap(pSourceLine, pixel, pSourceMD);
5594 FormatDesc.Map(pixel, pDestLine, pDestMD);
5598 FormatDesc.FreeMappingData(pDestMD);
5599 bfFormat.FreeMappingData(pSourceMD);
5606 if not Assigned(aImage) then
5609 with aImage.DataDescription do begin
5610 Mask.r := (QWord(1 shl RedPrec )-1) shl RedShift;
5611 Mask.g := (QWord(1 shl GreenPrec)-1) shl GreenShift;
5612 Mask.b := (QWord(1 shl BluePrec )-1) shl BlueShift;
5613 Mask.a := (QWord(1 shl AlphaPrec)-1) shl AlphaShift;
5615 FormatDesc := TFormatDescriptor.GetFromMask(Mask);
5616 f := FormatDesc.Format;
5617 if (f = tfEmpty) then
5621 (FormatDesc.BitsPerPixel = aImage.DataDescription.Depth) and
5622 (aImage.DataDescription.BitsPerPixel = aImage.DataDescription.Depth);
5624 ImageSize := FormatDesc.GetSize(aImage.Width, aImage.Height);
5625 ImageData := GetMem(ImageSize);
5628 Move(aImage.PixelData^, ImageData^, ImageSize)
5631 SetDataPointer(ImageData, f, aImage.Width, aImage.Height); //be careful, Data could be freed by this method
5633 if Assigned(ImageData) then
5641 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5642 function TglBitmap.AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
5644 rid: TRawImageDescription;
5645 FormatDesc: TFormatDescriptor;
5646 Pixel: TglBitmapPixelData;
5652 if not Assigned(aImage) or (Format = tfEmpty) then
5654 FormatDesc := TFormatDescriptor.Get(Format);
5655 if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
5658 FillChar(rid{%H-}, SizeOf(rid), 0);
5659 rid.Format := ricfGray;
5661 rid.Height := Height;
5662 rid.Depth := CountSetBits(FormatDesc.Range.a);
5663 rid.BitOrder := riboBitsInOrder;
5664 rid.ByteOrder := riboLSBFirst;
5665 rid.LineOrder := riloTopToBottom;
5666 rid.LineEnd := rileTight;
5667 rid.BitsPerPixel := 8 * Ceil(rid.Depth / 8);
5668 rid.RedPrec := CountSetBits(FormatDesc.Range.a);
5673 rid.GreenShift := 0;
5675 rid.AlphaShift := 0;
5677 rid.MaskBitsPerPixel := 0;
5678 rid.PaletteColorCount := 0;
5680 aImage.DataDescription := rid;
5683 srcMD := FormatDesc.CreateMappingData;
5685 FormatDesc.PreparePixel(Pixel);
5687 dst := aImage.PixelData;
5688 for y := 0 to Height-1 do
5689 for x := 0 to Width-1 do begin
5690 FormatDesc.Unmap(src, Pixel, srcMD);
5691 case rid.BitsPerPixel of
5693 dst^ := Pixel.Data.a;
5697 PWord(dst)^ := Pixel.Data.a;
5701 PByteArray(dst)^[0] := PByteArray(@Pixel.Data.a)^[0];
5702 PByteArray(dst)^[1] := PByteArray(@Pixel.Data.a)^[1];
5703 PByteArray(dst)^[2] := PByteArray(@Pixel.Data.a)^[2];
5707 PCardinal(dst)^ := Pixel.Data.a;
5711 raise EglBitmapUnsupportedFormat.Create(Format);
5715 FormatDesc.FreeMappingData(srcMD);
5720 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5721 function TglBitmap.AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5725 tex := TglBitmap2D.Create;
5727 tex.AssignFromLazIntfImage(aImage);
5728 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
5735 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5736 function TglBitmap.AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar;
5737 const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5739 rs: TResourceStream;
5741 PrepareResType(aResource, aResType);
5742 rs := TResourceStream.Create(aInstance, aResource, aResType);
5744 result := AddAlphaFromStream(rs, aFunc, aArgs);
5750 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5751 function TglBitmap.AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
5752 const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5754 rs: TResourceStream;
5756 rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
5758 result := AddAlphaFromStream(rs, aFunc, aArgs);
5764 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5765 function TglBitmap.AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5767 if TFormatDescriptor.Get(Format).IsCompressed then
5768 raise EglBitmapUnsupportedFormat.Create(Format);
5769 result := AddFunc(Self, aFunc, false, TFormatDescriptor.Get(Format).WithAlpha, aArgs);
5772 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5773 function TglBitmap.AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5777 FS := TFileStream.Create(aFileName, fmOpenRead);
5779 result := AddAlphaFromStream(FS, aFunc, aArgs);
5785 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5786 function TglBitmap.AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5790 tex := TglBitmap2D.Create(aStream);
5792 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
5798 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5799 function TglBitmap.AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5801 DestData, DestData2, SourceData: pByte;
5802 TempHeight, TempWidth: Integer;
5803 SourceFD, DestFD: TFormatDescriptor;
5804 SourceMD, DestMD, DestMD2: Pointer;
5806 FuncRec: TglBitmapFunctionRec;
5810 Assert(Assigned(Data));
5811 Assert(Assigned(aBitmap));
5812 Assert(Assigned(aBitmap.Data));
5814 if ((aBitmap.Width = Width) and (aBitmap.Height = Height)) then begin
5815 result := ConvertTo(TFormatDescriptor.Get(Format).WithAlpha);
5817 SourceFD := TFormatDescriptor.Get(aBitmap.Format);
5818 DestFD := TFormatDescriptor.Get(Format);
5820 if not Assigned(aFunc) then begin
5821 aFunc := glBitmapAlphaFunc;
5822 FuncRec.Args := {%H-}Pointer(SourceFD.HasAlpha);
5824 FuncRec.Args := aArgs;
5827 TempHeight := aBitmap.FileHeight;
5828 TempWidth := aBitmap.FileWidth;
5830 FuncRec.Sender := Self;
5831 FuncRec.Size := Dimension;
5832 FuncRec.Position.Fields := FuncRec.Size.Fields;
5836 SourceData := aBitmap.Data;
5839 SourceFD.PreparePixel(FuncRec.Source);
5840 DestFD.PreparePixel (FuncRec.Dest);
5842 SourceMD := SourceFD.CreateMappingData;
5843 DestMD := DestFD.CreateMappingData;
5844 DestMD2 := DestFD.CreateMappingData;
5846 FuncRec.Position.Y := 0;
5847 while FuncRec.Position.Y < TempHeight do begin
5848 FuncRec.Position.X := 0;
5849 while FuncRec.Position.X < TempWidth do begin
5850 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
5851 DestFD.Unmap (DestData, FuncRec.Dest, DestMD);
5853 DestFD.Map(FuncRec.Dest, DestData2, DestMD2);
5854 inc(FuncRec.Position.X);
5856 inc(FuncRec.Position.Y);
5859 SourceFD.FreeMappingData(SourceMD);
5860 DestFD.FreeMappingData(DestMD);
5861 DestFD.FreeMappingData(DestMD2);
5866 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5867 function TglBitmap.AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte): Boolean;
5869 result := AddAlphaFromColorKeyFloat(aRed / $FF, aGreen / $FF, aBlue / $FF, aDeviation / $FF);
5872 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5873 function TglBitmap.AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal): Boolean;
5875 PixelData: TglBitmapPixelData;
5877 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5878 result := AddAlphaFromColorKeyFloat(
5879 aRed / PixelData.Range.r,
5880 aGreen / PixelData.Range.g,
5881 aBlue / PixelData.Range.b,
5882 aDeviation / Max(PixelData.Range.r, Max(PixelData.Range.g, PixelData.Range.b)));
5885 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5886 function TglBitmap.AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single): Boolean;
5888 values: array[0..2] of Single;
5891 PixelData: TglBitmapPixelData;
5893 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5894 with PixelData do begin
5896 values[1] := aGreen;
5899 for i := 0 to 2 do begin
5900 tmp := Trunc(Range.arr[i] * aDeviation);
5901 Data.arr[i] := Min(Range.arr[i], Trunc(Range.arr[i] * values[i] + tmp));
5902 Range.arr[i] := Max(0, Trunc(Range.arr[i] * values[i] - tmp));
5907 result := AddAlphaFromFunc(glBitmapColorKeyAlphaFunc, @PixelData);
5910 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5911 function TglBitmap.AddAlphaFromValue(const aAlpha: Byte): Boolean;
5913 result := AddAlphaFromValueFloat(aAlpha / $FF);
5916 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5917 function TglBitmap.AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
5919 PixelData: TglBitmapPixelData;
5921 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5922 result := AddAlphaFromValueFloat(aAlpha / PixelData.Range.a);
5925 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5926 function TglBitmap.AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
5928 PixelData: TglBitmapPixelData;
5930 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5932 Data.a := Min(Range.a, Max(0, Round(Range.a * aAlpha)));
5933 result := AddAlphaFromFunc(glBitmapValueAlphaFunc, @PixelData.Data.a);
5936 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5937 function TglBitmap.RemoveAlpha: Boolean;
5939 FormatDesc: TFormatDescriptor;
5942 FormatDesc := TFormatDescriptor.Get(Format);
5943 if Assigned(Data) then begin
5944 if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
5945 raise EglBitmapUnsupportedFormat.Create(Format);
5946 result := ConvertTo(FormatDesc.WithoutAlpha);
5950 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5951 function TglBitmap.Clone: TglBitmap;
5958 Temp := (ClassType.Create as TglBitmap);
5960 // copy texture data if assigned
5961 if Assigned(Data) then begin
5962 Size := TFormatDescriptor.Get(Format).GetSize(fDimension);
5963 GetMem(TempPtr, Size);
5965 Move(Data^, TempPtr^, Size);
5966 Temp.SetDataPointer(TempPtr, Format, Width, Height); //be careful, Data could be freed by this method
5968 if Assigned(TempPtr) then
5974 Temp.SetDataPointer(TempPtr, Format, Width, Height); //be careful, Data could be freed by this method
5979 Temp.fTarget := Target;
5980 Temp.fFormat := Format;
5981 Temp.fMipMap := MipMap;
5982 Temp.fAnisotropic := Anisotropic;
5983 Temp.fBorderColor := fBorderColor;
5984 Temp.fDeleteTextureOnFree := DeleteTextureOnFree;
5985 Temp.fFreeDataAfterGenTexture := FreeDataAfterGenTexture;
5986 Temp.fFilterMin := fFilterMin;
5987 Temp.fFilterMag := fFilterMag;
5988 Temp.fWrapS := fWrapS;
5989 Temp.fWrapT := fWrapT;
5990 Temp.fWrapR := fWrapR;
5991 Temp.fFilename := fFilename;
5992 Temp.fCustomName := fCustomName;
5993 Temp.fCustomNameW := fCustomNameW;
5994 Temp.fCustomData := fCustomData;
6003 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6004 function TglBitmap.ConvertTo(const aFormat: TglBitmapFormat): Boolean;
6006 SourceFD, DestFD: TFormatDescriptor;
6007 SourcePD, DestPD: TglBitmapPixelData;
6008 ShiftData: TShiftData;
6010 function DataIsIdentical: Boolean;
6012 result := SourceFD.MaskMatch(DestFD.Mask);
6015 function CanCopyDirect: Boolean;
6018 ((SourcePD.Range.r = DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
6019 ((SourcePD.Range.g = DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
6020 ((SourcePD.Range.b = DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
6021 ((SourcePD.Range.a = DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
6024 function CanShift: Boolean;
6027 ((SourcePD.Range.r >= DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
6028 ((SourcePD.Range.g >= DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
6029 ((SourcePD.Range.b >= DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
6030 ((SourcePD.Range.a >= DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
6033 function GetShift(aSource, aDest: Cardinal) : ShortInt;
6036 while (aSource > aDest) and (aSource > 0) do begin
6038 aSource := aSource shr 1;
6043 if (aFormat <> fFormat) and (aFormat <> tfEmpty) then begin
6044 SourceFD := TFormatDescriptor.Get(Format);
6045 DestFD := TFormatDescriptor.Get(aFormat);
6047 if DataIsIdentical then begin
6053 SourceFD.PreparePixel(SourcePD);
6054 DestFD.PreparePixel (DestPD);
6056 if CanCopyDirect then
6057 result := AddFunc(Self, glBitmapConvertCopyFunc, false, aFormat)
6058 else if CanShift then begin
6059 ShiftData.r := GetShift(SourcePD.Range.r, DestPD.Range.r);
6060 ShiftData.g := GetShift(SourcePD.Range.g, DestPD.Range.g);
6061 ShiftData.b := GetShift(SourcePD.Range.b, DestPD.Range.b);
6062 ShiftData.a := GetShift(SourcePD.Range.a, DestPD.Range.a);
6063 result := AddFunc(Self, glBitmapConvertShiftRGBAFunc, false, aFormat, @ShiftData);
6065 result := AddFunc(Self, glBitmapConvertCalculateRGBAFunc, false, aFormat);
6070 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6071 procedure TglBitmap.Invert(const aUseRGB: Boolean; const aUseAlpha: Boolean);
6073 if aUseRGB or aUseAlpha then
6074 AddFunc(glBitmapInvertFunc, false, {%H-}Pointer(
6075 ((Byte(aUseAlpha) and 1) shl 1) or
6076 (Byte(aUseRGB) and 1) ));
6080 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6081 procedure TglBitmap.SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
6083 fBorderColor[0] := aRed;
6084 fBorderColor[1] := aGreen;
6085 fBorderColor[2] := aBlue;
6086 fBorderColor[3] := aAlpha;
6087 if (ID > 0) then begin
6089 glTexParameterfv(Target, GL_TEXTURE_BORDER_COLOR, @fBorderColor[0]);
6094 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6095 procedure TglBitmap.FreeData;
6100 SetDataPointer(TempPtr, tfEmpty); //be careful, Data could be freed by this method
6103 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6104 procedure TglBitmap.FillWithColor(const aRed, aGreen, aBlue: Byte;
6105 const aAlpha: Byte);
6107 FillWithColorFloat(aRed/$FF, aGreen/$FF, aBlue/$FF, aAlpha/$FF);
6110 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6111 procedure TglBitmap.FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal);
6113 PixelData: TglBitmapPixelData;
6115 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
6117 aRed / PixelData.Range.r,
6118 aGreen / PixelData.Range.g,
6119 aBlue / PixelData.Range.b,
6120 aAlpha / PixelData.Range.a);
6123 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6124 procedure TglBitmap.FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single);
6126 PixelData: TglBitmapPixelData;
6128 TFormatDescriptor.Get(Format).PreparePixel(PixelData);
6129 with PixelData do begin
6130 Data.r := Max(0, Min(Range.r, Trunc(Range.r * aRed)));
6131 Data.g := Max(0, Min(Range.g, Trunc(Range.g * aGreen)));
6132 Data.b := Max(0, Min(Range.b, Trunc(Range.b * aBlue)));
6133 Data.a := Max(0, Min(Range.a, Trunc(Range.a * aAlpha)));
6135 AddFunc(glBitmapFillWithColorFunc, false, @PixelData);
6138 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6139 procedure TglBitmap.SetFilter(const aMin, aMag: GLenum);
6144 fFilterMin := GL_NEAREST;
6146 fFilterMin := GL_LINEAR;
6147 GL_NEAREST_MIPMAP_NEAREST:
6148 fFilterMin := GL_NEAREST_MIPMAP_NEAREST;
6149 GL_LINEAR_MIPMAP_NEAREST:
6150 fFilterMin := GL_LINEAR_MIPMAP_NEAREST;
6151 GL_NEAREST_MIPMAP_LINEAR:
6152 fFilterMin := GL_NEAREST_MIPMAP_LINEAR;
6153 GL_LINEAR_MIPMAP_LINEAR:
6154 fFilterMin := GL_LINEAR_MIPMAP_LINEAR;
6156 raise EglBitmap.Create('SetFilter - Unknow MIN filter.');
6162 fFilterMag := GL_NEAREST;
6164 fFilterMag := GL_LINEAR;
6166 raise EglBitmap.Create('SetFilter - Unknow MAG filter.');
6170 if (ID > 0) then begin
6172 glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, fFilterMag);
6174 if (MipMap = mmNone) {$IFNDEF OPENGL_ES}or (Target = GL_TEXTURE_RECTANGLE){$ENDIF} then begin
6176 GL_NEAREST, GL_LINEAR:
6177 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
6178 GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR:
6179 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6180 GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR:
6181 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6184 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
6188 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6189 procedure TglBitmap.SetWrap(const S: GLenum; const T: GLenum; const R: GLenum);
6191 procedure CheckAndSetWrap(const aValue: Cardinal; var aTarget: Cardinal);
6196 aTarget := GL_CLAMP;
6200 aTarget := GL_REPEAT;
6202 GL_CLAMP_TO_EDGE: begin
6204 if not GL_VERSION_1_2 and not GL_EXT_texture_edge_clamp then
6208 aTarget := GL_CLAMP_TO_EDGE;
6212 GL_CLAMP_TO_BORDER: begin
6213 if GL_VERSION_1_3 or GL_ARB_texture_border_clamp then
6214 aTarget := GL_CLAMP_TO_BORDER
6216 aTarget := GL_CLAMP;
6220 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
6221 GL_MIRRORED_REPEAT: begin
6223 if GL_VERSION_1_4 or GL_ARB_texture_mirrored_repeat or GL_IBM_texture_mirrored_repeat then
6225 if GL_VERSION_2_0 then
6227 aTarget := GL_MIRRORED_REPEAT
6229 raise EglBitmap.Create('SetWrap - Unsupported Texturewrap GL_MIRRORED_REPEAT (S).');
6233 raise EglBitmap.Create('SetWrap - Unknow Texturewrap');
6238 CheckAndSetWrap(S, fWrapS);
6239 CheckAndSetWrap(T, fWrapT);
6240 CheckAndSetWrap(R, fWrapR);
6242 if (ID > 0) then begin
6244 glTexParameteri(Target, GL_TEXTURE_WRAP_S, fWrapS);
6245 glTexParameteri(Target, GL_TEXTURE_WRAP_T, fWrapT);
6246 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
6247 {$IFDEF OPENGL_ES} if GL_VERSION_3_0 then{$ENDIF}
6248 glTexParameteri(Target, GL_TEXTURE_WRAP_R, fWrapR);
6253 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
6254 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6255 procedure TglBitmap.SetSwizzle(const r, g, b, a: GLenum);
6257 procedure CheckAndSetValue(const aValue: GLenum; const aIndex: Integer);
6259 if (aValue = GL_ZERO) or (aValue = GL_ONE) or (aValue = GL_ALPHA) or
6260 (aValue = GL_RED) or (aValue = GL_GREEN) or (aValue = GL_BLUE) then
6261 fSwizzle[aIndex] := aValue
6263 raise EglBitmap.Create('SetSwizzle - Unknow Swizle Value');
6268 if not (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
6269 raise EglBitmapNotSupported.Create('texture swizzle is not supported');
6271 if not GL_VERSION_3_0 then
6272 raise EglBitmapNotSupported.Create('texture swizzle is not supported');
6274 CheckAndSetValue(r, 0);
6275 CheckAndSetValue(g, 1);
6276 CheckAndSetValue(b, 2);
6277 CheckAndSetValue(a, 3);
6279 if (ID > 0) then begin
6282 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_RGBA, PGLint(@fSwizzle[0]));
6284 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_R, PGLint(@fSwizzle[0]));
6285 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_G, PGLint(@fSwizzle[1]));
6286 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_B, PGLint(@fSwizzle[2]));
6287 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_A, PGLint(@fSwizzle[3]));
6293 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6294 procedure TglBitmap.Bind(const aEnableTextureUnit: Boolean);
6296 if aEnableTextureUnit then
6299 glBindTexture(Target, ID);
6302 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6303 procedure TglBitmap.Unbind(const aDisableTextureUnit: Boolean);
6305 if aDisableTextureUnit then
6307 glBindTexture(Target, 0);
6310 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6311 constructor TglBitmap.Create;
6313 if (ClassType = TglBitmap) then
6314 raise EglBitmap.Create('Don''t create TglBitmap directly. Use one of the deviated classes (TglBitmap2D) instead.');
6315 {$IFDEF GLB_NATIVE_OGL}
6316 glbReadOpenGLExtensions;
6319 fFormat := glBitmapGetDefaultFormat;
6320 fFreeDataOnDestroy := true;
6323 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6324 constructor TglBitmap.Create(const aFileName: String);
6327 LoadFromFile(aFileName);
6330 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6331 constructor TglBitmap.Create(const aStream: TStream);
6334 LoadFromStream(aStream);
6337 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6338 constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; aData: PByte);
6343 if not Assigned(aData) then begin
6344 ImageSize := TFormatDescriptor.Get(aFormat).GetSize(aSize);
6345 GetMem(aData, ImageSize);
6347 FillChar(aData^, ImageSize, #$FF);
6348 SetDataPointer(aData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
6350 if Assigned(aData) then
6355 SetDataPointer(aData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
6356 fFreeDataOnDestroy := false;
6360 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6361 constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer);
6364 LoadFromFunc(aSize, aFunc, aFormat, aArgs);
6367 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6368 constructor TglBitmap.Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar);
6371 LoadFromResource(aInstance, aResource, aResType);
6374 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6375 constructor TglBitmap.Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
6378 LoadFromResourceID(aInstance, aResourceID, aResType);
6381 {$IFDEF GLB_SUPPORT_PNG_READ}
6382 {$IF DEFINED(GLB_LAZ_PNG)}
6383 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6384 //PNG/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6385 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6386 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6389 PNG_MAGIC: String[MAGIC_LEN] = #$89#$50#$4E#$47#$0D#$0A#$1A#$0A;
6391 reader: TLazReaderPNG;
6392 intf: TLazIntfImage;
6394 magic: String[MAGIC_LEN];
6397 StreamPos := aStream.Position;
6399 SetLength(magic, MAGIC_LEN);
6400 aStream.Read(magic[1], MAGIC_LEN);
6401 aStream.Position := StreamPos;
6402 if (magic <> PNG_MAGIC) then begin
6407 intf := TLazIntfImage.Create(0, 0);
6408 reader := TLazReaderPNG.Create;
6410 reader.UpdateDescription := true;
6411 reader.ImageRead(aStream, intf);
6412 AssignFromLazIntfImage(intf);
6415 aStream.Position := StreamPos;
6424 {$ELSEIF DEFINED(GLB_SDL_IMAGE)}
6425 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6426 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6428 Surface: PSDL_Surface;
6432 RWops := glBitmapCreateRWops(aStream);
6434 if IMG_isPNG(RWops) > 0 then begin
6435 Surface := IMG_LoadPNG_RW(RWops);
6437 AssignFromSurface(Surface);
6440 SDL_FreeSurface(Surface);
6448 {$ELSEIF DEFINED(GLB_LIB_PNG)}
6449 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6450 procedure glBitmap_libPNG_read_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
6452 TStream(png_get_io_ptr(png)).Read(buffer^, size);
6455 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6456 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6459 signature: array [0..7] of byte;
6461 png_info: png_infop;
6463 TempHeight, TempWidth: Integer;
6464 Format: TglBitmapFormat;
6467 png_rows: array of pByte;
6468 Row, LineSize: Integer;
6472 if not init_libPNG then
6473 raise Exception.Create('LoadPNG - unable to initialize libPNG.');
6477 StreamPos := aStream.Position;
6478 aStream.Read(signature{%H-}, 8);
6479 aStream.Position := StreamPos;
6481 if png_check_sig(@signature, 8) <> 0 then begin
6483 png := png_create_read_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
6485 raise EglBitmapException.Create('LoadPng - couldn''t create read struct.');
6488 png_info := png_create_info_struct(png);
6489 if png_info = nil then begin
6490 png_destroy_read_struct(@png, nil, nil);
6491 raise EglBitmapException.Create('LoadPng - couldn''t create info struct.');
6494 // set read callback
6495 png_set_read_fn(png, aStream, glBitmap_libPNG_read_func);
6497 // read informations
6498 png_read_info(png, png_info);
6501 TempHeight := png_get_image_height(png, png_info);
6502 TempWidth := png_get_image_width(png, png_info);
6505 case png_get_color_type(png, png_info) of
6506 PNG_COLOR_TYPE_GRAY:
6507 Format := tfLuminance8ub1;
6508 PNG_COLOR_TYPE_GRAY_ALPHA:
6509 Format := tfLuminance8Alpha8us1;
6511 Format := tfRGB8ub3;
6512 PNG_COLOR_TYPE_RGB_ALPHA:
6513 Format := tfRGBA8ub4;
6515 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
6518 // cut upper 8 bit from 16 bit formats
6519 if png_get_bit_depth(png, png_info) > 8 then
6520 png_set_strip_16(png);
6522 // expand bitdepth smaller than 8
6523 if png_get_bit_depth(png, png_info) < 8 then
6524 png_set_expand(png);
6526 // allocating mem for scanlines
6527 LineSize := png_get_rowbytes(png, png_info);
6528 GetMem(png_data, TempHeight * LineSize);
6530 SetLength(png_rows, TempHeight);
6531 for Row := Low(png_rows) to High(png_rows) do begin
6532 png_rows[Row] := png_data;
6533 Inc(png_rows[Row], Row * LineSize);
6536 // read complete image into scanlines
6537 png_read_image(png, @png_rows[0]);
6540 png_read_end(png, png_info);
6542 // destroy read struct
6543 png_destroy_read_struct(@png, @png_info, nil);
6545 SetLength(png_rows, 0);
6548 SetDataPointer(png_data, Format, TempWidth, TempHeight); //be careful, Data could be freed by this method
6552 if Assigned(png_data) then
6562 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
6563 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6564 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6569 Row, Col, PixSize, LineSize: Integer;
6570 NewImage, pSource, pDest, pAlpha: pByte;
6571 PngFormat: TglBitmapFormat;
6572 FormatDesc: TFormatDescriptor;
6575 PngHeader: String[8] = #137#80#78#71#13#10#26#10;
6580 StreamPos := aStream.Position;
6581 aStream.Read(Header[0], SizeOf(Header));
6582 aStream.Position := StreamPos;
6584 {Test if the header matches}
6585 if Header = PngHeader then begin
6586 Png := TPNGObject.Create;
6588 Png.LoadFromStream(aStream);
6590 case Png.Header.ColorType of
6592 PngFormat := tfLuminance8ub1;
6593 COLOR_GRAYSCALEALPHA:
6594 PngFormat := tfLuminance8Alpha8us1;
6596 PngFormat := tfBGR8ub3;
6598 PngFormat := tfBGRA8ub4;
6600 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
6603 FormatDesc := TFormatDescriptor.Get(PngFormat);
6604 PixSize := Round(FormatDesc.PixelSize);
6605 LineSize := FormatDesc.GetSize(Png.Header.Width, 1);
6607 GetMem(NewImage, LineSize * Integer(Png.Header.Height));
6611 case Png.Header.ColorType of
6612 COLOR_RGB, COLOR_GRAYSCALE:
6614 for Row := 0 to Png.Height -1 do begin
6615 Move (Png.Scanline[Row]^, pDest^, LineSize);
6616 Inc(pDest, LineSize);
6619 COLOR_RGBALPHA, COLOR_GRAYSCALEALPHA:
6621 PixSize := PixSize -1;
6623 for Row := 0 to Png.Height -1 do begin
6624 pSource := Png.Scanline[Row];
6625 pAlpha := pByte(Png.AlphaScanline[Row]);
6627 for Col := 0 to Png.Width -1 do begin
6628 Move (pSource^, pDest^, PixSize);
6629 Inc(pSource, PixSize);
6630 Inc(pDest, PixSize);
6639 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
6642 SetDataPointer(NewImage, PngFormat, Png.Header.Width, Png.Header.Height); //be careful, Data could be freed by this method
6646 if Assigned(NewImage) then
6658 {$IFDEF GLB_SUPPORT_PNG_WRITE}
6659 {$IFDEF GLB_LIB_PNG}
6660 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6661 procedure glBitmap_libPNG_write_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
6663 TStream(png_get_io_ptr(png)).Write(buffer^, size);
6667 {$IF DEFINED(GLB_LAZ_PNG)}
6668 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6669 procedure TglBitmap.SavePNG(const aStream: TStream);
6671 png: TPortableNetworkGraphic;
6672 intf: TLazIntfImage;
6675 png := TPortableNetworkGraphic.Create;
6676 intf := TLazIntfImage.Create(0, 0);
6678 if not AssignToLazIntfImage(intf) then
6679 raise EglBitmap.Create('unable to create LazIntfImage from glBitmap');
6680 intf.GetRawImage(raw);
6681 png.LoadFromRawImage(raw, false);
6682 png.SaveToStream(aStream);
6689 {$ELSEIF DEFINED(GLB_LIB_PNG)}
6690 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6691 procedure TglBitmap.SavePNG(const aStream: TStream);
6694 png_info: png_infop;
6695 png_rows: array of pByte;
6699 FormatDesc: TFormatDescriptor;
6701 if not (ftPNG in FormatGetSupportedFiles(Format)) then
6702 raise EglBitmapUnsupportedFormat.Create(Format);
6704 if not init_libPNG then
6705 raise Exception.Create('unable to initialize libPNG.');
6709 tfAlpha8ub1, tfLuminance8ub1:
6710 ColorType := PNG_COLOR_TYPE_GRAY;
6711 tfLuminance8Alpha8us1:
6712 ColorType := PNG_COLOR_TYPE_GRAY_ALPHA;
6713 tfBGR8ub3, tfRGB8ub3:
6714 ColorType := PNG_COLOR_TYPE_RGB;
6715 tfBGRA8ub4, tfRGBA8ub4:
6716 ColorType := PNG_COLOR_TYPE_RGBA;
6718 raise EglBitmapUnsupportedFormat.Create(Format);
6721 FormatDesc := TFormatDescriptor.Get(Format);
6722 LineSize := FormatDesc.GetSize(Width, 1);
6724 // creating array for scanline
6725 SetLength(png_rows, Height);
6727 for Row := 0 to Height - 1 do begin
6728 png_rows[Row] := Data;
6729 Inc(png_rows[Row], Row * LineSize)
6733 png := png_create_write_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
6735 raise EglBitmapException.Create('SavePng - couldn''t create write struct.');
6738 png_info := png_create_info_struct(png);
6739 if png_info = nil then begin
6740 png_destroy_write_struct(@png, nil);
6741 raise EglBitmapException.Create('SavePng - couldn''t create info struct.');
6744 // set read callback
6745 png_set_write_fn(png, aStream, glBitmap_libPNG_write_func, nil);
6748 png_set_compression_level(png, 6);
6750 if Format in [tfBGR8ub3, tfBGRA8ub4] then
6753 png_set_IHDR(png, png_info, Width, Height, 8, ColorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
6754 png_write_info(png, png_info);
6755 png_write_image(png, @png_rows[0]);
6756 png_write_end(png, png_info);
6757 png_destroy_write_struct(@png, @png_info);
6759 SetLength(png_rows, 0);
6766 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
6767 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6768 procedure TglBitmap.SavePNG(const aStream: TStream);
6772 pSource, pDest: pByte;
6773 X, Y, PixSize: Integer;
6774 ColorType: Cardinal;
6780 if not (ftPNG in FormatGetSupportedFiles (Format)) then
6781 raise EglBitmapUnsupportedFormat.Create(Format);
6784 tfAlpha8ub1, tfLuminance8ub1: begin
6785 ColorType := COLOR_GRAYSCALE;
6789 tfLuminance8Alpha8us1: begin
6790 ColorType := COLOR_GRAYSCALEALPHA;
6794 tfBGR8ub3, tfRGB8ub3: begin
6795 ColorType := COLOR_RGB;
6799 tfBGRA8ub4, tfRGBA8ub4: begin
6800 ColorType := COLOR_RGBALPHA;
6805 raise EglBitmapUnsupportedFormat.Create(Format);
6808 Png := TPNGObject.CreateBlank(ColorType, 8, Width, Height);
6812 for Y := 0 to Height -1 do begin
6813 pDest := png.ScanLine[Y];
6814 for X := 0 to Width -1 do begin
6815 Move(pSource^, pDest^, PixSize);
6816 Inc(pDest, PixSize);
6817 Inc(pSource, PixSize);
6819 png.AlphaScanline[Y]^[X] := pSource^;
6824 // convert RGB line to BGR
6825 if Format in [tfRGB8ub3, tfRGBA8ub4] then begin
6826 pTemp := png.ScanLine[Y];
6827 for X := 0 to Width -1 do begin
6828 Temp := pByteArray(pTemp)^[0];
6829 pByteArray(pTemp)^[0] := pByteArray(pTemp)^[2];
6830 pByteArray(pTemp)^[2] := Temp;
6837 Png.CompressionLevel := 6;
6838 Png.SaveToStream(aStream);
6846 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6847 //JPEG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6848 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6849 {$IFDEF GLB_LIB_JPEG}
6851 glBitmap_libJPEG_source_mgr_ptr = ^glBitmap_libJPEG_source_mgr;
6852 glBitmap_libJPEG_source_mgr = record
6853 pub: jpeg_source_mgr;
6856 SrcBuffer: array [1..4096] of byte;
6859 glBitmap_libJPEG_dest_mgr_ptr = ^glBitmap_libJPEG_dest_mgr;
6860 glBitmap_libJPEG_dest_mgr = record
6861 pub: jpeg_destination_mgr;
6863 DestStream: TStream;
6864 DestBuffer: array [1..4096] of byte;
6867 procedure glBitmap_libJPEG_error_exit(cinfo: j_common_ptr); cdecl;
6873 procedure glBitmap_libJPEG_output_message(cinfo: j_common_ptr); cdecl;
6879 procedure glBitmap_libJPEG_init_source(cinfo: j_decompress_ptr); cdecl;
6884 procedure glBitmap_libJPEG_term_source(cinfo: j_decompress_ptr); cdecl;
6890 procedure glBitmap_libJPEG_init_destination(cinfo: j_compress_ptr); cdecl;
6896 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6897 function glBitmap_libJPEG_fill_input_buffer(cinfo: j_decompress_ptr): boolean; cdecl;
6899 src: glBitmap_libJPEG_source_mgr_ptr;
6902 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
6904 bytes := src^.SrcStream.Read(src^.SrcBuffer[1], 4096);
6905 if (bytes <= 0) then begin
6906 src^.SrcBuffer[1] := $FF;
6907 src^.SrcBuffer[2] := JPEG_EOI;
6911 src^.pub.next_input_byte := @(src^.SrcBuffer[1]);
6912 src^.pub.bytes_in_buffer := bytes;
6917 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6918 procedure glBitmap_libJPEG_skip_input_data(cinfo: j_decompress_ptr; num_bytes: Longint); cdecl;
6920 src: glBitmap_libJPEG_source_mgr_ptr;
6922 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
6924 if num_bytes > 0 then begin
6925 // wanted byte isn't in buffer so set stream position and read buffer
6926 if num_bytes > src^.pub.bytes_in_buffer then begin
6927 src^.SrcStream.Position := src^.SrcStream.Position + num_bytes - src^.pub.bytes_in_buffer;
6928 src^.pub.fill_input_buffer(cinfo);
6930 // wanted byte is in buffer so only skip
6931 inc(src^.pub.next_input_byte, num_bytes);
6932 dec(src^.pub.bytes_in_buffer, num_bytes);
6937 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6938 function glBitmap_libJPEG_empty_output_buffer(cinfo: j_compress_ptr): boolean; cdecl;
6940 dest: glBitmap_libJPEG_dest_mgr_ptr;
6942 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
6944 if dest^.pub.free_in_buffer < Cardinal(Length(dest^.DestBuffer)) then begin
6945 // write complete buffer
6946 dest^.DestStream.Write(dest^.DestBuffer[1], SizeOf(dest^.DestBuffer));
6949 dest^.pub.next_output_byte := @dest^.DestBuffer[1];
6950 dest^.pub.free_in_buffer := Length(dest^.DestBuffer);
6956 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6957 procedure glBitmap_libJPEG_term_destination(cinfo: j_compress_ptr); cdecl;
6960 dest: glBitmap_libJPEG_dest_mgr_ptr;
6962 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
6964 for Idx := Low(dest^.DestBuffer) to High(dest^.DestBuffer) do begin
6965 // check for endblock
6966 if (Idx < High(dest^.DestBuffer)) and (dest^.DestBuffer[Idx] = $FF) and (dest^.DestBuffer[Idx +1] = JPEG_EOI) then begin
6968 dest^.DestStream.Write(dest^.DestBuffer[Idx], 2);
6973 dest^.DestStream.Write(dest^.DestBuffer[Idx], 1);
6978 {$IFDEF GLB_SUPPORT_JPEG_READ}
6979 {$IF DEFINED(GLB_LAZ_JPEG)}
6980 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6981 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6984 JPEG_MAGIC: String[MAGIC_LEN] = #$FF#$D8;
6986 intf: TLazIntfImage;
6987 reader: TFPReaderJPEG;
6989 magic: String[MAGIC_LEN];
6992 StreamPos := aStream.Position;
6994 SetLength(magic, MAGIC_LEN);
6995 aStream.Read(magic[1], MAGIC_LEN);
6996 aStream.Position := StreamPos;
6997 if (magic <> JPEG_MAGIC) then begin
7002 reader := TFPReaderJPEG.Create;
7003 intf := TLazIntfImage.Create(0, 0);
7005 intf.DataDescription := GetDescriptionFromDevice(0, 0, 0);
7006 reader.ImageRead(aStream, intf);
7007 AssignFromLazIntfImage(intf);
7010 aStream.Position := StreamPos;
7019 {$ELSEIF DEFINED(GLB_SDL_IMAGE)}
7020 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7021 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
7023 Surface: PSDL_Surface;
7028 RWops := glBitmapCreateRWops(aStream);
7030 if IMG_isJPG(RWops) > 0 then begin
7031 Surface := IMG_LoadJPG_RW(RWops);
7033 AssignFromSurface(Surface);
7036 SDL_FreeSurface(Surface);
7044 {$ELSEIF DEFINED(GLB_LIB_JPEG)}
7045 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7046 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
7049 Temp: array[0..1]of Byte;
7051 jpeg: jpeg_decompress_struct;
7052 jpeg_err: jpeg_error_mgr;
7054 IntFormat: TglBitmapFormat;
7056 TempHeight, TempWidth: Integer;
7061 FormatDesc: TFormatDescriptor;
7065 if not init_libJPEG then
7066 raise Exception.Create('LoadJPG - unable to initialize libJPEG.');
7069 // reading first two bytes to test file and set cursor back to begin
7070 StreamPos := aStream.Position;
7071 aStream.Read({%H-}Temp[0], 2);
7072 aStream.Position := StreamPos;
7074 // if Bitmap then read file.
7075 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
7076 FillChar(jpeg{%H-}, SizeOf(jpeg_decompress_struct), $00);
7077 FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
7080 jpeg.err := jpeg_std_error(@jpeg_err);
7081 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
7082 jpeg_err.output_message := glBitmap_libJPEG_output_message;
7084 // decompression struct
7085 jpeg_create_decompress(@jpeg);
7087 // allocation space for streaming methods
7088 jpeg.src := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_source_mgr));
7090 // seeting up custom functions
7091 with glBitmap_libJPEG_source_mgr_ptr(jpeg.src)^ do begin
7092 pub.init_source := glBitmap_libJPEG_init_source;
7093 pub.fill_input_buffer := glBitmap_libJPEG_fill_input_buffer;
7094 pub.skip_input_data := glBitmap_libJPEG_skip_input_data;
7095 pub.resync_to_restart := jpeg_resync_to_restart; // use default method
7096 pub.term_source := glBitmap_libJPEG_term_source;
7098 pub.bytes_in_buffer := 0; // forces fill_input_buffer on first read
7099 pub.next_input_byte := nil; // until buffer loaded
7101 SrcStream := aStream;
7104 // set global decoding state
7105 jpeg.global_state := DSTATE_START;
7107 // read header of jpeg
7108 jpeg_read_header(@jpeg, false);
7110 // setting output parameter
7111 case jpeg.jpeg_color_space of
7114 jpeg.out_color_space := JCS_GRAYSCALE;
7115 IntFormat := tfLuminance8ub1;
7118 jpeg.out_color_space := JCS_RGB;
7119 IntFormat := tfRGB8ub3;
7123 jpeg_start_decompress(@jpeg);
7125 TempHeight := jpeg.output_height;
7126 TempWidth := jpeg.output_width;
7128 FormatDesc := TFormatDescriptor.Get(IntFormat);
7130 // creating new image
7131 GetMem(pImage, FormatDesc.GetSize(TempWidth, TempHeight));
7135 for Row := 0 to TempHeight -1 do begin
7136 jpeg_read_scanlines(@jpeg, @pTemp, 1);
7137 Inc(pTemp, FormatDesc.GetSize(TempWidth, 1));
7140 // finish decompression
7141 jpeg_finish_decompress(@jpeg);
7143 // destroy decompression
7144 jpeg_destroy_decompress(@jpeg);
7146 SetDataPointer(pImage, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
7150 if Assigned(pImage) then
7160 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
7161 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7162 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
7167 Temp: array[0..1]of Byte;
7171 // reading first two bytes to test file and set cursor back to begin
7172 StreamPos := aStream.Position;
7173 aStream.Read(Temp[0], 2);
7174 aStream.Position := StreamPos;
7176 // if Bitmap then read file.
7177 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
7178 bmp := TBitmap.Create;
7180 jpg := TJPEGImage.Create;
7182 jpg.LoadFromStream(aStream);
7184 result := AssignFromBitmap(bmp);
7196 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
7197 {$IF DEFINED(GLB_LAZ_JPEG)}
7198 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7199 procedure TglBitmap.SaveJPEG(const aStream: TStream);
7202 intf: TLazIntfImage;
7205 jpeg := TJPEGImage.Create;
7206 intf := TLazIntfImage.Create(0, 0);
7208 if not AssignToLazIntfImage(intf) then
7209 raise EglBitmap.Create('unable to create LazIntfImage from glBitmap');
7210 intf.GetRawImage(raw);
7211 jpeg.LoadFromRawImage(raw, false);
7212 jpeg.SaveToStream(aStream);
7219 {$ELSEIF DEFINED(GLB_LIB_JPEG)}
7220 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7221 procedure TglBitmap.SaveJPEG(const aStream: TStream);
7223 jpeg: jpeg_compress_struct;
7224 jpeg_err: jpeg_error_mgr;
7226 pTemp, pTemp2: pByte;
7228 procedure CopyRow(pDest, pSource: pByte);
7232 for X := 0 to Width - 1 do begin
7233 pByteArray(pDest)^[0] := pByteArray(pSource)^[2];
7234 pByteArray(pDest)^[1] := pByteArray(pSource)^[1];
7235 pByteArray(pDest)^[2] := pByteArray(pSource)^[0];
7242 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
7243 raise EglBitmapUnsupportedFormat.Create(Format);
7245 if not init_libJPEG then
7246 raise Exception.Create('SaveJPG - unable to initialize libJPEG.');
7249 FillChar(jpeg{%H-}, SizeOf(jpeg_compress_struct), $00);
7250 FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
7253 jpeg.err := jpeg_std_error(@jpeg_err);
7254 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
7255 jpeg_err.output_message := glBitmap_libJPEG_output_message;
7257 // compression struct
7258 jpeg_create_compress(@jpeg);
7260 // allocation space for streaming methods
7261 jpeg.dest := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_dest_mgr));
7263 // seeting up custom functions
7264 with glBitmap_libJPEG_dest_mgr_ptr(jpeg.dest)^ do begin
7265 pub.init_destination := glBitmap_libJPEG_init_destination;
7266 pub.empty_output_buffer := glBitmap_libJPEG_empty_output_buffer;
7267 pub.term_destination := glBitmap_libJPEG_term_destination;
7269 pub.next_output_byte := @DestBuffer[1];
7270 pub.free_in_buffer := Length(DestBuffer);
7272 DestStream := aStream;
7275 // very important state
7276 jpeg.global_state := CSTATE_START;
7277 jpeg.image_width := Width;
7278 jpeg.image_height := Height;
7280 tfAlpha8ub1, tfLuminance8ub1: begin
7281 jpeg.input_components := 1;
7282 jpeg.in_color_space := JCS_GRAYSCALE;
7284 tfRGB8ub3, tfBGR8ub3: begin
7285 jpeg.input_components := 3;
7286 jpeg.in_color_space := JCS_RGB;
7290 jpeg_set_defaults(@jpeg);
7291 jpeg_set_quality(@jpeg, 95, true);
7292 jpeg_start_compress(@jpeg, true);
7295 if Format = tfBGR8ub3 then
7296 GetMem(pTemp2, fRowSize)
7301 for Row := 0 to jpeg.image_height -1 do begin
7303 if Format = tfBGR8ub3 then
7304 CopyRow(pTemp2, pTemp)
7309 jpeg_write_scanlines(@jpeg, @pTemp2, 1);
7310 inc(pTemp, fRowSize);
7314 if Format = tfBGR8ub3 then
7317 jpeg_finish_compress(@jpeg);
7318 jpeg_destroy_compress(@jpeg);
7324 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
7325 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7326 procedure TglBitmap.SaveJPEG(const aStream: TStream);
7331 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
7332 raise EglBitmapUnsupportedFormat.Create(Format);
7334 Bmp := TBitmap.Create;
7336 Jpg := TJPEGImage.Create;
7338 AssignToBitmap(Bmp);
7339 if (Format in [tfAlpha8ub1, tfLuminance8ub1]) then begin
7340 Jpg.Grayscale := true;
7341 Jpg.PixelFormat := jf8Bit;
7344 Jpg.SaveToStream(aStream);
7355 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7356 //RAW/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7357 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7359 RawHeader = packed record
7365 BitsPerPixel: Integer;
7366 Precision: TglBitmapRec4ub;
7367 Shift: TglBitmapRec4ub;
7370 function TglBitmap.LoadRAW(const aStream: TStream): Boolean;
7374 fd: TFormatDescriptor;
7378 StartPos := aStream.Position;
7379 aStream.Read(header{%H-}, SizeOf(header));
7380 if (header.Magic <> 'glBMP') then begin
7381 aStream.Position := StartPos;
7385 fd := TFormatDescriptor.GetFromPrecShift(header.Precision, header.Shift, header.BitsPerPixel);
7386 if (fd.Format = tfEmpty) then
7387 raise EglBitmapUnsupportedFormat.Create('no supported format found');
7389 buf := GetMemory(header.DataSize);
7390 aStream.Read(buf^, header.DataSize);
7391 SetDataPointer(buf, fd.Format, header.Width, header.Height);
7396 procedure TglBitmap.SaveRAW(const aStream: TStream);
7399 fd: TFormatDescriptor;
7401 fd := TFormatDescriptor.Get(Format);
7402 header.Magic := 'glBMP';
7403 header.Version := 1;
7404 header.Width := Width;
7405 header.Height := Height;
7406 header.DataSize := fd.GetSize(fDimension);
7407 header.BitsPerPixel := fd.BitsPerPixel;
7408 header.Precision := fd.Precision;
7409 header.Shift := fd.Shift;
7410 aStream.Write(header, SizeOf(header));
7411 aStream.Write(Data^, header.DataSize);
7414 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7415 //BMP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7416 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7423 BMP_COMP_BITFIELDS = 3;
7426 TBMPHeader = packed record
7431 bfOffBits: Cardinal;
7434 TBMPInfo = packed record
7440 biCompression: Cardinal;
7441 biSizeImage: Cardinal;
7442 biXPelsPerMeter: Longint;
7443 biYPelsPerMeter: Longint;
7444 biClrUsed: Cardinal;
7445 biClrImportant: Cardinal;
7448 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7449 function TglBitmap.LoadBMP(const aStream: TStream): Boolean;
7451 //////////////////////////////////////////////////////////////////////////////////////////////////
7452 function ReadInfo(out aInfo: TBMPInfo; out aMask: TglBitmapRec4ul): TglBitmapFormat;
7455 aStream.Read(aInfo{%H-}, SizeOf(aInfo));
7456 FillChar(aMask{%H-}, SizeOf(aMask), 0);
7459 case aInfo.biCompression of
7461 BMP_COMP_RLE8: begin
7462 raise EglBitmap.Create('RLE compression is not supported');
7464 BMP_COMP_BITFIELDS: begin
7465 if (aInfo.biBitCount = 16) or (aInfo.biBitCount = 32) then begin
7466 aStream.Read(aMask.r, SizeOf(aMask.r));
7467 aStream.Read(aMask.g, SizeOf(aMask.g));
7468 aStream.Read(aMask.b, SizeOf(aMask.b));
7469 aStream.Read(aMask.a, SizeOf(aMask.a));
7471 raise EglBitmap.Create('Bitfields are only supported for 16bit and 32bit formats');
7475 //get suitable format
7476 case aInfo.biBitCount of
7477 8: result := tfLuminance8ub1;
7478 16: result := tfX1RGB5us1;
7479 24: result := tfBGR8ub3;
7480 32: result := tfXRGB8ui1;
7484 function ReadColorTable(var aFormat: TglBitmapFormat; const aInfo: TBMPInfo): TbmpColorTableFormat;
7487 ColorTable: TbmpColorTable;
7490 if (aInfo.biBitCount >= 16) then
7492 aFormat := tfLuminance8ub1;
7493 c := aInfo.biClrUsed;
7495 c := 1 shl aInfo.biBitCount;
7496 SetLength(ColorTable, c);
7497 for i := 0 to c-1 do begin
7498 aStream.Read(ColorTable[i], SizeOf(TbmpColorTableEnty));
7499 if (ColorTable[i].r <> ColorTable[i].g) or (ColorTable[i].g <> ColorTable[i].b) then
7500 aFormat := tfRGB8ub3;
7503 result := TbmpColorTableFormat.Create;
7504 result.BitsPerPixel := aInfo.biBitCount;
7505 result.ColorTable := ColorTable;
7509 //////////////////////////////////////////////////////////////////////////////////////////////////
7510 function CheckBitfields(var aFormat: TglBitmapFormat; const aMask: TglBitmapRec4ul; const aInfo: TBMPInfo): TbmpBitfieldFormat;
7512 FormatDesc: TFormatDescriptor;
7515 if (aMask.r <> 0) or (aMask.g <> 0) or (aMask.b <> 0) or (aMask.a <> 0) then begin
7516 FormatDesc := TFormatDescriptor.GetFromMask(aMask);
7517 if (FormatDesc.Format = tfEmpty) then
7519 aFormat := FormatDesc.Format;
7520 if (aMask.a = 0) and TFormatDescriptor.Get(aFormat).HasAlpha then
7521 aFormat := TFormatDescriptor.Get(aFormat).WithoutAlpha;
7522 if (aMask.a <> 0) and not TFormatDescriptor.Get(aFormat).HasAlpha then
7523 aFormat := TFormatDescriptor.Get(aFormat).WithAlpha;
7525 result := TbmpBitfieldFormat.Create;
7526 result.SetCustomValues(aInfo.biBitCount, aMask);
7533 ImageSize, rbLineSize, wbLineSize, Padding, i: Integer;
7534 PaddingBuff: Cardinal;
7535 LineBuf, ImageData, TmpData: PByte;
7536 SourceMD, DestMD: Pointer;
7537 BmpFormat: TglBitmapFormat;
7540 Mask: TglBitmapRec4ul;
7545 SpecialFormat: TFormatDescriptor;
7546 FormatDesc: TFormatDescriptor;
7548 //////////////////////////////////////////////////////////////////////////////////////////////////
7549 procedure SpecialFormatReadLine(aData: PByte; aLineBuf: PByte);
7552 Pixel: TglBitmapPixelData;
7554 aStream.Read(aLineBuf^, rbLineSize);
7555 SpecialFormat.PreparePixel(Pixel);
7556 for i := 0 to Info.biWidth-1 do begin
7557 SpecialFormat.Unmap(aLineBuf, Pixel, SourceMD);
7558 glBitmapConvertPixel(Pixel, SpecialFormat, FormatDesc);
7559 FormatDesc.Map(Pixel, aData, DestMD);
7565 BmpFormat := tfEmpty;
7566 SpecialFormat := nil;
7572 StartPos := aStream.Position;
7573 aStream.Read(Header{%H-}, SizeOf(Header));
7575 if Header.bfType = BMP_MAGIC then begin
7577 BmpFormat := ReadInfo(Info, Mask);
7578 SpecialFormat := ReadColorTable(BmpFormat, Info);
7579 if not Assigned(SpecialFormat) then
7580 SpecialFormat := CheckBitfields(BmpFormat, Mask, Info);
7581 aStream.Position := StartPos + Header.bfOffBits;
7583 if (BmpFormat <> tfEmpty) then begin
7584 FormatDesc := TFormatDescriptor.Get(BmpFormat);
7585 rbLineSize := Round(Info.biWidth * Info.biBitCount / 8); //ReadBuffer LineSize
7586 wbLineSize := Trunc(Info.biWidth * FormatDesc.BytesPerPixel);
7587 Padding := (((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3) - rbLineSize;
7590 DestMD := FormatDesc.CreateMappingData;
7591 ImageSize := FormatDesc.GetSize(Info.biWidth, abs(Info.biHeight));
7592 GetMem(ImageData, ImageSize);
7593 if Assigned(SpecialFormat) then begin
7594 GetMem(LineBuf, rbLineSize); //tmp Memory for converting Bitfields
7595 SourceMD := SpecialFormat.CreateMappingData;
7600 FillChar(ImageData^, ImageSize, $FF);
7601 TmpData := ImageData;
7602 if (Info.biHeight > 0) then
7603 Inc(TmpData, wbLineSize * (Info.biHeight-1));
7604 for i := 0 to Abs(Info.biHeight)-1 do begin
7605 if Assigned(SpecialFormat) then
7606 SpecialFormatReadLine(TmpData, LineBuf) //if is special format read and convert data
7608 aStream.Read(TmpData^, wbLineSize); //else only read data
7609 if (Info.biHeight > 0) then
7610 dec(TmpData, wbLineSize)
7612 inc(TmpData, wbLineSize);
7613 aStream.Read(PaddingBuff{%H-}, Padding);
7615 SetDataPointer(ImageData, BmpFormat, Info.biWidth, abs(Info.biHeight)); //be careful, Data could be freed by this method
7618 if Assigned(LineBuf) then
7620 if Assigned(SourceMD) then
7621 SpecialFormat.FreeMappingData(SourceMD);
7622 FormatDesc.FreeMappingData(DestMD);
7625 if Assigned(ImageData) then
7630 raise EglBitmap.Create('LoadBMP - No suitable format found');
7632 aStream.Position := StartPos;
7636 FreeAndNil(SpecialFormat);
7639 else aStream.Position := StartPos;
7642 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7643 procedure TglBitmap.SaveBMP(const aStream: TStream);
7647 Converter: TFormatDescriptor;
7648 FormatDesc: TFormatDescriptor;
7649 SourceFD, DestFD: Pointer;
7650 pData, srcData, dstData, ConvertBuffer: pByte;
7652 Pixel: TglBitmapPixelData;
7653 ImageSize, wbLineSize, rbLineSize, Padding, LineIdx, PixelIdx: Integer;
7654 RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
7656 PaddingBuff: Cardinal;
7658 function GetLineWidth : Integer;
7660 result := ((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3;
7664 if not (ftBMP in FormatGetSupportedFiles(Format)) then
7665 raise EglBitmapUnsupportedFormat.Create(Format);
7668 FormatDesc := TFormatDescriptor.Get(Format);
7669 ImageSize := FormatDesc.GetSize(Dimension);
7671 FillChar(Header{%H-}, SizeOf(Header), 0);
7672 Header.bfType := BMP_MAGIC;
7673 Header.bfSize := SizeOf(Header) + SizeOf(Info) + ImageSize;
7674 Header.bfReserved1 := 0;
7675 Header.bfReserved2 := 0;
7676 Header.bfOffBits := SizeOf(Header) + SizeOf(Info);
7678 FillChar(Info{%H-}, SizeOf(Info), 0);
7679 Info.biSize := SizeOf(Info);
7680 Info.biWidth := Width;
7681 Info.biHeight := Height;
7683 Info.biCompression := BMP_COMP_RGB;
7684 Info.biSizeImage := ImageSize;
7688 tfAlpha4ub1, tfAlpha8ub1, tfLuminance4ub1, tfLuminance8ub1, tfR3G3B2ub1:
7690 Info.biBitCount := 8;
7691 Header.bfSize := Header.bfSize + 256 * SizeOf(Cardinal);
7692 Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal); //256 ColorTable entries
7693 Converter := TbmpColorTableFormat.Create;
7694 with (Converter as TbmpColorTableFormat) do begin
7695 SetCustomValues(fFormat, 1, FormatDesc.Precision, FormatDesc.Shift);
7700 tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
7701 tfRGBX4us1, tfXRGB4us1, tfRGB5X1us1, tfX1RGB5us1, tfR5G6B5us1, tfRGB5A1us1, tfA1RGB5us1, tfRGBA4us1, tfARGB4us1,
7702 tfBGRX4us1, tfXBGR4us1, tfBGR5X1us1, tfX1BGR5us1, tfB5G6R5us1, tfBGR5A1us1, tfA1BGR5us1, tfBGRA4us1, tfABGR4us1:
7704 Info.biBitCount := 16;
7705 Info.biCompression := BMP_COMP_BITFIELDS;
7708 tfBGR8ub3, tfRGB8ub3:
7710 Info.biBitCount := 24;
7711 if (Format = tfRGB8ub3) then
7712 Converter := TfdBGR8ub3.Create; //use BGR8 Format Descriptor to Swap RGB Values
7715 tfRGBX8ui1, tfXRGB8ui1, tfRGB10X2ui1, tfX2RGB10ui1, tfRGBA8ui1, tfARGB8ui1, tfRGBA8ub4, tfRGB10A2ui1, tfA2RGB10ui1,
7716 tfBGRX8ui1, tfXBGR8ui1, tfBGR10X2ui1, tfX2BGR10ui1, tfBGRA8ui1, tfABGR8ui1, tfBGRA8ub4, tfBGR10A2ui1, tfA2BGR10ui1:
7718 Info.biBitCount := 32;
7719 Info.biCompression := BMP_COMP_BITFIELDS;
7722 raise EglBitmapUnsupportedFormat.Create(Format);
7724 Info.biXPelsPerMeter := 2835;
7725 Info.biYPelsPerMeter := 2835;
7728 if Info.biCompression = BMP_COMP_BITFIELDS then begin
7729 Header.bfSize := Header.bfSize + 4 * SizeOf(Cardinal);
7730 Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal);
7732 RedMask := FormatDesc.Mask.r;
7733 GreenMask := FormatDesc.Mask.g;
7734 BlueMask := FormatDesc.Mask.b;
7735 AlphaMask := FormatDesc.Mask.a;
7739 aStream.Write(Header, SizeOf(Header));
7740 aStream.Write(Info, SizeOf(Info));
7743 if Assigned(Converter) and (Converter is TbmpColorTableFormat) then
7744 with (Converter as TbmpColorTableFormat) do
7745 aStream.Write(ColorTable[0].b,
7746 SizeOf(TbmpColorTableEnty) * Length(ColorTable));
7749 if Info.biCompression = BMP_COMP_BITFIELDS then begin
7750 aStream.Write(RedMask, SizeOf(Cardinal));
7751 aStream.Write(GreenMask, SizeOf(Cardinal));
7752 aStream.Write(BlueMask, SizeOf(Cardinal));
7753 aStream.Write(AlphaMask, SizeOf(Cardinal));
7757 rbLineSize := Round(Info.biWidth * FormatDesc.BytesPerPixel);
7758 wbLineSize := Round(Info.biWidth * Info.biBitCount / 8);
7759 Padding := GetLineWidth - wbLineSize;
7763 inc(pData, (Height-1) * rbLineSize);
7765 // prepare row buffer. But only for RGB because RGBA supports color masks
7766 // so it's possible to change color within the image.
7767 if Assigned(Converter) then begin
7768 FormatDesc.PreparePixel(Pixel);
7769 GetMem(ConvertBuffer, wbLineSize);
7770 SourceFD := FormatDesc.CreateMappingData;
7771 DestFD := Converter.CreateMappingData;
7773 ConvertBuffer := nil;
7776 for LineIdx := 0 to Height - 1 do begin
7778 if Assigned(Converter) then begin
7780 dstData := ConvertBuffer;
7781 for PixelIdx := 0 to Info.biWidth-1 do begin
7782 FormatDesc.Unmap(srcData, Pixel, SourceFD);
7783 glBitmapConvertPixel(Pixel, FormatDesc, Converter);
7784 Converter.Map(Pixel, dstData, DestFD);
7786 aStream.Write(ConvertBuffer^, wbLineSize);
7788 aStream.Write(pData^, rbLineSize);
7790 dec(pData, rbLineSize);
7791 if (Padding > 0) then
7792 aStream.Write(PaddingBuff, Padding);
7795 // destroy row buffer
7796 if Assigned(ConvertBuffer) then begin
7797 FormatDesc.FreeMappingData(SourceFD);
7798 Converter.FreeMappingData(DestFD);
7799 FreeMem(ConvertBuffer);
7803 if Assigned(Converter) then
7808 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7809 //TGA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7810 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7812 TTGAHeader = packed record
7816 //ColorMapSpec: Array[0..4] of Byte;
7817 ColorMapStart: Word;
7818 ColorMapLength: Word;
7819 ColorMapEntrySize: Byte;
7829 TGA_UNCOMPRESSED_RGB = 2;
7830 TGA_UNCOMPRESSED_GRAY = 3;
7831 TGA_COMPRESSED_RGB = 10;
7832 TGA_COMPRESSED_GRAY = 11;
7834 TGA_NONE_COLOR_TABLE = 0;
7836 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7837 function TglBitmap.LoadTGA(const aStream: TStream): Boolean;
7840 ImageData: System.PByte;
7841 StartPosition: Int64;
7842 PixelSize, LineSize: Integer;
7843 tgaFormat: TglBitmapFormat;
7844 FormatDesc: TFormatDescriptor;
7845 Counter: packed record
7847 low, high, dir: Integer;
7854 ////////////////////////////////////////////////////////////////////////////////////////
7855 procedure ReadUncompressed;
7858 buf, tmp1, tmp2: System.PByte;
7861 if (Counter.X.dir < 0) then
7862 GetMem(buf, LineSize);
7864 while (Counter.Y.low <> Counter.Y.high + counter.Y.dir) do begin
7866 inc(tmp1, (Counter.Y.low * LineSize)); //pointer to LineStart
7867 if (Counter.X.dir < 0) then begin //flip X
7868 aStream.Read(buf^, LineSize);
7870 inc(tmp2, LineSize - PixelSize); //pointer to last pixel in line
7871 for i := 0 to Header.Width-1 do begin //for all pixels in line
7872 for j := 0 to PixelSize-1 do begin //for all bytes in pixel
7877 dec(tmp2, 2*PixelSize); //move 2 backwards, because j-loop moved 1 forward
7880 aStream.Read(tmp1^, LineSize);
7881 inc(Counter.Y.low, Counter.Y.dir); //move to next line index
7884 if Assigned(buf) then
7889 ////////////////////////////////////////////////////////////////////////////////////////
7890 procedure ReadCompressed;
7892 /////////////////////////////////////////////////////////////////
7894 TmpData: System.PByte;
7895 LinePixelsRead: Integer;
7896 procedure CheckLine;
7898 if (LinePixelsRead >= Header.Width) then begin
7899 LinePixelsRead := 0;
7900 inc(Counter.Y.low, Counter.Y.dir); //next line index
7901 TmpData := ImageData;
7902 inc(TmpData, Counter.Y.low * LineSize); //set line
7903 if (Counter.X.dir < 0) then //if x flipped then
7904 inc(TmpData, LineSize - PixelSize); //set last pixel
7908 /////////////////////////////////////////////////////////////////
7911 CacheSize, CachePos: Integer;
7912 procedure CachedRead(out Buffer; Count: Integer);
7916 if (CachePos + Count > CacheSize) then begin
7917 //if buffer overflow save non read bytes
7919 if (CacheSize - CachePos > 0) then begin
7920 BytesRead := CacheSize - CachePos;
7921 Move(PByteArray(Cache)^[CachePos], Buffer{%H-}, BytesRead);
7922 inc(CachePos, BytesRead);
7925 //load cache from file
7926 CacheSize := Min(CACHE_SIZE, aStream.Size - aStream.Position);
7927 aStream.Read(Cache^, CacheSize);
7930 //read rest of requested bytes
7931 if (Count - BytesRead > 0) then begin
7932 Move(PByteArray(Cache)^[CachePos], TByteArray(Buffer)[BytesRead], Count - BytesRead);
7933 inc(CachePos, Count - BytesRead);
7936 //if no buffer overflow just read the data
7937 Move(PByteArray(Cache)^[CachePos], Buffer, Count);
7938 inc(CachePos, Count);
7942 procedure PixelToBuffer(const aData: PByte; var aBuffer: PByte);
7947 inc(aBuffer, Counter.X.dir);
7950 PWord(aBuffer)^ := PWord(aData)^;
7951 inc(aBuffer, 2 * Counter.X.dir);
7954 PByteArray(aBuffer)^[0] := PByteArray(aData)^[0];
7955 PByteArray(aBuffer)^[1] := PByteArray(aData)^[1];
7956 PByteArray(aBuffer)^[2] := PByteArray(aData)^[2];
7957 inc(aBuffer, 3 * Counter.X.dir);
7960 PCardinal(aBuffer)^ := PCardinal(aData)^;
7961 inc(aBuffer, 4 * Counter.X.dir);
7967 TotalPixelsToRead, TotalPixelsRead: Integer;
7969 buf: array [0..3] of Byte; //1 pixel is max 32bit long
7970 PixelRepeat: Boolean;
7971 PixelsToRead, PixelCount: Integer;
7976 TotalPixelsToRead := Header.Width * Header.Height;
7977 TotalPixelsRead := 0;
7978 LinePixelsRead := 0;
7980 GetMem(Cache, CACHE_SIZE);
7982 TmpData := ImageData;
7983 inc(TmpData, Counter.Y.low * LineSize); //set line
7984 if (Counter.X.dir < 0) then //if x flipped then
7985 inc(TmpData, LineSize - PixelSize); //set last pixel
7989 CachedRead(Temp, 1);
7990 PixelRepeat := (Temp and $80) > 0;
7991 PixelsToRead := (Temp and $7F) + 1;
7992 inc(TotalPixelsRead, PixelsToRead);
7995 CachedRead(buf[0], PixelSize);
7996 while (PixelsToRead > 0) do begin
7998 PixelCount := Min(Header.Width - LinePixelsRead, PixelsToRead); //max read to EOL or EOF
7999 while (PixelCount > 0) do begin
8000 if not PixelRepeat then
8001 CachedRead(buf[0], PixelSize);
8002 PixelToBuffer(@buf[0], TmpData);
8003 inc(LinePixelsRead);
8008 until (TotalPixelsRead >= TotalPixelsToRead);
8014 function IsGrayFormat: Boolean;
8016 result := Header.ImageType in [TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_GRAY];
8022 // reading header to test file and set cursor back to begin
8023 StartPosition := aStream.Position;
8024 aStream.Read(Header{%H-}, SizeOf(Header));
8026 // no colormapped files
8027 if (Header.ColorMapType = TGA_NONE_COLOR_TABLE) and (Header.ImageType in [
8028 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY]) then
8031 if Header.ImageID <> 0 then // skip image ID
8032 aStream.Position := aStream.Position + Header.ImageID;
8034 tgaFormat := tfEmpty;
8036 8: if IsGrayFormat then case (Header.ImageDesc and $F) of
8037 0: tgaFormat := tfLuminance8ub1;
8038 8: tgaFormat := tfAlpha8ub1;
8041 16: if IsGrayFormat then case (Header.ImageDesc and $F) of
8042 0: tgaFormat := tfLuminance16us1;
8043 8: tgaFormat := tfLuminance8Alpha8ub2;
8044 end else case (Header.ImageDesc and $F) of
8045 0: tgaFormat := tfX1RGB5us1;
8046 1: tgaFormat := tfA1RGB5us1;
8047 4: tgaFormat := tfARGB4us1;
8050 24: if not IsGrayFormat then case (Header.ImageDesc and $F) of
8051 0: tgaFormat := tfBGR8ub3;
8054 32: if IsGrayFormat then case (Header.ImageDesc and $F) of
8055 0: tgaFormat := tfDepth32ui1;
8056 end else case (Header.ImageDesc and $F) of
8057 0: tgaFormat := tfX2RGB10ui1;
8058 2: tgaFormat := tfA2RGB10ui1;
8059 8: tgaFormat := tfARGB8ui1;
8063 if (tgaFormat = tfEmpty) then
8064 raise EglBitmap.Create('LoadTga - unsupported format');
8066 FormatDesc := TFormatDescriptor.Get(tgaFormat);
8067 PixelSize := FormatDesc.GetSize(1, 1);
8068 LineSize := FormatDesc.GetSize(Header.Width, 1);
8070 GetMem(ImageData, LineSize * Header.Height);
8073 if ((Header.ImageDesc and (1 shl 4)) > 0) then begin
8074 Counter.X.low := Header.Height-1;;
8075 Counter.X.high := 0;
8076 Counter.X.dir := -1;
8079 Counter.X.high := Header.Height-1;
8084 if ((Header.ImageDesc and (1 shl 5)) > 0) then begin
8086 Counter.Y.high := Header.Height-1;
8089 Counter.Y.low := Header.Height-1;;
8090 Counter.Y.high := 0;
8091 Counter.Y.dir := -1;
8095 case Header.ImageType of
8096 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY:
8098 TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY:
8102 SetDataPointer(ImageData, tgaFormat, Header.Width, Header.Height); //be careful, Data could be freed by this method
8105 if Assigned(ImageData) then
8110 aStream.Position := StartPosition;
8113 else aStream.Position := StartPosition;
8116 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8117 procedure TglBitmap.SaveTGA(const aStream: TStream);
8121 FormatDesc: TFormatDescriptor;
8123 if not (ftTGA in FormatGetSupportedFiles(Format)) then
8124 raise EglBitmapUnsupportedFormat.Create(Format);
8127 FormatDesc := TFormatDescriptor.Get(Format);
8128 FillChar(Header{%H-}, SizeOf(Header), 0);
8129 Header.ImageDesc := CountSetBits(FormatDesc.Range.a) and $F;
8130 Header.Bpp := FormatDesc.BitsPerPixel;
8131 Header.Width := Width;
8132 Header.Height := Height;
8133 Header.ImageDesc := Header.ImageDesc or $20; //flip y
8134 if FormatDesc.IsGrayscale or (not FormatDesc.IsGrayscale and not FormatDesc.HasRed and FormatDesc.HasAlpha) then
8135 Header.ImageType := TGA_UNCOMPRESSED_GRAY
8137 Header.ImageType := TGA_UNCOMPRESSED_RGB;
8138 aStream.Write(Header, SizeOf(Header));
8141 Size := FormatDesc.GetSize(Dimension);
8142 aStream.Write(Data^, Size);
8145 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8146 //DDS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8147 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8149 DDS_MAGIC: Cardinal = $20534444;
8151 // DDS_header.dwFlags
8152 DDSD_CAPS = $00000001;
8153 DDSD_HEIGHT = $00000002;
8154 DDSD_WIDTH = $00000004;
8155 DDSD_PIXELFORMAT = $00001000;
8157 // DDS_header.sPixelFormat.dwFlags
8158 DDPF_ALPHAPIXELS = $00000001;
8159 DDPF_ALPHA = $00000002;
8160 DDPF_FOURCC = $00000004;
8161 DDPF_RGB = $00000040;
8162 DDPF_LUMINANCE = $00020000;
8164 // DDS_header.sCaps.dwCaps1
8165 DDSCAPS_TEXTURE = $00001000;
8167 // DDS_header.sCaps.dwCaps2
8168 DDSCAPS2_CUBEMAP = $00000200;
8170 D3DFMT_DXT1 = $31545844;
8171 D3DFMT_DXT3 = $33545844;
8172 D3DFMT_DXT5 = $35545844;
8175 TDDSPixelFormat = packed record
8179 dwRGBBitCount: Cardinal;
8180 dwRBitMask: Cardinal;
8181 dwGBitMask: Cardinal;
8182 dwBBitMask: Cardinal;
8183 dwABitMask: Cardinal;
8186 TDDSCaps = packed record
8190 dwReserved: Cardinal;
8193 TDDSHeader = packed record
8198 dwPitchOrLinearSize: Cardinal;
8200 dwMipMapCount: Cardinal;
8201 dwReserved: array[0..10] of Cardinal;
8202 PixelFormat: TDDSPixelFormat;
8204 dwReserved2: Cardinal;
8207 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8208 function TglBitmap.LoadDDS(const aStream: TStream): Boolean;
8211 Converter: TbmpBitfieldFormat;
8213 function GetDDSFormat: TglBitmapFormat;
8215 fd: TFormatDescriptor;
8217 Mask: TglBitmapRec4ul;
8218 Range: TglBitmapRec4ui;
8222 with Header.PixelFormat do begin
8224 if ((dwFlags and DDPF_FOURCC) > 0) then begin
8225 case Header.PixelFormat.dwFourCC of
8226 D3DFMT_DXT1: result := tfS3tcDtx1RGBA;
8227 D3DFMT_DXT3: result := tfS3tcDtx3RGBA;
8228 D3DFMT_DXT5: result := tfS3tcDtx5RGBA;
8230 end else if ((dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE or DDPF_ALPHA)) > 0) then begin
8232 if ((dwFlags and DDPF_LUMINANCE) = 0) then begin
8233 Mask.r := dwRBitMask;
8234 Mask.g := dwGBitMask;
8235 Mask.b := dwBBitMask;
8237 Mask.r := dwRBitMask;
8238 Mask.g := dwRBitMask;
8239 Mask.b := dwRBitMask;
8241 if (dwFlags and DDPF_ALPHAPIXELS > 0) then
8242 Mask.a := dwABitMask
8246 //find matching format
8247 fd := TFormatDescriptor.GetFromMask(Mask, dwRGBBitCount);
8248 result := fd.Format;
8249 if (result <> tfEmpty) then
8252 //find format with same Range
8254 Range.arr[i] := (2 shl CountSetBits(Mask.arr[i])) - 1;
8255 for result := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
8256 fd := TFormatDescriptor.Get(result);
8259 if (fd.Range.arr[i] <> Range.arr[i]) then begin
8267 //no format with same range found -> use default
8268 if (result = tfEmpty) then begin
8269 if (dwABitMask > 0) then
8270 result := tfRGBA8ui1
8272 result := tfRGB8ub3;
8275 Converter := TbmpBitfieldFormat.Create;
8276 Converter.SetCustomValues(dwRGBBitCount, glBitmapRec4ul(dwRBitMask, dwGBitMask, dwBBitMask, dwABitMask));
8283 x, y, LineSize, RowSize, Magic: Cardinal;
8284 NewImage, TmpData, RowData, SrcData: System.PByte;
8285 SourceMD, DestMD: Pointer;
8286 Pixel: TglBitmapPixelData;
8287 ddsFormat: TglBitmapFormat;
8288 FormatDesc: TFormatDescriptor;
8293 StreamPos := aStream.Position;
8296 aStream.Read(Magic{%H-}, sizeof(Magic));
8297 if (Magic <> DDS_MAGIC) then begin
8298 aStream.Position := StreamPos;
8303 aStream.Read(Header{%H-}, sizeof(Header));
8304 if (Header.dwSize <> SizeOf(Header)) or
8305 ((Header.dwFlags and (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) <>
8306 (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) then
8308 aStream.Position := StreamPos;
8312 if ((Header.Caps.dwCaps1 and DDSCAPS2_CUBEMAP) > 0) then
8313 raise EglBitmap.Create('LoadDDS - CubeMaps are not supported');
8315 ddsFormat := GetDDSFormat;
8317 if (ddsFormat = tfEmpty) then
8318 raise EglBitmap.Create('LoadDDS - unsupported Pixelformat found.');
8320 FormatDesc := TFormatDescriptor.Get(ddsFormat);
8321 LineSize := Trunc(Header.dwWidth * FormatDesc.BytesPerPixel);
8322 GetMem(NewImage, Header.dwHeight * LineSize);
8324 TmpData := NewImage;
8327 if Assigned(Converter) then begin
8328 RowSize := Round(Header.dwWidth * Header.PixelFormat.dwRGBBitCount / 8);
8329 GetMem(RowData, RowSize);
8330 SourceMD := Converter.CreateMappingData;
8331 DestMD := FormatDesc.CreateMappingData;
8333 for y := 0 to Header.dwHeight-1 do begin
8334 TmpData := NewImage;
8335 inc(TmpData, y * LineSize);
8337 aStream.Read(SrcData^, RowSize);
8338 for x := 0 to Header.dwWidth-1 do begin
8339 Converter.Unmap(SrcData, Pixel, SourceMD);
8340 glBitmapConvertPixel(Pixel, Converter, FormatDesc);
8341 FormatDesc.Map(Pixel, TmpData, DestMD);
8345 Converter.FreeMappingData(SourceMD);
8346 FormatDesc.FreeMappingData(DestMD);
8352 if ((Header.PixelFormat.dwFlags and DDPF_FOURCC) > 0) then begin
8353 RowSize := Header.dwPitchOrLinearSize div Header.dwWidth;
8354 for Y := 0 to Header.dwHeight-1 do begin
8355 aStream.Read(TmpData^, RowSize);
8356 Inc(TmpData, LineSize);
8361 if (Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE)) > 0 then begin
8362 RowSize := (Header.PixelFormat.dwRGBBitCount * Header.dwWidth) shr 3;
8363 for Y := 0 to Header.dwHeight-1 do begin
8364 aStream.Read(TmpData^, RowSize);
8365 Inc(TmpData, LineSize);
8368 raise EglBitmap.Create('LoadDDS - unsupported Pixelformat found.');
8370 SetDataPointer(NewImage, ddsFormat, Header.dwWidth, Header.dwHeight); //be careful, Data could be freed by this method
8373 if Assigned(NewImage) then
8378 FreeAndNil(Converter);
8382 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8383 procedure TglBitmap.SaveDDS(const aStream: TStream);
8386 FormatDesc: TFormatDescriptor;
8388 if not (ftDDS in FormatGetSupportedFiles(Format)) then
8389 raise EglBitmapUnsupportedFormat.Create(Format);
8391 FormatDesc := TFormatDescriptor.Get(Format);
8394 FillChar(Header{%H-}, SizeOf(Header), 0);
8395 Header.dwSize := SizeOf(Header);
8396 Header.dwFlags := DDSD_WIDTH or DDSD_HEIGHT or DDSD_CAPS or DDSD_PIXELFORMAT;
8398 Header.dwWidth := Max(1, Width);
8399 Header.dwHeight := Max(1, Height);
8402 Header.Caps.dwCaps1 := DDSCAPS_TEXTURE;
8405 Header.PixelFormat.dwSize := sizeof(Header);
8406 if (FormatDesc.IsCompressed) then begin
8407 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_FOURCC;
8409 tfS3tcDtx1RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT1;
8410 tfS3tcDtx3RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT3;
8411 tfS3tcDtx5RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT5;
8413 end else if not FormatDesc.HasColor and FormatDesc.HasAlpha then begin
8414 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHA;
8415 Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
8416 Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
8417 end else if FormatDesc.IsGrayscale then begin
8418 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_LUMINANCE;
8419 Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
8420 Header.PixelFormat.dwRBitMask := FormatDesc.Mask.r;
8421 Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
8423 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_RGB;
8424 Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
8425 Header.PixelFormat.dwRBitMask := FormatDesc.Mask.r;
8426 Header.PixelFormat.dwGBitMask := FormatDesc.Mask.g;
8427 Header.PixelFormat.dwBBitMask := FormatDesc.Mask.b;
8428 Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
8431 if (FormatDesc.HasAlpha) then
8432 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHAPIXELS;
8434 aStream.Write(DDS_MAGIC, sizeof(DDS_MAGIC));
8435 aStream.Write(Header, SizeOf(Header));
8436 aStream.Write(Data^, FormatDesc.GetSize(Dimension));
8440 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8441 //TglBitmap1D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8442 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8443 procedure TglBitmap1D.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
8444 const aWidth: Integer; const aHeight: Integer);
8449 if (aHeight > 1) then begin
8450 Size := TFormatDescriptor.Get(aFormat).GetSize(aWidth, 1);
8451 GetMem(pTemp, Size);
8453 Move(aData^, pTemp^, Size);
8462 inherited SetDataPointer(pTemp, aFormat, aWidth);
8465 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8466 function TglBitmap1D.FlipHorz: Boolean;
8469 pTempDest, pDest, pSource: PByte;
8471 result := inherited FlipHorz;
8472 if Assigned(Data) and not TFormatDescriptor.Get(Format).IsCompressed then begin
8474 GetMem(pDest, fRowSize);
8477 Inc(pTempDest, fRowSize);
8478 for Col := 0 to Width-1 do begin
8479 dec(pTempDest, fPixelSize); //dec before, because ptr is behind last byte of data
8480 Move(pSource^, pTempDest^, fPixelSize);
8481 Inc(pSource, fPixelSize);
8483 SetDataPointer(pDest, Format, Width); //be careful, Data could be freed by this method
8486 if Assigned(pDest) then
8493 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8494 procedure TglBitmap1D.UploadData(const aBuildWithGlu: Boolean);
8496 FormatDesc: TFormatDescriptor;
8499 FormatDesc := TFormatDescriptor.Get(Format);
8500 if (FormatDesc.glInternalFormat = 0) or (FormatDesc.glDataFormat = 0) then
8501 raise EglBitmap.Create('format is not supported by video adapter, please convert before uploading data');
8503 if FormatDesc.IsCompressed then begin
8504 if not Assigned(glCompressedTexImage1D) then
8505 raise EglBitmap.Create('compressed formats not supported by video adapter');
8506 glCompressedTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.GetSize(Width, 1), Data)
8507 end else if aBuildWithGlu then
8508 gluBuild1DMipmaps(Target, FormatDesc.glInternalFormat, Width, FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
8510 glTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
8513 if (FreeDataAfterGenTexture) then
8517 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8518 procedure TglBitmap1D.GenTexture(const aTestTextureSize: Boolean);
8520 BuildWithGlu, TexRec: Boolean;
8523 if Assigned(Data) then begin
8524 // Check Texture Size
8525 if (aTestTextureSize) then begin
8526 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
8528 if (Width > TexSize) then
8529 raise EglBitmapSizeToLarge.Create('TglBitmap1D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
8531 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and
8532 (Target = GL_TEXTURE_RECTANGLE);
8533 if not (IsPowerOfTwo(Width) or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
8534 raise EglBitmapNonPowerOfTwo.Create('TglBitmap1D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8538 SetupParameters(BuildWithGlu);
8539 UploadData(BuildWithGlu);
8540 glAreTexturesResident(1, @fID, @fIsResident);
8544 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8545 procedure TglBitmap1D.AfterConstruction;
8548 Target := GL_TEXTURE_1D;
8552 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8553 //TglBitmap2D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8554 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8555 function TglBitmap2D.GetScanline(const aIndex: Integer): Pointer;
8557 if (aIndex >= Low(fLines)) and (aIndex <= High(fLines)) then
8558 result := fLines[aIndex]
8563 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8564 procedure TglBitmap2D.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
8565 const aWidth: Integer; const aHeight: Integer);
8567 Idx, LineWidth: Integer;
8569 inherited SetDataPointer(aData, aFormat, aWidth, aHeight);
8571 if not TFormatDescriptor.Get(aFormat).IsCompressed then begin
8573 if Assigned(Data) then begin
8574 SetLength(fLines, GetHeight);
8575 LineWidth := Trunc(GetWidth * TFormatDescriptor.Get(Format).BytesPerPixel);
8577 for Idx := 0 to GetHeight-1 do begin
8578 fLines[Idx] := Data;
8579 Inc(fLines[Idx], Idx * LineWidth);
8582 else SetLength(fLines, 0);
8584 SetLength(fLines, 0);
8588 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8589 procedure TglBitmap2D.UploadData(const aTarget: GLenum{$IFNDEF OPENGL_ES}; const aBuildWithGlu: Boolean{$ENDIF});
8591 FormatDesc: TFormatDescriptor;
8593 FormatDesc := TFormatDescriptor.Get(Format);
8594 if (FormatDesc.glInternalFormat = 0) or (FormatDesc.glDataFormat = 0) then
8595 raise EglBitmap.Create('format is not supported by video adapter, please convert before uploading data');
8597 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
8599 if FormatDesc.IsCompressed then begin
8600 if not Assigned(glCompressedTexImage2D) then
8601 raise EglBitmap.Create('compressed formats not supported by video adapter');
8602 glCompressedTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0, FormatDesc.GetSize(fDimension), Data)
8604 end else if aBuildWithGlu then begin
8605 gluBuild2DMipmaps(aTarget, FormatDesc.ChannelCount, Width, Height,
8606 FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
8609 glTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0,
8610 FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
8614 if (FreeDataAfterGenTexture) then
8618 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8619 procedure TglBitmap2D.AfterConstruction;
8622 Target := GL_TEXTURE_2D;
8625 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8626 procedure TglBitmap2D.GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
8629 Size, w, h: Integer;
8630 FormatDesc: TFormatDescriptor;
8632 FormatDesc := TFormatDescriptor.Get(aFormat);
8633 if FormatDesc.IsCompressed then
8634 raise EglBitmapUnsupportedFormat.Create(aFormat);
8636 w := aRight - aLeft;
8637 h := aBottom - aTop;
8638 Size := FormatDesc.GetSize(w, h);
8641 glPixelStorei(GL_PACK_ALIGNMENT, 1);
8642 glReadPixels(aLeft, aTop, w, h, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
8643 SetDataPointer(Temp, aFormat, w, h); //be careful, Data could be freed by this method
8646 if Assigned(Temp) then
8653 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8654 procedure TglBitmap2D.GetDataFromTexture;
8657 TempWidth, TempHeight: Integer;
8658 TempIntFormat: GLint;
8659 IntFormat: TglBitmapFormat;
8660 FormatDesc: TFormatDescriptor;
8665 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_WIDTH, @TempWidth);
8666 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT, @TempHeight);
8667 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat);
8669 FormatDesc := (TglBitmapFormatDescriptor.GetByFormat(TempIntFormat) as TFormatDescriptor);
8670 IntFormat := FormatDesc.Format;
8672 // Getting data from OpenGL
8673 FormatDesc := TFormatDescriptor.Get(IntFormat);
8674 GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight));
8676 if FormatDesc.IsCompressed then begin
8677 if not Assigned(glGetCompressedTexImage) then
8678 raise EglBitmap.Create('compressed formats not supported by video adapter');
8679 glGetCompressedTexImage(Target, 0, Temp)
8681 glGetTexImage(Target, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
8682 SetDataPointer(Temp, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
8684 if Assigned(Temp) then
8691 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8692 procedure TglBitmap2D.GenTexture(const aTestTextureSize: Boolean);
8695 BuildWithGlu, TexRec: Boolean;
8700 if Assigned(Data) then begin
8701 // Check Texture Size
8702 if (aTestTextureSize) then begin
8703 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
8705 if ((Height > TexSize) or (Width > TexSize)) then
8706 raise EglBitmapSizeToLarge.Create('TglBitmap2D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
8708 PotTex := IsPowerOfTwo(Height) and IsPowerOfTwo(Width);
8709 {$IF NOT DEFINED(OPENGL_ES)}
8710 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and (Target = GL_TEXTURE_RECTANGLE);
8711 if not (PotTex or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
8712 raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8713 {$ELSEIF DEFINED(OPENGL_ES_EXT)}
8714 if not PotTex and not GL_OES_texture_npot then
8715 raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8718 raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8723 SetupParameters({$IFNDEF OPENGL_ES}BuildWithGlu{$ENDIF});
8724 UploadData(Target{$IFNDEF OPENGL_ES}, BuildWithGlu{$ENDIF});
8726 glAreTexturesResident(1, @fID, @fIsResident);
8731 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8732 function TglBitmap2D.FlipHorz: Boolean;
8735 TempDestData, DestData, SourceData: PByte;
8738 result := inherited FlipHorz;
8739 if Assigned(Data) then begin
8741 ImgSize := Height * fRowSize;
8742 GetMem(DestData, ImgSize);
8744 TempDestData := DestData;
8745 Dec(TempDestData, fRowSize + fPixelSize);
8746 for Row := 0 to Height -1 do begin
8747 Inc(TempDestData, fRowSize * 2);
8748 for Col := 0 to Width -1 do begin
8749 Move(SourceData^, TempDestData^, fPixelSize);
8750 Inc(SourceData, fPixelSize);
8751 Dec(TempDestData, fPixelSize);
8754 SetDataPointer(DestData, Format, Width, Height); //be careful, Data could be freed by this method
8757 if Assigned(DestData) then
8764 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8765 function TglBitmap2D.FlipVert: Boolean;
8768 TempDestData, DestData, SourceData: PByte;
8770 result := inherited FlipVert;
8771 if Assigned(Data) then begin
8773 GetMem(DestData, Height * fRowSize);
8775 TempDestData := DestData;
8776 Inc(TempDestData, Width * (Height -1) * fPixelSize);
8777 for Row := 0 to Height -1 do begin
8778 Move(SourceData^, TempDestData^, fRowSize);
8779 Dec(TempDestData, fRowSize);
8780 Inc(SourceData, fRowSize);
8782 SetDataPointer(DestData, Format, Width, Height); //be careful, Data could be freed by this method
8785 if Assigned(DestData) then
8792 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8793 //TglBitmap2D - ToNormalMap///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8794 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8796 TMatrixItem = record
8801 PglBitmapToNormalMapRec = ^TglBitmapToNormalMapRec;
8802 TglBitmapToNormalMapRec = Record
8804 Heights: array of Single;
8805 MatrixU : array of TMatrixItem;
8806 MatrixV : array of TMatrixItem;
8810 ONE_OVER_255 = 1 / 255;
8812 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8813 procedure glBitmapToNormalMapPrepareFunc(var FuncRec: TglBitmapFunctionRec);
8817 with FuncRec do begin
8819 Source.Data.r * LUMINANCE_WEIGHT_R +
8820 Source.Data.g * LUMINANCE_WEIGHT_G +
8821 Source.Data.b * LUMINANCE_WEIGHT_B;
8822 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Val * ONE_OVER_255;
8826 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8827 procedure glBitmapToNormalMapPrepareAlphaFunc(var FuncRec: TglBitmapFunctionRec);
8830 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Source.Data.a * ONE_OVER_255;
8833 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8834 procedure glBitmapToNormalMapFunc (var FuncRec: TglBitmapFunctionRec);
8836 TVec = Array[0..2] of Single;
8843 function GetHeight(X, Y: Integer): Single;
8845 with FuncRec do begin
8846 X := Max(0, Min(Size.X -1, X));
8847 Y := Max(0, Min(Size.Y -1, Y));
8848 result := PglBitmapToNormalMapRec(Args)^.Heights[Y * Size.X + X];
8853 with FuncRec do begin
8854 with PglBitmapToNormalMapRec(Args)^ do begin
8856 for Idx := Low(MatrixU) to High(MatrixU) do
8857 du := du + GetHeight(Position.X + MatrixU[Idx].X, Position.Y + MatrixU[Idx].Y) * MatrixU[Idx].W;
8860 for Idx := Low(MatrixU) to High(MatrixU) do
8861 dv := dv + GetHeight(Position.X + MatrixV[Idx].X, Position.Y + MatrixV[Idx].Y) * MatrixV[Idx].W;
8863 Vec[0] := -du * Scale;
8864 Vec[1] := -dv * Scale;
8869 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
8870 if Len <> 0 then begin
8871 Vec[0] := Vec[0] * Len;
8872 Vec[1] := Vec[1] * Len;
8873 Vec[2] := Vec[2] * Len;
8877 Dest.Data.r := Trunc((Vec[0] + 1) * 127.5);
8878 Dest.Data.g := Trunc((Vec[1] + 1) * 127.5);
8879 Dest.Data.b := Trunc((Vec[2] + 1) * 127.5);
8883 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8884 procedure TglBitmap2D.ToNormalMap(const aFunc: TglBitmapNormalMapFunc; const aScale: Single; const aUseAlpha: Boolean);
8886 Rec: TglBitmapToNormalMapRec;
8888 procedure SetEntry (var Matrix: array of TMatrixItem; Index, X, Y: Integer; W: Single);
8890 if (Index >= Low(Matrix)) and (Index <= High(Matrix)) then begin
8891 Matrix[Index].X := X;
8892 Matrix[Index].Y := Y;
8893 Matrix[Index].W := W;
8898 if TFormatDescriptor.Get(Format).IsCompressed then
8899 raise EglBitmapUnsupportedFormat.Create(Format);
8901 if aScale > 100 then
8903 else if aScale < -100 then
8906 Rec.Scale := aScale;
8908 SetLength(Rec.Heights, Width * Height);
8912 SetLength(Rec.MatrixU, 2);
8913 SetEntry(Rec.MatrixU, 0, -1, 0, -0.5);
8914 SetEntry(Rec.MatrixU, 1, 1, 0, 0.5);
8916 SetLength(Rec.MatrixV, 2);
8917 SetEntry(Rec.MatrixV, 0, 0, 1, 0.5);
8918 SetEntry(Rec.MatrixV, 1, 0, -1, -0.5);
8922 SetLength(Rec.MatrixU, 6);
8923 SetEntry(Rec.MatrixU, 0, -1, 1, -1.0);
8924 SetEntry(Rec.MatrixU, 1, -1, 0, -2.0);
8925 SetEntry(Rec.MatrixU, 2, -1, -1, -1.0);
8926 SetEntry(Rec.MatrixU, 3, 1, 1, 1.0);
8927 SetEntry(Rec.MatrixU, 4, 1, 0, 2.0);
8928 SetEntry(Rec.MatrixU, 5, 1, -1, 1.0);
8930 SetLength(Rec.MatrixV, 6);
8931 SetEntry(Rec.MatrixV, 0, -1, 1, 1.0);
8932 SetEntry(Rec.MatrixV, 1, 0, 1, 2.0);
8933 SetEntry(Rec.MatrixV, 2, 1, 1, 1.0);
8934 SetEntry(Rec.MatrixV, 3, -1, -1, -1.0);
8935 SetEntry(Rec.MatrixV, 4, 0, -1, -2.0);
8936 SetEntry(Rec.MatrixV, 5, 1, -1, -1.0);
8940 SetLength(Rec.MatrixU, 6);
8941 SetEntry(Rec.MatrixU, 0, -1, 1, -1/6);
8942 SetEntry(Rec.MatrixU, 1, -1, 0, -1/6);
8943 SetEntry(Rec.MatrixU, 2, -1, -1, -1/6);
8944 SetEntry(Rec.MatrixU, 3, 1, 1, 1/6);
8945 SetEntry(Rec.MatrixU, 4, 1, 0, 1/6);
8946 SetEntry(Rec.MatrixU, 5, 1, -1, 1/6);
8948 SetLength(Rec.MatrixV, 6);
8949 SetEntry(Rec.MatrixV, 0, -1, 1, 1/6);
8950 SetEntry(Rec.MatrixV, 1, 0, 1, 1/6);
8951 SetEntry(Rec.MatrixV, 2, 1, 1, 1/6);
8952 SetEntry(Rec.MatrixV, 3, -1, -1, -1/6);
8953 SetEntry(Rec.MatrixV, 4, 0, -1, -1/6);
8954 SetEntry(Rec.MatrixV, 5, 1, -1, -1/6);
8958 SetLength(Rec.MatrixU, 20);
8959 SetEntry(Rec.MatrixU, 0, -2, 2, -1 / 16);
8960 SetEntry(Rec.MatrixU, 1, -1, 2, -1 / 10);
8961 SetEntry(Rec.MatrixU, 2, 1, 2, 1 / 10);
8962 SetEntry(Rec.MatrixU, 3, 2, 2, 1 / 16);
8963 SetEntry(Rec.MatrixU, 4, -2, 1, -1 / 10);
8964 SetEntry(Rec.MatrixU, 5, -1, 1, -1 / 8);
8965 SetEntry(Rec.MatrixU, 6, 1, 1, 1 / 8);
8966 SetEntry(Rec.MatrixU, 7, 2, 1, 1 / 10);
8967 SetEntry(Rec.MatrixU, 8, -2, 0, -1 / 2.8);
8968 SetEntry(Rec.MatrixU, 9, -1, 0, -0.5);
8969 SetEntry(Rec.MatrixU, 10, 1, 0, 0.5);
8970 SetEntry(Rec.MatrixU, 11, 2, 0, 1 / 2.8);
8971 SetEntry(Rec.MatrixU, 12, -2, -1, -1 / 10);
8972 SetEntry(Rec.MatrixU, 13, -1, -1, -1 / 8);
8973 SetEntry(Rec.MatrixU, 14, 1, -1, 1 / 8);
8974 SetEntry(Rec.MatrixU, 15, 2, -1, 1 / 10);
8975 SetEntry(Rec.MatrixU, 16, -2, -2, -1 / 16);
8976 SetEntry(Rec.MatrixU, 17, -1, -2, -1 / 10);
8977 SetEntry(Rec.MatrixU, 18, 1, -2, 1 / 10);
8978 SetEntry(Rec.MatrixU, 19, 2, -2, 1 / 16);
8980 SetLength(Rec.MatrixV, 20);
8981 SetEntry(Rec.MatrixV, 0, -2, 2, 1 / 16);
8982 SetEntry(Rec.MatrixV, 1, -1, 2, 1 / 10);
8983 SetEntry(Rec.MatrixV, 2, 0, 2, 0.25);
8984 SetEntry(Rec.MatrixV, 3, 1, 2, 1 / 10);
8985 SetEntry(Rec.MatrixV, 4, 2, 2, 1 / 16);
8986 SetEntry(Rec.MatrixV, 5, -2, 1, 1 / 10);
8987 SetEntry(Rec.MatrixV, 6, -1, 1, 1 / 8);
8988 SetEntry(Rec.MatrixV, 7, 0, 1, 0.5);
8989 SetEntry(Rec.MatrixV, 8, 1, 1, 1 / 8);
8990 SetEntry(Rec.MatrixV, 9, 2, 1, 1 / 16);
8991 SetEntry(Rec.MatrixV, 10, -2, -1, -1 / 16);
8992 SetEntry(Rec.MatrixV, 11, -1, -1, -1 / 8);
8993 SetEntry(Rec.MatrixV, 12, 0, -1, -0.5);
8994 SetEntry(Rec.MatrixV, 13, 1, -1, -1 / 8);
8995 SetEntry(Rec.MatrixV, 14, 2, -1, -1 / 10);
8996 SetEntry(Rec.MatrixV, 15, -2, -2, -1 / 16);
8997 SetEntry(Rec.MatrixV, 16, -1, -2, -1 / 10);
8998 SetEntry(Rec.MatrixV, 17, 0, -2, -0.25);
8999 SetEntry(Rec.MatrixV, 18, 1, -2, -1 / 10);
9000 SetEntry(Rec.MatrixV, 19, 2, -2, -1 / 16);
9005 if aUseAlpha and TFormatDescriptor.Get(Format).HasAlpha then
9006 AddFunc(glBitmapToNormalMapPrepareAlphaFunc, false, @Rec)
9008 AddFunc(glBitmapToNormalMapPrepareFunc, false, @Rec);
9009 AddFunc(glBitmapToNormalMapFunc, false, @Rec);
9011 SetLength(Rec.Heights, 0);
9015 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
9016 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9017 //TglBitmapCubeMap////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9018 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9019 procedure TglBitmapCubeMap.GenTexture(const aTestTextureSize: Boolean);
9021 Assert(false, 'TglBitmapCubeMap.GenTexture - Don''t call GenTextures directly.');
9024 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9025 procedure TglBitmapCubeMap.AfterConstruction;
9030 if not (GL_VERSION_1_3 or GL_ARB_texture_cube_map or GL_EXT_texture_cube_map) then
9031 raise EglBitmap.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
9033 if not (GL_VERSION_2_0) then
9034 raise EglBitmap.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
9038 Target := GL_TEXTURE_CUBE_MAP;
9040 fGenMode := GL_REFLECTION_MAP;
9044 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9045 procedure TglBitmapCubeMap.GenerateCubeMap(const aCubeTarget: Cardinal; const aTestTextureSize: Boolean);
9048 BuildWithGlu: Boolean;
9052 if (aTestTextureSize) then begin
9053 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, @TexSize);
9055 if (Height > TexSize) or (Width > TexSize) then
9056 raise EglBitmapSizeToLarge.Create('TglBitmapCubeMap.GenerateCubeMap - The size for the Cubemap is to large. It''s may be not conform with the Hardware.');
9058 {$IF NOT DEFINED(OPENGL_ES)}
9059 if not ((IsPowerOfTwo(Height) and IsPowerOfTwo(Width)) or GL_VERSION_2_0 or GL_ARB_texture_non_power_of_two) then
9060 raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenerateCubeMap - Cubemaps dosn''t support non power of two texture.');
9061 {$ELSEIF DEFINED(OPENGL_ES_EXT)}
9062 if not (IsPowerOfTwo(Height) and IsPowerOfTwo(Width)) and not GL_OES_texture_npot then
9063 raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenerateCubeMap - Cubemaps dosn''t support non power of two texture.');
9065 if not (IsPowerOfTwo(Height) and IsPowerOfTwo(Width)) then
9066 raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenerateCubeMap - Cubemaps dosn''t support non power of two texture.');
9072 SetupParameters({$IFNDEF OPENGL_ES}BuildWithGlu{$ENDIF});
9073 UploadData(aCubeTarget{$IFNDEF OPENGL_ES}, BuildWithGlu{$ENDIF});
9076 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9077 procedure TglBitmapCubeMap.Bind({$IFNDEF OPENGL_ES}const aEnableTexCoordsGen: Boolean;{$ENDIF} const aEnableTextureUnit: Boolean);
9079 inherited Bind (aEnableTextureUnit);
9081 if aEnableTexCoordsGen then begin
9082 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, fGenMode);
9083 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, fGenMode);
9084 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, fGenMode);
9085 glEnable(GL_TEXTURE_GEN_S);
9086 glEnable(GL_TEXTURE_GEN_T);
9087 glEnable(GL_TEXTURE_GEN_R);
9092 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9093 procedure TglBitmapCubeMap.Unbind({$IFNDEF OPENGL_ES}const aDisableTexCoordsGen: Boolean;{$ENDIF} const aDisableTextureUnit: Boolean);
9095 inherited Unbind(aDisableTextureUnit);
9097 if aDisableTexCoordsGen then begin
9098 glDisable(GL_TEXTURE_GEN_S);
9099 glDisable(GL_TEXTURE_GEN_T);
9100 glDisable(GL_TEXTURE_GEN_R);
9106 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
9107 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9108 //TglBitmapNormalMap//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9109 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9111 TVec = Array[0..2] of Single;
9112 TglBitmapNormalMapGetVectorFunc = procedure (out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
9114 PglBitmapNormalMapRec = ^TglBitmapNormalMapRec;
9115 TglBitmapNormalMapRec = record
9117 Func: TglBitmapNormalMapGetVectorFunc;
9120 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9121 procedure glBitmapNormalMapPosX(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
9123 aVec[0] := aHalfSize;
9124 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
9125 aVec[2] := - (aPosition.X + 0.5 - aHalfSize);
9128 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9129 procedure glBitmapNormalMapNegX(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
9131 aVec[0] := - aHalfSize;
9132 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
9133 aVec[2] := aPosition.X + 0.5 - aHalfSize;
9136 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9137 procedure glBitmapNormalMapPosY(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
9139 aVec[0] := aPosition.X + 0.5 - aHalfSize;
9140 aVec[1] := aHalfSize;
9141 aVec[2] := aPosition.Y + 0.5 - aHalfSize;
9144 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9145 procedure glBitmapNormalMapNegY(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
9147 aVec[0] := aPosition.X + 0.5 - aHalfSize;
9148 aVec[1] := - aHalfSize;
9149 aVec[2] := - (aPosition.Y + 0.5 - aHalfSize);
9152 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9153 procedure glBitmapNormalMapPosZ(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
9155 aVec[0] := aPosition.X + 0.5 - aHalfSize;
9156 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
9157 aVec[2] := aHalfSize;
9160 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9161 procedure glBitmapNormalMapNegZ(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
9163 aVec[0] := - (aPosition.X + 0.5 - aHalfSize);
9164 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
9165 aVec[2] := - aHalfSize;
9168 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9169 procedure glBitmapNormalMapFunc(var FuncRec: TglBitmapFunctionRec);
9175 with FuncRec do begin
9176 with PglBitmapNormalMapRec(Args)^ do begin
9177 Func(Vec, Position, HalfSize);
9180 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
9181 if Len <> 0 then begin
9182 Vec[0] := Vec[0] * Len;
9183 Vec[1] := Vec[1] * Len;
9184 Vec[2] := Vec[2] * Len;
9187 // Scale Vector and AddVectro
9188 Vec[0] := Vec[0] * 0.5 + 0.5;
9189 Vec[1] := Vec[1] * 0.5 + 0.5;
9190 Vec[2] := Vec[2] * 0.5 + 0.5;
9195 Dest.Data.arr[i] := Round(Vec[i] * 255);
9199 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9200 procedure TglBitmapNormalMap.AfterConstruction;
9204 fGenMode := GL_NORMAL_MAP;
9208 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9209 procedure TglBitmapNormalMap.GenerateNormalMap(const aSize: Integer; const aTestTextureSize: Boolean);
9211 Rec: TglBitmapNormalMapRec;
9212 SizeRec: TglBitmapPixelPosition;
9214 Rec.HalfSize := aSize div 2;
9215 FreeDataAfterGenTexture := false;
9217 SizeRec.Fields := [ffX, ffY];
9222 Rec.Func := glBitmapNormalMapPosX;
9223 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
9224 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X, aTestTextureSize);
9227 Rec.Func := glBitmapNormalMapNegX;
9228 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
9229 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, aTestTextureSize);
9232 Rec.Func := glBitmapNormalMapPosY;
9233 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
9234 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, aTestTextureSize);
9237 Rec.Func := glBitmapNormalMapNegY;
9238 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
9239 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, aTestTextureSize);
9242 Rec.Func := glBitmapNormalMapPosZ;
9243 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
9244 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, aTestTextureSize);
9247 Rec.Func := glBitmapNormalMapNegZ;
9248 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
9249 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, aTestTextureSize);
9254 glBitmapSetDefaultFormat (tfEmpty);
9255 glBitmapSetDefaultMipmap (mmMipmap);
9256 glBitmapSetDefaultFilter (GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
9257 glBitmapSetDefaultWrap (GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
9258 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
9259 glBitmapSetDefaultSwizzle(GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA);
9262 glBitmapSetDefaultFreeDataAfterGenTexture(true);
9263 glBitmapSetDefaultDeleteTextureOnFree (true);
9265 TFormatDescriptor.Init;
9267 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
9268 OpenGLInitialized := false;
9269 InitOpenGLCS := TCriticalSection.Create;
9273 TFormatDescriptor.Finalize;
9275 {$IFDEF GLB_NATIVE_OGL}
9276 if Assigned(GL_LibHandle) then
9277 glbFreeLibrary(GL_LibHandle);
9279 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
9280 if Assigned(GLU_LibHandle) then
9281 glbFreeLibrary(GLU_LibHandle);
9282 FreeAndNil(InitOpenGLCS);