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 TglcBitmap1D = TglBitmap1D;
1324 TglcBitmap2D = TglBitmap2D;
1325 TglcBitmapCubeMap = TglBitmapCubeMap;
1326 TglcBitmapNormalMap = TglBitmapNormalMap;
1329 NULL_SIZE: TglBitmapPixelPosition = (Fields: []; X: 0; Y: 0);
1331 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
1332 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
1333 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
1334 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
1335 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
1336 procedure glBitmapSetDefaultWrap(
1337 const S: Cardinal = GL_CLAMP_TO_EDGE;
1338 const T: Cardinal = GL_CLAMP_TO_EDGE;
1339 const R: Cardinal = GL_CLAMP_TO_EDGE);
1341 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
1342 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
1343 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
1344 function glBitmapGetDefaultFormat: TglBitmapFormat;
1345 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
1346 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
1348 function glBitmapPosition(X: Integer = -1; Y: Integer = -1): TglBitmapPixelPosition;
1349 function glBitmapRec4ub(const r, g, b, a: Byte): TglBitmapRec4ub;
1350 function glBitmapRec4ui(const r, g, b, a: Cardinal): TglBitmapRec4ui;
1351 function glBitmapRec4ul(const r, g, b, a: QWord): TglBitmapRec4ul;
1352 function glBitmapRec4ubCompare(const r1, r2: TglBitmapRec4ub): Boolean;
1353 function glBitmapRec4uiCompare(const r1, r2: TglBitmapRec4ui): Boolean;
1355 function glBitmapCreateTestTexture(const aFormat: TglBitmapFormat): TglBitmap2D;
1358 glBitmapDefaultDeleteTextureOnFree: Boolean;
1359 glBitmapDefaultFreeDataAfterGenTextures: Boolean;
1360 glBitmapDefaultFormat: TglBitmapFormat;
1361 glBitmapDefaultMipmap: TglBitmapMipMap;
1362 glBitmapDefaultFilterMin: Cardinal;
1363 glBitmapDefaultFilterMag: Cardinal;
1364 glBitmapDefaultWrapS: Cardinal;
1365 glBitmapDefaultWrapT: Cardinal;
1366 glBitmapDefaultWrapR: Cardinal;
1367 glDefaultSwizzle: array[0..3] of GLenum;
1370 function CreateGrayPalette: HPALETTE;
1376 Math, syncobjs, typinfo
1377 {$IF DEFINED(GLB_SUPPORT_JPEG_READ) AND DEFINED(GLB_LAZ_JPEG)}, FPReadJPEG{$IFEND};
1379 ////////////////////////////////////////////////////////////////////////////////////////////////////
1381 TFormatDescriptor = class(TglBitmapFormatDescriptor)
1383 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); virtual; abstract;
1384 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); virtual; abstract;
1386 function GetSize(const aSize: TglBitmapPixelPosition): Integer; overload; virtual;
1387 function GetSize(const aWidth, aHeight: Integer): Integer; overload; virtual;
1389 function CreateMappingData: Pointer; virtual;
1390 procedure FreeMappingData(var aMappingData: Pointer); virtual;
1392 function IsEmpty: Boolean; virtual;
1393 function MaskMatch(const aMask: TglBitmapRec4ul): Boolean; virtual;
1395 procedure PreparePixel(out aPixel: TglBitmapPixelData); virtual;
1397 constructor Create; virtual;
1399 class procedure Init;
1400 class function Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
1401 class function GetAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
1402 class function GetFromMask(const aMask: TglBitmapRec4ul; const aBitCount: Integer = 0): TFormatDescriptor;
1403 class function GetFromPrecShift(const aPrec, aShift: TglBitmapRec4ub; const aBitCount: Integer): TFormatDescriptor;
1404 class procedure Clear;
1405 class procedure Finalize;
1407 TFormatDescriptorClass = class of TFormatDescriptor;
1409 TfdEmpty = class(TFormatDescriptor);
1411 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1412 TfdAlphaUB1 = class(TFormatDescriptor) //1* unsigned byte
1413 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1414 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1417 TfdLuminanceUB1 = 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 TfdUniversalUB1 = 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 TfdLuminanceAlphaUB2 = class(TfdLuminanceUB1) //2* 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 TfdRGBub3 = class(TFormatDescriptor) //3* 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 TfdBGRub3 = class(TFormatDescriptor) //3* unsigned byte (inverse)
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 TfdRGBAub4 = class(TfdRGBub3) //3* unsigned byte
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 TfdBGRAub4 = class(TfdBGRub3) //3* unsigned byte (inverse)
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 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1453 TfdAlphaUS1 = class(TFormatDescriptor) //1* unsigned short
1454 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1455 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1458 TfdLuminanceUS1 = 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 TfdUniversalUS1 = 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 TfdDepthUS1 = 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 TfdLuminanceAlphaUS2 = class(TfdLuminanceUS1) //2* 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 TfdRGBus3 = class(TFormatDescriptor) //3* 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 TfdBGRus3 = class(TFormatDescriptor) //3* unsigned short (inverse)
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 TfdRGBAus4 = class(TfdRGBus3) //4* unsigned short
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 TfdARGBus4 = 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 TfdBGRAus4 = class(TfdBGRus3) //4* unsigned short (inverse)
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 TfdABGRus4 = 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 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1509 TfdUniversalUI1 = class(TFormatDescriptor) //1* unsigned int
1510 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1511 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1514 TfdDepthUI1 = 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 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1520 TfdAlpha4ub1 = class(TfdAlphaUB1)
1521 procedure SetValues; override;
1524 TfdAlpha8ub1 = class(TfdAlphaUB1)
1525 procedure SetValues; override;
1528 TfdAlpha16us1 = class(TfdAlphaUS1)
1529 procedure SetValues; override;
1532 TfdLuminance4ub1 = class(TfdLuminanceUB1)
1533 procedure SetValues; override;
1536 TfdLuminance8ub1 = class(TfdLuminanceUB1)
1537 procedure SetValues; override;
1540 TfdLuminance16us1 = class(TfdLuminanceUS1)
1541 procedure SetValues; override;
1544 TfdLuminance4Alpha4ub2 = class(TfdLuminanceAlphaUB2)
1545 procedure SetValues; override;
1548 TfdLuminance6Alpha2ub2 = class(TfdLuminanceAlphaUB2)
1549 procedure SetValues; override;
1552 TfdLuminance8Alpha8ub2 = class(TfdLuminanceAlphaUB2)
1553 procedure SetValues; override;
1556 TfdLuminance12Alpha4us2 = class(TfdLuminanceAlphaUS2)
1557 procedure SetValues; override;
1560 TfdLuminance16Alpha16us2 = class(TfdLuminanceAlphaUS2)
1561 procedure SetValues; override;
1564 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1565 TfdR3G3B2ub1 = class(TfdUniversalUB1)
1566 procedure SetValues; override;
1569 TfdRGBX4us1 = class(TfdUniversalUS1)
1570 procedure SetValues; override;
1573 TfdXRGB4us1 = class(TfdUniversalUS1)
1574 procedure SetValues; override;
1577 TfdR5G6B5us1 = class(TfdUniversalUS1)
1578 procedure SetValues; override;
1581 TfdRGB5X1us1 = class(TfdUniversalUS1)
1582 procedure SetValues; override;
1585 TfdX1RGB5us1 = class(TfdUniversalUS1)
1586 procedure SetValues; override;
1589 TfdRGB8ub3 = class(TfdRGBub3)
1590 procedure SetValues; override;
1593 TfdRGBX8ui1 = class(TfdUniversalUI1)
1594 procedure SetValues; override;
1597 TfdXRGB8ui1 = class(TfdUniversalUI1)
1598 procedure SetValues; override;
1601 TfdRGB10X2ui1 = class(TfdUniversalUI1)
1602 procedure SetValues; override;
1605 TfdX2RGB10ui1 = class(TfdUniversalUI1)
1606 procedure SetValues; override;
1609 TfdRGB16us3 = class(TfdRGBus3)
1610 procedure SetValues; override;
1613 TfdRGBA4us1 = class(TfdUniversalUS1)
1614 procedure SetValues; override;
1617 TfdARGB4us1 = class(TfdUniversalUS1)
1618 procedure SetValues; override;
1621 TfdRGB5A1us1 = class(TfdUniversalUS1)
1622 procedure SetValues; override;
1625 TfdA1RGB5us1 = class(TfdUniversalUS1)
1626 procedure SetValues; override;
1629 TfdRGBA8ui1 = class(TfdUniversalUI1)
1630 procedure SetValues; override;
1633 TfdARGB8ui1 = class(TfdUniversalUI1)
1634 procedure SetValues; override;
1637 TfdRGBA8ub4 = class(TfdRGBAub4)
1638 procedure SetValues; override;
1641 TfdRGB10A2ui1 = class(TfdUniversalUI1)
1642 procedure SetValues; override;
1645 TfdA2RGB10ui1 = class(TfdUniversalUI1)
1646 procedure SetValues; override;
1649 TfdRGBA16us4 = class(TfdRGBAus4)
1650 procedure SetValues; override;
1653 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1654 TfdBGRX4us1 = class(TfdUniversalUS1)
1655 procedure SetValues; override;
1658 TfdXBGR4us1 = class(TfdUniversalUS1)
1659 procedure SetValues; override;
1662 TfdB5G6R5us1 = class(TfdUniversalUS1)
1663 procedure SetValues; override;
1666 TfdBGR5X1us1 = class(TfdUniversalUS1)
1667 procedure SetValues; override;
1670 TfdX1BGR5us1 = class(TfdUniversalUS1)
1671 procedure SetValues; override;
1674 TfdBGR8ub3 = class(TfdBGRub3)
1675 procedure SetValues; override;
1678 TfdBGRX8ui1 = class(TfdUniversalUI1)
1679 procedure SetValues; override;
1682 TfdXBGR8ui1 = class(TfdUniversalUI1)
1683 procedure SetValues; override;
1686 TfdBGR10X2ui1 = class(TfdUniversalUI1)
1687 procedure SetValues; override;
1690 TfdX2BGR10ui1 = class(TfdUniversalUI1)
1691 procedure SetValues; override;
1694 TfdBGR16us3 = class(TfdBGRus3)
1695 procedure SetValues; override;
1698 TfdBGRA4us1 = class(TfdUniversalUS1)
1699 procedure SetValues; override;
1702 TfdABGR4us1 = class(TfdUniversalUS1)
1703 procedure SetValues; override;
1706 TfdBGR5A1us1 = class(TfdUniversalUS1)
1707 procedure SetValues; override;
1710 TfdA1BGR5us1 = class(TfdUniversalUS1)
1711 procedure SetValues; override;
1714 TfdBGRA8ui1 = class(TfdUniversalUI1)
1715 procedure SetValues; override;
1718 TfdABGR8ui1 = class(TfdUniversalUI1)
1719 procedure SetValues; override;
1722 TfdBGRA8ub4 = class(TfdBGRAub4)
1723 procedure SetValues; override;
1726 TfdBGR10A2ui1 = class(TfdUniversalUI1)
1727 procedure SetValues; override;
1730 TfdA2BGR10ui1 = class(TfdUniversalUI1)
1731 procedure SetValues; override;
1734 TfdBGRA16us4 = class(TfdBGRAus4)
1735 procedure SetValues; override;
1738 TfdDepth16us1 = class(TfdDepthUS1)
1739 procedure SetValues; override;
1742 TfdDepth24ui1 = class(TfdDepthUI1)
1743 procedure SetValues; override;
1746 TfdDepth32ui1 = class(TfdDepthUI1)
1747 procedure SetValues; override;
1750 TfdS3tcDtx1RGBA = class(TFormatDescriptor)
1751 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1752 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1753 procedure SetValues; override;
1756 TfdS3tcDtx3RGBA = class(TFormatDescriptor)
1757 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1758 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1759 procedure SetValues; override;
1762 TfdS3tcDtx5RGBA = class(TFormatDescriptor)
1763 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1764 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1765 procedure SetValues; override;
1768 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1769 TbmpBitfieldFormat = class(TFormatDescriptor)
1771 procedure SetCustomValues(const aBPP: Integer; aMask: TglBitmapRec4ul); overload;
1772 procedure SetCustomValues(const aBBP: Integer; const aPrec, aShift: TglBitmapRec4ub); overload;
1773 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1774 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1777 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1778 TbmpColorTableEnty = packed record
1781 TbmpColorTable = array of TbmpColorTableEnty;
1782 TbmpColorTableFormat = class(TFormatDescriptor)
1784 fBitsPerPixel: Integer;
1785 fColorTable: TbmpColorTable;
1787 procedure SetValues; override;
1789 property ColorTable: TbmpColorTable read fColorTable write fColorTable;
1790 property BitsPerPixel: Integer read fBitsPerPixel write fBitsPerPixel;
1792 procedure SetCustomValues(const aFormat: TglBitmapFormat; const aBPP: Integer; const aPrec, aShift: TglBitmapRec4ub); overload;
1793 procedure CalcValues;
1794 procedure CreateColorTable;
1796 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1797 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1798 destructor Destroy; override;
1802 LUMINANCE_WEIGHT_R = 0.30;
1803 LUMINANCE_WEIGHT_G = 0.59;
1804 LUMINANCE_WEIGHT_B = 0.11;
1806 ALPHA_WEIGHT_R = 0.30;
1807 ALPHA_WEIGHT_G = 0.59;
1808 ALPHA_WEIGHT_B = 0.11;
1810 DEPTH_WEIGHT_R = 0.333333333;
1811 DEPTH_WEIGHT_G = 0.333333333;
1812 DEPTH_WEIGHT_B = 0.333333333;
1814 FORMAT_DESCRIPTOR_CLASSES: array[TglBitmapFormat] of TFormatDescriptorClass = (
1825 TfdLuminance4Alpha4ub2,
1826 TfdLuminance6Alpha2ub2,
1827 TfdLuminance8Alpha8ub2,
1828 TfdLuminance12Alpha4us2,
1829 TfdLuminance16Alpha16us2,
1888 FormatDescriptorCS: TCriticalSection;
1889 FormatDescriptors: array[TglBitmapFormat] of TFormatDescriptor;
1891 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1892 constructor EglBitmapUnsupportedFormat.Create(const aFormat: TglBitmapFormat);
1894 inherited Create('unsupported format: ' + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
1897 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1898 constructor EglBitmapUnsupportedFormat.Create(const aMsg: String; const aFormat: TglBitmapFormat);
1900 inherited Create(aMsg + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
1903 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1904 function glBitmapPosition(X: Integer; Y: Integer): TglBitmapPixelPosition;
1906 result.Fields := [];
1909 result.Fields := result.Fields + [ffX];
1911 result.Fields := result.Fields + [ffY];
1913 result.X := Max(0, X);
1914 result.Y := Max(0, Y);
1917 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1918 function glBitmapRec4ub(const r, g, b, a: Byte): TglBitmapRec4ub;
1926 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1927 function glBitmapRec4ui(const r, g, b, a: Cardinal): TglBitmapRec4ui;
1935 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1936 function glBitmapRec4ul(const r, g, b, a: QWord): TglBitmapRec4ul;
1944 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1945 function glBitmapRec4ubCompare(const r1, r2: TglBitmapRec4ub): Boolean;
1950 for i := 0 to high(r1.arr) do
1951 if (r1.arr[i] <> r2.arr[i]) then
1956 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1957 function glBitmapRec4uiCompare(const r1, r2: TglBitmapRec4ui): Boolean;
1962 for i := 0 to high(r1.arr) do
1963 if (r1.arr[i] <> r2.arr[i]) then
1968 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1969 function glBitmapCreateTestTexture(const aFormat: TglBitmapFormat): TglBitmap2D;
1971 desc: TFormatDescriptor;
1975 px: TglBitmapPixelData;
1978 desc := TFormatDescriptor.Get(aFormat);
1979 if (desc.IsCompressed) or (desc.glFormat = 0) then
1982 p := GetMemory(ceil(25 * desc.BytesPerPixel)); // 5 x 5 pixel
1983 md := desc.CreateMappingData;
1986 desc.PreparePixel(px);
1988 for x := 0 to 4 do begin
1989 px.Data := glBitmapRec4ui(0, 0, 0, 0);
1990 for i := 0 to 3 do begin
1991 if ((y < 3) and (y = i)) or
1992 ((y = 3) and (i < 3)) or
1993 ((y = 4) and (i = 3))
1995 px.Data.arr[i] := Trunc(px.Range.arr[i] / 4 * x)
1996 else if ((y < 4) and (i = 3)) or
1997 ((y = 4) and (i < 3))
1999 px.Data.arr[i] := px.Range.arr[i]
2001 px.Data.arr[i] := 0; //px.Range.arr[i];
2003 desc.Map(px, tmp, md);
2006 desc.FreeMappingData(md);
2009 result := TglBitmap2D.Create(glBitmapPosition(5, 5), aFormat, p);
2010 result.FreeDataOnDestroy := true;
2011 result.FreeDataAfterGenTexture := false;
2012 result.SetFilter(GL_NEAREST, GL_NEAREST);
2015 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2016 function glBitmapShiftRec(const r, g, b, a: Byte): TglBitmapRec4ub;
2024 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2025 function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes;
2031 tfAlpha4ub1, tfAlpha8ub1,
2032 tfLuminance4ub1, tfLuminance8ub1, tfR3G3B2ub1,
2035 tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
2036 tfRGBX4us1, tfXRGB4us1, tfRGB5X1us1, tfX1RGB5us1, tfR5G6B5us1, tfRGB5A1us1, tfA1RGB5us1, tfRGBA4us1, tfARGB4us1,
2037 tfBGRX4us1, tfXBGR4us1, tfBGR5X1us1, tfX1BGR5us1, tfB5G6R5us1, tfBGR5A1us1, tfA1BGR5us1, tfBGRA4us1, tfABGR4us1,
2040 tfBGR8ub3, tfRGB8ub3,
2043 tfRGBX8ui1, tfXRGB8ui1, tfRGB10X2ui1, tfX2RGB10ui1, tfRGBA8ui1, tfARGB8ui1, tfRGBA8ub4, tfRGB10A2ui1, tfA2RGB10ui1,
2044 tfBGRX8ui1, tfXBGR8ui1, tfBGR10X2ui1, tfX2BGR10ui1, tfBGRA8ui1, tfABGR8ui1, tfBGRA8ub4, tfBGR10A2ui1, tfA2BGR10ui1])
2046 result := result + [ ftBMP ];
2050 tfAlpha4ub1, tfAlpha8ub1, tfLuminance4ub1, tfLuminance8ub1,
2053 tfAlpha16us1, tfLuminance16us1,
2054 tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
2055 tfX1RGB5us1, tfARGB4us1, tfA1RGB5us1, tfDepth16us1,
2061 tfX2RGB10ui1, tfARGB8ui1, tfBGRA8ub4, tfA2RGB10ui1,
2062 tfDepth24ui1, tfDepth32ui1])
2064 result := result + [ftTGA];
2066 if not (aFormat in [tfEmpty, tfRGB16us3, tfBGR16us3]) then
2067 result := result + [ftDDS];
2069 {$IFDEF GLB_SUPPORT_PNG_WRITE}
2071 tfAlpha8ub1, tfLuminance8ub1, tfLuminance8Alpha8ub2,
2072 tfRGB8ub3, tfRGBA8ui1,
2073 tfBGR8ub3, tfBGRA8ui1] then
2074 result := result + [ftPNG];
2077 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
2078 if aFormat in [tfAlpha8ub1, tfLuminance8ub1, tfRGB8ub3, tfBGR8ub3] then
2079 result := result + [ftJPEG];
2083 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2084 function IsPowerOfTwo(aNumber: Integer): Boolean;
2086 while (aNumber and 1) = 0 do
2087 aNumber := aNumber shr 1;
2088 result := aNumber = 1;
2091 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2092 function GetTopMostBit(aBitSet: QWord): Integer;
2095 while aBitSet > 0 do begin
2097 aBitSet := aBitSet shr 1;
2101 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2102 function CountSetBits(aBitSet: QWord): Integer;
2105 while aBitSet > 0 do begin
2106 if (aBitSet and 1) = 1 then
2108 aBitSet := aBitSet shr 1;
2112 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2113 function LuminanceWeight(const aPixel: TglBitmapPixelData): Cardinal;
2116 LUMINANCE_WEIGHT_R * aPixel.Data.r +
2117 LUMINANCE_WEIGHT_G * aPixel.Data.g +
2118 LUMINANCE_WEIGHT_B * aPixel.Data.b);
2121 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2122 function DepthWeight(const aPixel: TglBitmapPixelData): Cardinal;
2125 DEPTH_WEIGHT_R * aPixel.Data.r +
2126 DEPTH_WEIGHT_G * aPixel.Data.g +
2127 DEPTH_WEIGHT_B * aPixel.Data.b);
2130 {$IFDEF GLB_NATIVE_OGL}
2131 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2132 //OpenGLInitialization///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2133 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2135 GL_LibHandle: Pointer = nil;
2137 function glbGetProcAddress(aProcName: PAnsiChar; aLibHandle: Pointer = nil; const aRaiseOnErr: Boolean = true): Pointer;
2139 if not Assigned(aLibHandle) then
2140 aLibHandle := GL_LibHandle;
2142 {$IF DEFINED(GLB_WIN)}
2143 result := GetProcAddress({%H-}HMODULE(aLibHandle), aProcName);
2144 if Assigned(result) then
2147 if Assigned(wglGetProcAddress) then
2148 result := wglGetProcAddress(aProcName);
2149 {$ELSEIF DEFINED(GLB_LINUX)}
2150 if Assigned(glXGetProcAddress) then begin
2151 result := glXGetProcAddress(aProcName);
2152 if Assigned(result) then
2156 if Assigned(glXGetProcAddressARB) then begin
2157 result := glXGetProcAddressARB(aProcName);
2158 if Assigned(result) then
2162 result := dlsym(aLibHandle, aProcName);
2164 if not Assigned(result) and aRaiseOnErr then
2165 raise EglBitmap.Create('unable to load procedure form library: ' + aProcName);
2168 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
2170 GLU_LibHandle: Pointer = nil;
2171 OpenGLInitialized: Boolean;
2172 InitOpenGLCS: TCriticalSection;
2174 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2175 procedure glbInitOpenGL;
2177 ////////////////////////////////////////////////////////////////////////////////
2178 function glbLoadLibrary(const aName: PChar): Pointer;
2180 {$IF DEFINED(GLB_WIN)}
2181 result := {%H-}Pointer(LoadLibrary(aName));
2182 {$ELSEIF DEFINED(GLB_LINUX)}
2183 result := dlopen(Name, RTLD_LAZY);
2189 ////////////////////////////////////////////////////////////////////////////////
2190 function glbFreeLibrary(const aLibHandle: Pointer): Boolean;
2193 if not Assigned(aLibHandle) then
2196 {$IF DEFINED(GLB_WIN)}
2197 Result := FreeLibrary({%H-}HINST(aLibHandle));
2198 {$ELSEIF DEFINED(GLB_LINUX)}
2199 Result := dlclose(aLibHandle) = 0;
2204 if Assigned(GL_LibHandle) then
2205 glbFreeLibrary(GL_LibHandle);
2207 if Assigned(GLU_LibHandle) then
2208 glbFreeLibrary(GLU_LibHandle);
2210 GL_LibHandle := glbLoadLibrary(libopengl);
2211 if not Assigned(GL_LibHandle) then
2212 raise EglBitmap.Create('unable to load library: ' + libopengl);
2214 GLU_LibHandle := glbLoadLibrary(libglu);
2215 if not Assigned(GLU_LibHandle) then
2216 raise EglBitmap.Create('unable to load library: ' + libglu);
2218 {$IF DEFINED(GLB_WIN)}
2219 wglGetProcAddress := glbGetProcAddress('wglGetProcAddress');
2220 {$ELSEIF DEFINED(GLB_LINUX)}
2221 glXGetProcAddress := glbGetProcAddress('glXGetProcAddress');
2222 glXGetProcAddressARB := glbGetProcAddress('glXGetProcAddressARB');
2225 glEnable := glbGetProcAddress('glEnable');
2226 glDisable := glbGetProcAddress('glDisable');
2227 glGetString := glbGetProcAddress('glGetString');
2228 glGetIntegerv := glbGetProcAddress('glGetIntegerv');
2229 glTexParameteri := glbGetProcAddress('glTexParameteri');
2230 glTexParameteriv := glbGetProcAddress('glTexParameteriv');
2231 glTexParameterfv := glbGetProcAddress('glTexParameterfv');
2232 glGetTexParameteriv := glbGetProcAddress('glGetTexParameteriv');
2233 glGetTexParameterfv := glbGetProcAddress('glGetTexParameterfv');
2234 glGetTexLevelParameteriv := glbGetProcAddress('glGetTexLevelParameteriv');
2235 glGetTexLevelParameterfv := glbGetProcAddress('glGetTexLevelParameterfv');
2236 glTexGeni := glbGetProcAddress('glTexGeni');
2237 glGenTextures := glbGetProcAddress('glGenTextures');
2238 glBindTexture := glbGetProcAddress('glBindTexture');
2239 glDeleteTextures := glbGetProcAddress('glDeleteTextures');
2240 glAreTexturesResident := glbGetProcAddress('glAreTexturesResident');
2241 glReadPixels := glbGetProcAddress('glReadPixels');
2242 glPixelStorei := glbGetProcAddress('glPixelStorei');
2243 glTexImage1D := glbGetProcAddress('glTexImage1D');
2244 glTexImage2D := glbGetProcAddress('glTexImage2D');
2245 glGetTexImage := glbGetProcAddress('glGetTexImage');
2247 gluBuild1DMipmaps := glbGetProcAddress('gluBuild1DMipmaps', GLU_LibHandle);
2248 gluBuild2DMipmaps := glbGetProcAddress('gluBuild2DMipmaps', GLU_LibHandle);
2252 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2253 procedure glbReadOpenGLExtensions;
2256 MajorVersion, MinorVersion: Integer;
2258 ///////////////////////////////////////////////////////////////////////////////////////////
2259 procedure TrimVersionString(aBuffer: AnsiString; out aMajor, aMinor: Integer);
2266 Separator := Pos(AnsiString('.'), aBuffer);
2267 if (Separator > 1) and (Separator < Length(aBuffer)) and
2268 (aBuffer[Separator - 1] in ['0'..'9']) and
2269 (aBuffer[Separator + 1] in ['0'..'9']) then begin
2272 while (Separator > 0) and (aBuffer[Separator] in ['0'..'9']) do
2275 Delete(aBuffer, 1, Separator);
2276 Separator := Pos(AnsiString('.'), aBuffer) + 1;
2278 while (Separator <= Length(aBuffer)) and (AnsiChar(aBuffer[Separator]) in ['0'..'9']) do
2281 Delete(aBuffer, Separator, 255);
2282 Separator := Pos(AnsiString('.'), aBuffer);
2284 aMajor := StrToInt(Copy(String(aBuffer), 1, Separator - 1));
2285 aMinor := StrToInt(Copy(String(aBuffer), Separator + 1, 1));
2289 ///////////////////////////////////////////////////////////////////////////////////////////
2290 function CheckExtension(const Extension: AnsiString): Boolean;
2294 ExtPos := Pos(Extension, Buffer);
2295 result := ExtPos > 0;
2297 result := ((ExtPos + Length(Extension) - 1) = Length(Buffer)) or not (Buffer[ExtPos + Length(Extension)] in ['_', 'A'..'Z', 'a'..'z']);
2300 ///////////////////////////////////////////////////////////////////////////////////////////
2301 function CheckVersion(const aMajor, aMinor: Integer): Boolean;
2303 result := (MajorVersion > aMajor) or ((MajorVersion = aMajor) and (MinorVersion >= aMinor));
2307 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
2310 if not OpenGLInitialized then begin
2312 OpenGLInitialized := true;
2320 Buffer := glGetString(GL_VERSION);
2321 TrimVersionString(Buffer, MajorVersion, MinorVersion);
2323 GL_VERSION_1_2 := CheckVersion(1, 2);
2324 GL_VERSION_1_3 := CheckVersion(1, 3);
2325 GL_VERSION_1_4 := CheckVersion(1, 4);
2326 GL_VERSION_2_0 := CheckVersion(2, 0);
2327 GL_VERSION_3_3 := CheckVersion(3, 3);
2330 Buffer := glGetString(GL_EXTENSIONS);
2331 GL_ARB_texture_border_clamp := CheckExtension('GL_ARB_texture_border_clamp');
2332 GL_ARB_texture_non_power_of_two := CheckExtension('GL_ARB_texture_non_power_of_two');
2333 GL_ARB_texture_swizzle := CheckExtension('GL_ARB_texture_swizzle');
2334 GL_ARB_texture_cube_map := CheckExtension('GL_ARB_texture_cube_map');
2335 GL_ARB_texture_rectangle := CheckExtension('GL_ARB_texture_rectangle');
2336 GL_ARB_texture_mirrored_repeat := CheckExtension('GL_ARB_texture_mirrored_repeat');
2337 GL_EXT_texture_edge_clamp := CheckExtension('GL_EXT_texture_edge_clamp');
2338 GL_EXT_texture_filter_anisotropic := CheckExtension('GL_EXT_texture_filter_anisotropic');
2339 GL_EXT_texture_rectangle := CheckExtension('GL_EXT_texture_rectangle');
2340 GL_EXT_texture_swizzle := CheckExtension('GL_EXT_texture_swizzle');
2341 GL_EXT_texture_cube_map := CheckExtension('GL_EXT_texture_cube_map');
2342 GL_NV_texture_rectangle := CheckExtension('GL_NV_texture_rectangle');
2343 GL_IBM_texture_mirrored_repeat := CheckExtension('GL_IBM_texture_mirrored_repeat');
2344 GL_SGIS_generate_mipmap := CheckExtension('GL_SGIS_generate_mipmap');
2346 if GL_VERSION_1_3 then begin
2347 glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1D');
2348 glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2D');
2349 glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImage');
2351 glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1DARB', nil, false);
2352 glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2DARB', nil, false);
2353 glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImageARB', nil, false);
2358 {$IFDEF GLB_SDL_IMAGE}
2359 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2360 // SDL Image Helper /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2361 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2362 function glBitmapRWseek(context: PSDL_RWops; offset: Integer; whence: Integer): Integer; cdecl;
2364 result := TStream(context^.unknown.data1).Seek(offset, whence);
2367 function glBitmapRWread(context: PSDL_RWops; Ptr: Pointer; size: Integer; maxnum : Integer): Integer; cdecl;
2369 result := TStream(context^.unknown.data1).Read(Ptr^, size * maxnum);
2372 function glBitmapRWwrite(context: PSDL_RWops; Ptr: Pointer; size: Integer; num: Integer): Integer; cdecl;
2374 result := TStream(context^.unknown.data1).Write(Ptr^, size * num);
2377 function glBitmapRWclose(context: PSDL_RWops): Integer; cdecl;
2382 function glBitmapCreateRWops(Stream: TStream): PSDL_RWops;
2384 result := SDL_AllocRW;
2386 if result = nil then
2387 raise EglBitmap.Create('glBitmapCreateRWops - SDL_AllocRW failed.');
2389 result^.seek := glBitmapRWseek;
2390 result^.read := glBitmapRWread;
2391 result^.write := glBitmapRWwrite;
2392 result^.close := glBitmapRWclose;
2393 result^.unknown.data1 := Stream;
2397 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2398 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
2400 glBitmapDefaultDeleteTextureOnFree := aDeleteTextureOnFree;
2403 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2404 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
2406 glBitmapDefaultFreeDataAfterGenTextures := aFreeData;
2409 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2410 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
2412 glBitmapDefaultMipmap := aValue;
2415 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2416 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
2418 glBitmapDefaultFormat := aFormat;
2421 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2422 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
2424 glBitmapDefaultFilterMin := aMin;
2425 glBitmapDefaultFilterMag := aMag;
2428 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2429 procedure glBitmapSetDefaultWrap(const S: Cardinal = GL_CLAMP_TO_EDGE; const T: Cardinal = GL_CLAMP_TO_EDGE; const R: Cardinal = GL_CLAMP_TO_EDGE);
2431 glBitmapDefaultWrapS := S;
2432 glBitmapDefaultWrapT := T;
2433 glBitmapDefaultWrapR := R;
2436 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2437 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
2438 procedure glBitmapSetDefaultSwizzle(const r: GLenum = GL_RED; g: GLenum = GL_GREEN; b: GLenum = GL_BLUE; a: GLenum = GL_ALPHA);
2440 glDefaultSwizzle[0] := r;
2441 glDefaultSwizzle[1] := g;
2442 glDefaultSwizzle[2] := b;
2443 glDefaultSwizzle[3] := a;
2447 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2448 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
2450 result := glBitmapDefaultDeleteTextureOnFree;
2453 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2454 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
2456 result := glBitmapDefaultFreeDataAfterGenTextures;
2459 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2460 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
2462 result := glBitmapDefaultMipmap;
2465 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2466 function glBitmapGetDefaultFormat: TglBitmapFormat;
2468 result := glBitmapDefaultFormat;
2471 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2472 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
2474 aMin := glBitmapDefaultFilterMin;
2475 aMag := glBitmapDefaultFilterMag;
2478 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2479 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
2481 S := glBitmapDefaultWrapS;
2482 T := glBitmapDefaultWrapT;
2483 R := glBitmapDefaultWrapR;
2487 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2488 procedure glBitmapGetDefaultSwizzle(var r, g, b, a: GLenum);
2490 r := glDefaultSwizzle[0];
2491 g := glDefaultSwizzle[1];
2492 b := glDefaultSwizzle[2];
2493 a := glDefaultSwizzle[3];
2497 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2498 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2499 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2500 function TFormatDescriptor.GetSize(const aSize: TglBitmapPixelPosition): Integer;
2504 if (ffX in aSize.Fields) or (ffY in aSize.Fields) then begin
2505 w := Max(1, aSize.X);
2506 h := Max(1, aSize.Y);
2507 result := GetSize(w, h);
2512 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2513 function TFormatDescriptor.GetSize(const aWidth, aHeight: Integer): Integer;
2516 if (aWidth <= 0) or (aHeight <= 0) then
2518 result := Ceil(aWidth * aHeight * BytesPerPixel);
2521 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2522 function TFormatDescriptor.CreateMappingData: Pointer;
2527 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2528 procedure TFormatDescriptor.FreeMappingData(var aMappingData: Pointer);
2533 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2534 function TFormatDescriptor.IsEmpty: Boolean;
2536 result := (fFormat = tfEmpty);
2539 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2540 function TFormatDescriptor.MaskMatch(const aMask: TglBitmapRec4ul): Boolean;
2546 if (aMask.r = 0) and (aMask.g = 0) and (aMask.b = 0) and (aMask.a = 0) then
2547 raise EglBitmap.Create('FormatCheckFormat - All Masks are 0');
2550 if (aMask.arr[i] <> m.arr[i]) then
2555 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2556 procedure TFormatDescriptor.PreparePixel(out aPixel: TglBitmapPixelData);
2558 FillChar(aPixel{%H-}, SizeOf(aPixel), 0);
2559 aPixel.Data := Range;
2560 aPixel.Format := fFormat;
2561 aPixel.Range := Range;
2564 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2565 constructor TFormatDescriptor.Create;
2570 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2571 //TfdAlpha_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2572 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2573 procedure TfdAlphaUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2575 aData^ := aPixel.Data.a;
2579 procedure TfdAlphaUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2584 aPixel.Data.a := aData^;
2588 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2589 //TfdLuminance_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2590 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2591 procedure TfdLuminanceUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2593 aData^ := LuminanceWeight(aPixel);
2597 procedure TfdLuminanceUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2599 aPixel.Data.r := aData^;
2600 aPixel.Data.g := aData^;
2601 aPixel.Data.b := aData^;
2606 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2607 //TfdUniversal_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2608 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2609 procedure TfdUniversalUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2615 if (Range.arr[i] > 0) then
2616 aData^ := aData^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
2620 procedure TfdUniversalUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2625 aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and Range.arr[i];
2629 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2630 //TfdLuminanceAlpha_UB2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2631 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2632 procedure TfdLuminanceAlphaUB2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2634 inherited Map(aPixel, aData, aMapData);
2635 aData^ := aPixel.Data.a;
2639 procedure TfdLuminanceAlphaUB2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2641 inherited Unmap(aData, aPixel, aMapData);
2642 aPixel.Data.a := aData^;
2646 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2647 //TfdRGB_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2648 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2649 procedure TfdRGBub3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2651 aData^ := aPixel.Data.r;
2653 aData^ := aPixel.Data.g;
2655 aData^ := aPixel.Data.b;
2659 procedure TfdRGBub3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2661 aPixel.Data.r := aData^;
2663 aPixel.Data.g := aData^;
2665 aPixel.Data.b := aData^;
2670 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2671 //TfdBGR_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2672 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2673 procedure TfdBGRub3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2675 aData^ := aPixel.Data.b;
2677 aData^ := aPixel.Data.g;
2679 aData^ := aPixel.Data.r;
2683 procedure TfdBGRub3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2685 aPixel.Data.b := aData^;
2687 aPixel.Data.g := aData^;
2689 aPixel.Data.r := aData^;
2694 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2695 //TfdRGBA_UB4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2696 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2697 procedure TfdRGBAub4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2699 inherited Map(aPixel, aData, aMapData);
2700 aData^ := aPixel.Data.a;
2704 procedure TfdRGBAub4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2706 inherited Unmap(aData, aPixel, aMapData);
2707 aPixel.Data.a := aData^;
2711 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2712 //TfdBGRA_UB4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2713 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2714 procedure TfdBGRAub4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2716 inherited Map(aPixel, aData, aMapData);
2717 aData^ := aPixel.Data.a;
2721 procedure TfdBGRAub4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2723 inherited Unmap(aData, aPixel, aMapData);
2724 aPixel.Data.a := aData^;
2728 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2729 //TfdAlpha_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2730 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2731 procedure TfdAlphaUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2733 PWord(aData)^ := aPixel.Data.a;
2737 procedure TfdAlphaUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2742 aPixel.Data.a := PWord(aData)^;
2746 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2747 //TfdLuminance_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2748 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2749 procedure TfdLuminanceUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2751 PWord(aData)^ := LuminanceWeight(aPixel);
2755 procedure TfdLuminanceUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2757 aPixel.Data.r := PWord(aData)^;
2758 aPixel.Data.g := PWord(aData)^;
2759 aPixel.Data.b := PWord(aData)^;
2764 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2765 //TfdUniversal_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2766 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2767 procedure TfdUniversalUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2773 if (Range.arr[i] > 0) then
2774 PWord(aData)^ := PWord(aData)^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
2778 procedure TfdUniversalUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2783 aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and Range.arr[i];
2787 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2788 //TfdDepth_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2789 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2790 procedure TfdDepthUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2792 PWord(aData)^ := DepthWeight(aPixel);
2796 procedure TfdDepthUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2798 aPixel.Data.r := PWord(aData)^;
2799 aPixel.Data.g := PWord(aData)^;
2800 aPixel.Data.b := PWord(aData)^;
2801 aPixel.Data.a := PWord(aData)^;;
2805 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2806 //TfdLuminanceAlpha_US2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2807 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2808 procedure TfdLuminanceAlphaUS2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2810 inherited Map(aPixel, aData, aMapData);
2811 PWord(aData)^ := aPixel.Data.a;
2815 procedure TfdLuminanceAlphaUS2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2817 inherited Unmap(aData, aPixel, aMapData);
2818 aPixel.Data.a := PWord(aData)^;
2822 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2823 //TfdRGB_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2824 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2825 procedure TfdRGBus3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2827 PWord(aData)^ := aPixel.Data.r;
2829 PWord(aData)^ := aPixel.Data.g;
2831 PWord(aData)^ := aPixel.Data.b;
2835 procedure TfdRGBus3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2837 aPixel.Data.r := PWord(aData)^;
2839 aPixel.Data.g := PWord(aData)^;
2841 aPixel.Data.b := PWord(aData)^;
2846 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2847 //TfdBGR_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2848 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2849 procedure TfdBGRus3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2851 PWord(aData)^ := aPixel.Data.b;
2853 PWord(aData)^ := aPixel.Data.g;
2855 PWord(aData)^ := aPixel.Data.r;
2859 procedure TfdBGRus3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2861 aPixel.Data.b := PWord(aData)^;
2863 aPixel.Data.g := PWord(aData)^;
2865 aPixel.Data.r := PWord(aData)^;
2870 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2871 //TfdRGBA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2872 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2873 procedure TfdRGBAus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2875 inherited Map(aPixel, aData, aMapData);
2876 PWord(aData)^ := aPixel.Data.a;
2880 procedure TfdRGBAus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2882 inherited Unmap(aData, aPixel, aMapData);
2883 aPixel.Data.a := PWord(aData)^;
2887 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2888 //TfdARGB_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2889 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2890 procedure TfdARGBus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2892 PWord(aData)^ := aPixel.Data.a;
2894 inherited Map(aPixel, aData, aMapData);
2897 procedure TfdARGBus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2899 aPixel.Data.a := PWord(aData)^;
2901 inherited Unmap(aData, aPixel, aMapData);
2904 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2905 //TfdBGRA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2906 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2907 procedure TfdBGRAus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2909 inherited Map(aPixel, aData, aMapData);
2910 PWord(aData)^ := aPixel.Data.a;
2914 procedure TfdBGRAus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2916 inherited Unmap(aData, aPixel, aMapData);
2917 aPixel.Data.a := PWord(aData)^;
2921 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2922 //TfdABGR_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2923 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2924 procedure TfdABGRus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2926 PWord(aData)^ := aPixel.Data.a;
2928 inherited Map(aPixel, aData, aMapData);
2931 procedure TfdABGRus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2933 aPixel.Data.a := PWord(aData)^;
2935 inherited Unmap(aData, aPixel, aMapData);
2938 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2939 //TfdUniversal_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2940 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2941 procedure TfdUniversalUI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2945 PCardinal(aData)^ := 0;
2947 if (Range.arr[i] > 0) then
2948 PCardinal(aData)^ := PCardinal(aData)^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
2952 procedure TfdUniversalUI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2957 aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and Range.arr[i];
2961 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2962 //TfdDepth_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2963 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2964 procedure TfdDepthUI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2966 PCardinal(aData)^ := DepthWeight(aPixel);
2970 procedure TfdDepthUI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2972 aPixel.Data.r := PCardinal(aData)^;
2973 aPixel.Data.g := PCardinal(aData)^;
2974 aPixel.Data.b := PCardinal(aData)^;
2975 aPixel.Data.a := PCardinal(aData)^;
2979 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2980 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2981 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2982 procedure TfdAlpha4ub1.SetValues;
2984 inherited SetValues;
2986 fFormat := tfAlpha4ub1;
2987 fWithAlpha := tfAlpha4ub1;
2988 fPrecision := glBitmapRec4ub(0, 0, 0, 8);
2989 fShift := glBitmapRec4ub(0, 0, 0, 0);
2991 fOpenGLFormat := tfAlpha4ub1;
2992 fglFormat := GL_ALPHA;
2993 fglInternalFormat := GL_ALPHA4;
2994 fglDataFormat := GL_UNSIGNED_BYTE;
2996 fOpenGLFormat := tfAlpha8ub1;
3000 procedure TfdAlpha8ub1.SetValues;
3002 inherited SetValues;
3004 fFormat := tfAlpha8ub1;
3005 fWithAlpha := tfAlpha8ub1;
3006 fPrecision := glBitmapRec4ub(0, 0, 0, 8);
3007 fShift := glBitmapRec4ub(0, 0, 0, 0);
3008 fOpenGLFormat := tfAlpha8ub1;
3009 fglFormat := GL_ALPHA;
3010 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_ALPHA8{$ELSE}GL_ALPHA{$ENDIF};
3011 fglDataFormat := GL_UNSIGNED_BYTE;
3014 procedure TfdAlpha16us1.SetValues;
3016 inherited SetValues;
3017 fBitsPerPixel := 16;
3018 fFormat := tfAlpha16us1;
3019 fWithAlpha := tfAlpha16us1;
3020 fPrecision := glBitmapRec4ub(0, 0, 0, 16);
3021 fShift := glBitmapRec4ub(0, 0, 0, 0);
3023 fOpenGLFormat := tfAlpha16us1;
3024 fglFormat := GL_ALPHA;
3025 fglInternalFormat := GL_ALPHA16;
3026 fglDataFormat := GL_UNSIGNED_SHORT;
3028 fOpenGLFormat := tfAlpha8ub1;
3032 procedure TfdLuminance4ub1.SetValues;
3034 inherited SetValues;
3036 fFormat := tfLuminance4ub1;
3037 fWithAlpha := tfLuminance4Alpha4ub2;
3038 fWithoutAlpha := tfLuminance4ub1;
3039 fPrecision := glBitmapRec4ub(8, 8, 8, 0);
3040 fShift := glBitmapRec4ub(0, 0, 0, 0);
3042 fOpenGLFormat := tfLuminance4ub1;
3043 fglFormat := GL_LUMINANCE;
3044 fglInternalFormat := GL_LUMINANCE4;
3045 fglDataFormat := GL_UNSIGNED_BYTE;
3047 fOpenGLFormat := tfLuminance8ub1;
3051 procedure TfdLuminance8ub1.SetValues;
3053 inherited SetValues;
3055 fFormat := tfLuminance8ub1;
3056 fWithAlpha := tfLuminance8Alpha8ub2;
3057 fWithoutAlpha := tfLuminance8ub1;
3058 fOpenGLFormat := tfLuminance8ub1;
3059 fPrecision := glBitmapRec4ub(8, 8, 8, 0);
3060 fShift := glBitmapRec4ub(0, 0, 0, 0);
3061 fglFormat := GL_LUMINANCE;
3062 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_LUMINANCE8{$ELSE}GL_LUMINANCE{$ENDIF};
3063 fglDataFormat := GL_UNSIGNED_BYTE;
3066 procedure TfdLuminance16us1.SetValues;
3068 inherited SetValues;
3069 fBitsPerPixel := 16;
3070 fFormat := tfLuminance16us1;
3071 fWithAlpha := tfLuminance16Alpha16us2;
3072 fWithoutAlpha := tfLuminance16us1;
3073 fPrecision := glBitmapRec4ub(16, 16, 16, 0);
3074 fShift := glBitmapRec4ub( 0, 0, 0, 0);
3076 fOpenGLFormat := tfLuminance16us1;
3077 fglFormat := GL_LUMINANCE;
3078 fglInternalFormat := GL_LUMINANCE16;
3079 fglDataFormat := GL_UNSIGNED_SHORT;
3081 fOpenGLFormat := tfLuminance8ub1;
3085 procedure TfdLuminance4Alpha4ub2.SetValues;
3087 inherited SetValues;
3088 fBitsPerPixel := 16;
3089 fFormat := tfLuminance4Alpha4ub2;
3090 fWithAlpha := tfLuminance4Alpha4ub2;
3091 fWithoutAlpha := tfLuminance4ub1;
3092 fPrecision := glBitmapRec4ub(8, 8, 8, 8);
3093 fShift := glBitmapRec4ub(0, 0, 0, 8);
3095 fOpenGLFormat := tfLuminance4Alpha4ub2;
3096 fglFormat := GL_LUMINANCE_ALPHA;
3097 fglInternalFormat := GL_LUMINANCE4_ALPHA4;
3098 fglDataFormat := GL_UNSIGNED_BYTE;
3100 fOpenGLFormat := tfLuminance8Alpha8ub2;
3104 procedure TfdLuminance6Alpha2ub2.SetValues;
3106 inherited SetValues;
3107 fBitsPerPixel := 16;
3108 fFormat := tfLuminance6Alpha2ub2;
3109 fWithAlpha := tfLuminance6Alpha2ub2;
3110 fWithoutAlpha := tfLuminance8ub1;
3111 fPrecision := glBitmapRec4ub(8, 8, 8, 8);
3112 fShift := glBitmapRec4ub(0, 0, 0, 8);
3114 fOpenGLFormat := tfLuminance6Alpha2ub2;
3115 fglFormat := GL_LUMINANCE_ALPHA;
3116 fglInternalFormat := GL_LUMINANCE6_ALPHA2;
3117 fglDataFormat := GL_UNSIGNED_BYTE;
3119 fOpenGLFormat := tfLuminance8Alpha8ub2;
3123 procedure TfdLuminance8Alpha8ub2.SetValues;
3125 inherited SetValues;
3126 fBitsPerPixel := 16;
3127 fFormat := tfLuminance8Alpha8ub2;
3128 fWithAlpha := tfLuminance8Alpha8ub2;
3129 fWithoutAlpha := tfLuminance8ub1;
3130 fOpenGLFormat := tfLuminance8Alpha8ub2;
3131 fPrecision := glBitmapRec4ub(8, 8, 8, 8);
3132 fShift := glBitmapRec4ub(0, 0, 0, 8);
3133 fglFormat := GL_LUMINANCE_ALPHA;
3134 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_LUMINANCE8_ALPHA8{$ELSE}GL_LUMINANCE_ALPHA{$ENDIF};
3135 fglDataFormat := GL_UNSIGNED_BYTE;
3138 procedure TfdLuminance12Alpha4us2.SetValues;
3140 inherited SetValues;
3141 fBitsPerPixel := 32;
3142 fFormat := tfLuminance12Alpha4us2;
3143 fWithAlpha := tfLuminance12Alpha4us2;
3144 fWithoutAlpha := tfLuminance16us1;
3145 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3146 fShift := glBitmapRec4ub( 0, 0, 0, 16);
3148 fOpenGLFormat := tfLuminance12Alpha4us2;
3149 fglFormat := GL_LUMINANCE_ALPHA;
3150 fglInternalFormat := GL_LUMINANCE12_ALPHA4;
3151 fglDataFormat := GL_UNSIGNED_SHORT;
3153 fOpenGLFormat := tfLuminance8Alpha8ub2;
3157 procedure TfdLuminance16Alpha16us2.SetValues;
3159 inherited SetValues;
3160 fBitsPerPixel := 32;
3161 fFormat := tfLuminance16Alpha16us2;
3162 fWithAlpha := tfLuminance16Alpha16us2;
3163 fWithoutAlpha := tfLuminance16us1;
3164 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3165 fShift := glBitmapRec4ub( 0, 0, 0, 16);
3167 fOpenGLFormat := tfLuminance16Alpha16us2;
3168 fglFormat := GL_LUMINANCE_ALPHA;
3169 fglInternalFormat := GL_LUMINANCE16_ALPHA16;
3170 fglDataFormat := GL_UNSIGNED_SHORT;
3172 fOpenGLFormat := tfLuminance8Alpha8ub2;
3176 procedure TfdR3G3B2ub1.SetValues;
3178 inherited SetValues;
3180 fFormat := tfR3G3B2ub1;
3181 fWithAlpha := tfRGBA4us1;
3182 fWithoutAlpha := tfR3G3B2ub1;
3183 fRGBInverted := tfEmpty;
3184 fPrecision := glBitmapRec4ub(3, 3, 2, 0);
3185 fShift := glBitmapRec4ub(5, 2, 0, 0);
3187 fOpenGLFormat := tfR3G3B2ub1;
3188 fglFormat := GL_RGB;
3189 fglInternalFormat := GL_R3_G3_B2;
3190 fglDataFormat := GL_UNSIGNED_BYTE_3_3_2;
3192 fOpenGLFormat := tfR5G6B5us1;
3196 procedure TfdRGBX4us1.SetValues;
3198 inherited SetValues;
3199 fBitsPerPixel := 16;
3200 fFormat := tfRGBX4us1;
3201 fWithAlpha := tfRGBA4us1;
3202 fWithoutAlpha := tfRGBX4us1;
3203 fRGBInverted := tfBGRX4us1;
3204 fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
3205 fShift := glBitmapRec4ub(12, 8, 4, 0);
3207 fOpenGLFormat := tfRGBX4us1;
3208 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3209 fglInternalFormat := GL_RGB4;
3210 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3212 fOpenGLFormat := tfR5G6B5us1;
3216 procedure TfdXRGB4us1.SetValues;
3218 inherited SetValues;
3219 fBitsPerPixel := 16;
3220 fFormat := tfXRGB4us1;
3221 fWithAlpha := tfARGB4us1;
3222 fWithoutAlpha := tfXRGB4us1;
3223 fRGBInverted := tfXBGR4us1;
3224 fPrecision := glBitmapRec4ub(4, 4, 4, 0);
3225 fShift := glBitmapRec4ub(8, 4, 0, 0);
3227 fOpenGLFormat := tfXRGB4us1;
3228 fglFormat := GL_BGRA;
3229 fglInternalFormat := GL_RGB4;
3230 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3232 fOpenGLFormat := tfR5G6B5us1;
3236 procedure TfdR5G6B5us1.SetValues;
3238 inherited SetValues;
3239 fBitsPerPixel := 16;
3240 fFormat := tfR5G6B5us1;
3241 fWithAlpha := tfRGB5A1us1;
3242 fWithoutAlpha := tfR5G6B5us1;
3243 fRGBInverted := tfB5G6R5us1;
3244 fPrecision := glBitmapRec4ub( 5, 6, 5, 0);
3245 fShift := glBitmapRec4ub(11, 5, 0, 0);
3246 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
3247 fOpenGLFormat := tfR5G6B5us1;
3248 fglFormat := GL_RGB;
3249 fglInternalFormat := GL_RGB565;
3250 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5;
3252 fOpenGLFormat := tfRGB8ub3;
3256 procedure TfdRGB5X1us1.SetValues;
3258 inherited SetValues;
3259 fBitsPerPixel := 16;
3260 fFormat := tfRGB5X1us1;
3261 fWithAlpha := tfRGB5A1us1;
3262 fWithoutAlpha := tfRGB5X1us1;
3263 fRGBInverted := tfBGR5X1us1;
3264 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
3265 fShift := glBitmapRec4ub(11, 6, 1, 0);
3267 fOpenGLFormat := tfRGB5X1us1;
3268 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3269 fglInternalFormat := GL_RGB5;
3270 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3272 fOpenGLFormat := tfR5G6B5us1;
3276 procedure TfdX1RGB5us1.SetValues;
3278 inherited SetValues;
3279 fBitsPerPixel := 16;
3280 fFormat := tfX1RGB5us1;
3281 fWithAlpha := tfA1RGB5us1;
3282 fWithoutAlpha := tfX1RGB5us1;
3283 fRGBInverted := tfX1BGR5us1;
3284 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
3285 fShift := glBitmapRec4ub(10, 5, 0, 0);
3287 fOpenGLFormat := tfX1RGB5us1;
3288 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3289 fglInternalFormat := GL_RGB5;
3290 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3292 fOpenGLFormat := tfR5G6B5us1;
3296 procedure TfdRGB8ub3.SetValues;
3298 inherited SetValues;
3299 fBitsPerPixel := 24;
3300 fFormat := tfRGB8ub3;
3301 fWithAlpha := tfRGBA8ub4;
3302 fWithoutAlpha := tfRGB8ub3;
3303 fRGBInverted := tfBGR8ub3;
3304 fPrecision := glBitmapRec4ub(8, 8, 8, 0);
3305 fShift := glBitmapRec4ub(0, 8, 16, 0);
3306 fOpenGLFormat := tfRGB8ub3;
3307 fglFormat := GL_RGB;
3308 fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}GL_RGB8{$ELSE}GL_RGB{$IFEND};
3309 fglDataFormat := GL_UNSIGNED_BYTE;
3312 procedure TfdRGBX8ui1.SetValues;
3314 inherited SetValues;
3315 fBitsPerPixel := 32;
3316 fFormat := tfRGBX8ui1;
3317 fWithAlpha := tfRGBA8ui1;
3318 fWithoutAlpha := tfRGBX8ui1;
3319 fRGBInverted := tfBGRX8ui1;
3320 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3321 fShift := glBitmapRec4ub(24, 16, 8, 0);
3323 fOpenGLFormat := tfRGBX8ui1;
3324 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3325 fglInternalFormat := GL_RGB8;
3326 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3328 fOpenGLFormat := tfRGB8ub3;
3332 procedure TfdXRGB8ui1.SetValues;
3334 inherited SetValues;
3335 fBitsPerPixel := 32;
3336 fFormat := tfXRGB8ui1;
3337 fWithAlpha := tfXRGB8ui1;
3338 fWithoutAlpha := tfXRGB8ui1;
3339 fOpenGLFormat := tfXRGB8ui1;
3340 fRGBInverted := tfXBGR8ui1;
3341 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3342 fShift := glBitmapRec4ub(16, 8, 0, 0);
3344 fOpenGLFormat := tfXRGB8ui1;
3345 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3346 fglInternalFormat := GL_RGB8;
3347 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3349 fOpenGLFormat := tfRGB8ub3;
3353 procedure TfdRGB10X2ui1.SetValues;
3355 inherited SetValues;
3356 fBitsPerPixel := 32;
3357 fFormat := tfRGB10X2ui1;
3358 fWithAlpha := tfRGB10A2ui1;
3359 fWithoutAlpha := tfRGB10X2ui1;
3360 fRGBInverted := tfBGR10X2ui1;
3361 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3362 fShift := glBitmapRec4ub(22, 12, 2, 0);
3364 fOpenGLFormat := tfRGB10X2ui1;
3365 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3366 fglInternalFormat := GL_RGB10;
3367 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3369 fOpenGLFormat := tfRGB16us3;
3373 procedure TfdX2RGB10ui1.SetValues;
3375 inherited SetValues;
3376 fBitsPerPixel := 32;
3377 fFormat := tfX2RGB10ui1;
3378 fWithAlpha := tfA2RGB10ui1;
3379 fWithoutAlpha := tfX2RGB10ui1;
3380 fRGBInverted := tfX2BGR10ui1;
3381 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3382 fShift := glBitmapRec4ub(20, 10, 0, 0);
3384 fOpenGLFormat := tfX2RGB10ui1;
3385 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3386 fglInternalFormat := GL_RGB10;
3387 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3389 fOpenGLFormat := tfRGB16us3;
3393 procedure TfdRGB16us3.SetValues;
3395 inherited SetValues;
3396 fBitsPerPixel := 48;
3397 fFormat := tfRGB16us3;
3398 fWithAlpha := tfRGBA16us4;
3399 fWithoutAlpha := tfRGB16us3;
3400 fRGBInverted := tfBGR16us3;
3401 fPrecision := glBitmapRec4ub(16, 16, 16, 0);
3402 fShift := glBitmapRec4ub( 0, 16, 32, 0);
3403 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
3404 fOpenGLFormat := tfRGB16us3;
3405 fglFormat := GL_RGB;
3406 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_RGB16{$ELSE}GL_RGB16UI{$ENDIF};
3407 fglDataFormat := GL_UNSIGNED_SHORT;
3409 fOpenGLFormat := tfRGB8ub3;
3413 procedure TfdRGBA4us1.SetValues;
3415 inherited SetValues;
3416 fBitsPerPixel := 16;
3417 fFormat := tfRGBA4us1;
3418 fWithAlpha := tfRGBA4us1;
3419 fWithoutAlpha := tfRGBX4us1;
3420 fOpenGLFormat := tfRGBA4us1;
3421 fRGBInverted := tfBGRA4us1;
3422 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3423 fShift := glBitmapRec4ub(12, 8, 4, 0);
3424 fglFormat := GL_RGBA;
3425 fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}GL_RGBA8{$ELSE}GL_RGBA{$IFEND};
3426 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3429 procedure TfdARGB4us1.SetValues;
3431 inherited SetValues;
3432 fBitsPerPixel := 16;
3433 fFormat := tfARGB4us1;
3434 fWithAlpha := tfARGB4us1;
3435 fWithoutAlpha := tfXRGB4us1;
3436 fRGBInverted := tfABGR4us1;
3437 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3438 fShift := glBitmapRec4ub( 8, 4, 0, 12);
3440 fOpenGLFormat := tfARGB4us1;
3441 fglFormat := GL_BGRA;
3442 fglInternalFormat := GL_RGBA4;
3443 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3445 fOpenGLFormat := tfRGBA4us1;
3449 procedure TfdRGB5A1us1.SetValues;
3451 inherited SetValues;
3452 fBitsPerPixel := 16;
3453 fFormat := tfRGB5A1us1;
3454 fWithAlpha := tfRGB5A1us1;
3455 fWithoutAlpha := tfRGB5X1us1;
3456 fOpenGLFormat := tfRGB5A1us1;
3457 fRGBInverted := tfBGR5A1us1;
3458 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3459 fShift := glBitmapRec4ub(11, 6, 1, 0);
3460 fglFormat := GL_RGBA;
3461 fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}GL_RGB5_A1{$ELSE}GL_RGBA{$IFEND};
3462 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3465 procedure TfdA1RGB5us1.SetValues;
3467 inherited SetValues;
3468 fBitsPerPixel := 16;
3469 fFormat := tfA1RGB5us1;
3470 fWithAlpha := tfA1RGB5us1;
3471 fWithoutAlpha := tfX1RGB5us1;
3472 fRGBInverted := tfA1BGR5us1;
3473 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3474 fShift := glBitmapRec4ub(10, 5, 0, 15);
3476 fOpenGLFormat := tfA1RGB5us1;
3477 fglFormat := GL_BGRA;
3478 fglInternalFormat := GL_RGB5_A1;
3479 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3481 fOpenGLFormat := tfRGB5A1us1;
3485 procedure TfdRGBA8ui1.SetValues;
3487 inherited SetValues;
3488 fBitsPerPixel := 32;
3489 fFormat := tfRGBA8ui1;
3490 fWithAlpha := tfRGBA8ui1;
3491 fWithoutAlpha := tfRGBX8ui1;
3492 fRGBInverted := tfBGRA8ui1;
3493 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3494 fShift := glBitmapRec4ub(24, 16, 8, 0);
3496 fOpenGLFormat := tfRGBA8ui1;
3497 fglFormat := GL_RGBA;
3498 fglInternalFormat := GL_RGBA8;
3499 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3501 fOpenGLFormat := tfRGBA8ub4;
3505 procedure TfdARGB8ui1.SetValues;
3507 inherited SetValues;
3508 fBitsPerPixel := 32;
3509 fFormat := tfARGB8ui1;
3510 fWithAlpha := tfARGB8ui1;
3511 fWithoutAlpha := tfXRGB8ui1;
3512 fRGBInverted := tfABGR8ui1;
3513 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3514 fShift := glBitmapRec4ub(16, 8, 0, 24);
3516 fOpenGLFormat := tfARGB8ui1;
3517 fglFormat := GL_BGRA;
3518 fglInternalFormat := GL_RGBA8;
3519 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3521 fOpenGLFormat := tfRGBA8ub4;
3525 procedure TfdRGBA8ub4.SetValues;
3527 inherited SetValues;
3528 fBitsPerPixel := 32;
3529 fFormat := tfRGBA8ub4;
3530 fWithAlpha := tfRGBA8ub4;
3531 fWithoutAlpha := tfRGB8ub3;
3532 fOpenGLFormat := tfRGBA8ub4;
3533 fRGBInverted := tfBGRA8ub4;
3534 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3535 fShift := glBitmapRec4ub( 0, 8, 16, 24);
3536 fglFormat := GL_RGBA;
3537 fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}GL_RGBA8{$ELSE}GL_RGBA{$IFEND};
3538 fglDataFormat := GL_UNSIGNED_BYTE;
3541 procedure TfdRGB10A2ui1.SetValues;
3543 inherited SetValues;
3544 fBitsPerPixel := 32;
3545 fFormat := tfRGB10A2ui1;
3546 fWithAlpha := tfRGB10A2ui1;
3547 fWithoutAlpha := tfRGB10X2ui1;
3548 fRGBInverted := tfBGR10A2ui1;
3549 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3550 fShift := glBitmapRec4ub(22, 12, 2, 0);
3552 fOpenGLFormat := tfRGB10A2ui1;
3553 fglFormat := GL_RGBA;
3554 fglInternalFormat := GL_RGB10_A2;
3555 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3557 fOpenGLFormat := tfA2RGB10ui1;
3561 procedure TfdA2RGB10ui1.SetValues;
3563 inherited SetValues;
3564 fBitsPerPixel := 32;
3565 fFormat := tfA2RGB10ui1;
3566 fWithAlpha := tfA2RGB10ui1;
3567 fWithoutAlpha := tfX2RGB10ui1;
3568 fRGBInverted := tfA2BGR10ui1;
3569 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3570 fShift := glBitmapRec4ub(20, 10, 0, 30);
3571 {$IF NOT DEFINED(OPENGL_ES)}
3572 fOpenGLFormat := tfA2RGB10ui1;
3573 fglFormat := GL_BGRA;
3574 fglInternalFormat := GL_RGB10_A2;
3575 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3576 {$ELSEIF DEFINED(OPENGL_ES_3_0)}
3577 fOpenGLFormat := tfA2RGB10ui1;
3578 fglFormat := GL_RGBA;
3579 fglInternalFormat := GL_RGB10_A2;
3580 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3582 fOpenGLFormat := tfRGBA8ui1;
3586 procedure TfdRGBA16us4.SetValues;
3588 inherited SetValues;
3589 fBitsPerPixel := 64;
3590 fFormat := tfRGBA16us4;
3591 fWithAlpha := tfRGBA16us4;
3592 fWithoutAlpha := tfRGB16us3;
3593 fRGBInverted := tfBGRA16us4;
3594 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3595 fShift := glBitmapRec4ub( 0, 16, 32, 48);
3596 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
3597 fOpenGLFormat := tfRGBA16us4;
3598 fglFormat := GL_RGBA;
3599 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_RGBA16{$ELSE}GL_RGBA16UI{$ENDIF};
3600 fglDataFormat := GL_UNSIGNED_SHORT;
3602 fOpenGLFormat := tfRGBA8ub4;
3606 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3607 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3608 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3609 procedure TfdBGRX4us1.SetValues;
3611 inherited SetValues;
3612 fBitsPerPixel := 16;
3613 fFormat := tfBGRX4us1;
3614 fWithAlpha := tfBGRA4us1;
3615 fWithoutAlpha := tfBGRX4us1;
3616 fRGBInverted := tfRGBX4us1;
3617 fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
3618 fShift := glBitmapRec4ub( 4, 8, 12, 0);
3620 fOpenGLFormat := tfBGRX4us1;
3621 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3622 fglInternalFormat := GL_RGB4;
3623 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3625 fOpenGLFormat := tfR5G6B5us1;
3629 procedure TfdXBGR4us1.SetValues;
3631 inherited SetValues;
3632 fBitsPerPixel := 16;
3633 fFormat := tfXBGR4us1;
3634 fWithAlpha := tfABGR4us1;
3635 fWithoutAlpha := tfXBGR4us1;
3636 fRGBInverted := tfXRGB4us1;
3637 fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
3638 fShift := glBitmapRec4ub( 0, 4, 8, 0);
3640 fOpenGLFormat := tfXBGR4us1;
3641 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3642 fglInternalFormat := GL_RGB4;
3643 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3645 fOpenGLFormat := tfR5G6B5us1;
3649 procedure TfdB5G6R5us1.SetValues;
3651 inherited SetValues;
3652 fBitsPerPixel := 16;
3653 fFormat := tfB5G6R5us1;
3654 fWithAlpha := tfBGR5A1us1;
3655 fWithoutAlpha := tfB5G6R5us1;
3656 fRGBInverted := tfR5G6B5us1;
3657 fPrecision := glBitmapRec4ub( 5, 6, 5, 0);
3658 fShift := glBitmapRec4ub( 0, 5, 11, 0);
3660 fOpenGLFormat := tfB5G6R5us1;
3661 fglFormat := GL_RGB;
3662 fglInternalFormat := GL_RGB565;
3663 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5_REV;
3665 fOpenGLFormat := tfR5G6B5us1;
3669 procedure TfdBGR5X1us1.SetValues;
3671 inherited SetValues;
3672 fBitsPerPixel := 16;
3673 fFormat := tfBGR5X1us1;
3674 fWithAlpha := tfBGR5A1us1;
3675 fWithoutAlpha := tfBGR5X1us1;
3676 fRGBInverted := tfRGB5X1us1;
3677 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
3678 fShift := glBitmapRec4ub( 1, 6, 11, 0);
3680 fOpenGLFormat := tfBGR5X1us1;
3681 fglFormat := GL_BGRA;
3682 fglInternalFormat := GL_RGB5;
3683 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3685 fOpenGLFormat := tfR5G6B5us1;
3689 procedure TfdX1BGR5us1.SetValues;
3691 inherited SetValues;
3692 fBitsPerPixel := 16;
3693 fFormat := tfX1BGR5us1;
3694 fWithAlpha := tfA1BGR5us1;
3695 fWithoutAlpha := tfX1BGR5us1;
3696 fRGBInverted := tfX1RGB5us1;
3697 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
3698 fShift := glBitmapRec4ub( 0, 5, 10, 0);
3700 fOpenGLFormat := tfX1BGR5us1;
3701 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3702 fglInternalFormat := GL_RGB5;
3703 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3705 fOpenGLFormat := tfR5G6B5us1;
3709 procedure TfdBGR8ub3.SetValues;
3711 inherited SetValues;
3712 fBitsPerPixel := 24;
3713 fFormat := tfBGR8ub3;
3714 fWithAlpha := tfBGRA8ub4;
3715 fWithoutAlpha := tfBGR8ub3;
3716 fRGBInverted := tfRGB8ub3;
3717 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3718 fShift := glBitmapRec4ub(16, 8, 0, 0);
3720 fOpenGLFormat := tfBGR8ub3;
3721 fglFormat := GL_BGR;
3722 fglInternalFormat := GL_RGB8;
3723 fglDataFormat := GL_UNSIGNED_BYTE;
3725 fOpenGLFormat := tfRGB8ub3;
3729 procedure TfdBGRX8ui1.SetValues;
3731 inherited SetValues;
3732 fBitsPerPixel := 32;
3733 fFormat := tfBGRX8ui1;
3734 fWithAlpha := tfBGRA8ui1;
3735 fWithoutAlpha := tfBGRX8ui1;
3736 fRGBInverted := tfRGBX8ui1;
3737 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3738 fShift := glBitmapRec4ub( 8, 16, 24, 0);
3740 fOpenGLFormat := tfBGRX8ui1;
3741 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3742 fglInternalFormat := GL_RGB8;
3743 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3745 fOpenGLFormat := tfRGB8ub3;
3749 procedure TfdXBGR8ui1.SetValues;
3751 inherited SetValues;
3752 fBitsPerPixel := 32;
3753 fFormat := tfXBGR8ui1;
3754 fWithAlpha := tfABGR8ui1;
3755 fWithoutAlpha := tfXBGR8ui1;
3756 fRGBInverted := tfXRGB8ui1;
3757 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3758 fShift := glBitmapRec4ub( 0, 8, 16, 0);
3760 fOpenGLFormat := tfXBGR8ui1;
3761 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3762 fglInternalFormat := GL_RGB8;
3763 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3765 fOpenGLFormat := tfRGB8ub3;
3769 procedure TfdBGR10X2ui1.SetValues;
3771 inherited SetValues;
3772 fBitsPerPixel := 32;
3773 fFormat := tfBGR10X2ui1;
3774 fWithAlpha := tfBGR10A2ui1;
3775 fWithoutAlpha := tfBGR10X2ui1;
3776 fRGBInverted := tfRGB10X2ui1;
3777 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3778 fShift := glBitmapRec4ub( 2, 12, 22, 0);
3780 fOpenGLFormat := tfBGR10X2ui1;
3781 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3782 fglInternalFormat := GL_RGB10;
3783 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3785 fOpenGLFormat := tfRGB16us3;
3789 procedure TfdX2BGR10ui1.SetValues;
3791 inherited SetValues;
3792 fBitsPerPixel := 32;
3793 fFormat := tfX2BGR10ui1;
3794 fWithAlpha := tfA2BGR10ui1;
3795 fWithoutAlpha := tfX2BGR10ui1;
3796 fRGBInverted := tfX2RGB10ui1;
3797 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3798 fShift := glBitmapRec4ub( 0, 10, 20, 0);
3800 fOpenGLFormat := tfX2BGR10ui1;
3801 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3802 fglInternalFormat := GL_RGB10;
3803 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3805 fOpenGLFormat := tfRGB16us3;
3809 procedure TfdBGR16us3.SetValues;
3811 inherited SetValues;
3812 fBitsPerPixel := 48;
3813 fFormat := tfBGR16us3;
3814 fWithAlpha := tfBGRA16us4;
3815 fWithoutAlpha := tfBGR16us3;
3816 fRGBInverted := tfRGB16us3;
3817 fPrecision := glBitmapRec4ub(16, 16, 16, 0);
3818 fShift := glBitmapRec4ub(32, 16, 0, 0);
3820 fOpenGLFormat := tfBGR16us3;
3821 fglFormat := GL_BGR;
3822 fglInternalFormat := GL_RGB16;
3823 fglDataFormat := GL_UNSIGNED_SHORT;
3825 fOpenGLFormat := tfRGB16us3;
3829 procedure TfdBGRA4us1.SetValues;
3831 inherited SetValues;
3832 fBitsPerPixel := 16;
3833 fFormat := tfBGRA4us1;
3834 fWithAlpha := tfBGRA4us1;
3835 fWithoutAlpha := tfBGRX4us1;
3836 fRGBInverted := tfRGBA4us1;
3837 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3838 fShift := glBitmapRec4ub( 4, 8, 12, 0);
3840 fOpenGLFormat := tfBGRA4us1;
3841 fglFormat := GL_BGRA;
3842 fglInternalFormat := GL_RGBA4;
3843 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3845 fOpenGLFormat := tfRGBA4us1;
3849 procedure TfdABGR4us1.SetValues;
3851 inherited SetValues;
3852 fBitsPerPixel := 16;
3853 fFormat := tfABGR4us1;
3854 fWithAlpha := tfABGR4us1;
3855 fWithoutAlpha := tfXBGR4us1;
3856 fRGBInverted := tfARGB4us1;
3857 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3858 fShift := glBitmapRec4ub( 0, 4, 8, 12);
3860 fOpenGLFormat := tfABGR4us1;
3861 fglFormat := GL_RGBA;
3862 fglInternalFormat := GL_RGBA4;
3863 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3865 fOpenGLFormat := tfRGBA4us1;
3869 procedure TfdBGR5A1us1.SetValues;
3871 inherited SetValues;
3872 fBitsPerPixel := 16;
3873 fFormat := tfBGR5A1us1;
3874 fWithAlpha := tfBGR5A1us1;
3875 fWithoutAlpha := tfBGR5X1us1;
3876 fRGBInverted := tfRGB5A1us1;
3877 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3878 fShift := glBitmapRec4ub( 1, 6, 11, 0);
3880 fOpenGLFormat := tfBGR5A1us1;
3881 fglFormat := GL_BGRA;
3882 fglInternalFormat := GL_RGB5_A1;
3883 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3885 fOpenGLFormat := tfRGB5A1us1;
3889 procedure TfdA1BGR5us1.SetValues;
3891 inherited SetValues;
3892 fBitsPerPixel := 16;
3893 fFormat := tfA1BGR5us1;
3894 fWithAlpha := tfA1BGR5us1;
3895 fWithoutAlpha := tfX1BGR5us1;
3896 fRGBInverted := tfA1RGB5us1;
3897 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3898 fShift := glBitmapRec4ub( 0, 5, 10, 15);
3900 fOpenGLFormat := tfA1BGR5us1;
3901 fglFormat := GL_RGBA;
3902 fglInternalFormat := GL_RGB5_A1;
3903 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3905 fOpenGLFormat := tfRGB5A1us1;
3909 procedure TfdBGRA8ui1.SetValues;
3911 inherited SetValues;
3912 fBitsPerPixel := 32;
3913 fFormat := tfBGRA8ui1;
3914 fWithAlpha := tfBGRA8ui1;
3915 fWithoutAlpha := tfBGRX8ui1;
3916 fRGBInverted := tfRGBA8ui1;
3917 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3918 fShift := glBitmapRec4ub( 8, 16, 24, 0);
3920 fOpenGLFormat := tfBGRA8ui1;
3921 fglFormat := GL_BGRA;
3922 fglInternalFormat := GL_RGBA8;
3923 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3925 fOpenGLFormat := tfRGBA8ub4;
3929 procedure TfdABGR8ui1.SetValues;
3931 inherited SetValues;
3932 fBitsPerPixel := 32;
3933 fFormat := tfABGR8ui1;
3934 fWithAlpha := tfABGR8ui1;
3935 fWithoutAlpha := tfXBGR8ui1;
3936 fRGBInverted := tfARGB8ui1;
3937 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3938 fShift := glBitmapRec4ub( 0, 8, 16, 24);
3940 fOpenGLFormat := tfABGR8ui1;
3941 fglFormat := GL_RGBA;
3942 fglInternalFormat := GL_RGBA8;
3943 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3945 fOpenGLFormat := tfRGBA8ub4
3949 procedure TfdBGRA8ub4.SetValues;
3951 inherited SetValues;
3952 fBitsPerPixel := 32;
3953 fFormat := tfBGRA8ub4;
3954 fWithAlpha := tfBGRA8ub4;
3955 fWithoutAlpha := tfBGR8ub3;
3956 fRGBInverted := tfRGBA8ub4;
3957 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3958 fShift := glBitmapRec4ub(16, 8, 0, 24);
3960 fOpenGLFormat := tfBGRA8ub4;
3961 fglFormat := GL_BGRA;
3962 fglInternalFormat := GL_RGBA8;
3963 fglDataFormat := GL_UNSIGNED_BYTE;
3965 fOpenGLFormat := tfRGBA8ub4;
3969 procedure TfdBGR10A2ui1.SetValues;
3971 inherited SetValues;
3972 fBitsPerPixel := 32;
3973 fFormat := tfBGR10A2ui1;
3974 fWithAlpha := tfBGR10A2ui1;
3975 fWithoutAlpha := tfBGR10X2ui1;
3976 fRGBInverted := tfRGB10A2ui1;
3977 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3978 fShift := glBitmapRec4ub( 2, 12, 22, 0);
3980 fOpenGLFormat := tfBGR10A2ui1;
3981 fglFormat := GL_BGRA;
3982 fglInternalFormat := GL_RGB10_A2;
3983 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3985 fOpenGLFormat := tfA2RGB10ui1;
3989 procedure TfdA2BGR10ui1.SetValues;
3991 inherited SetValues;
3992 fBitsPerPixel := 32;
3993 fFormat := tfA2BGR10ui1;
3994 fWithAlpha := tfA2BGR10ui1;
3995 fWithoutAlpha := tfX2BGR10ui1;
3996 fRGBInverted := tfA2RGB10ui1;
3997 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3998 fShift := glBitmapRec4ub( 0, 10, 20, 30);
4000 fOpenGLFormat := tfA2BGR10ui1;
4001 fglFormat := GL_RGBA;
4002 fglInternalFormat := GL_RGB10_A2;
4003 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
4005 fOpenGLFormat := tfA2RGB10ui1;
4009 procedure TfdBGRA16us4.SetValues;
4011 inherited SetValues;
4012 fBitsPerPixel := 64;
4013 fFormat := tfBGRA16us4;
4014 fWithAlpha := tfBGRA16us4;
4015 fWithoutAlpha := tfBGR16us3;
4016 fRGBInverted := tfRGBA16us4;
4017 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
4018 fShift := glBitmapRec4ub(32, 16, 0, 48);
4020 fOpenGLFormat := tfBGRA16us4;
4021 fglFormat := GL_BGRA;
4022 fglInternalFormat := GL_RGBA16;
4023 fglDataFormat := GL_UNSIGNED_SHORT;
4025 fOpenGLFormat := tfRGBA16us4;
4029 procedure TfdDepth16us1.SetValues;
4031 inherited SetValues;
4032 fBitsPerPixel := 16;
4033 fFormat := tfDepth16us1;
4034 fWithoutAlpha := tfDepth16us1;
4035 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
4036 fShift := glBitmapRec4ub( 0, 0, 0, 0);
4037 {$IF NOT DEFINED (OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
4038 fOpenGLFormat := tfDepth16us1;
4039 fglFormat := GL_DEPTH_COMPONENT;
4040 fglInternalFormat := GL_DEPTH_COMPONENT16;
4041 fglDataFormat := GL_UNSIGNED_SHORT;
4045 procedure TfdDepth24ui1.SetValues;
4047 inherited SetValues;
4048 fBitsPerPixel := 32;
4049 fFormat := tfDepth24ui1;
4050 fWithoutAlpha := tfDepth24ui1;
4051 fOpenGLFormat := tfDepth24ui1;
4052 fPrecision := glBitmapRec4ub(32, 32, 32, 32);
4053 fShift := glBitmapRec4ub( 0, 0, 0, 0);
4054 {$IF NOT DEFINED (OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
4055 fOpenGLFormat := tfDepth24ui1;
4056 fglFormat := GL_DEPTH_COMPONENT;
4057 fglInternalFormat := GL_DEPTH_COMPONENT24;
4058 fglDataFormat := GL_UNSIGNED_INT;
4062 procedure TfdDepth32ui1.SetValues;
4064 inherited SetValues;
4065 fBitsPerPixel := 32;
4066 fFormat := tfDepth32ui1;
4067 fWithoutAlpha := tfDepth32ui1;
4068 fPrecision := glBitmapRec4ub(32, 32, 32, 32);
4069 fShift := glBitmapRec4ub( 0, 0, 0, 0);
4070 {$IF NOT DEFINED(OPENGL_ES)}
4071 fOpenGLFormat := tfDepth32ui1;
4072 fglFormat := GL_DEPTH_COMPONENT;
4073 fglInternalFormat := GL_DEPTH_COMPONENT32;
4074 fglDataFormat := GL_UNSIGNED_INT;
4075 {$ELSEIF DEFINED(OPENGL_ES_3_0)}
4076 fOpenGLFormat := tfDepth24ui1;
4077 {$ELSEIF DEFINED(OPENGL_ES_2_0)}
4078 fOpenGLFormat := tfDepth16us1;
4082 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4083 //TfdS3tcDtx1RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4084 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4085 procedure TfdS3tcDtx1RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4087 raise EglBitmap.Create('mapping for compressed formats is not supported');
4090 procedure TfdS3tcDtx1RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4092 raise EglBitmap.Create('mapping for compressed formats is not supported');
4095 procedure TfdS3tcDtx1RGBA.SetValues;
4097 inherited SetValues;
4098 fFormat := tfS3tcDtx1RGBA;
4099 fWithAlpha := tfS3tcDtx1RGBA;
4100 fUncompressed := tfRGB5A1us1;
4102 fIsCompressed := true;
4104 fOpenGLFormat := tfS3tcDtx1RGBA;
4105 fglFormat := GL_COMPRESSED_RGBA;
4106 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
4107 fglDataFormat := GL_UNSIGNED_BYTE;
4109 fOpenGLFormat := fUncompressed;
4113 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4114 //TfdS3tcDtx3RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4115 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4116 procedure TfdS3tcDtx3RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4118 raise EglBitmap.Create('mapping for compressed formats is not supported');
4121 procedure TfdS3tcDtx3RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4123 raise EglBitmap.Create('mapping for compressed formats is not supported');
4126 procedure TfdS3tcDtx3RGBA.SetValues;
4128 inherited SetValues;
4129 fFormat := tfS3tcDtx3RGBA;
4130 fWithAlpha := tfS3tcDtx3RGBA;
4131 fUncompressed := tfRGBA8ub4;
4133 fIsCompressed := true;
4135 fOpenGLFormat := tfS3tcDtx3RGBA;
4136 fglFormat := GL_COMPRESSED_RGBA;
4137 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
4138 fglDataFormat := GL_UNSIGNED_BYTE;
4140 fOpenGLFormat := fUncompressed;
4144 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4145 //TfdS3tcDtx5RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4146 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4147 procedure TfdS3tcDtx5RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4149 raise EglBitmap.Create('mapping for compressed formats is not supported');
4152 procedure TfdS3tcDtx5RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4154 raise EglBitmap.Create('mapping for compressed formats is not supported');
4157 procedure TfdS3tcDtx5RGBA.SetValues;
4159 inherited SetValues;
4160 fFormat := tfS3tcDtx3RGBA;
4161 fWithAlpha := tfS3tcDtx3RGBA;
4162 fUncompressed := tfRGBA8ub4;
4164 fIsCompressed := true;
4166 fOpenGLFormat := tfS3tcDtx3RGBA;
4167 fglFormat := GL_COMPRESSED_RGBA;
4168 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
4169 fglDataFormat := GL_UNSIGNED_BYTE;
4171 fOpenGLFormat := fUncompressed;
4175 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4176 //TglBitmapFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4177 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4178 function TglBitmapFormatDescriptor.GetHasRed: Boolean;
4180 result := (fPrecision.r > 0);
4183 function TglBitmapFormatDescriptor.GetHasGreen: Boolean;
4185 result := (fPrecision.g > 0);
4188 function TglBitmapFormatDescriptor.GetHasBlue: Boolean;
4190 result := (fPrecision.b > 0);
4193 function TglBitmapFormatDescriptor.GetHasAlpha: Boolean;
4195 result := (fPrecision.a > 0);
4198 function TglBitmapFormatDescriptor.GetHasColor: Boolean;
4200 result := HasRed or HasGreen or HasBlue;
4203 function TglBitmapFormatDescriptor.GetIsGrayscale: Boolean;
4205 result := (Mask.r = Mask.g) and (Mask.g = Mask.b) and (Mask.r > 0);
4208 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4209 procedure TglBitmapFormatDescriptor.SetValues;
4212 fWithAlpha := tfEmpty;
4213 fWithoutAlpha := tfEmpty;
4214 fOpenGLFormat := tfEmpty;
4215 fRGBInverted := tfEmpty;
4216 fUncompressed := tfEmpty;
4219 fIsCompressed := false;
4222 fglInternalFormat := 0;
4225 FillChar(fPrecision, 0, SizeOf(fPrecision));
4226 FillChar(fShift, 0, SizeOf(fShift));
4229 procedure TglBitmapFormatDescriptor.CalcValues;
4233 fBytesPerPixel := fBitsPerPixel / 8;
4235 for i := 0 to 3 do begin
4236 if (fPrecision.arr[i] > 0) then
4238 fRange.arr[i] := (1 shl fPrecision.arr[i]) - 1;
4239 fMask.arr[i] := fRange.arr[i] shl fShift.arr[i];
4243 constructor TglBitmapFormatDescriptor.Create;
4250 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4251 class function TglBitmapFormatDescriptor.GetByFormat(const aInternalFormat: GLenum): TglBitmapFormatDescriptor;
4255 for f := Low(TglBitmapFormat) to High(TglBitmapFormat) do begin
4256 result := TFormatDescriptor.Get(f);
4257 if (result.glInternalFormat = aInternalFormat) then
4260 result := TFormatDescriptor.Get(tfEmpty);
4263 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4264 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4265 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4266 class procedure TFormatDescriptor.Init;
4268 if not Assigned(FormatDescriptorCS) then
4269 FormatDescriptorCS := TCriticalSection.Create;
4272 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4273 class function TFormatDescriptor.Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
4275 FormatDescriptorCS.Enter;
4277 result := FormatDescriptors[aFormat];
4278 if not Assigned(result) then begin
4279 result := FORMAT_DESCRIPTOR_CLASSES[aFormat].Create;
4280 FormatDescriptors[aFormat] := result;
4283 FormatDescriptorCS.Leave;
4287 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4288 class function TFormatDescriptor.GetAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
4290 result := Get(Get(aFormat).WithAlpha);
4293 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4294 class function TFormatDescriptor.GetFromMask(const aMask: TglBitmapRec4ul; const aBitCount: Integer): TFormatDescriptor;
4296 ft: TglBitmapFormat;
4298 // find matching format with OpenGL support
4299 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
4301 if (result.MaskMatch(aMask)) and
4302 (result.glFormat <> 0) and
4303 (result.glInternalFormat <> 0) and
4304 ((aBitCount = 0) or (aBitCount = result.BitsPerPixel))
4309 // find matching format without OpenGL Support
4310 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
4312 if result.MaskMatch(aMask) and ((aBitCount = 0) or (aBitCount = result.BitsPerPixel)) then
4316 result := TFormatDescriptor.Get(tfEmpty);
4319 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4320 class function TFormatDescriptor.GetFromPrecShift(const aPrec, aShift: TglBitmapRec4ub; const aBitCount: Integer): TFormatDescriptor;
4322 ft: TglBitmapFormat;
4324 // find matching format with OpenGL support
4325 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
4327 if glBitmapRec4ubCompare(result.Shift, aShift) and
4328 glBitmapRec4ubCompare(result.Precision, aPrec) and
4329 (result.glFormat <> 0) and
4330 (result.glInternalFormat <> 0) and
4331 ((aBitCount = 0) or (aBitCount = result.BitsPerPixel))
4336 // find matching format without OpenGL Support
4337 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
4339 if glBitmapRec4ubCompare(result.Shift, aShift) and
4340 glBitmapRec4ubCompare(result.Precision, aPrec) and
4341 ((aBitCount = 0) or (aBitCount = result.BitsPerPixel)) then
4345 result := TFormatDescriptor.Get(tfEmpty);
4348 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4349 class procedure TFormatDescriptor.Clear;
4353 FormatDescriptorCS.Enter;
4355 for f := low(FormatDescriptors) to high(FormatDescriptors) do
4356 FreeAndNil(FormatDescriptors[f]);
4358 FormatDescriptorCS.Leave;
4362 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4363 class procedure TFormatDescriptor.Finalize;
4366 FreeAndNil(FormatDescriptorCS);
4369 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4370 //TBitfieldFormat/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4371 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4372 procedure TbmpBitfieldFormat.SetCustomValues(const aBPP: Integer; aMask: TglBitmapRec4ul);
4376 for i := 0 to 3 do begin
4378 while (aMask.arr[i] > 0) and (aMask.arr[i] and 1 > 0) do begin
4379 aMask.arr[i] := aMask.arr[i] shr 1;
4382 fPrecision.arr[i] := CountSetBits(aMask.arr[i]);
4387 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4388 procedure TbmpBitfieldFormat.SetCustomValues(const aBBP: Integer; const aPrec, aShift: TglBitmapRec4ub);
4390 fBitsPerPixel := aBBP;
4391 fPrecision := aPrec;
4396 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4397 procedure TbmpBitfieldFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4402 ((aPixel.Data.r and Range.r) shl Shift.r) or
4403 ((aPixel.Data.g and Range.g) shl Shift.g) or
4404 ((aPixel.Data.b and Range.b) shl Shift.b) or
4405 ((aPixel.Data.a and Range.a) shl Shift.a);
4406 case BitsPerPixel of
4408 16: PWord(aData)^ := data;
4409 32: PCardinal(aData)^ := data;
4410 64: PQWord(aData)^ := data;
4412 raise EglBitmap.CreateFmt('invalid pixel size: %d', [BitsPerPixel]);
4414 inc(aData, Round(BytesPerPixel));
4417 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4418 procedure TbmpBitfieldFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4423 case BitsPerPixel of
4425 16: data := PWord(aData)^;
4426 32: data := PCardinal(aData)^;
4427 64: data := PQWord(aData)^;
4429 raise EglBitmap.CreateFmt('invalid pixel size: %d', [BitsPerPixel]);
4432 aPixel.Data.arr[i] := (data shr fShift.arr[i]) and Range.arr[i];
4433 inc(aData, Round(BytesPerPixel));
4436 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4437 //TColorTableFormat///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4438 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4439 procedure TbmpColorTableFormat.SetValues;
4441 inherited SetValues;
4442 fShift := glBitmapRec4ub(8, 8, 8, 0);
4445 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4446 procedure TbmpColorTableFormat.SetCustomValues(const aFormat: TglBitmapFormat; const aBPP: Integer; const aPrec, aShift: TglBitmapRec4ub);
4449 fBitsPerPixel := aBPP;
4450 fPrecision := aPrec;
4455 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4456 procedure TbmpColorTableFormat.CalcValues;
4458 inherited CalcValues;
4461 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4462 procedure TbmpColorTableFormat.CreateColorTable;
4466 SetLength(fColorTable, 256);
4467 if not HasColor then begin
4469 for i := 0 to High(fColorTable) do begin
4470 fColorTable[i].r := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
4471 fColorTable[i].g := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
4472 fColorTable[i].b := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
4473 fColorTable[i].a := 0;
4477 for i := 0 to High(fColorTable) do begin
4478 fColorTable[i].r := Round(((i shr Shift.r) and Range.r) / Range.r * 255);
4479 fColorTable[i].g := Round(((i shr Shift.g) and Range.g) / Range.g * 255);
4480 fColorTable[i].b := Round(((i shr Shift.b) and Range.b) / Range.b * 255);
4481 fColorTable[i].a := 0;
4486 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4487 procedure TbmpColorTableFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4489 if (BitsPerPixel <> 8) then
4490 raise EglBitmapUnsupportedFormat.Create('color table are only supported for 8bit formats');
4491 if not HasColor then
4493 aData^ := aPixel.Data.a
4497 ((aPixel.Data.r and Range.r) shl Shift.r) or
4498 ((aPixel.Data.g and Range.g) shl Shift.g) or
4499 ((aPixel.Data.b and Range.b) shl Shift.b));
4503 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4504 procedure TbmpColorTableFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4506 if (BitsPerPixel <> 8) then
4507 raise EglBitmapUnsupportedFormat.Create('color table are only supported for 8bit formats');
4508 with fColorTable[aData^] do begin
4517 destructor TbmpColorTableFormat.Destroy;
4519 SetLength(fColorTable, 0);
4523 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4524 //TglBitmap - Helper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4525 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4526 procedure glBitmapConvertPixel(var aPixel: TglBitmapPixelData; const aSourceFD, aDestFD: TFormatDescriptor);
4530 for i := 0 to 3 do begin
4531 if (aSourceFD.Range.arr[i] <> aDestFD.Range.arr[i]) then begin
4532 if (aSourceFD.Range.arr[i] > 0) then
4533 aPixel.Data.arr[i] := Round(aPixel.Data.arr[i] / aSourceFD.Range.arr[i] * aDestFD.Range.arr[i])
4535 aPixel.Data.arr[i] := 0;
4540 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4541 procedure glBitmapConvertCopyFunc(var aFuncRec: TglBitmapFunctionRec);
4543 with aFuncRec do begin
4544 if (Source.Range.r > 0) then
4545 Dest.Data.r := Source.Data.r;
4546 if (Source.Range.g > 0) then
4547 Dest.Data.g := Source.Data.g;
4548 if (Source.Range.b > 0) then
4549 Dest.Data.b := Source.Data.b;
4550 if (Source.Range.a > 0) then
4551 Dest.Data.a := Source.Data.a;
4555 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4556 procedure glBitmapConvertCalculateRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
4560 with aFuncRec do begin
4562 if (Source.Range.arr[i] > 0) then
4563 Dest.Data.arr[i] := Round(Dest.Range.arr[i] * Source.Data.arr[i] / Source.Range.arr[i]);
4568 TShiftData = packed record
4570 0: (r, g, b, a: SmallInt);
4571 1: (arr: array[0..3] of SmallInt);
4573 PShiftData = ^TShiftData;
4575 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4576 procedure glBitmapConvertShiftRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
4582 if (Source.Range.arr[i] > 0) then
4583 Dest.Data.arr[i] := Source.Data.arr[i] shr PShiftData(Args)^.arr[i];
4586 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4587 procedure glBitmapInvertFunc(var aFuncRec: TglBitmapFunctionRec);
4589 with aFuncRec do begin
4590 Dest.Data := Source.Data;
4591 if ({%H-}PtrUInt(Args) and $1 > 0) then begin
4592 Dest.Data.r := Dest.Data.r xor Dest.Range.r;
4593 Dest.Data.g := Dest.Data.g xor Dest.Range.g;
4594 Dest.Data.b := Dest.Data.b xor Dest.Range.b;
4596 if ({%H-}PtrUInt(Args) and $2 > 0) then begin
4597 Dest.Data.a := Dest.Data.a xor Dest.Range.a;
4602 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4603 procedure glBitmapFillWithColorFunc(var aFuncRec: TglBitmapFunctionRec);
4607 with aFuncRec do begin
4609 Dest.Data.arr[i] := PglBitmapPixelData(Args)^.Data.arr[i];
4613 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4614 procedure glBitmapAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4618 with FuncRec do begin
4619 if (FuncRec.Args = nil) then begin //source has no alpha
4621 Source.Data.r / Source.Range.r * ALPHA_WEIGHT_R +
4622 Source.Data.g / Source.Range.g * ALPHA_WEIGHT_G +
4623 Source.Data.b / Source.Range.b * ALPHA_WEIGHT_B;
4624 Dest.Data.a := Round(Dest.Range.a * Temp);
4626 Dest.Data.a := Round(Source.Data.a / Source.Range.a * Dest.Range.a);
4630 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4631 procedure glBitmapColorKeyAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4633 PglBitmapPixelData = ^TglBitmapPixelData;
4635 with FuncRec do begin
4636 Dest.Data.r := Source.Data.r;
4637 Dest.Data.g := Source.Data.g;
4638 Dest.Data.b := Source.Data.b;
4640 with PglBitmapPixelData(Args)^ do
4641 if ((Dest.Data.r <= Data.r) and (Dest.Data.r >= Range.r) and
4642 (Dest.Data.g <= Data.g) and (Dest.Data.g >= Range.g) and
4643 (Dest.Data.b <= Data.b) and (Dest.Data.b >= Range.b)) then
4646 Dest.Data.a := Dest.Range.a;
4650 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4651 procedure glBitmapValueAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4653 with FuncRec do begin
4654 Dest.Data.r := Source.Data.r;
4655 Dest.Data.g := Source.Data.g;
4656 Dest.Data.b := Source.Data.b;
4657 Dest.Data.a := PCardinal(Args)^;
4661 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4662 procedure SwapRGB(aData: PByte; aWidth: Integer; const aHasAlpha: Boolean);
4665 TRGBPix = array [0..2] of byte;
4669 while aWidth > 0 do begin
4670 Temp := PRGBPix(aData)^[0];
4671 PRGBPix(aData)^[0] := PRGBPix(aData)^[2];
4672 PRGBPix(aData)^[2] := Temp;
4682 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4683 //TglBitmap - PROTECTED///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4684 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4685 function TglBitmap.GetFormatDesc: TglBitmapFormatDescriptor;
4687 result := TFormatDescriptor.Get(Format);
4690 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4691 function TglBitmap.GetWidth: Integer;
4693 if (ffX in fDimension.Fields) then
4694 result := fDimension.X
4699 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4700 function TglBitmap.GetHeight: Integer;
4702 if (ffY in fDimension.Fields) then
4703 result := fDimension.Y
4708 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4709 function TglBitmap.GetFileWidth: Integer;
4711 result := Max(1, Width);
4714 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4715 function TglBitmap.GetFileHeight: Integer;
4717 result := Max(1, Height);
4720 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4721 procedure TglBitmap.SetCustomData(const aValue: Pointer);
4723 if fCustomData = aValue then
4725 fCustomData := aValue;
4728 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4729 procedure TglBitmap.SetCustomName(const aValue: String);
4731 if fCustomName = aValue then
4733 fCustomName := aValue;
4736 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4737 procedure TglBitmap.SetCustomNameW(const aValue: WideString);
4739 if fCustomNameW = aValue then
4741 fCustomNameW := aValue;
4744 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4745 procedure TglBitmap.SetFreeDataOnDestroy(const aValue: Boolean);
4747 if fFreeDataOnDestroy = aValue then
4749 fFreeDataOnDestroy := aValue;
4752 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4753 procedure TglBitmap.SetDeleteTextureOnFree(const aValue: Boolean);
4755 if fDeleteTextureOnFree = aValue then
4757 fDeleteTextureOnFree := aValue;
4760 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4761 procedure TglBitmap.SetFormat(const aValue: TglBitmapFormat);
4763 if fFormat = aValue then
4765 if TFormatDescriptor.Get(Format).BitsPerPixel <> TFormatDescriptor.Get(aValue).BitsPerPixel then
4766 raise EglBitmapUnsupportedFormat.Create(Format);
4767 SetDataPointer(fData, aValue, Width, Height); //be careful, Data could be freed by this method
4770 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4771 procedure TglBitmap.SetFreeDataAfterGenTexture(const aValue: Boolean);
4773 if fFreeDataAfterGenTexture = aValue then
4775 fFreeDataAfterGenTexture := aValue;
4778 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4779 procedure TglBitmap.SetID(const aValue: Cardinal);
4781 if fID = aValue then
4786 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4787 procedure TglBitmap.SetMipMap(const aValue: TglBitmapMipMap);
4789 if fMipMap = aValue then
4794 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4795 procedure TglBitmap.SetTarget(const aValue: Cardinal);
4797 if fTarget = aValue then
4802 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4803 procedure TglBitmap.SetAnisotropic(const aValue: Integer);
4804 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_EXT)}
4806 MaxAnisotropic: Integer;
4809 fAnisotropic := aValue;
4810 if (ID > 0) then begin
4811 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_EXT)}
4812 if GL_EXT_texture_filter_anisotropic then begin
4813 if fAnisotropic > 0 then begin
4815 glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @MaxAnisotropic);
4816 if aValue > MaxAnisotropic then
4817 fAnisotropic := MaxAnisotropic;
4818 glTexParameteri(Target, GL_TEXTURE_MAX_ANISOTROPY_EXT, fAnisotropic);
4829 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4830 procedure TglBitmap.CreateID;
4833 glDeleteTextures(1, @fID);
4834 glGenTextures(1, @fID);
4838 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4839 procedure TglBitmap.SetupParameters({$IFNDEF OPENGL_ES}out aBuildWithGlu: Boolean{$ENDIF});
4841 // Set Up Parameters
4842 SetWrap(fWrapS, fWrapT, fWrapR);
4843 SetFilter(fFilterMin, fFilterMag);
4844 SetAnisotropic(fAnisotropic);
4847 SetBorderColor(fBorderColor[0], fBorderColor[1], fBorderColor[2], fBorderColor[3]);
4848 if (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
4849 SetSwizzle(fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
4853 // Mip Maps Generation Mode
4854 aBuildWithGlu := false;
4855 if (MipMap = mmMipmap) then begin
4856 if (GL_VERSION_1_4 or GL_SGIS_generate_mipmap) then
4857 glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE)
4859 aBuildWithGlu := true;
4860 end else if (MipMap = mmMipmapGlu) then
4861 aBuildWithGlu := true;
4863 if (MipMap = mmMipmap) then
4864 glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE);
4868 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4869 procedure TglBitmap.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
4870 const aWidth: Integer; const aHeight: Integer);
4874 if (Data <> aData) then begin
4875 if (Assigned(Data)) then
4880 if not Assigned(fData) then begin
4884 FillChar(fDimension, SizeOf(fDimension), 0);
4885 if aWidth <> -1 then begin
4886 fDimension.Fields := fDimension.Fields + [ffX];
4887 fDimension.X := aWidth;
4890 if aHeight <> -1 then begin
4891 fDimension.Fields := fDimension.Fields + [ffY];
4892 fDimension.Y := aHeight;
4895 s := TFormatDescriptor.Get(aFormat).BytesPerPixel;
4897 fPixelSize := Ceil(s);
4898 fRowSize := Ceil(s * aWidth);
4902 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4903 function TglBitmap.FlipHorz: Boolean;
4908 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4909 function TglBitmap.FlipVert: Boolean;
4914 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4915 //TglBitmap - PUBLIC//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4916 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4917 procedure TglBitmap.AfterConstruction;
4919 inherited AfterConstruction;
4924 fIsResident := false;
4927 fMipMap := glBitmapDefaultMipmap;
4928 fFreeDataAfterGenTexture := glBitmapGetDefaultFreeDataAfterGenTexture;
4929 fDeleteTextureOnFree := glBitmapGetDefaultDeleteTextureOnFree;
4931 glBitmapGetDefaultFilter (fFilterMin, fFilterMag);
4932 glBitmapGetDefaultTextureWrap(fWrapS, fWrapT, fWrapR);
4934 glBitmapGetDefaultSwizzle (fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
4938 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4939 procedure TglBitmap.BeforeDestruction;
4943 if fFreeDataOnDestroy then begin
4945 SetDataPointer(NewData, tfEmpty); //be careful, Data could be freed by this method
4947 if (fID > 0) and fDeleteTextureOnFree then
4948 glDeleteTextures(1, @fID);
4949 inherited BeforeDestruction;
4952 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4953 procedure TglBitmap.PrepareResType(var aResource: String; var aResType: PChar);
4957 if not Assigned(aResType) then begin
4958 TempPos := Pos('.', aResource);
4959 aResType := PChar(UpperCase(Copy(aResource, TempPos + 1, Length(aResource) - TempPos)));
4960 aResource := UpperCase(Copy(aResource, 0, TempPos -1));
4964 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4965 procedure TglBitmap.LoadFromFile(const aFilename: String);
4969 if not FileExists(aFilename) then
4970 raise EglBitmap.Create('file does not exist: ' + aFilename);
4971 fFilename := aFilename;
4972 fs := TFileStream.Create(fFilename, fmOpenRead);
4981 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4982 procedure TglBitmap.LoadFromStream(const aStream: TStream);
4984 {$IFDEF GLB_SUPPORT_PNG_READ}
4985 if not LoadPNG(aStream) then
4987 {$IFDEF GLB_SUPPORT_JPEG_READ}
4988 if not LoadJPEG(aStream) then
4990 if not LoadDDS(aStream) then
4991 if not LoadTGA(aStream) then
4992 if not LoadBMP(aStream) then
4993 if not LoadRAW(aStream) then
4994 raise EglBitmap.Create('LoadFromStream - Couldn''t load Stream. It''s possible to be an unknow Streamtype.');
4997 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4998 procedure TglBitmap.LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
4999 const aFormat: TglBitmapFormat; const aArgs: Pointer);
5004 size := TFormatDescriptor.Get(aFormat).GetSize(aSize);
5005 GetMem(tmpData, size);
5007 FillChar(tmpData^, size, #$FF);
5008 SetDataPointer(tmpData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
5010 if Assigned(tmpData) then
5014 AddFunc(Self, aFunc, false, aFormat, aArgs);
5017 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5018 procedure TglBitmap.LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar);
5020 rs: TResourceStream;
5022 PrepareResType(aResource, aResType);
5023 rs := TResourceStream.Create(aInstance, aResource, aResType);
5031 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5032 procedure TglBitmap.LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
5034 rs: TResourceStream;
5036 rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
5044 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5045 procedure TglBitmap.SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
5049 fs := TFileStream.Create(aFileName, fmCreate);
5052 SaveToStream(fs, aFileType);
5058 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5059 procedure TglBitmap.SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType);
5062 {$IFDEF GLB_SUPPORT_PNG_WRITE}
5063 ftPNG: SavePNG(aStream);
5065 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
5066 ftJPEG: SaveJPEG(aStream);
5068 ftDDS: SaveDDS(aStream);
5069 ftTGA: SaveTGA(aStream);
5070 ftBMP: SaveBMP(aStream);
5071 ftRAW: SaveRAW(aStream);
5075 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5076 function TglBitmap.AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer): Boolean;
5078 result := AddFunc(Self, aFunc, aCreateTemp, Format, aArgs);
5081 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5082 function TglBitmap.AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
5083 const aFormat: TglBitmapFormat; const aArgs: Pointer): Boolean;
5085 DestData, TmpData, SourceData: pByte;
5086 TempHeight, TempWidth: Integer;
5087 SourceFD, DestFD: TFormatDescriptor;
5088 SourceMD, DestMD: Pointer;
5090 FuncRec: TglBitmapFunctionRec;
5092 Assert(Assigned(Data));
5093 Assert(Assigned(aSource));
5094 Assert(Assigned(aSource.Data));
5097 if Assigned(aSource.Data) and ((aSource.Height > 0) or (aSource.Width > 0)) then begin
5098 SourceFD := TFormatDescriptor.Get(aSource.Format);
5099 DestFD := TFormatDescriptor.Get(aFormat);
5101 if (SourceFD.IsCompressed) then
5102 raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', SourceFD.Format);
5103 if (DestFD.IsCompressed) then
5104 raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', DestFD.Format);
5106 // inkompatible Formats so CreateTemp
5107 if (SourceFD.BitsPerPixel <> DestFD.BitsPerPixel) then
5108 aCreateTemp := true;
5111 TempHeight := Max(1, aSource.Height);
5112 TempWidth := Max(1, aSource.Width);
5114 FuncRec.Sender := Self;
5115 FuncRec.Args := aArgs;
5118 if aCreateTemp then begin
5119 GetMem(TmpData, DestFD.GetSize(TempWidth, TempHeight));
5120 DestData := TmpData;
5125 SourceFD.PreparePixel(FuncRec.Source);
5126 DestFD.PreparePixel (FuncRec.Dest);
5128 SourceMD := SourceFD.CreateMappingData;
5129 DestMD := DestFD.CreateMappingData;
5131 FuncRec.Size := aSource.Dimension;
5132 FuncRec.Position.Fields := FuncRec.Size.Fields;
5135 SourceData := aSource.Data;
5136 FuncRec.Position.Y := 0;
5137 while FuncRec.Position.Y < TempHeight do begin
5138 FuncRec.Position.X := 0;
5139 while FuncRec.Position.X < TempWidth do begin
5140 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
5142 DestFD.Map(FuncRec.Dest, DestData, DestMD);
5143 inc(FuncRec.Position.X);
5145 inc(FuncRec.Position.Y);
5148 // Updating Image or InternalFormat
5150 SetDataPointer(TmpData, aFormat, aSource.Width, aSource.Height) //be careful, Data could be freed by this method
5151 else if (aFormat <> fFormat) then
5156 SourceFD.FreeMappingData(SourceMD);
5157 DestFD.FreeMappingData(DestMD);
5160 if aCreateTemp and Assigned(TmpData) then
5168 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5169 function TglBitmap.AssignToSurface(out aSurface: PSDL_Surface): Boolean;
5171 Row, RowSize: Integer;
5172 SourceData, TmpData: PByte;
5174 FormatDesc: TFormatDescriptor;
5176 function GetRowPointer(Row: Integer): pByte;
5178 result := aSurface.pixels;
5179 Inc(result, Row * RowSize);
5185 FormatDesc := TFormatDescriptor.Get(Format);
5186 if FormatDesc.IsCompressed then
5187 raise EglBitmapUnsupportedFormat.Create(Format);
5189 if Assigned(Data) then begin
5190 case Trunc(FormatDesc.PixelSize) of
5196 raise EglBitmapUnsupportedFormat.Create(Format);
5199 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, TempDepth,
5200 FormatDesc.RedMask, FormatDesc.GreenMask, FormatDesc.BlueMask, FormatDesc.AlphaMask);
5202 RowSize := FormatDesc.GetSize(FileWidth, 1);
5204 for Row := 0 to FileHeight-1 do begin
5205 TmpData := GetRowPointer(Row);
5206 if Assigned(TmpData) then begin
5207 Move(SourceData^, TmpData^, RowSize);
5208 inc(SourceData, RowSize);
5215 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5216 function TglBitmap.AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
5218 pSource, pData, pTempData: PByte;
5219 Row, RowSize, TempWidth, TempHeight: Integer;
5220 IntFormat: TglBitmapFormat;
5221 fd: TFormatDescriptor;
5222 Mask: TglBitmapMask;
5224 function GetRowPointer(Row: Integer): pByte;
5226 result := aSurface^.pixels;
5227 Inc(result, Row * RowSize);
5232 if (Assigned(aSurface)) then begin
5233 with aSurface^.format^ do begin
5238 IntFormat := TFormatDescriptor.GetFromMask(Mask).Format;
5239 if (IntFormat = tfEmpty) then
5240 raise EglBitmap.Create('AssignFromSurface - Invalid Pixelformat.');
5243 fd := TFormatDescriptor.Get(IntFormat);
5244 TempWidth := aSurface^.w;
5245 TempHeight := aSurface^.h;
5246 RowSize := fd.GetSize(TempWidth, 1);
5247 GetMem(pData, TempHeight * RowSize);
5250 for Row := 0 to TempHeight -1 do begin
5251 pSource := GetRowPointer(Row);
5252 if (Assigned(pSource)) then begin
5253 Move(pSource^, pTempData^, RowSize);
5254 Inc(pTempData, RowSize);
5257 SetDataPointer(pData, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
5260 if Assigned(pData) then
5267 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5268 function TglBitmap.AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
5270 Row, Col, AlphaInterleave: Integer;
5271 pSource, pDest: PByte;
5273 function GetRowPointer(Row: Integer): pByte;
5275 result := aSurface.pixels;
5276 Inc(result, Row * Width);
5281 if Assigned(Data) then begin
5282 if Format in [tfAlpha8ub1, tfLuminance8Alpha8ub2, tfBGRA8ub4, tfRGBA8ub4] then begin
5283 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, 8, $FF, $FF, $FF, 0);
5285 AlphaInterleave := 0;
5287 tfLuminance8Alpha8ub2:
5288 AlphaInterleave := 1;
5289 tfBGRA8ub4, tfRGBA8ub4:
5290 AlphaInterleave := 3;
5294 for Row := 0 to Height -1 do begin
5295 pDest := GetRowPointer(Row);
5296 if Assigned(pDest) then begin
5297 for Col := 0 to Width -1 do begin
5298 Inc(pSource, AlphaInterleave);
5310 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5311 function TglBitmap.AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
5315 bmp := TglBitmap2D.Create;
5317 bmp.AssignFromSurface(aSurface);
5318 result := AddAlphaFromGlBitmap(bmp, aFunc, aArgs);
5326 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5327 function CreateGrayPalette: HPALETTE;
5332 GetMem(Pal, SizeOf(TLogPalette) + (SizeOf(TPaletteEntry) * 256));
5334 Pal.palVersion := $300;
5335 Pal.palNumEntries := 256;
5337 for Idx := 0 to Pal.palNumEntries - 1 do begin
5338 Pal.palPalEntry[Idx].peRed := Idx;
5339 Pal.palPalEntry[Idx].peGreen := Idx;
5340 Pal.palPalEntry[Idx].peBlue := Idx;
5341 Pal.palPalEntry[Idx].peFlags := 0;
5343 Result := CreatePalette(Pal^);
5347 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5348 function TglBitmap.AssignToBitmap(const aBitmap: TBitmap): Boolean;
5351 pSource, pData: PByte;
5354 if Assigned(Data) then begin
5355 if Assigned(aBitmap) then begin
5356 aBitmap.Width := Width;
5357 aBitmap.Height := Height;
5360 tfAlpha8ub1, tfLuminance8ub1: begin
5361 aBitmap.PixelFormat := pf8bit;
5362 aBitmap.Palette := CreateGrayPalette;
5365 aBitmap.PixelFormat := pf15bit;
5367 aBitmap.PixelFormat := pf16bit;
5368 tfRGB8ub3, tfBGR8ub3:
5369 aBitmap.PixelFormat := pf24bit;
5370 tfRGBA8ub4, tfBGRA8ub4:
5371 aBitmap.PixelFormat := pf32bit;
5373 raise EglBitmap.Create('AssignToBitmap - Invalid Pixelformat.');
5377 for Row := 0 to FileHeight -1 do begin
5378 pData := aBitmap.Scanline[Row];
5379 Move(pSource^, pData^, fRowSize);
5380 Inc(pSource, fRowSize);
5381 if (Format in [tfRGB8ub3, tfRGBA8ub4]) then // swap RGB(A) to BGR(A)
5382 SwapRGB(pData, FileWidth, Format = tfRGBA8ub4);
5389 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5390 function TglBitmap.AssignFromBitmap(const aBitmap: TBitmap): Boolean;
5392 pSource, pData, pTempData: PByte;
5393 Row, RowSize, TempWidth, TempHeight: Integer;
5394 IntFormat: TglBitmapFormat;
5398 if (Assigned(aBitmap)) then begin
5399 case aBitmap.PixelFormat of
5401 IntFormat := tfLuminance8ub1;
5403 IntFormat := tfRGB5A1us1;
5405 IntFormat := tfR5G6B5us1;
5407 IntFormat := tfBGR8ub3;
5409 IntFormat := tfBGRA8ub4;
5411 raise EglBitmap.Create('AssignFromBitmap - Invalid Pixelformat.');
5414 TempWidth := aBitmap.Width;
5415 TempHeight := aBitmap.Height;
5416 RowSize := TFormatDescriptor.Get(IntFormat).GetSize(TempWidth, 1);
5417 GetMem(pData, TempHeight * RowSize);
5420 for Row := 0 to TempHeight -1 do begin
5421 pSource := aBitmap.Scanline[Row];
5422 if (Assigned(pSource)) then begin
5423 Move(pSource^, pTempData^, RowSize);
5424 Inc(pTempData, RowSize);
5427 SetDataPointer(pData, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
5430 if Assigned(pData) then
5437 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5438 function TglBitmap.AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
5440 Row, Col, AlphaInterleave: Integer;
5441 pSource, pDest: PByte;
5445 if Assigned(Data) then begin
5446 if (Format in [tfAlpha8ub1, tfLuminance8Alpha8ub2, tfRGBA8ub4, tfBGRA8ub4]) then begin
5447 if Assigned(aBitmap) then begin
5448 aBitmap.PixelFormat := pf8bit;
5449 aBitmap.Palette := CreateGrayPalette;
5450 aBitmap.Width := Width;
5451 aBitmap.Height := Height;
5454 tfLuminance8Alpha8ub2:
5455 AlphaInterleave := 1;
5456 tfRGBA8ub4, tfBGRA8ub4:
5457 AlphaInterleave := 3;
5459 AlphaInterleave := 0;
5465 for Row := 0 to Height -1 do begin
5466 pDest := aBitmap.Scanline[Row];
5467 if Assigned(pDest) then begin
5468 for Col := 0 to Width -1 do begin
5469 Inc(pSource, AlphaInterleave);
5482 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5483 function TglBitmap.AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5487 tex := TglBitmap2D.Create;
5489 tex.AssignFromBitmap(ABitmap);
5490 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
5497 {$IFDEF GLB_LAZARUS}
5498 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5499 function TglBitmap.AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
5501 rid: TRawImageDescription;
5502 FormatDesc: TFormatDescriptor;
5504 if not Assigned(Data) then
5505 raise EglBitmap.Create('no pixel data assigned. load data before save');
5508 if not Assigned(aImage) or (Format = tfEmpty) then
5510 FormatDesc := TFormatDescriptor.Get(Format);
5511 if FormatDesc.IsCompressed then
5514 FillChar(rid{%H-}, SizeOf(rid), 0);
5515 if FormatDesc.IsGrayscale then
5516 rid.Format := ricfGray
5518 rid.Format := ricfRGBA;
5521 rid.Height := Height;
5522 rid.Depth := FormatDesc.BitsPerPixel;
5523 rid.BitOrder := riboBitsInOrder;
5524 rid.ByteOrder := riboLSBFirst;
5525 rid.LineOrder := riloTopToBottom;
5526 rid.LineEnd := rileTight;
5527 rid.BitsPerPixel := FormatDesc.BitsPerPixel;
5528 rid.RedPrec := CountSetBits(FormatDesc.Range.r);
5529 rid.GreenPrec := CountSetBits(FormatDesc.Range.g);
5530 rid.BluePrec := CountSetBits(FormatDesc.Range.b);
5531 rid.AlphaPrec := CountSetBits(FormatDesc.Range.a);
5532 rid.RedShift := FormatDesc.Shift.r;
5533 rid.GreenShift := FormatDesc.Shift.g;
5534 rid.BlueShift := FormatDesc.Shift.b;
5535 rid.AlphaShift := FormatDesc.Shift.a;
5537 rid.MaskBitsPerPixel := 0;
5538 rid.PaletteColorCount := 0;
5540 aImage.DataDescription := rid;
5543 if not Assigned(aImage.PixelData) then
5544 raise EglBitmap.Create('error while creating LazIntfImage');
5545 Move(Data^, aImage.PixelData^, FormatDesc.GetSize(Dimension));
5550 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5551 function TglBitmap.AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
5554 FormatDesc: TFormatDescriptor;
5558 Mask: TglBitmapRec4ul;
5560 procedure CopyConvert;
5562 bfFormat: TbmpBitfieldFormat;
5563 pSourceLine, pDestLine: PByte;
5564 pSourceMD, pDestMD: Pointer;
5565 Shift, Prec: TglBitmapRec4ub;
5567 pixel: TglBitmapPixelData;
5569 bfFormat := TbmpBitfieldFormat.Create;
5570 with aImage.DataDescription do begin
5572 Prec.g := GreenPrec;
5574 Prec.a := AlphaPrec;
5575 Shift.r := RedShift;
5576 Shift.g := GreenShift;
5577 Shift.b := BlueShift;
5578 Shift.a := AlphaShift;
5579 bfFormat.SetCustomValues(BitsPerPixel, Prec, Shift);
5581 pSourceMD := bfFormat.CreateMappingData;
5582 pDestMD := FormatDesc.CreateMappingData;
5584 for y := 0 to aImage.Height-1 do begin
5585 pSourceLine := aImage.PixelData + y {%H-}* aImage.DataDescription.BytesPerLine;
5586 pDestLine := ImageData + y * Round(FormatDesc.BytesPerPixel * aImage.Width);
5587 for x := 0 to aImage.Width-1 do begin
5588 bfFormat.Unmap(pSourceLine, pixel, pSourceMD);
5589 FormatDesc.Map(pixel, pDestLine, pDestMD);
5593 FormatDesc.FreeMappingData(pDestMD);
5594 bfFormat.FreeMappingData(pSourceMD);
5601 if not Assigned(aImage) then
5604 with aImage.DataDescription do begin
5605 Mask.r := (QWord(1 shl RedPrec )-1) shl RedShift;
5606 Mask.g := (QWord(1 shl GreenPrec)-1) shl GreenShift;
5607 Mask.b := (QWord(1 shl BluePrec )-1) shl BlueShift;
5608 Mask.a := (QWord(1 shl AlphaPrec)-1) shl AlphaShift;
5610 FormatDesc := TFormatDescriptor.GetFromMask(Mask);
5611 f := FormatDesc.Format;
5612 if (f = tfEmpty) then
5616 (FormatDesc.BitsPerPixel = aImage.DataDescription.Depth) and
5617 (aImage.DataDescription.BitsPerPixel = aImage.DataDescription.Depth);
5619 ImageSize := FormatDesc.GetSize(aImage.Width, aImage.Height);
5620 ImageData := GetMem(ImageSize);
5623 Move(aImage.PixelData^, ImageData^, ImageSize)
5626 SetDataPointer(ImageData, f, aImage.Width, aImage.Height); //be careful, Data could be freed by this method
5628 if Assigned(ImageData) then
5636 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5637 function TglBitmap.AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
5639 rid: TRawImageDescription;
5640 FormatDesc: TFormatDescriptor;
5641 Pixel: TglBitmapPixelData;
5647 if not Assigned(aImage) or (Format = tfEmpty) then
5649 FormatDesc := TFormatDescriptor.Get(Format);
5650 if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
5653 FillChar(rid{%H-}, SizeOf(rid), 0);
5654 rid.Format := ricfGray;
5656 rid.Height := Height;
5657 rid.Depth := CountSetBits(FormatDesc.Range.a);
5658 rid.BitOrder := riboBitsInOrder;
5659 rid.ByteOrder := riboLSBFirst;
5660 rid.LineOrder := riloTopToBottom;
5661 rid.LineEnd := rileTight;
5662 rid.BitsPerPixel := 8 * Ceil(rid.Depth / 8);
5663 rid.RedPrec := CountSetBits(FormatDesc.Range.a);
5668 rid.GreenShift := 0;
5670 rid.AlphaShift := 0;
5672 rid.MaskBitsPerPixel := 0;
5673 rid.PaletteColorCount := 0;
5675 aImage.DataDescription := rid;
5678 srcMD := FormatDesc.CreateMappingData;
5680 FormatDesc.PreparePixel(Pixel);
5682 dst := aImage.PixelData;
5683 for y := 0 to Height-1 do
5684 for x := 0 to Width-1 do begin
5685 FormatDesc.Unmap(src, Pixel, srcMD);
5686 case rid.BitsPerPixel of
5688 dst^ := Pixel.Data.a;
5692 PWord(dst)^ := Pixel.Data.a;
5696 PByteArray(dst)^[0] := PByteArray(@Pixel.Data.a)^[0];
5697 PByteArray(dst)^[1] := PByteArray(@Pixel.Data.a)^[1];
5698 PByteArray(dst)^[2] := PByteArray(@Pixel.Data.a)^[2];
5702 PCardinal(dst)^ := Pixel.Data.a;
5706 raise EglBitmapUnsupportedFormat.Create(Format);
5710 FormatDesc.FreeMappingData(srcMD);
5715 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5716 function TglBitmap.AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5720 tex := TglBitmap2D.Create;
5722 tex.AssignFromLazIntfImage(aImage);
5723 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
5730 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5731 function TglBitmap.AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar;
5732 const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5734 rs: TResourceStream;
5736 PrepareResType(aResource, aResType);
5737 rs := TResourceStream.Create(aInstance, aResource, aResType);
5739 result := AddAlphaFromStream(rs, aFunc, aArgs);
5745 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5746 function TglBitmap.AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
5747 const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5749 rs: TResourceStream;
5751 rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
5753 result := AddAlphaFromStream(rs, aFunc, aArgs);
5759 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5760 function TglBitmap.AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5762 if TFormatDescriptor.Get(Format).IsCompressed then
5763 raise EglBitmapUnsupportedFormat.Create(Format);
5764 result := AddFunc(Self, aFunc, false, TFormatDescriptor.Get(Format).WithAlpha, aArgs);
5767 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5768 function TglBitmap.AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5772 FS := TFileStream.Create(aFileName, fmOpenRead);
5774 result := AddAlphaFromStream(FS, aFunc, aArgs);
5780 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5781 function TglBitmap.AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5785 tex := TglBitmap2D.Create(aStream);
5787 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
5793 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5794 function TglBitmap.AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5796 DestData, DestData2, SourceData: pByte;
5797 TempHeight, TempWidth: Integer;
5798 SourceFD, DestFD: TFormatDescriptor;
5799 SourceMD, DestMD, DestMD2: Pointer;
5801 FuncRec: TglBitmapFunctionRec;
5805 Assert(Assigned(Data));
5806 Assert(Assigned(aBitmap));
5807 Assert(Assigned(aBitmap.Data));
5809 if ((aBitmap.Width = Width) and (aBitmap.Height = Height)) then begin
5810 result := ConvertTo(TFormatDescriptor.Get(Format).WithAlpha);
5812 SourceFD := TFormatDescriptor.Get(aBitmap.Format);
5813 DestFD := TFormatDescriptor.Get(Format);
5815 if not Assigned(aFunc) then begin
5816 aFunc := glBitmapAlphaFunc;
5817 FuncRec.Args := {%H-}Pointer(SourceFD.HasAlpha);
5819 FuncRec.Args := aArgs;
5822 TempHeight := aBitmap.FileHeight;
5823 TempWidth := aBitmap.FileWidth;
5825 FuncRec.Sender := Self;
5826 FuncRec.Size := Dimension;
5827 FuncRec.Position.Fields := FuncRec.Size.Fields;
5831 SourceData := aBitmap.Data;
5834 SourceFD.PreparePixel(FuncRec.Source);
5835 DestFD.PreparePixel (FuncRec.Dest);
5837 SourceMD := SourceFD.CreateMappingData;
5838 DestMD := DestFD.CreateMappingData;
5839 DestMD2 := DestFD.CreateMappingData;
5841 FuncRec.Position.Y := 0;
5842 while FuncRec.Position.Y < TempHeight do begin
5843 FuncRec.Position.X := 0;
5844 while FuncRec.Position.X < TempWidth do begin
5845 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
5846 DestFD.Unmap (DestData, FuncRec.Dest, DestMD);
5848 DestFD.Map(FuncRec.Dest, DestData2, DestMD2);
5849 inc(FuncRec.Position.X);
5851 inc(FuncRec.Position.Y);
5854 SourceFD.FreeMappingData(SourceMD);
5855 DestFD.FreeMappingData(DestMD);
5856 DestFD.FreeMappingData(DestMD2);
5861 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5862 function TglBitmap.AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte): Boolean;
5864 result := AddAlphaFromColorKeyFloat(aRed / $FF, aGreen / $FF, aBlue / $FF, aDeviation / $FF);
5867 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5868 function TglBitmap.AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal): Boolean;
5870 PixelData: TglBitmapPixelData;
5872 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5873 result := AddAlphaFromColorKeyFloat(
5874 aRed / PixelData.Range.r,
5875 aGreen / PixelData.Range.g,
5876 aBlue / PixelData.Range.b,
5877 aDeviation / Max(PixelData.Range.r, Max(PixelData.Range.g, PixelData.Range.b)));
5880 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5881 function TglBitmap.AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single): Boolean;
5883 values: array[0..2] of Single;
5886 PixelData: TglBitmapPixelData;
5888 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5889 with PixelData do begin
5891 values[1] := aGreen;
5894 for i := 0 to 2 do begin
5895 tmp := Trunc(Range.arr[i] * aDeviation);
5896 Data.arr[i] := Min(Range.arr[i], Trunc(Range.arr[i] * values[i] + tmp));
5897 Range.arr[i] := Max(0, Trunc(Range.arr[i] * values[i] - tmp));
5902 result := AddAlphaFromFunc(glBitmapColorKeyAlphaFunc, @PixelData);
5905 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5906 function TglBitmap.AddAlphaFromValue(const aAlpha: Byte): Boolean;
5908 result := AddAlphaFromValueFloat(aAlpha / $FF);
5911 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5912 function TglBitmap.AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
5914 PixelData: TglBitmapPixelData;
5916 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5917 result := AddAlphaFromValueFloat(aAlpha / PixelData.Range.a);
5920 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5921 function TglBitmap.AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
5923 PixelData: TglBitmapPixelData;
5925 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5927 Data.a := Min(Range.a, Max(0, Round(Range.a * aAlpha)));
5928 result := AddAlphaFromFunc(glBitmapValueAlphaFunc, @PixelData.Data.a);
5931 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5932 function TglBitmap.RemoveAlpha: Boolean;
5934 FormatDesc: TFormatDescriptor;
5937 FormatDesc := TFormatDescriptor.Get(Format);
5938 if Assigned(Data) then begin
5939 if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
5940 raise EglBitmapUnsupportedFormat.Create(Format);
5941 result := ConvertTo(FormatDesc.WithoutAlpha);
5945 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5946 function TglBitmap.Clone: TglBitmap;
5953 Temp := (ClassType.Create as TglBitmap);
5955 // copy texture data if assigned
5956 if Assigned(Data) then begin
5957 Size := TFormatDescriptor.Get(Format).GetSize(fDimension);
5958 GetMem(TempPtr, Size);
5960 Move(Data^, TempPtr^, Size);
5961 Temp.SetDataPointer(TempPtr, Format, Width, Height); //be careful, Data could be freed by this method
5963 if Assigned(TempPtr) then
5969 Temp.SetDataPointer(TempPtr, Format, Width, Height); //be careful, Data could be freed by this method
5974 Temp.fTarget := Target;
5975 Temp.fFormat := Format;
5976 Temp.fMipMap := MipMap;
5977 Temp.fAnisotropic := Anisotropic;
5978 Temp.fBorderColor := fBorderColor;
5979 Temp.fDeleteTextureOnFree := DeleteTextureOnFree;
5980 Temp.fFreeDataAfterGenTexture := FreeDataAfterGenTexture;
5981 Temp.fFilterMin := fFilterMin;
5982 Temp.fFilterMag := fFilterMag;
5983 Temp.fWrapS := fWrapS;
5984 Temp.fWrapT := fWrapT;
5985 Temp.fWrapR := fWrapR;
5986 Temp.fFilename := fFilename;
5987 Temp.fCustomName := fCustomName;
5988 Temp.fCustomNameW := fCustomNameW;
5989 Temp.fCustomData := fCustomData;
5998 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5999 function TglBitmap.ConvertTo(const aFormat: TglBitmapFormat): Boolean;
6001 SourceFD, DestFD: TFormatDescriptor;
6002 SourcePD, DestPD: TglBitmapPixelData;
6003 ShiftData: TShiftData;
6005 function DataIsIdentical: Boolean;
6007 result := SourceFD.MaskMatch(DestFD.Mask);
6010 function CanCopyDirect: Boolean;
6013 ((SourcePD.Range.r = DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
6014 ((SourcePD.Range.g = DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
6015 ((SourcePD.Range.b = DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
6016 ((SourcePD.Range.a = DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
6019 function CanShift: Boolean;
6022 ((SourcePD.Range.r >= DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
6023 ((SourcePD.Range.g >= DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
6024 ((SourcePD.Range.b >= DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
6025 ((SourcePD.Range.a >= DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
6028 function GetShift(aSource, aDest: Cardinal) : ShortInt;
6031 while (aSource > aDest) and (aSource > 0) do begin
6033 aSource := aSource shr 1;
6038 if (aFormat <> fFormat) and (aFormat <> tfEmpty) then begin
6039 SourceFD := TFormatDescriptor.Get(Format);
6040 DestFD := TFormatDescriptor.Get(aFormat);
6042 if DataIsIdentical then begin
6048 SourceFD.PreparePixel(SourcePD);
6049 DestFD.PreparePixel (DestPD);
6051 if CanCopyDirect then
6052 result := AddFunc(Self, glBitmapConvertCopyFunc, false, aFormat)
6053 else if CanShift then begin
6054 ShiftData.r := GetShift(SourcePD.Range.r, DestPD.Range.r);
6055 ShiftData.g := GetShift(SourcePD.Range.g, DestPD.Range.g);
6056 ShiftData.b := GetShift(SourcePD.Range.b, DestPD.Range.b);
6057 ShiftData.a := GetShift(SourcePD.Range.a, DestPD.Range.a);
6058 result := AddFunc(Self, glBitmapConvertShiftRGBAFunc, false, aFormat, @ShiftData);
6060 result := AddFunc(Self, glBitmapConvertCalculateRGBAFunc, false, aFormat);
6065 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6066 procedure TglBitmap.Invert(const aUseRGB: Boolean; const aUseAlpha: Boolean);
6068 if aUseRGB or aUseAlpha then
6069 AddFunc(glBitmapInvertFunc, false, {%H-}Pointer(
6070 ((Byte(aUseAlpha) and 1) shl 1) or
6071 (Byte(aUseRGB) and 1) ));
6075 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6076 procedure TglBitmap.SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
6078 fBorderColor[0] := aRed;
6079 fBorderColor[1] := aGreen;
6080 fBorderColor[2] := aBlue;
6081 fBorderColor[3] := aAlpha;
6082 if (ID > 0) then begin
6084 glTexParameterfv(Target, GL_TEXTURE_BORDER_COLOR, @fBorderColor[0]);
6089 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6090 procedure TglBitmap.FreeData;
6095 SetDataPointer(TempPtr, tfEmpty); //be careful, Data could be freed by this method
6098 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6099 procedure TglBitmap.FillWithColor(const aRed, aGreen, aBlue: Byte;
6100 const aAlpha: Byte);
6102 FillWithColorFloat(aRed/$FF, aGreen/$FF, aBlue/$FF, aAlpha/$FF);
6105 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6106 procedure TglBitmap.FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal);
6108 PixelData: TglBitmapPixelData;
6110 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
6112 aRed / PixelData.Range.r,
6113 aGreen / PixelData.Range.g,
6114 aBlue / PixelData.Range.b,
6115 aAlpha / PixelData.Range.a);
6118 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6119 procedure TglBitmap.FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single);
6121 PixelData: TglBitmapPixelData;
6123 TFormatDescriptor.Get(Format).PreparePixel(PixelData);
6124 with PixelData do begin
6125 Data.r := Max(0, Min(Range.r, Trunc(Range.r * aRed)));
6126 Data.g := Max(0, Min(Range.g, Trunc(Range.g * aGreen)));
6127 Data.b := Max(0, Min(Range.b, Trunc(Range.b * aBlue)));
6128 Data.a := Max(0, Min(Range.a, Trunc(Range.a * aAlpha)));
6130 AddFunc(glBitmapFillWithColorFunc, false, @PixelData);
6133 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6134 procedure TglBitmap.SetFilter(const aMin, aMag: GLenum);
6139 fFilterMin := GL_NEAREST;
6141 fFilterMin := GL_LINEAR;
6142 GL_NEAREST_MIPMAP_NEAREST:
6143 fFilterMin := GL_NEAREST_MIPMAP_NEAREST;
6144 GL_LINEAR_MIPMAP_NEAREST:
6145 fFilterMin := GL_LINEAR_MIPMAP_NEAREST;
6146 GL_NEAREST_MIPMAP_LINEAR:
6147 fFilterMin := GL_NEAREST_MIPMAP_LINEAR;
6148 GL_LINEAR_MIPMAP_LINEAR:
6149 fFilterMin := GL_LINEAR_MIPMAP_LINEAR;
6151 raise EglBitmap.Create('SetFilter - Unknow MIN filter.');
6157 fFilterMag := GL_NEAREST;
6159 fFilterMag := GL_LINEAR;
6161 raise EglBitmap.Create('SetFilter - Unknow MAG filter.');
6165 if (ID > 0) then begin
6167 glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, fFilterMag);
6169 if (MipMap = mmNone) {$IFNDEF OPENGL_ES}or (Target = GL_TEXTURE_RECTANGLE){$ENDIF} then begin
6171 GL_NEAREST, GL_LINEAR:
6172 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
6173 GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR:
6174 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6175 GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR:
6176 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6179 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
6183 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6184 procedure TglBitmap.SetWrap(const S: GLenum; const T: GLenum; const R: GLenum);
6186 procedure CheckAndSetWrap(const aValue: Cardinal; var aTarget: Cardinal);
6191 aTarget := GL_CLAMP;
6195 aTarget := GL_REPEAT;
6197 GL_CLAMP_TO_EDGE: begin
6199 if not GL_VERSION_1_2 and not GL_EXT_texture_edge_clamp then
6203 aTarget := GL_CLAMP_TO_EDGE;
6207 GL_CLAMP_TO_BORDER: begin
6208 if GL_VERSION_1_3 or GL_ARB_texture_border_clamp then
6209 aTarget := GL_CLAMP_TO_BORDER
6211 aTarget := GL_CLAMP;
6215 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
6216 GL_MIRRORED_REPEAT: begin
6218 if GL_VERSION_1_4 or GL_ARB_texture_mirrored_repeat or GL_IBM_texture_mirrored_repeat then
6220 if GL_VERSION_2_0 then
6222 aTarget := GL_MIRRORED_REPEAT
6224 raise EglBitmap.Create('SetWrap - Unsupported Texturewrap GL_MIRRORED_REPEAT (S).');
6228 raise EglBitmap.Create('SetWrap - Unknow Texturewrap');
6233 CheckAndSetWrap(S, fWrapS);
6234 CheckAndSetWrap(T, fWrapT);
6235 CheckAndSetWrap(R, fWrapR);
6237 if (ID > 0) then begin
6239 glTexParameteri(Target, GL_TEXTURE_WRAP_S, fWrapS);
6240 glTexParameteri(Target, GL_TEXTURE_WRAP_T, fWrapT);
6241 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
6242 {$IFDEF OPENGL_ES} if GL_VERSION_3_0 then{$ENDIF}
6243 glTexParameteri(Target, GL_TEXTURE_WRAP_R, fWrapR);
6248 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
6249 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6250 procedure TglBitmap.SetSwizzle(const r, g, b, a: GLenum);
6252 procedure CheckAndSetValue(const aValue: GLenum; const aIndex: Integer);
6254 if (aValue = GL_ZERO) or (aValue = GL_ONE) or (aValue = GL_ALPHA) or
6255 (aValue = GL_RED) or (aValue = GL_GREEN) or (aValue = GL_BLUE) then
6256 fSwizzle[aIndex] := aValue
6258 raise EglBitmap.Create('SetSwizzle - Unknow Swizle Value');
6263 if not (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
6264 raise EglBitmapNotSupported.Create('texture swizzle is not supported');
6266 if not GL_VERSION_3_0 then
6267 raise EglBitmapNotSupported.Create('texture swizzle is not supported');
6269 CheckAndSetValue(r, 0);
6270 CheckAndSetValue(g, 1);
6271 CheckAndSetValue(b, 2);
6272 CheckAndSetValue(a, 3);
6274 if (ID > 0) then begin
6277 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_RGBA, PGLint(@fSwizzle[0]));
6279 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_R, PGLint(@fSwizzle[0]));
6280 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_G, PGLint(@fSwizzle[1]));
6281 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_B, PGLint(@fSwizzle[2]));
6282 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_A, PGLint(@fSwizzle[3]));
6288 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6289 procedure TglBitmap.Bind(const aEnableTextureUnit: Boolean);
6291 if aEnableTextureUnit then
6294 glBindTexture(Target, ID);
6297 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6298 procedure TglBitmap.Unbind(const aDisableTextureUnit: Boolean);
6300 if aDisableTextureUnit then
6302 glBindTexture(Target, 0);
6305 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6306 constructor TglBitmap.Create;
6308 if (ClassType = TglBitmap) then
6309 raise EglBitmap.Create('Don''t create TglBitmap directly. Use one of the deviated classes (TglBitmap2D) instead.');
6310 {$IFDEF GLB_NATIVE_OGL}
6311 glbReadOpenGLExtensions;
6314 fFormat := glBitmapGetDefaultFormat;
6315 fFreeDataOnDestroy := true;
6318 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6319 constructor TglBitmap.Create(const aFileName: String);
6322 LoadFromFile(aFileName);
6325 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6326 constructor TglBitmap.Create(const aStream: TStream);
6329 LoadFromStream(aStream);
6332 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6333 constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; aData: PByte);
6338 if not Assigned(aData) then begin
6339 ImageSize := TFormatDescriptor.Get(aFormat).GetSize(aSize);
6340 GetMem(aData, ImageSize);
6342 FillChar(aData^, ImageSize, #$FF);
6343 SetDataPointer(aData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
6345 if Assigned(aData) then
6350 SetDataPointer(aData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
6351 fFreeDataOnDestroy := false;
6355 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6356 constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer);
6359 LoadFromFunc(aSize, aFunc, aFormat, aArgs);
6362 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6363 constructor TglBitmap.Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar);
6366 LoadFromResource(aInstance, aResource, aResType);
6369 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6370 constructor TglBitmap.Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
6373 LoadFromResourceID(aInstance, aResourceID, aResType);
6376 {$IFDEF GLB_SUPPORT_PNG_READ}
6377 {$IF DEFINED(GLB_LAZ_PNG)}
6378 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6379 //PNG/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6380 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6381 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6384 PNG_MAGIC: String[MAGIC_LEN] = #$89#$50#$4E#$47#$0D#$0A#$1A#$0A;
6386 reader: TLazReaderPNG;
6387 intf: TLazIntfImage;
6389 magic: String[MAGIC_LEN];
6392 StreamPos := aStream.Position;
6394 SetLength(magic, MAGIC_LEN);
6395 aStream.Read(magic[1], MAGIC_LEN);
6396 aStream.Position := StreamPos;
6397 if (magic <> PNG_MAGIC) then begin
6402 intf := TLazIntfImage.Create(0, 0);
6403 reader := TLazReaderPNG.Create;
6405 reader.UpdateDescription := true;
6406 reader.ImageRead(aStream, intf);
6407 AssignFromLazIntfImage(intf);
6410 aStream.Position := StreamPos;
6419 {$ELSEIF DEFINED(GLB_SDL_IMAGE)}
6420 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6421 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6423 Surface: PSDL_Surface;
6427 RWops := glBitmapCreateRWops(aStream);
6429 if IMG_isPNG(RWops) > 0 then begin
6430 Surface := IMG_LoadPNG_RW(RWops);
6432 AssignFromSurface(Surface);
6435 SDL_FreeSurface(Surface);
6443 {$ELSEIF DEFINED(GLB_LIB_PNG)}
6444 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6445 procedure glBitmap_libPNG_read_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
6447 TStream(png_get_io_ptr(png)).Read(buffer^, size);
6450 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6451 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6454 signature: array [0..7] of byte;
6456 png_info: png_infop;
6458 TempHeight, TempWidth: Integer;
6459 Format: TglBitmapFormat;
6462 png_rows: array of pByte;
6463 Row, LineSize: Integer;
6467 if not init_libPNG then
6468 raise Exception.Create('LoadPNG - unable to initialize libPNG.');
6472 StreamPos := aStream.Position;
6473 aStream.Read(signature{%H-}, 8);
6474 aStream.Position := StreamPos;
6476 if png_check_sig(@signature, 8) <> 0 then begin
6478 png := png_create_read_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
6480 raise EglBitmapException.Create('LoadPng - couldn''t create read struct.');
6483 png_info := png_create_info_struct(png);
6484 if png_info = nil then begin
6485 png_destroy_read_struct(@png, nil, nil);
6486 raise EglBitmapException.Create('LoadPng - couldn''t create info struct.');
6489 // set read callback
6490 png_set_read_fn(png, aStream, glBitmap_libPNG_read_func);
6492 // read informations
6493 png_read_info(png, png_info);
6496 TempHeight := png_get_image_height(png, png_info);
6497 TempWidth := png_get_image_width(png, png_info);
6500 case png_get_color_type(png, png_info) of
6501 PNG_COLOR_TYPE_GRAY:
6502 Format := tfLuminance8ub1;
6503 PNG_COLOR_TYPE_GRAY_ALPHA:
6504 Format := tfLuminance8Alpha8us1;
6506 Format := tfRGB8ub3;
6507 PNG_COLOR_TYPE_RGB_ALPHA:
6508 Format := tfRGBA8ub4;
6510 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
6513 // cut upper 8 bit from 16 bit formats
6514 if png_get_bit_depth(png, png_info) > 8 then
6515 png_set_strip_16(png);
6517 // expand bitdepth smaller than 8
6518 if png_get_bit_depth(png, png_info) < 8 then
6519 png_set_expand(png);
6521 // allocating mem for scanlines
6522 LineSize := png_get_rowbytes(png, png_info);
6523 GetMem(png_data, TempHeight * LineSize);
6525 SetLength(png_rows, TempHeight);
6526 for Row := Low(png_rows) to High(png_rows) do begin
6527 png_rows[Row] := png_data;
6528 Inc(png_rows[Row], Row * LineSize);
6531 // read complete image into scanlines
6532 png_read_image(png, @png_rows[0]);
6535 png_read_end(png, png_info);
6537 // destroy read struct
6538 png_destroy_read_struct(@png, @png_info, nil);
6540 SetLength(png_rows, 0);
6543 SetDataPointer(png_data, Format, TempWidth, TempHeight); //be careful, Data could be freed by this method
6547 if Assigned(png_data) then
6557 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
6558 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6559 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6564 Row, Col, PixSize, LineSize: Integer;
6565 NewImage, pSource, pDest, pAlpha: pByte;
6566 PngFormat: TglBitmapFormat;
6567 FormatDesc: TFormatDescriptor;
6570 PngHeader: String[8] = #137#80#78#71#13#10#26#10;
6575 StreamPos := aStream.Position;
6576 aStream.Read(Header[0], SizeOf(Header));
6577 aStream.Position := StreamPos;
6579 {Test if the header matches}
6580 if Header = PngHeader then begin
6581 Png := TPNGObject.Create;
6583 Png.LoadFromStream(aStream);
6585 case Png.Header.ColorType of
6587 PngFormat := tfLuminance8ub1;
6588 COLOR_GRAYSCALEALPHA:
6589 PngFormat := tfLuminance8Alpha8us1;
6591 PngFormat := tfBGR8ub3;
6593 PngFormat := tfBGRA8ub4;
6595 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
6598 FormatDesc := TFormatDescriptor.Get(PngFormat);
6599 PixSize := Round(FormatDesc.PixelSize);
6600 LineSize := FormatDesc.GetSize(Png.Header.Width, 1);
6602 GetMem(NewImage, LineSize * Integer(Png.Header.Height));
6606 case Png.Header.ColorType of
6607 COLOR_RGB, COLOR_GRAYSCALE:
6609 for Row := 0 to Png.Height -1 do begin
6610 Move (Png.Scanline[Row]^, pDest^, LineSize);
6611 Inc(pDest, LineSize);
6614 COLOR_RGBALPHA, COLOR_GRAYSCALEALPHA:
6616 PixSize := PixSize -1;
6618 for Row := 0 to Png.Height -1 do begin
6619 pSource := Png.Scanline[Row];
6620 pAlpha := pByte(Png.AlphaScanline[Row]);
6622 for Col := 0 to Png.Width -1 do begin
6623 Move (pSource^, pDest^, PixSize);
6624 Inc(pSource, PixSize);
6625 Inc(pDest, PixSize);
6634 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
6637 SetDataPointer(NewImage, PngFormat, Png.Header.Width, Png.Header.Height); //be careful, Data could be freed by this method
6641 if Assigned(NewImage) then
6653 {$IFDEF GLB_SUPPORT_PNG_WRITE}
6654 {$IFDEF GLB_LIB_PNG}
6655 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6656 procedure glBitmap_libPNG_write_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
6658 TStream(png_get_io_ptr(png)).Write(buffer^, size);
6662 {$IF DEFINED(GLB_LAZ_PNG)}
6663 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6664 procedure TglBitmap.SavePNG(const aStream: TStream);
6666 png: TPortableNetworkGraphic;
6667 intf: TLazIntfImage;
6670 png := TPortableNetworkGraphic.Create;
6671 intf := TLazIntfImage.Create(0, 0);
6673 if not AssignToLazIntfImage(intf) then
6674 raise EglBitmap.Create('unable to create LazIntfImage from glBitmap');
6675 intf.GetRawImage(raw);
6676 png.LoadFromRawImage(raw, false);
6677 png.SaveToStream(aStream);
6684 {$ELSEIF DEFINED(GLB_LIB_PNG)}
6685 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6686 procedure TglBitmap.SavePNG(const aStream: TStream);
6689 png_info: png_infop;
6690 png_rows: array of pByte;
6694 FormatDesc: TFormatDescriptor;
6696 if not (ftPNG in FormatGetSupportedFiles(Format)) then
6697 raise EglBitmapUnsupportedFormat.Create(Format);
6699 if not init_libPNG then
6700 raise Exception.Create('unable to initialize libPNG.');
6704 tfAlpha8ub1, tfLuminance8ub1:
6705 ColorType := PNG_COLOR_TYPE_GRAY;
6706 tfLuminance8Alpha8us1:
6707 ColorType := PNG_COLOR_TYPE_GRAY_ALPHA;
6708 tfBGR8ub3, tfRGB8ub3:
6709 ColorType := PNG_COLOR_TYPE_RGB;
6710 tfBGRA8ub4, tfRGBA8ub4:
6711 ColorType := PNG_COLOR_TYPE_RGBA;
6713 raise EglBitmapUnsupportedFormat.Create(Format);
6716 FormatDesc := TFormatDescriptor.Get(Format);
6717 LineSize := FormatDesc.GetSize(Width, 1);
6719 // creating array for scanline
6720 SetLength(png_rows, Height);
6722 for Row := 0 to Height - 1 do begin
6723 png_rows[Row] := Data;
6724 Inc(png_rows[Row], Row * LineSize)
6728 png := png_create_write_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
6730 raise EglBitmapException.Create('SavePng - couldn''t create write struct.');
6733 png_info := png_create_info_struct(png);
6734 if png_info = nil then begin
6735 png_destroy_write_struct(@png, nil);
6736 raise EglBitmapException.Create('SavePng - couldn''t create info struct.');
6739 // set read callback
6740 png_set_write_fn(png, aStream, glBitmap_libPNG_write_func, nil);
6743 png_set_compression_level(png, 6);
6745 if Format in [tfBGR8ub3, tfBGRA8ub4] then
6748 png_set_IHDR(png, png_info, Width, Height, 8, ColorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
6749 png_write_info(png, png_info);
6750 png_write_image(png, @png_rows[0]);
6751 png_write_end(png, png_info);
6752 png_destroy_write_struct(@png, @png_info);
6754 SetLength(png_rows, 0);
6761 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
6762 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6763 procedure TglBitmap.SavePNG(const aStream: TStream);
6767 pSource, pDest: pByte;
6768 X, Y, PixSize: Integer;
6769 ColorType: Cardinal;
6775 if not (ftPNG in FormatGetSupportedFiles (Format)) then
6776 raise EglBitmapUnsupportedFormat.Create(Format);
6779 tfAlpha8ub1, tfLuminance8ub1: begin
6780 ColorType := COLOR_GRAYSCALE;
6784 tfLuminance8Alpha8us1: begin
6785 ColorType := COLOR_GRAYSCALEALPHA;
6789 tfBGR8ub3, tfRGB8ub3: begin
6790 ColorType := COLOR_RGB;
6794 tfBGRA8ub4, tfRGBA8ub4: begin
6795 ColorType := COLOR_RGBALPHA;
6800 raise EglBitmapUnsupportedFormat.Create(Format);
6803 Png := TPNGObject.CreateBlank(ColorType, 8, Width, Height);
6807 for Y := 0 to Height -1 do begin
6808 pDest := png.ScanLine[Y];
6809 for X := 0 to Width -1 do begin
6810 Move(pSource^, pDest^, PixSize);
6811 Inc(pDest, PixSize);
6812 Inc(pSource, PixSize);
6814 png.AlphaScanline[Y]^[X] := pSource^;
6819 // convert RGB line to BGR
6820 if Format in [tfRGB8ub3, tfRGBA8ub4] then begin
6821 pTemp := png.ScanLine[Y];
6822 for X := 0 to Width -1 do begin
6823 Temp := pByteArray(pTemp)^[0];
6824 pByteArray(pTemp)^[0] := pByteArray(pTemp)^[2];
6825 pByteArray(pTemp)^[2] := Temp;
6832 Png.CompressionLevel := 6;
6833 Png.SaveToStream(aStream);
6841 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6842 //JPEG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6843 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6844 {$IFDEF GLB_LIB_JPEG}
6846 glBitmap_libJPEG_source_mgr_ptr = ^glBitmap_libJPEG_source_mgr;
6847 glBitmap_libJPEG_source_mgr = record
6848 pub: jpeg_source_mgr;
6851 SrcBuffer: array [1..4096] of byte;
6854 glBitmap_libJPEG_dest_mgr_ptr = ^glBitmap_libJPEG_dest_mgr;
6855 glBitmap_libJPEG_dest_mgr = record
6856 pub: jpeg_destination_mgr;
6858 DestStream: TStream;
6859 DestBuffer: array [1..4096] of byte;
6862 procedure glBitmap_libJPEG_error_exit(cinfo: j_common_ptr); cdecl;
6868 procedure glBitmap_libJPEG_output_message(cinfo: j_common_ptr); cdecl;
6874 procedure glBitmap_libJPEG_init_source(cinfo: j_decompress_ptr); cdecl;
6879 procedure glBitmap_libJPEG_term_source(cinfo: j_decompress_ptr); cdecl;
6885 procedure glBitmap_libJPEG_init_destination(cinfo: j_compress_ptr); cdecl;
6891 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6892 function glBitmap_libJPEG_fill_input_buffer(cinfo: j_decompress_ptr): boolean; cdecl;
6894 src: glBitmap_libJPEG_source_mgr_ptr;
6897 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
6899 bytes := src^.SrcStream.Read(src^.SrcBuffer[1], 4096);
6900 if (bytes <= 0) then begin
6901 src^.SrcBuffer[1] := $FF;
6902 src^.SrcBuffer[2] := JPEG_EOI;
6906 src^.pub.next_input_byte := @(src^.SrcBuffer[1]);
6907 src^.pub.bytes_in_buffer := bytes;
6912 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6913 procedure glBitmap_libJPEG_skip_input_data(cinfo: j_decompress_ptr; num_bytes: Longint); cdecl;
6915 src: glBitmap_libJPEG_source_mgr_ptr;
6917 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
6919 if num_bytes > 0 then begin
6920 // wanted byte isn't in buffer so set stream position and read buffer
6921 if num_bytes > src^.pub.bytes_in_buffer then begin
6922 src^.SrcStream.Position := src^.SrcStream.Position + num_bytes - src^.pub.bytes_in_buffer;
6923 src^.pub.fill_input_buffer(cinfo);
6925 // wanted byte is in buffer so only skip
6926 inc(src^.pub.next_input_byte, num_bytes);
6927 dec(src^.pub.bytes_in_buffer, num_bytes);
6932 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6933 function glBitmap_libJPEG_empty_output_buffer(cinfo: j_compress_ptr): boolean; cdecl;
6935 dest: glBitmap_libJPEG_dest_mgr_ptr;
6937 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
6939 if dest^.pub.free_in_buffer < Cardinal(Length(dest^.DestBuffer)) then begin
6940 // write complete buffer
6941 dest^.DestStream.Write(dest^.DestBuffer[1], SizeOf(dest^.DestBuffer));
6944 dest^.pub.next_output_byte := @dest^.DestBuffer[1];
6945 dest^.pub.free_in_buffer := Length(dest^.DestBuffer);
6951 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6952 procedure glBitmap_libJPEG_term_destination(cinfo: j_compress_ptr); cdecl;
6955 dest: glBitmap_libJPEG_dest_mgr_ptr;
6957 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
6959 for Idx := Low(dest^.DestBuffer) to High(dest^.DestBuffer) do begin
6960 // check for endblock
6961 if (Idx < High(dest^.DestBuffer)) and (dest^.DestBuffer[Idx] = $FF) and (dest^.DestBuffer[Idx +1] = JPEG_EOI) then begin
6963 dest^.DestStream.Write(dest^.DestBuffer[Idx], 2);
6968 dest^.DestStream.Write(dest^.DestBuffer[Idx], 1);
6973 {$IFDEF GLB_SUPPORT_JPEG_READ}
6974 {$IF DEFINED(GLB_LAZ_JPEG)}
6975 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6976 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6979 JPEG_MAGIC: String[MAGIC_LEN] = #$FF#$D8;
6981 intf: TLazIntfImage;
6982 reader: TFPReaderJPEG;
6984 magic: String[MAGIC_LEN];
6987 StreamPos := aStream.Position;
6989 SetLength(magic, MAGIC_LEN);
6990 aStream.Read(magic[1], MAGIC_LEN);
6991 aStream.Position := StreamPos;
6992 if (magic <> JPEG_MAGIC) then begin
6997 reader := TFPReaderJPEG.Create;
6998 intf := TLazIntfImage.Create(0, 0);
7000 intf.DataDescription := GetDescriptionFromDevice(0, 0, 0);
7001 reader.ImageRead(aStream, intf);
7002 AssignFromLazIntfImage(intf);
7005 aStream.Position := StreamPos;
7014 {$ELSEIF DEFINED(GLB_SDL_IMAGE)}
7015 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7016 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
7018 Surface: PSDL_Surface;
7023 RWops := glBitmapCreateRWops(aStream);
7025 if IMG_isJPG(RWops) > 0 then begin
7026 Surface := IMG_LoadJPG_RW(RWops);
7028 AssignFromSurface(Surface);
7031 SDL_FreeSurface(Surface);
7039 {$ELSEIF DEFINED(GLB_LIB_JPEG)}
7040 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7041 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
7044 Temp: array[0..1]of Byte;
7046 jpeg: jpeg_decompress_struct;
7047 jpeg_err: jpeg_error_mgr;
7049 IntFormat: TglBitmapFormat;
7051 TempHeight, TempWidth: Integer;
7056 FormatDesc: TFormatDescriptor;
7060 if not init_libJPEG then
7061 raise Exception.Create('LoadJPG - unable to initialize libJPEG.');
7064 // reading first two bytes to test file and set cursor back to begin
7065 StreamPos := aStream.Position;
7066 aStream.Read({%H-}Temp[0], 2);
7067 aStream.Position := StreamPos;
7069 // if Bitmap then read file.
7070 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
7071 FillChar(jpeg{%H-}, SizeOf(jpeg_decompress_struct), $00);
7072 FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
7075 jpeg.err := jpeg_std_error(@jpeg_err);
7076 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
7077 jpeg_err.output_message := glBitmap_libJPEG_output_message;
7079 // decompression struct
7080 jpeg_create_decompress(@jpeg);
7082 // allocation space for streaming methods
7083 jpeg.src := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_source_mgr));
7085 // seeting up custom functions
7086 with glBitmap_libJPEG_source_mgr_ptr(jpeg.src)^ do begin
7087 pub.init_source := glBitmap_libJPEG_init_source;
7088 pub.fill_input_buffer := glBitmap_libJPEG_fill_input_buffer;
7089 pub.skip_input_data := glBitmap_libJPEG_skip_input_data;
7090 pub.resync_to_restart := jpeg_resync_to_restart; // use default method
7091 pub.term_source := glBitmap_libJPEG_term_source;
7093 pub.bytes_in_buffer := 0; // forces fill_input_buffer on first read
7094 pub.next_input_byte := nil; // until buffer loaded
7096 SrcStream := aStream;
7099 // set global decoding state
7100 jpeg.global_state := DSTATE_START;
7102 // read header of jpeg
7103 jpeg_read_header(@jpeg, false);
7105 // setting output parameter
7106 case jpeg.jpeg_color_space of
7109 jpeg.out_color_space := JCS_GRAYSCALE;
7110 IntFormat := tfLuminance8ub1;
7113 jpeg.out_color_space := JCS_RGB;
7114 IntFormat := tfRGB8ub3;
7118 jpeg_start_decompress(@jpeg);
7120 TempHeight := jpeg.output_height;
7121 TempWidth := jpeg.output_width;
7123 FormatDesc := TFormatDescriptor.Get(IntFormat);
7125 // creating new image
7126 GetMem(pImage, FormatDesc.GetSize(TempWidth, TempHeight));
7130 for Row := 0 to TempHeight -1 do begin
7131 jpeg_read_scanlines(@jpeg, @pTemp, 1);
7132 Inc(pTemp, FormatDesc.GetSize(TempWidth, 1));
7135 // finish decompression
7136 jpeg_finish_decompress(@jpeg);
7138 // destroy decompression
7139 jpeg_destroy_decompress(@jpeg);
7141 SetDataPointer(pImage, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
7145 if Assigned(pImage) then
7155 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
7156 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7157 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
7162 Temp: array[0..1]of Byte;
7166 // reading first two bytes to test file and set cursor back to begin
7167 StreamPos := aStream.Position;
7168 aStream.Read(Temp[0], 2);
7169 aStream.Position := StreamPos;
7171 // if Bitmap then read file.
7172 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
7173 bmp := TBitmap.Create;
7175 jpg := TJPEGImage.Create;
7177 jpg.LoadFromStream(aStream);
7179 result := AssignFromBitmap(bmp);
7191 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
7192 {$IF DEFINED(GLB_LAZ_JPEG)}
7193 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7194 procedure TglBitmap.SaveJPEG(const aStream: TStream);
7197 intf: TLazIntfImage;
7200 jpeg := TJPEGImage.Create;
7201 intf := TLazIntfImage.Create(0, 0);
7203 if not AssignToLazIntfImage(intf) then
7204 raise EglBitmap.Create('unable to create LazIntfImage from glBitmap');
7205 intf.GetRawImage(raw);
7206 jpeg.LoadFromRawImage(raw, false);
7207 jpeg.SaveToStream(aStream);
7214 {$ELSEIF DEFINED(GLB_LIB_JPEG)}
7215 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7216 procedure TglBitmap.SaveJPEG(const aStream: TStream);
7218 jpeg: jpeg_compress_struct;
7219 jpeg_err: jpeg_error_mgr;
7221 pTemp, pTemp2: pByte;
7223 procedure CopyRow(pDest, pSource: pByte);
7227 for X := 0 to Width - 1 do begin
7228 pByteArray(pDest)^[0] := pByteArray(pSource)^[2];
7229 pByteArray(pDest)^[1] := pByteArray(pSource)^[1];
7230 pByteArray(pDest)^[2] := pByteArray(pSource)^[0];
7237 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
7238 raise EglBitmapUnsupportedFormat.Create(Format);
7240 if not init_libJPEG then
7241 raise Exception.Create('SaveJPG - unable to initialize libJPEG.');
7244 FillChar(jpeg{%H-}, SizeOf(jpeg_compress_struct), $00);
7245 FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
7248 jpeg.err := jpeg_std_error(@jpeg_err);
7249 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
7250 jpeg_err.output_message := glBitmap_libJPEG_output_message;
7252 // compression struct
7253 jpeg_create_compress(@jpeg);
7255 // allocation space for streaming methods
7256 jpeg.dest := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_dest_mgr));
7258 // seeting up custom functions
7259 with glBitmap_libJPEG_dest_mgr_ptr(jpeg.dest)^ do begin
7260 pub.init_destination := glBitmap_libJPEG_init_destination;
7261 pub.empty_output_buffer := glBitmap_libJPEG_empty_output_buffer;
7262 pub.term_destination := glBitmap_libJPEG_term_destination;
7264 pub.next_output_byte := @DestBuffer[1];
7265 pub.free_in_buffer := Length(DestBuffer);
7267 DestStream := aStream;
7270 // very important state
7271 jpeg.global_state := CSTATE_START;
7272 jpeg.image_width := Width;
7273 jpeg.image_height := Height;
7275 tfAlpha8ub1, tfLuminance8ub1: begin
7276 jpeg.input_components := 1;
7277 jpeg.in_color_space := JCS_GRAYSCALE;
7279 tfRGB8ub3, tfBGR8ub3: begin
7280 jpeg.input_components := 3;
7281 jpeg.in_color_space := JCS_RGB;
7285 jpeg_set_defaults(@jpeg);
7286 jpeg_set_quality(@jpeg, 95, true);
7287 jpeg_start_compress(@jpeg, true);
7290 if Format = tfBGR8ub3 then
7291 GetMem(pTemp2, fRowSize)
7296 for Row := 0 to jpeg.image_height -1 do begin
7298 if Format = tfBGR8ub3 then
7299 CopyRow(pTemp2, pTemp)
7304 jpeg_write_scanlines(@jpeg, @pTemp2, 1);
7305 inc(pTemp, fRowSize);
7309 if Format = tfBGR8ub3 then
7312 jpeg_finish_compress(@jpeg);
7313 jpeg_destroy_compress(@jpeg);
7319 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
7320 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7321 procedure TglBitmap.SaveJPEG(const aStream: TStream);
7326 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
7327 raise EglBitmapUnsupportedFormat.Create(Format);
7329 Bmp := TBitmap.Create;
7331 Jpg := TJPEGImage.Create;
7333 AssignToBitmap(Bmp);
7334 if (Format in [tfAlpha8ub1, tfLuminance8ub1]) then begin
7335 Jpg.Grayscale := true;
7336 Jpg.PixelFormat := jf8Bit;
7339 Jpg.SaveToStream(aStream);
7350 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7351 //RAW/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7352 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7354 RawHeader = packed record
7360 BitsPerPixel: Integer;
7361 Precision: TglBitmapRec4ub;
7362 Shift: TglBitmapRec4ub;
7365 function TglBitmap.LoadRAW(const aStream: TStream): Boolean;
7369 fd: TFormatDescriptor;
7373 StartPos := aStream.Position;
7374 aStream.Read(header{%H-}, SizeOf(header));
7375 if (header.Magic <> 'glBMP') then begin
7376 aStream.Position := StartPos;
7380 fd := TFormatDescriptor.GetFromPrecShift(header.Precision, header.Shift, header.BitsPerPixel);
7381 if (fd.Format = tfEmpty) then
7382 raise EglBitmapUnsupportedFormat.Create('no supported format found');
7384 buf := GetMemory(header.DataSize);
7385 aStream.Read(buf^, header.DataSize);
7386 SetDataPointer(buf, fd.Format, header.Width, header.Height);
7391 procedure TglBitmap.SaveRAW(const aStream: TStream);
7394 fd: TFormatDescriptor;
7396 fd := TFormatDescriptor.Get(Format);
7397 header.Magic := 'glBMP';
7398 header.Version := 1;
7399 header.Width := Width;
7400 header.Height := Height;
7401 header.DataSize := fd.GetSize(fDimension);
7402 header.BitsPerPixel := fd.BitsPerPixel;
7403 header.Precision := fd.Precision;
7404 header.Shift := fd.Shift;
7405 aStream.Write(header, SizeOf(header));
7406 aStream.Write(Data^, header.DataSize);
7409 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7410 //BMP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7411 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7418 BMP_COMP_BITFIELDS = 3;
7421 TBMPHeader = packed record
7426 bfOffBits: Cardinal;
7429 TBMPInfo = packed record
7435 biCompression: Cardinal;
7436 biSizeImage: Cardinal;
7437 biXPelsPerMeter: Longint;
7438 biYPelsPerMeter: Longint;
7439 biClrUsed: Cardinal;
7440 biClrImportant: Cardinal;
7443 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7444 function TglBitmap.LoadBMP(const aStream: TStream): Boolean;
7446 //////////////////////////////////////////////////////////////////////////////////////////////////
7447 function ReadInfo(out aInfo: TBMPInfo; out aMask: TglBitmapRec4ul): TglBitmapFormat;
7450 aStream.Read(aInfo{%H-}, SizeOf(aInfo));
7451 FillChar(aMask{%H-}, SizeOf(aMask), 0);
7454 case aInfo.biCompression of
7456 BMP_COMP_RLE8: begin
7457 raise EglBitmap.Create('RLE compression is not supported');
7459 BMP_COMP_BITFIELDS: begin
7460 if (aInfo.biBitCount = 16) or (aInfo.biBitCount = 32) then begin
7461 aStream.Read(aMask.r, SizeOf(aMask.r));
7462 aStream.Read(aMask.g, SizeOf(aMask.g));
7463 aStream.Read(aMask.b, SizeOf(aMask.b));
7464 aStream.Read(aMask.a, SizeOf(aMask.a));
7466 raise EglBitmap.Create('Bitfields are only supported for 16bit and 32bit formats');
7470 //get suitable format
7471 case aInfo.biBitCount of
7472 8: result := tfLuminance8ub1;
7473 16: result := tfX1RGB5us1;
7474 24: result := tfBGR8ub3;
7475 32: result := tfXRGB8ui1;
7479 function ReadColorTable(var aFormat: TglBitmapFormat; const aInfo: TBMPInfo): TbmpColorTableFormat;
7482 ColorTable: TbmpColorTable;
7485 if (aInfo.biBitCount >= 16) then
7487 aFormat := tfLuminance8ub1;
7488 c := aInfo.biClrUsed;
7490 c := 1 shl aInfo.biBitCount;
7491 SetLength(ColorTable, c);
7492 for i := 0 to c-1 do begin
7493 aStream.Read(ColorTable[i], SizeOf(TbmpColorTableEnty));
7494 if (ColorTable[i].r <> ColorTable[i].g) or (ColorTable[i].g <> ColorTable[i].b) then
7495 aFormat := tfRGB8ub3;
7498 result := TbmpColorTableFormat.Create;
7499 result.BitsPerPixel := aInfo.biBitCount;
7500 result.ColorTable := ColorTable;
7504 //////////////////////////////////////////////////////////////////////////////////////////////////
7505 function CheckBitfields(var aFormat: TglBitmapFormat; const aMask: TglBitmapRec4ul; const aInfo: TBMPInfo): TbmpBitfieldFormat;
7507 FormatDesc: TFormatDescriptor;
7510 if (aMask.r <> 0) or (aMask.g <> 0) or (aMask.b <> 0) or (aMask.a <> 0) then begin
7511 FormatDesc := TFormatDescriptor.GetFromMask(aMask);
7512 if (FormatDesc.Format = tfEmpty) then
7514 aFormat := FormatDesc.Format;
7515 if (aMask.a = 0) and TFormatDescriptor.Get(aFormat).HasAlpha then
7516 aFormat := TFormatDescriptor.Get(aFormat).WithoutAlpha;
7517 if (aMask.a <> 0) and not TFormatDescriptor.Get(aFormat).HasAlpha then
7518 aFormat := TFormatDescriptor.Get(aFormat).WithAlpha;
7520 result := TbmpBitfieldFormat.Create;
7521 result.SetCustomValues(aInfo.biBitCount, aMask);
7528 ImageSize, rbLineSize, wbLineSize, Padding, i: Integer;
7529 PaddingBuff: Cardinal;
7530 LineBuf, ImageData, TmpData: PByte;
7531 SourceMD, DestMD: Pointer;
7532 BmpFormat: TglBitmapFormat;
7535 Mask: TglBitmapRec4ul;
7540 SpecialFormat: TFormatDescriptor;
7541 FormatDesc: TFormatDescriptor;
7543 //////////////////////////////////////////////////////////////////////////////////////////////////
7544 procedure SpecialFormatReadLine(aData: PByte; aLineBuf: PByte);
7547 Pixel: TglBitmapPixelData;
7549 aStream.Read(aLineBuf^, rbLineSize);
7550 SpecialFormat.PreparePixel(Pixel);
7551 for i := 0 to Info.biWidth-1 do begin
7552 SpecialFormat.Unmap(aLineBuf, Pixel, SourceMD);
7553 glBitmapConvertPixel(Pixel, SpecialFormat, FormatDesc);
7554 FormatDesc.Map(Pixel, aData, DestMD);
7560 BmpFormat := tfEmpty;
7561 SpecialFormat := nil;
7567 StartPos := aStream.Position;
7568 aStream.Read(Header{%H-}, SizeOf(Header));
7570 if Header.bfType = BMP_MAGIC then begin
7572 BmpFormat := ReadInfo(Info, Mask);
7573 SpecialFormat := ReadColorTable(BmpFormat, Info);
7574 if not Assigned(SpecialFormat) then
7575 SpecialFormat := CheckBitfields(BmpFormat, Mask, Info);
7576 aStream.Position := StartPos + Header.bfOffBits;
7578 if (BmpFormat <> tfEmpty) then begin
7579 FormatDesc := TFormatDescriptor.Get(BmpFormat);
7580 rbLineSize := Round(Info.biWidth * Info.biBitCount / 8); //ReadBuffer LineSize
7581 wbLineSize := Trunc(Info.biWidth * FormatDesc.BytesPerPixel);
7582 Padding := (((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3) - rbLineSize;
7585 DestMD := FormatDesc.CreateMappingData;
7586 ImageSize := FormatDesc.GetSize(Info.biWidth, abs(Info.biHeight));
7587 GetMem(ImageData, ImageSize);
7588 if Assigned(SpecialFormat) then begin
7589 GetMem(LineBuf, rbLineSize); //tmp Memory for converting Bitfields
7590 SourceMD := SpecialFormat.CreateMappingData;
7595 FillChar(ImageData^, ImageSize, $FF);
7596 TmpData := ImageData;
7597 if (Info.biHeight > 0) then
7598 Inc(TmpData, wbLineSize * (Info.biHeight-1));
7599 for i := 0 to Abs(Info.biHeight)-1 do begin
7600 if Assigned(SpecialFormat) then
7601 SpecialFormatReadLine(TmpData, LineBuf) //if is special format read and convert data
7603 aStream.Read(TmpData^, wbLineSize); //else only read data
7604 if (Info.biHeight > 0) then
7605 dec(TmpData, wbLineSize)
7607 inc(TmpData, wbLineSize);
7608 aStream.Read(PaddingBuff{%H-}, Padding);
7610 SetDataPointer(ImageData, BmpFormat, Info.biWidth, abs(Info.biHeight)); //be careful, Data could be freed by this method
7613 if Assigned(LineBuf) then
7615 if Assigned(SourceMD) then
7616 SpecialFormat.FreeMappingData(SourceMD);
7617 FormatDesc.FreeMappingData(DestMD);
7620 if Assigned(ImageData) then
7625 raise EglBitmap.Create('LoadBMP - No suitable format found');
7627 aStream.Position := StartPos;
7631 FreeAndNil(SpecialFormat);
7634 else aStream.Position := StartPos;
7637 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7638 procedure TglBitmap.SaveBMP(const aStream: TStream);
7642 Converter: TFormatDescriptor;
7643 FormatDesc: TFormatDescriptor;
7644 SourceFD, DestFD: Pointer;
7645 pData, srcData, dstData, ConvertBuffer: pByte;
7647 Pixel: TglBitmapPixelData;
7648 ImageSize, wbLineSize, rbLineSize, Padding, LineIdx, PixelIdx: Integer;
7649 RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
7651 PaddingBuff: Cardinal;
7653 function GetLineWidth : Integer;
7655 result := ((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3;
7659 if not (ftBMP in FormatGetSupportedFiles(Format)) then
7660 raise EglBitmapUnsupportedFormat.Create(Format);
7663 FormatDesc := TFormatDescriptor.Get(Format);
7664 ImageSize := FormatDesc.GetSize(Dimension);
7666 FillChar(Header{%H-}, SizeOf(Header), 0);
7667 Header.bfType := BMP_MAGIC;
7668 Header.bfSize := SizeOf(Header) + SizeOf(Info) + ImageSize;
7669 Header.bfReserved1 := 0;
7670 Header.bfReserved2 := 0;
7671 Header.bfOffBits := SizeOf(Header) + SizeOf(Info);
7673 FillChar(Info{%H-}, SizeOf(Info), 0);
7674 Info.biSize := SizeOf(Info);
7675 Info.biWidth := Width;
7676 Info.biHeight := Height;
7678 Info.biCompression := BMP_COMP_RGB;
7679 Info.biSizeImage := ImageSize;
7683 tfAlpha4ub1, tfAlpha8ub1, tfLuminance4ub1, tfLuminance8ub1, tfR3G3B2ub1:
7685 Info.biBitCount := 8;
7686 Header.bfSize := Header.bfSize + 256 * SizeOf(Cardinal);
7687 Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal); //256 ColorTable entries
7688 Converter := TbmpColorTableFormat.Create;
7689 with (Converter as TbmpColorTableFormat) do begin
7690 SetCustomValues(fFormat, 1, FormatDesc.Precision, FormatDesc.Shift);
7695 tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
7696 tfRGBX4us1, tfXRGB4us1, tfRGB5X1us1, tfX1RGB5us1, tfR5G6B5us1, tfRGB5A1us1, tfA1RGB5us1, tfRGBA4us1, tfARGB4us1,
7697 tfBGRX4us1, tfXBGR4us1, tfBGR5X1us1, tfX1BGR5us1, tfB5G6R5us1, tfBGR5A1us1, tfA1BGR5us1, tfBGRA4us1, tfABGR4us1:
7699 Info.biBitCount := 16;
7700 Info.biCompression := BMP_COMP_BITFIELDS;
7703 tfBGR8ub3, tfRGB8ub3:
7705 Info.biBitCount := 24;
7706 if (Format = tfRGB8ub3) then
7707 Converter := TfdBGR8ub3.Create; //use BGR8 Format Descriptor to Swap RGB Values
7710 tfRGBX8ui1, tfXRGB8ui1, tfRGB10X2ui1, tfX2RGB10ui1, tfRGBA8ui1, tfARGB8ui1, tfRGBA8ub4, tfRGB10A2ui1, tfA2RGB10ui1,
7711 tfBGRX8ui1, tfXBGR8ui1, tfBGR10X2ui1, tfX2BGR10ui1, tfBGRA8ui1, tfABGR8ui1, tfBGRA8ub4, tfBGR10A2ui1, tfA2BGR10ui1:
7713 Info.biBitCount := 32;
7714 Info.biCompression := BMP_COMP_BITFIELDS;
7717 raise EglBitmapUnsupportedFormat.Create(Format);
7719 Info.biXPelsPerMeter := 2835;
7720 Info.biYPelsPerMeter := 2835;
7723 if Info.biCompression = BMP_COMP_BITFIELDS then begin
7724 Header.bfSize := Header.bfSize + 4 * SizeOf(Cardinal);
7725 Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal);
7727 RedMask := FormatDesc.Mask.r;
7728 GreenMask := FormatDesc.Mask.g;
7729 BlueMask := FormatDesc.Mask.b;
7730 AlphaMask := FormatDesc.Mask.a;
7734 aStream.Write(Header, SizeOf(Header));
7735 aStream.Write(Info, SizeOf(Info));
7738 if Assigned(Converter) and (Converter is TbmpColorTableFormat) then
7739 with (Converter as TbmpColorTableFormat) do
7740 aStream.Write(ColorTable[0].b,
7741 SizeOf(TbmpColorTableEnty) * Length(ColorTable));
7744 if Info.biCompression = BMP_COMP_BITFIELDS then begin
7745 aStream.Write(RedMask, SizeOf(Cardinal));
7746 aStream.Write(GreenMask, SizeOf(Cardinal));
7747 aStream.Write(BlueMask, SizeOf(Cardinal));
7748 aStream.Write(AlphaMask, SizeOf(Cardinal));
7752 rbLineSize := Round(Info.biWidth * FormatDesc.BytesPerPixel);
7753 wbLineSize := Round(Info.biWidth * Info.biBitCount / 8);
7754 Padding := GetLineWidth - wbLineSize;
7758 inc(pData, (Height-1) * rbLineSize);
7760 // prepare row buffer. But only for RGB because RGBA supports color masks
7761 // so it's possible to change color within the image.
7762 if Assigned(Converter) then begin
7763 FormatDesc.PreparePixel(Pixel);
7764 GetMem(ConvertBuffer, wbLineSize);
7765 SourceFD := FormatDesc.CreateMappingData;
7766 DestFD := Converter.CreateMappingData;
7768 ConvertBuffer := nil;
7771 for LineIdx := 0 to Height - 1 do begin
7773 if Assigned(Converter) then begin
7775 dstData := ConvertBuffer;
7776 for PixelIdx := 0 to Info.biWidth-1 do begin
7777 FormatDesc.Unmap(srcData, Pixel, SourceFD);
7778 glBitmapConvertPixel(Pixel, FormatDesc, Converter);
7779 Converter.Map(Pixel, dstData, DestFD);
7781 aStream.Write(ConvertBuffer^, wbLineSize);
7783 aStream.Write(pData^, rbLineSize);
7785 dec(pData, rbLineSize);
7786 if (Padding > 0) then
7787 aStream.Write(PaddingBuff, Padding);
7790 // destroy row buffer
7791 if Assigned(ConvertBuffer) then begin
7792 FormatDesc.FreeMappingData(SourceFD);
7793 Converter.FreeMappingData(DestFD);
7794 FreeMem(ConvertBuffer);
7798 if Assigned(Converter) then
7803 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7804 //TGA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7805 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7807 TTGAHeader = packed record
7811 //ColorMapSpec: Array[0..4] of Byte;
7812 ColorMapStart: Word;
7813 ColorMapLength: Word;
7814 ColorMapEntrySize: Byte;
7824 TGA_UNCOMPRESSED_RGB = 2;
7825 TGA_UNCOMPRESSED_GRAY = 3;
7826 TGA_COMPRESSED_RGB = 10;
7827 TGA_COMPRESSED_GRAY = 11;
7829 TGA_NONE_COLOR_TABLE = 0;
7831 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7832 function TglBitmap.LoadTGA(const aStream: TStream): Boolean;
7835 ImageData: System.PByte;
7836 StartPosition: Int64;
7837 PixelSize, LineSize: Integer;
7838 tgaFormat: TglBitmapFormat;
7839 FormatDesc: TFormatDescriptor;
7840 Counter: packed record
7842 low, high, dir: Integer;
7849 ////////////////////////////////////////////////////////////////////////////////////////
7850 procedure ReadUncompressed;
7853 buf, tmp1, tmp2: System.PByte;
7856 if (Counter.X.dir < 0) then
7857 GetMem(buf, LineSize);
7859 while (Counter.Y.low <> Counter.Y.high + counter.Y.dir) do begin
7861 inc(tmp1, (Counter.Y.low * LineSize)); //pointer to LineStart
7862 if (Counter.X.dir < 0) then begin //flip X
7863 aStream.Read(buf^, LineSize);
7865 inc(tmp2, LineSize - PixelSize); //pointer to last pixel in line
7866 for i := 0 to Header.Width-1 do begin //for all pixels in line
7867 for j := 0 to PixelSize-1 do begin //for all bytes in pixel
7872 dec(tmp2, 2*PixelSize); //move 2 backwards, because j-loop moved 1 forward
7875 aStream.Read(tmp1^, LineSize);
7876 inc(Counter.Y.low, Counter.Y.dir); //move to next line index
7879 if Assigned(buf) then
7884 ////////////////////////////////////////////////////////////////////////////////////////
7885 procedure ReadCompressed;
7887 /////////////////////////////////////////////////////////////////
7889 TmpData: System.PByte;
7890 LinePixelsRead: Integer;
7891 procedure CheckLine;
7893 if (LinePixelsRead >= Header.Width) then begin
7894 LinePixelsRead := 0;
7895 inc(Counter.Y.low, Counter.Y.dir); //next line index
7896 TmpData := ImageData;
7897 inc(TmpData, Counter.Y.low * LineSize); //set line
7898 if (Counter.X.dir < 0) then //if x flipped then
7899 inc(TmpData, LineSize - PixelSize); //set last pixel
7903 /////////////////////////////////////////////////////////////////
7906 CacheSize, CachePos: Integer;
7907 procedure CachedRead(out Buffer; Count: Integer);
7911 if (CachePos + Count > CacheSize) then begin
7912 //if buffer overflow save non read bytes
7914 if (CacheSize - CachePos > 0) then begin
7915 BytesRead := CacheSize - CachePos;
7916 Move(PByteArray(Cache)^[CachePos], Buffer{%H-}, BytesRead);
7917 inc(CachePos, BytesRead);
7920 //load cache from file
7921 CacheSize := Min(CACHE_SIZE, aStream.Size - aStream.Position);
7922 aStream.Read(Cache^, CacheSize);
7925 //read rest of requested bytes
7926 if (Count - BytesRead > 0) then begin
7927 Move(PByteArray(Cache)^[CachePos], TByteArray(Buffer)[BytesRead], Count - BytesRead);
7928 inc(CachePos, Count - BytesRead);
7931 //if no buffer overflow just read the data
7932 Move(PByteArray(Cache)^[CachePos], Buffer, Count);
7933 inc(CachePos, Count);
7937 procedure PixelToBuffer(const aData: PByte; var aBuffer: PByte);
7942 inc(aBuffer, Counter.X.dir);
7945 PWord(aBuffer)^ := PWord(aData)^;
7946 inc(aBuffer, 2 * Counter.X.dir);
7949 PByteArray(aBuffer)^[0] := PByteArray(aData)^[0];
7950 PByteArray(aBuffer)^[1] := PByteArray(aData)^[1];
7951 PByteArray(aBuffer)^[2] := PByteArray(aData)^[2];
7952 inc(aBuffer, 3 * Counter.X.dir);
7955 PCardinal(aBuffer)^ := PCardinal(aData)^;
7956 inc(aBuffer, 4 * Counter.X.dir);
7962 TotalPixelsToRead, TotalPixelsRead: Integer;
7964 buf: array [0..3] of Byte; //1 pixel is max 32bit long
7965 PixelRepeat: Boolean;
7966 PixelsToRead, PixelCount: Integer;
7971 TotalPixelsToRead := Header.Width * Header.Height;
7972 TotalPixelsRead := 0;
7973 LinePixelsRead := 0;
7975 GetMem(Cache, CACHE_SIZE);
7977 TmpData := ImageData;
7978 inc(TmpData, Counter.Y.low * LineSize); //set line
7979 if (Counter.X.dir < 0) then //if x flipped then
7980 inc(TmpData, LineSize - PixelSize); //set last pixel
7984 CachedRead(Temp, 1);
7985 PixelRepeat := (Temp and $80) > 0;
7986 PixelsToRead := (Temp and $7F) + 1;
7987 inc(TotalPixelsRead, PixelsToRead);
7990 CachedRead(buf[0], PixelSize);
7991 while (PixelsToRead > 0) do begin
7993 PixelCount := Min(Header.Width - LinePixelsRead, PixelsToRead); //max read to EOL or EOF
7994 while (PixelCount > 0) do begin
7995 if not PixelRepeat then
7996 CachedRead(buf[0], PixelSize);
7997 PixelToBuffer(@buf[0], TmpData);
7998 inc(LinePixelsRead);
8003 until (TotalPixelsRead >= TotalPixelsToRead);
8009 function IsGrayFormat: Boolean;
8011 result := Header.ImageType in [TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_GRAY];
8017 // reading header to test file and set cursor back to begin
8018 StartPosition := aStream.Position;
8019 aStream.Read(Header{%H-}, SizeOf(Header));
8021 // no colormapped files
8022 if (Header.ColorMapType = TGA_NONE_COLOR_TABLE) and (Header.ImageType in [
8023 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY]) then
8026 if Header.ImageID <> 0 then // skip image ID
8027 aStream.Position := aStream.Position + Header.ImageID;
8029 tgaFormat := tfEmpty;
8031 8: if IsGrayFormat then case (Header.ImageDesc and $F) of
8032 0: tgaFormat := tfLuminance8ub1;
8033 8: tgaFormat := tfAlpha8ub1;
8036 16: if IsGrayFormat then case (Header.ImageDesc and $F) of
8037 0: tgaFormat := tfLuminance16us1;
8038 8: tgaFormat := tfLuminance8Alpha8ub2;
8039 end else case (Header.ImageDesc and $F) of
8040 0: tgaFormat := tfX1RGB5us1;
8041 1: tgaFormat := tfA1RGB5us1;
8042 4: tgaFormat := tfARGB4us1;
8045 24: if not IsGrayFormat then case (Header.ImageDesc and $F) of
8046 0: tgaFormat := tfBGR8ub3;
8049 32: if IsGrayFormat then case (Header.ImageDesc and $F) of
8050 0: tgaFormat := tfDepth32ui1;
8051 end else case (Header.ImageDesc and $F) of
8052 0: tgaFormat := tfX2RGB10ui1;
8053 2: tgaFormat := tfA2RGB10ui1;
8054 8: tgaFormat := tfARGB8ui1;
8058 if (tgaFormat = tfEmpty) then
8059 raise EglBitmap.Create('LoadTga - unsupported format');
8061 FormatDesc := TFormatDescriptor.Get(tgaFormat);
8062 PixelSize := FormatDesc.GetSize(1, 1);
8063 LineSize := FormatDesc.GetSize(Header.Width, 1);
8065 GetMem(ImageData, LineSize * Header.Height);
8068 if ((Header.ImageDesc and (1 shl 4)) > 0) then begin
8069 Counter.X.low := Header.Height-1;;
8070 Counter.X.high := 0;
8071 Counter.X.dir := -1;
8074 Counter.X.high := Header.Height-1;
8079 if ((Header.ImageDesc and (1 shl 5)) > 0) then begin
8081 Counter.Y.high := Header.Height-1;
8084 Counter.Y.low := Header.Height-1;;
8085 Counter.Y.high := 0;
8086 Counter.Y.dir := -1;
8090 case Header.ImageType of
8091 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY:
8093 TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY:
8097 SetDataPointer(ImageData, tgaFormat, Header.Width, Header.Height); //be careful, Data could be freed by this method
8100 if Assigned(ImageData) then
8105 aStream.Position := StartPosition;
8108 else aStream.Position := StartPosition;
8111 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8112 procedure TglBitmap.SaveTGA(const aStream: TStream);
8116 FormatDesc: TFormatDescriptor;
8118 if not (ftTGA in FormatGetSupportedFiles(Format)) then
8119 raise EglBitmapUnsupportedFormat.Create(Format);
8122 FormatDesc := TFormatDescriptor.Get(Format);
8123 FillChar(Header{%H-}, SizeOf(Header), 0);
8124 Header.ImageDesc := CountSetBits(FormatDesc.Range.a) and $F;
8125 Header.Bpp := FormatDesc.BitsPerPixel;
8126 Header.Width := Width;
8127 Header.Height := Height;
8128 Header.ImageDesc := Header.ImageDesc or $20; //flip y
8129 if FormatDesc.IsGrayscale or (not FormatDesc.IsGrayscale and not FormatDesc.HasRed and FormatDesc.HasAlpha) then
8130 Header.ImageType := TGA_UNCOMPRESSED_GRAY
8132 Header.ImageType := TGA_UNCOMPRESSED_RGB;
8133 aStream.Write(Header, SizeOf(Header));
8136 Size := FormatDesc.GetSize(Dimension);
8137 aStream.Write(Data^, Size);
8140 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8141 //DDS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8142 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8144 DDS_MAGIC: Cardinal = $20534444;
8146 // DDS_header.dwFlags
8147 DDSD_CAPS = $00000001;
8148 DDSD_HEIGHT = $00000002;
8149 DDSD_WIDTH = $00000004;
8150 DDSD_PIXELFORMAT = $00001000;
8152 // DDS_header.sPixelFormat.dwFlags
8153 DDPF_ALPHAPIXELS = $00000001;
8154 DDPF_ALPHA = $00000002;
8155 DDPF_FOURCC = $00000004;
8156 DDPF_RGB = $00000040;
8157 DDPF_LUMINANCE = $00020000;
8159 // DDS_header.sCaps.dwCaps1
8160 DDSCAPS_TEXTURE = $00001000;
8162 // DDS_header.sCaps.dwCaps2
8163 DDSCAPS2_CUBEMAP = $00000200;
8165 D3DFMT_DXT1 = $31545844;
8166 D3DFMT_DXT3 = $33545844;
8167 D3DFMT_DXT5 = $35545844;
8170 TDDSPixelFormat = packed record
8174 dwRGBBitCount: Cardinal;
8175 dwRBitMask: Cardinal;
8176 dwGBitMask: Cardinal;
8177 dwBBitMask: Cardinal;
8178 dwABitMask: Cardinal;
8181 TDDSCaps = packed record
8185 dwReserved: Cardinal;
8188 TDDSHeader = packed record
8193 dwPitchOrLinearSize: Cardinal;
8195 dwMipMapCount: Cardinal;
8196 dwReserved: array[0..10] of Cardinal;
8197 PixelFormat: TDDSPixelFormat;
8199 dwReserved2: Cardinal;
8202 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8203 function TglBitmap.LoadDDS(const aStream: TStream): Boolean;
8206 Converter: TbmpBitfieldFormat;
8208 function GetDDSFormat: TglBitmapFormat;
8210 fd: TFormatDescriptor;
8212 Mask: TglBitmapRec4ul;
8213 Range: TglBitmapRec4ui;
8217 with Header.PixelFormat do begin
8219 if ((dwFlags and DDPF_FOURCC) > 0) then begin
8220 case Header.PixelFormat.dwFourCC of
8221 D3DFMT_DXT1: result := tfS3tcDtx1RGBA;
8222 D3DFMT_DXT3: result := tfS3tcDtx3RGBA;
8223 D3DFMT_DXT5: result := tfS3tcDtx5RGBA;
8225 end else if ((dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE or DDPF_ALPHA)) > 0) then begin
8227 if ((dwFlags and DDPF_LUMINANCE) = 0) then begin
8228 Mask.r := dwRBitMask;
8229 Mask.g := dwGBitMask;
8230 Mask.b := dwBBitMask;
8232 Mask.r := dwRBitMask;
8233 Mask.g := dwRBitMask;
8234 Mask.b := dwRBitMask;
8236 if (dwFlags and DDPF_ALPHAPIXELS > 0) then
8237 Mask.a := dwABitMask
8241 //find matching format
8242 fd := TFormatDescriptor.GetFromMask(Mask, dwRGBBitCount);
8243 result := fd.Format;
8244 if (result <> tfEmpty) then
8247 //find format with same Range
8249 Range.arr[i] := (2 shl CountSetBits(Mask.arr[i])) - 1;
8250 for result := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
8251 fd := TFormatDescriptor.Get(result);
8254 if (fd.Range.arr[i] <> Range.arr[i]) then begin
8262 //no format with same range found -> use default
8263 if (result = tfEmpty) then begin
8264 if (dwABitMask > 0) then
8265 result := tfRGBA8ui1
8267 result := tfRGB8ub3;
8270 Converter := TbmpBitfieldFormat.Create;
8271 Converter.SetCustomValues(dwRGBBitCount, glBitmapRec4ul(dwRBitMask, dwGBitMask, dwBBitMask, dwABitMask));
8278 x, y, LineSize, RowSize, Magic: Cardinal;
8279 NewImage, TmpData, RowData, SrcData: System.PByte;
8280 SourceMD, DestMD: Pointer;
8281 Pixel: TglBitmapPixelData;
8282 ddsFormat: TglBitmapFormat;
8283 FormatDesc: TFormatDescriptor;
8288 StreamPos := aStream.Position;
8291 aStream.Read(Magic{%H-}, sizeof(Magic));
8292 if (Magic <> DDS_MAGIC) then begin
8293 aStream.Position := StreamPos;
8298 aStream.Read(Header{%H-}, sizeof(Header));
8299 if (Header.dwSize <> SizeOf(Header)) or
8300 ((Header.dwFlags and (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) <>
8301 (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) then
8303 aStream.Position := StreamPos;
8307 if ((Header.Caps.dwCaps1 and DDSCAPS2_CUBEMAP) > 0) then
8308 raise EglBitmap.Create('LoadDDS - CubeMaps are not supported');
8310 ddsFormat := GetDDSFormat;
8312 if (ddsFormat = tfEmpty) then
8313 raise EglBitmap.Create('LoadDDS - unsupported Pixelformat found.');
8315 FormatDesc := TFormatDescriptor.Get(ddsFormat);
8316 LineSize := Trunc(Header.dwWidth * FormatDesc.BytesPerPixel);
8317 GetMem(NewImage, Header.dwHeight * LineSize);
8319 TmpData := NewImage;
8322 if Assigned(Converter) then begin
8323 RowSize := Round(Header.dwWidth * Header.PixelFormat.dwRGBBitCount / 8);
8324 GetMem(RowData, RowSize);
8325 SourceMD := Converter.CreateMappingData;
8326 DestMD := FormatDesc.CreateMappingData;
8328 for y := 0 to Header.dwHeight-1 do begin
8329 TmpData := NewImage;
8330 inc(TmpData, y * LineSize);
8332 aStream.Read(SrcData^, RowSize);
8333 for x := 0 to Header.dwWidth-1 do begin
8334 Converter.Unmap(SrcData, Pixel, SourceMD);
8335 glBitmapConvertPixel(Pixel, Converter, FormatDesc);
8336 FormatDesc.Map(Pixel, TmpData, DestMD);
8340 Converter.FreeMappingData(SourceMD);
8341 FormatDesc.FreeMappingData(DestMD);
8347 if ((Header.PixelFormat.dwFlags and DDPF_FOURCC) > 0) then begin
8348 RowSize := Header.dwPitchOrLinearSize div Header.dwWidth;
8349 for Y := 0 to Header.dwHeight-1 do begin
8350 aStream.Read(TmpData^, RowSize);
8351 Inc(TmpData, LineSize);
8356 if (Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE)) > 0 then begin
8357 RowSize := (Header.PixelFormat.dwRGBBitCount * Header.dwWidth) shr 3;
8358 for Y := 0 to Header.dwHeight-1 do begin
8359 aStream.Read(TmpData^, RowSize);
8360 Inc(TmpData, LineSize);
8363 raise EglBitmap.Create('LoadDDS - unsupported Pixelformat found.');
8365 SetDataPointer(NewImage, ddsFormat, Header.dwWidth, Header.dwHeight); //be careful, Data could be freed by this method
8368 if Assigned(NewImage) then
8373 FreeAndNil(Converter);
8377 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8378 procedure TglBitmap.SaveDDS(const aStream: TStream);
8381 FormatDesc: TFormatDescriptor;
8383 if not (ftDDS in FormatGetSupportedFiles(Format)) then
8384 raise EglBitmapUnsupportedFormat.Create(Format);
8386 FormatDesc := TFormatDescriptor.Get(Format);
8389 FillChar(Header{%H-}, SizeOf(Header), 0);
8390 Header.dwSize := SizeOf(Header);
8391 Header.dwFlags := DDSD_WIDTH or DDSD_HEIGHT or DDSD_CAPS or DDSD_PIXELFORMAT;
8393 Header.dwWidth := Max(1, Width);
8394 Header.dwHeight := Max(1, Height);
8397 Header.Caps.dwCaps1 := DDSCAPS_TEXTURE;
8400 Header.PixelFormat.dwSize := sizeof(Header);
8401 if (FormatDesc.IsCompressed) then begin
8402 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_FOURCC;
8404 tfS3tcDtx1RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT1;
8405 tfS3tcDtx3RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT3;
8406 tfS3tcDtx5RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT5;
8408 end else if not FormatDesc.HasColor and FormatDesc.HasAlpha then begin
8409 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHA;
8410 Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
8411 Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
8412 end else if FormatDesc.IsGrayscale then begin
8413 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_LUMINANCE;
8414 Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
8415 Header.PixelFormat.dwRBitMask := FormatDesc.Mask.r;
8416 Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
8418 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_RGB;
8419 Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
8420 Header.PixelFormat.dwRBitMask := FormatDesc.Mask.r;
8421 Header.PixelFormat.dwGBitMask := FormatDesc.Mask.g;
8422 Header.PixelFormat.dwBBitMask := FormatDesc.Mask.b;
8423 Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
8426 if (FormatDesc.HasAlpha) then
8427 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHAPIXELS;
8429 aStream.Write(DDS_MAGIC, sizeof(DDS_MAGIC));
8430 aStream.Write(Header, SizeOf(Header));
8431 aStream.Write(Data^, FormatDesc.GetSize(Dimension));
8435 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8436 //TglBitmap1D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8437 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8438 procedure TglBitmap1D.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
8439 const aWidth: Integer; const aHeight: Integer);
8444 if (aHeight > 1) then begin
8445 Size := TFormatDescriptor.Get(aFormat).GetSize(aWidth, 1);
8446 GetMem(pTemp, Size);
8448 Move(aData^, pTemp^, Size);
8457 inherited SetDataPointer(pTemp, aFormat, aWidth);
8460 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8461 function TglBitmap1D.FlipHorz: Boolean;
8464 pTempDest, pDest, pSource: PByte;
8466 result := inherited FlipHorz;
8467 if Assigned(Data) and not TFormatDescriptor.Get(Format).IsCompressed then begin
8469 GetMem(pDest, fRowSize);
8472 Inc(pTempDest, fRowSize);
8473 for Col := 0 to Width-1 do begin
8474 dec(pTempDest, fPixelSize); //dec before, because ptr is behind last byte of data
8475 Move(pSource^, pTempDest^, fPixelSize);
8476 Inc(pSource, fPixelSize);
8478 SetDataPointer(pDest, Format, Width); //be careful, Data could be freed by this method
8481 if Assigned(pDest) then
8488 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8489 procedure TglBitmap1D.UploadData(const aBuildWithGlu: Boolean);
8491 FormatDesc: TFormatDescriptor;
8494 FormatDesc := TFormatDescriptor.Get(Format);
8495 if (FormatDesc.glInternalFormat = 0) or (FormatDesc.glDataFormat = 0) then
8496 raise EglBitmap.Create('format is not supported by video adapter, please convert before uploading data');
8498 if FormatDesc.IsCompressed then begin
8499 if not Assigned(glCompressedTexImage1D) then
8500 raise EglBitmap.Create('compressed formats not supported by video adapter');
8501 glCompressedTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.GetSize(Width, 1), Data)
8502 end else if aBuildWithGlu then
8503 gluBuild1DMipmaps(Target, FormatDesc.glInternalFormat, Width, FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
8505 glTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
8508 if (FreeDataAfterGenTexture) then
8512 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8513 procedure TglBitmap1D.GenTexture(const aTestTextureSize: Boolean);
8515 BuildWithGlu, TexRec: Boolean;
8518 if Assigned(Data) then begin
8519 // Check Texture Size
8520 if (aTestTextureSize) then begin
8521 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
8523 if (Width > TexSize) then
8524 raise EglBitmapSizeToLarge.Create('TglBitmap1D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
8526 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and
8527 (Target = GL_TEXTURE_RECTANGLE);
8528 if not (IsPowerOfTwo(Width) or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
8529 raise EglBitmapNonPowerOfTwo.Create('TglBitmap1D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8533 SetupParameters(BuildWithGlu);
8534 UploadData(BuildWithGlu);
8535 glAreTexturesResident(1, @fID, @fIsResident);
8539 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8540 procedure TglBitmap1D.AfterConstruction;
8543 Target := GL_TEXTURE_1D;
8547 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8548 //TglBitmap2D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8549 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8550 function TglBitmap2D.GetScanline(const aIndex: Integer): Pointer;
8552 if (aIndex >= Low(fLines)) and (aIndex <= High(fLines)) then
8553 result := fLines[aIndex]
8558 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8559 procedure TglBitmap2D.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
8560 const aWidth: Integer; const aHeight: Integer);
8562 Idx, LineWidth: Integer;
8564 inherited SetDataPointer(aData, aFormat, aWidth, aHeight);
8566 if not TFormatDescriptor.Get(aFormat).IsCompressed then begin
8568 if Assigned(Data) then begin
8569 SetLength(fLines, GetHeight);
8570 LineWidth := Trunc(GetWidth * TFormatDescriptor.Get(Format).BytesPerPixel);
8572 for Idx := 0 to GetHeight-1 do begin
8573 fLines[Idx] := Data;
8574 Inc(fLines[Idx], Idx * LineWidth);
8577 else SetLength(fLines, 0);
8579 SetLength(fLines, 0);
8583 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8584 procedure TglBitmap2D.UploadData(const aTarget: GLenum{$IFNDEF OPENGL_ES}; const aBuildWithGlu: Boolean{$ENDIF});
8586 FormatDesc: TFormatDescriptor;
8588 FormatDesc := TFormatDescriptor.Get(Format);
8589 if (FormatDesc.glInternalFormat = 0) or (FormatDesc.glDataFormat = 0) then
8590 raise EglBitmap.Create('format is not supported by video adapter, please convert before uploading data');
8592 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
8594 if FormatDesc.IsCompressed then begin
8595 if not Assigned(glCompressedTexImage2D) then
8596 raise EglBitmap.Create('compressed formats not supported by video adapter');
8597 glCompressedTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0, FormatDesc.GetSize(fDimension), Data)
8599 end else if aBuildWithGlu then begin
8600 gluBuild2DMipmaps(aTarget, FormatDesc.ChannelCount, Width, Height,
8601 FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
8604 glTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0,
8605 FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
8609 if (FreeDataAfterGenTexture) then
8613 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8614 procedure TglBitmap2D.AfterConstruction;
8617 Target := GL_TEXTURE_2D;
8620 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8621 procedure TglBitmap2D.GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
8624 Size, w, h: Integer;
8625 FormatDesc: TFormatDescriptor;
8627 FormatDesc := TFormatDescriptor.Get(aFormat);
8628 if FormatDesc.IsCompressed then
8629 raise EglBitmapUnsupportedFormat.Create(aFormat);
8631 w := aRight - aLeft;
8632 h := aBottom - aTop;
8633 Size := FormatDesc.GetSize(w, h);
8636 glPixelStorei(GL_PACK_ALIGNMENT, 1);
8637 glReadPixels(aLeft, aTop, w, h, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
8638 SetDataPointer(Temp, aFormat, w, h); //be careful, Data could be freed by this method
8641 if Assigned(Temp) then
8648 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8649 procedure TglBitmap2D.GetDataFromTexture;
8652 TempWidth, TempHeight: Integer;
8653 TempIntFormat: GLint;
8654 IntFormat: TglBitmapFormat;
8655 FormatDesc: TFormatDescriptor;
8660 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_WIDTH, @TempWidth);
8661 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT, @TempHeight);
8662 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat);
8664 FormatDesc := (TglBitmapFormatDescriptor.GetByFormat(TempIntFormat) as TFormatDescriptor);
8665 IntFormat := FormatDesc.Format;
8667 // Getting data from OpenGL
8668 FormatDesc := TFormatDescriptor.Get(IntFormat);
8669 GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight));
8671 if FormatDesc.IsCompressed then begin
8672 if not Assigned(glGetCompressedTexImage) then
8673 raise EglBitmap.Create('compressed formats not supported by video adapter');
8674 glGetCompressedTexImage(Target, 0, Temp)
8676 glGetTexImage(Target, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
8677 SetDataPointer(Temp, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
8679 if Assigned(Temp) then
8686 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8687 procedure TglBitmap2D.GenTexture(const aTestTextureSize: Boolean);
8690 BuildWithGlu, TexRec: Boolean;
8695 if Assigned(Data) then begin
8696 // Check Texture Size
8697 if (aTestTextureSize) then begin
8698 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
8700 if ((Height > TexSize) or (Width > TexSize)) then
8701 raise EglBitmapSizeToLarge.Create('TglBitmap2D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
8703 PotTex := IsPowerOfTwo(Height) and IsPowerOfTwo(Width);
8704 {$IF NOT DEFINED(OPENGL_ES)}
8705 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and (Target = GL_TEXTURE_RECTANGLE);
8706 if not (PotTex or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
8707 raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8708 {$ELSEIF DEFINED(OPENGL_ES_EXT)}
8709 if not PotTex and not GL_OES_texture_npot then
8710 raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8713 raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8718 SetupParameters({$IFNDEF OPENGL_ES}BuildWithGlu{$ENDIF});
8719 UploadData(Target{$IFNDEF OPENGL_ES}, BuildWithGlu{$ENDIF});
8721 glAreTexturesResident(1, @fID, @fIsResident);
8726 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8727 function TglBitmap2D.FlipHorz: Boolean;
8730 TempDestData, DestData, SourceData: PByte;
8733 result := inherited FlipHorz;
8734 if Assigned(Data) then begin
8736 ImgSize := Height * fRowSize;
8737 GetMem(DestData, ImgSize);
8739 TempDestData := DestData;
8740 Dec(TempDestData, fRowSize + fPixelSize);
8741 for Row := 0 to Height -1 do begin
8742 Inc(TempDestData, fRowSize * 2);
8743 for Col := 0 to Width -1 do begin
8744 Move(SourceData^, TempDestData^, fPixelSize);
8745 Inc(SourceData, fPixelSize);
8746 Dec(TempDestData, fPixelSize);
8749 SetDataPointer(DestData, Format, Width, Height); //be careful, Data could be freed by this method
8752 if Assigned(DestData) then
8759 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8760 function TglBitmap2D.FlipVert: Boolean;
8763 TempDestData, DestData, SourceData: PByte;
8765 result := inherited FlipVert;
8766 if Assigned(Data) then begin
8768 GetMem(DestData, Height * fRowSize);
8770 TempDestData := DestData;
8771 Inc(TempDestData, Width * (Height -1) * fPixelSize);
8772 for Row := 0 to Height -1 do begin
8773 Move(SourceData^, TempDestData^, fRowSize);
8774 Dec(TempDestData, fRowSize);
8775 Inc(SourceData, fRowSize);
8777 SetDataPointer(DestData, Format, Width, Height); //be careful, Data could be freed by this method
8780 if Assigned(DestData) then
8787 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8788 //TglBitmap2D - ToNormalMap///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8789 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8791 TMatrixItem = record
8796 PglBitmapToNormalMapRec = ^TglBitmapToNormalMapRec;
8797 TglBitmapToNormalMapRec = Record
8799 Heights: array of Single;
8800 MatrixU : array of TMatrixItem;
8801 MatrixV : array of TMatrixItem;
8805 ONE_OVER_255 = 1 / 255;
8807 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8808 procedure glBitmapToNormalMapPrepareFunc(var FuncRec: TglBitmapFunctionRec);
8812 with FuncRec do begin
8814 Source.Data.r * LUMINANCE_WEIGHT_R +
8815 Source.Data.g * LUMINANCE_WEIGHT_G +
8816 Source.Data.b * LUMINANCE_WEIGHT_B;
8817 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Val * ONE_OVER_255;
8821 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8822 procedure glBitmapToNormalMapPrepareAlphaFunc(var FuncRec: TglBitmapFunctionRec);
8825 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Source.Data.a * ONE_OVER_255;
8828 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8829 procedure glBitmapToNormalMapFunc (var FuncRec: TglBitmapFunctionRec);
8831 TVec = Array[0..2] of Single;
8838 function GetHeight(X, Y: Integer): Single;
8840 with FuncRec do begin
8841 X := Max(0, Min(Size.X -1, X));
8842 Y := Max(0, Min(Size.Y -1, Y));
8843 result := PglBitmapToNormalMapRec(Args)^.Heights[Y * Size.X + X];
8848 with FuncRec do begin
8849 with PglBitmapToNormalMapRec(Args)^ do begin
8851 for Idx := Low(MatrixU) to High(MatrixU) do
8852 du := du + GetHeight(Position.X + MatrixU[Idx].X, Position.Y + MatrixU[Idx].Y) * MatrixU[Idx].W;
8855 for Idx := Low(MatrixU) to High(MatrixU) do
8856 dv := dv + GetHeight(Position.X + MatrixV[Idx].X, Position.Y + MatrixV[Idx].Y) * MatrixV[Idx].W;
8858 Vec[0] := -du * Scale;
8859 Vec[1] := -dv * Scale;
8864 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
8865 if Len <> 0 then begin
8866 Vec[0] := Vec[0] * Len;
8867 Vec[1] := Vec[1] * Len;
8868 Vec[2] := Vec[2] * Len;
8872 Dest.Data.r := Trunc((Vec[0] + 1) * 127.5);
8873 Dest.Data.g := Trunc((Vec[1] + 1) * 127.5);
8874 Dest.Data.b := Trunc((Vec[2] + 1) * 127.5);
8878 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8879 procedure TglBitmap2D.ToNormalMap(const aFunc: TglBitmapNormalMapFunc; const aScale: Single; const aUseAlpha: Boolean);
8881 Rec: TglBitmapToNormalMapRec;
8883 procedure SetEntry (var Matrix: array of TMatrixItem; Index, X, Y: Integer; W: Single);
8885 if (Index >= Low(Matrix)) and (Index <= High(Matrix)) then begin
8886 Matrix[Index].X := X;
8887 Matrix[Index].Y := Y;
8888 Matrix[Index].W := W;
8893 if TFormatDescriptor.Get(Format).IsCompressed then
8894 raise EglBitmapUnsupportedFormat.Create(Format);
8896 if aScale > 100 then
8898 else if aScale < -100 then
8901 Rec.Scale := aScale;
8903 SetLength(Rec.Heights, Width * Height);
8907 SetLength(Rec.MatrixU, 2);
8908 SetEntry(Rec.MatrixU, 0, -1, 0, -0.5);
8909 SetEntry(Rec.MatrixU, 1, 1, 0, 0.5);
8911 SetLength(Rec.MatrixV, 2);
8912 SetEntry(Rec.MatrixV, 0, 0, 1, 0.5);
8913 SetEntry(Rec.MatrixV, 1, 0, -1, -0.5);
8917 SetLength(Rec.MatrixU, 6);
8918 SetEntry(Rec.MatrixU, 0, -1, 1, -1.0);
8919 SetEntry(Rec.MatrixU, 1, -1, 0, -2.0);
8920 SetEntry(Rec.MatrixU, 2, -1, -1, -1.0);
8921 SetEntry(Rec.MatrixU, 3, 1, 1, 1.0);
8922 SetEntry(Rec.MatrixU, 4, 1, 0, 2.0);
8923 SetEntry(Rec.MatrixU, 5, 1, -1, 1.0);
8925 SetLength(Rec.MatrixV, 6);
8926 SetEntry(Rec.MatrixV, 0, -1, 1, 1.0);
8927 SetEntry(Rec.MatrixV, 1, 0, 1, 2.0);
8928 SetEntry(Rec.MatrixV, 2, 1, 1, 1.0);
8929 SetEntry(Rec.MatrixV, 3, -1, -1, -1.0);
8930 SetEntry(Rec.MatrixV, 4, 0, -1, -2.0);
8931 SetEntry(Rec.MatrixV, 5, 1, -1, -1.0);
8935 SetLength(Rec.MatrixU, 6);
8936 SetEntry(Rec.MatrixU, 0, -1, 1, -1/6);
8937 SetEntry(Rec.MatrixU, 1, -1, 0, -1/6);
8938 SetEntry(Rec.MatrixU, 2, -1, -1, -1/6);
8939 SetEntry(Rec.MatrixU, 3, 1, 1, 1/6);
8940 SetEntry(Rec.MatrixU, 4, 1, 0, 1/6);
8941 SetEntry(Rec.MatrixU, 5, 1, -1, 1/6);
8943 SetLength(Rec.MatrixV, 6);
8944 SetEntry(Rec.MatrixV, 0, -1, 1, 1/6);
8945 SetEntry(Rec.MatrixV, 1, 0, 1, 1/6);
8946 SetEntry(Rec.MatrixV, 2, 1, 1, 1/6);
8947 SetEntry(Rec.MatrixV, 3, -1, -1, -1/6);
8948 SetEntry(Rec.MatrixV, 4, 0, -1, -1/6);
8949 SetEntry(Rec.MatrixV, 5, 1, -1, -1/6);
8953 SetLength(Rec.MatrixU, 20);
8954 SetEntry(Rec.MatrixU, 0, -2, 2, -1 / 16);
8955 SetEntry(Rec.MatrixU, 1, -1, 2, -1 / 10);
8956 SetEntry(Rec.MatrixU, 2, 1, 2, 1 / 10);
8957 SetEntry(Rec.MatrixU, 3, 2, 2, 1 / 16);
8958 SetEntry(Rec.MatrixU, 4, -2, 1, -1 / 10);
8959 SetEntry(Rec.MatrixU, 5, -1, 1, -1 / 8);
8960 SetEntry(Rec.MatrixU, 6, 1, 1, 1 / 8);
8961 SetEntry(Rec.MatrixU, 7, 2, 1, 1 / 10);
8962 SetEntry(Rec.MatrixU, 8, -2, 0, -1 / 2.8);
8963 SetEntry(Rec.MatrixU, 9, -1, 0, -0.5);
8964 SetEntry(Rec.MatrixU, 10, 1, 0, 0.5);
8965 SetEntry(Rec.MatrixU, 11, 2, 0, 1 / 2.8);
8966 SetEntry(Rec.MatrixU, 12, -2, -1, -1 / 10);
8967 SetEntry(Rec.MatrixU, 13, -1, -1, -1 / 8);
8968 SetEntry(Rec.MatrixU, 14, 1, -1, 1 / 8);
8969 SetEntry(Rec.MatrixU, 15, 2, -1, 1 / 10);
8970 SetEntry(Rec.MatrixU, 16, -2, -2, -1 / 16);
8971 SetEntry(Rec.MatrixU, 17, -1, -2, -1 / 10);
8972 SetEntry(Rec.MatrixU, 18, 1, -2, 1 / 10);
8973 SetEntry(Rec.MatrixU, 19, 2, -2, 1 / 16);
8975 SetLength(Rec.MatrixV, 20);
8976 SetEntry(Rec.MatrixV, 0, -2, 2, 1 / 16);
8977 SetEntry(Rec.MatrixV, 1, -1, 2, 1 / 10);
8978 SetEntry(Rec.MatrixV, 2, 0, 2, 0.25);
8979 SetEntry(Rec.MatrixV, 3, 1, 2, 1 / 10);
8980 SetEntry(Rec.MatrixV, 4, 2, 2, 1 / 16);
8981 SetEntry(Rec.MatrixV, 5, -2, 1, 1 / 10);
8982 SetEntry(Rec.MatrixV, 6, -1, 1, 1 / 8);
8983 SetEntry(Rec.MatrixV, 7, 0, 1, 0.5);
8984 SetEntry(Rec.MatrixV, 8, 1, 1, 1 / 8);
8985 SetEntry(Rec.MatrixV, 9, 2, 1, 1 / 16);
8986 SetEntry(Rec.MatrixV, 10, -2, -1, -1 / 16);
8987 SetEntry(Rec.MatrixV, 11, -1, -1, -1 / 8);
8988 SetEntry(Rec.MatrixV, 12, 0, -1, -0.5);
8989 SetEntry(Rec.MatrixV, 13, 1, -1, -1 / 8);
8990 SetEntry(Rec.MatrixV, 14, 2, -1, -1 / 10);
8991 SetEntry(Rec.MatrixV, 15, -2, -2, -1 / 16);
8992 SetEntry(Rec.MatrixV, 16, -1, -2, -1 / 10);
8993 SetEntry(Rec.MatrixV, 17, 0, -2, -0.25);
8994 SetEntry(Rec.MatrixV, 18, 1, -2, -1 / 10);
8995 SetEntry(Rec.MatrixV, 19, 2, -2, -1 / 16);
9000 if aUseAlpha and TFormatDescriptor.Get(Format).HasAlpha then
9001 AddFunc(glBitmapToNormalMapPrepareAlphaFunc, false, @Rec)
9003 AddFunc(glBitmapToNormalMapPrepareFunc, false, @Rec);
9004 AddFunc(glBitmapToNormalMapFunc, false, @Rec);
9006 SetLength(Rec.Heights, 0);
9010 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
9011 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9012 //TglBitmapCubeMap////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9013 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9014 procedure TglBitmapCubeMap.GenTexture(const aTestTextureSize: Boolean);
9016 Assert(false, 'TglBitmapCubeMap.GenTexture - Don''t call GenTextures directly.');
9019 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9020 procedure TglBitmapCubeMap.AfterConstruction;
9025 if not (GL_VERSION_1_3 or GL_ARB_texture_cube_map or GL_EXT_texture_cube_map) then
9026 raise EglBitmap.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
9028 if not (GL_VERSION_2_0) then
9029 raise EglBitmap.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
9033 Target := GL_TEXTURE_CUBE_MAP;
9035 fGenMode := GL_REFLECTION_MAP;
9039 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9040 procedure TglBitmapCubeMap.GenerateCubeMap(const aCubeTarget: Cardinal; const aTestTextureSize: Boolean);
9043 BuildWithGlu: Boolean;
9047 if (aTestTextureSize) then begin
9048 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, @TexSize);
9050 if (Height > TexSize) or (Width > TexSize) then
9051 raise EglBitmapSizeToLarge.Create('TglBitmapCubeMap.GenerateCubeMap - The size for the Cubemap is to large. It''s may be not conform with the Hardware.');
9053 {$IF NOT DEFINED(OPENGL_ES)}
9054 if not ((IsPowerOfTwo(Height) and IsPowerOfTwo(Width)) or GL_VERSION_2_0 or GL_ARB_texture_non_power_of_two) then
9055 raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenerateCubeMap - Cubemaps dosn''t support non power of two texture.');
9056 {$ELSEIF DEFINED(OPENGL_ES_EXT)}
9057 if not (IsPowerOfTwo(Height) and IsPowerOfTwo(Width)) and not GL_OES_texture_npot then
9058 raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenerateCubeMap - Cubemaps dosn''t support non power of two texture.');
9060 if not (IsPowerOfTwo(Height) and IsPowerOfTwo(Width)) then
9061 raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenerateCubeMap - Cubemaps dosn''t support non power of two texture.');
9067 SetupParameters({$IFNDEF OPENGL_ES}BuildWithGlu{$ENDIF});
9068 UploadData(aCubeTarget{$IFNDEF OPENGL_ES}, BuildWithGlu{$ENDIF});
9071 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9072 procedure TglBitmapCubeMap.Bind({$IFNDEF OPENGL_ES}const aEnableTexCoordsGen: Boolean;{$ENDIF} const aEnableTextureUnit: Boolean);
9074 inherited Bind (aEnableTextureUnit);
9076 if aEnableTexCoordsGen then begin
9077 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, fGenMode);
9078 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, fGenMode);
9079 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, fGenMode);
9080 glEnable(GL_TEXTURE_GEN_S);
9081 glEnable(GL_TEXTURE_GEN_T);
9082 glEnable(GL_TEXTURE_GEN_R);
9087 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9088 procedure TglBitmapCubeMap.Unbind({$IFNDEF OPENGL_ES}const aDisableTexCoordsGen: Boolean;{$ENDIF} const aDisableTextureUnit: Boolean);
9090 inherited Unbind(aDisableTextureUnit);
9092 if aDisableTexCoordsGen then begin
9093 glDisable(GL_TEXTURE_GEN_S);
9094 glDisable(GL_TEXTURE_GEN_T);
9095 glDisable(GL_TEXTURE_GEN_R);
9101 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
9102 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9103 //TglBitmapNormalMap//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9104 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9106 TVec = Array[0..2] of Single;
9107 TglBitmapNormalMapGetVectorFunc = procedure (out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
9109 PglBitmapNormalMapRec = ^TglBitmapNormalMapRec;
9110 TglBitmapNormalMapRec = record
9112 Func: TglBitmapNormalMapGetVectorFunc;
9115 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9116 procedure glBitmapNormalMapPosX(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
9118 aVec[0] := aHalfSize;
9119 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
9120 aVec[2] := - (aPosition.X + 0.5 - aHalfSize);
9123 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9124 procedure glBitmapNormalMapNegX(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
9126 aVec[0] := - aHalfSize;
9127 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
9128 aVec[2] := aPosition.X + 0.5 - aHalfSize;
9131 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9132 procedure glBitmapNormalMapPosY(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
9134 aVec[0] := aPosition.X + 0.5 - aHalfSize;
9135 aVec[1] := aHalfSize;
9136 aVec[2] := aPosition.Y + 0.5 - aHalfSize;
9139 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9140 procedure glBitmapNormalMapNegY(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
9142 aVec[0] := aPosition.X + 0.5 - aHalfSize;
9143 aVec[1] := - aHalfSize;
9144 aVec[2] := - (aPosition.Y + 0.5 - aHalfSize);
9147 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9148 procedure glBitmapNormalMapPosZ(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
9150 aVec[0] := aPosition.X + 0.5 - aHalfSize;
9151 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
9152 aVec[2] := aHalfSize;
9155 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9156 procedure glBitmapNormalMapNegZ(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
9158 aVec[0] := - (aPosition.X + 0.5 - aHalfSize);
9159 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
9160 aVec[2] := - aHalfSize;
9163 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9164 procedure glBitmapNormalMapFunc(var FuncRec: TglBitmapFunctionRec);
9170 with FuncRec do begin
9171 with PglBitmapNormalMapRec(Args)^ do begin
9172 Func(Vec, Position, HalfSize);
9175 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
9176 if Len <> 0 then begin
9177 Vec[0] := Vec[0] * Len;
9178 Vec[1] := Vec[1] * Len;
9179 Vec[2] := Vec[2] * Len;
9182 // Scale Vector and AddVectro
9183 Vec[0] := Vec[0] * 0.5 + 0.5;
9184 Vec[1] := Vec[1] * 0.5 + 0.5;
9185 Vec[2] := Vec[2] * 0.5 + 0.5;
9190 Dest.Data.arr[i] := Round(Vec[i] * 255);
9194 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9195 procedure TglBitmapNormalMap.AfterConstruction;
9199 fGenMode := GL_NORMAL_MAP;
9203 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9204 procedure TglBitmapNormalMap.GenerateNormalMap(const aSize: Integer; const aTestTextureSize: Boolean);
9206 Rec: TglBitmapNormalMapRec;
9207 SizeRec: TglBitmapPixelPosition;
9209 Rec.HalfSize := aSize div 2;
9210 FreeDataAfterGenTexture := false;
9212 SizeRec.Fields := [ffX, ffY];
9217 Rec.Func := glBitmapNormalMapPosX;
9218 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
9219 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X, aTestTextureSize);
9222 Rec.Func := glBitmapNormalMapNegX;
9223 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
9224 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, aTestTextureSize);
9227 Rec.Func := glBitmapNormalMapPosY;
9228 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
9229 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, aTestTextureSize);
9232 Rec.Func := glBitmapNormalMapNegY;
9233 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
9234 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, aTestTextureSize);
9237 Rec.Func := glBitmapNormalMapPosZ;
9238 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
9239 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, aTestTextureSize);
9242 Rec.Func := glBitmapNormalMapNegZ;
9243 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
9244 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, aTestTextureSize);
9249 glBitmapSetDefaultFormat (tfEmpty);
9250 glBitmapSetDefaultMipmap (mmMipmap);
9251 glBitmapSetDefaultFilter (GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
9252 glBitmapSetDefaultWrap (GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
9253 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
9254 glBitmapSetDefaultSwizzle(GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA);
9257 glBitmapSetDefaultFreeDataAfterGenTexture(true);
9258 glBitmapSetDefaultDeleteTextureOnFree (true);
9260 TFormatDescriptor.Init;
9262 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
9263 OpenGLInitialized := false;
9264 InitOpenGLCS := TCriticalSection.Create;
9268 TFormatDescriptor.Finalize;
9270 {$IFDEF GLB_NATIVE_OGL}
9271 if Assigned(GL_LibHandle) then
9272 glbFreeLibrary(GL_LibHandle);
9274 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
9275 if Assigned(GLU_LibHandle) then
9276 glbFreeLibrary(GLU_LibHandle);
9277 FreeAndNil(InitOpenGLCS);