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);
1323 NULL_SIZE: TglBitmapPixelPosition = (Fields: []; X: 0; Y: 0);
1325 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
1326 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
1327 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
1328 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
1329 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
1330 procedure glBitmapSetDefaultWrap(
1331 const S: Cardinal = GL_CLAMP_TO_EDGE;
1332 const T: Cardinal = GL_CLAMP_TO_EDGE;
1333 const R: Cardinal = GL_CLAMP_TO_EDGE);
1335 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
1336 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
1337 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
1338 function glBitmapGetDefaultFormat: TglBitmapFormat;
1339 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
1340 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
1342 function glBitmapPosition(X: Integer = -1; Y: Integer = -1): TglBitmapPixelPosition;
1343 function glBitmapRec4ub(const r, g, b, a: Byte): TglBitmapRec4ub;
1344 function glBitmapRec4ui(const r, g, b, a: Cardinal): TglBitmapRec4ui;
1345 function glBitmapRec4ul(const r, g, b, a: QWord): TglBitmapRec4ul;
1346 function glBitmapRec4ubCompare(const r1, r2: TglBitmapRec4ub): Boolean;
1347 function glBitmapRec4uiCompare(const r1, r2: TglBitmapRec4ui): Boolean;
1349 function glBitmapCreateTestTexture(const aFormat: TglBitmapFormat): TglBitmap2D;
1352 glBitmapDefaultDeleteTextureOnFree: Boolean;
1353 glBitmapDefaultFreeDataAfterGenTextures: Boolean;
1354 glBitmapDefaultFormat: TglBitmapFormat;
1355 glBitmapDefaultMipmap: TglBitmapMipMap;
1356 glBitmapDefaultFilterMin: Cardinal;
1357 glBitmapDefaultFilterMag: Cardinal;
1358 glBitmapDefaultWrapS: Cardinal;
1359 glBitmapDefaultWrapT: Cardinal;
1360 glBitmapDefaultWrapR: Cardinal;
1361 glDefaultSwizzle: array[0..3] of GLenum;
1364 function CreateGrayPalette: HPALETTE;
1370 Math, syncobjs, typinfo
1371 {$IF DEFINED(GLB_SUPPORT_JPEG_READ) AND DEFINED(GLB_LAZ_JPEG)}, FPReadJPEG{$IFEND};
1373 ////////////////////////////////////////////////////////////////////////////////////////////////////
1375 TFormatDescriptor = class(TglBitmapFormatDescriptor)
1377 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); virtual; abstract;
1378 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); virtual; abstract;
1380 function GetSize(const aSize: TglBitmapPixelPosition): Integer; overload; virtual;
1381 function GetSize(const aWidth, aHeight: Integer): Integer; overload; virtual;
1383 function CreateMappingData: Pointer; virtual;
1384 procedure FreeMappingData(var aMappingData: Pointer); virtual;
1386 function IsEmpty: Boolean; virtual;
1387 function MaskMatch(const aMask: TglBitmapRec4ul): Boolean; virtual;
1389 procedure PreparePixel(out aPixel: TglBitmapPixelData); virtual;
1391 constructor Create; virtual;
1393 class procedure Init;
1394 class function Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
1395 class function GetAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
1396 class function GetFromMask(const aMask: TglBitmapRec4ul; const aBitCount: Integer = 0): TFormatDescriptor;
1397 class function GetFromPrecShift(const aPrec, aShift: TglBitmapRec4ub; const aBitCount: Integer): TFormatDescriptor;
1398 class procedure Clear;
1399 class procedure Finalize;
1401 TFormatDescriptorClass = class of TFormatDescriptor;
1403 TfdEmpty = class(TFormatDescriptor);
1405 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1406 TfdAlphaUB1 = class(TFormatDescriptor) //1* unsigned byte
1407 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1408 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1411 TfdLuminanceUB1 = class(TFormatDescriptor) //1* unsigned byte
1412 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1413 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1416 TfdUniversalUB1 = class(TFormatDescriptor) //1* unsigned byte
1417 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1418 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1421 TfdLuminanceAlphaUB2 = class(TfdLuminanceUB1) //2* unsigned byte
1422 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1423 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1426 TfdRGBub3 = class(TFormatDescriptor) //3* unsigned byte
1427 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1428 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1431 TfdBGRub3 = class(TFormatDescriptor) //3* unsigned byte (inverse)
1432 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1433 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1436 TfdRGBAub4 = class(TfdRGBub3) //3* unsigned byte
1437 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1438 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1441 TfdBGRAub4 = class(TfdBGRub3) //3* unsigned byte (inverse)
1442 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1443 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1446 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1447 TfdAlphaUS1 = class(TFormatDescriptor) //1* unsigned short
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 TfdLuminanceUS1 = class(TFormatDescriptor) //1* unsigned short
1453 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1454 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1457 TfdUniversalUS1 = class(TFormatDescriptor) //1* unsigned short
1458 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1459 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1462 TfdDepthUS1 = class(TFormatDescriptor) //1* unsigned short
1463 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1464 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1467 TfdLuminanceAlphaUS2 = class(TfdLuminanceUS1) //2* unsigned short
1468 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1469 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1472 TfdRGBus3 = class(TFormatDescriptor) //3* unsigned short
1473 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1474 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1477 TfdBGRus3 = class(TFormatDescriptor) //3* unsigned short (inverse)
1478 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1479 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1482 TfdRGBAus4 = class(TfdRGBus3) //4* unsigned short
1483 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1484 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1487 TfdARGBus4 = class(TfdRGBus3) //4* unsigned short
1488 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1489 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1492 TfdBGRAus4 = class(TfdBGRus3) //4* unsigned short (inverse)
1493 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1494 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1497 TfdABGRus4 = class(TfdBGRus3) //4* unsigned short (inverse)
1498 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1499 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1502 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1503 TfdUniversalUI1 = class(TFormatDescriptor) //1* unsigned int
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 TfdDepthUI1 = class(TFormatDescriptor) //1* unsigned int
1509 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1510 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1513 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1514 TfdAlpha4ub1 = class(TfdAlphaUB1)
1515 procedure SetValues; override;
1518 TfdAlpha8ub1 = class(TfdAlphaUB1)
1519 procedure SetValues; override;
1522 TfdAlpha16us1 = class(TfdAlphaUS1)
1523 procedure SetValues; override;
1526 TfdLuminance4ub1 = class(TfdLuminanceUB1)
1527 procedure SetValues; override;
1530 TfdLuminance8ub1 = class(TfdLuminanceUB1)
1531 procedure SetValues; override;
1534 TfdLuminance16us1 = class(TfdLuminanceUS1)
1535 procedure SetValues; override;
1538 TfdLuminance4Alpha4ub2 = class(TfdLuminanceAlphaUB2)
1539 procedure SetValues; override;
1542 TfdLuminance6Alpha2ub2 = class(TfdLuminanceAlphaUB2)
1543 procedure SetValues; override;
1546 TfdLuminance8Alpha8ub2 = class(TfdLuminanceAlphaUB2)
1547 procedure SetValues; override;
1550 TfdLuminance12Alpha4us2 = class(TfdLuminanceAlphaUS2)
1551 procedure SetValues; override;
1554 TfdLuminance16Alpha16us2 = class(TfdLuminanceAlphaUS2)
1555 procedure SetValues; override;
1558 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1559 TfdR3G3B2ub1 = class(TfdUniversalUB1)
1560 procedure SetValues; override;
1563 TfdRGBX4us1 = class(TfdUniversalUS1)
1564 procedure SetValues; override;
1567 TfdXRGB4us1 = class(TfdUniversalUS1)
1568 procedure SetValues; override;
1571 TfdR5G6B5us1 = class(TfdUniversalUS1)
1572 procedure SetValues; override;
1575 TfdRGB5X1us1 = class(TfdUniversalUS1)
1576 procedure SetValues; override;
1579 TfdX1RGB5us1 = class(TfdUniversalUS1)
1580 procedure SetValues; override;
1583 TfdRGB8ub3 = class(TfdRGBub3)
1584 procedure SetValues; override;
1587 TfdRGBX8ui1 = class(TfdUniversalUI1)
1588 procedure SetValues; override;
1591 TfdXRGB8ui1 = class(TfdUniversalUI1)
1592 procedure SetValues; override;
1595 TfdRGB10X2ui1 = class(TfdUniversalUI1)
1596 procedure SetValues; override;
1599 TfdX2RGB10ui1 = class(TfdUniversalUI1)
1600 procedure SetValues; override;
1603 TfdRGB16us3 = class(TfdRGBus3)
1604 procedure SetValues; override;
1607 TfdRGBA4us1 = class(TfdUniversalUS1)
1608 procedure SetValues; override;
1611 TfdARGB4us1 = class(TfdUniversalUS1)
1612 procedure SetValues; override;
1615 TfdRGB5A1us1 = class(TfdUniversalUS1)
1616 procedure SetValues; override;
1619 TfdA1RGB5us1 = class(TfdUniversalUS1)
1620 procedure SetValues; override;
1623 TfdRGBA8ui1 = class(TfdUniversalUI1)
1624 procedure SetValues; override;
1627 TfdARGB8ui1 = class(TfdUniversalUI1)
1628 procedure SetValues; override;
1631 TfdRGBA8ub4 = class(TfdRGBAub4)
1632 procedure SetValues; override;
1635 TfdRGB10A2ui1 = class(TfdUniversalUI1)
1636 procedure SetValues; override;
1639 TfdA2RGB10ui1 = class(TfdUniversalUI1)
1640 procedure SetValues; override;
1643 TfdRGBA16us4 = class(TfdRGBAus4)
1644 procedure SetValues; override;
1647 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1648 TfdBGRX4us1 = class(TfdUniversalUS1)
1649 procedure SetValues; override;
1652 TfdXBGR4us1 = class(TfdUniversalUS1)
1653 procedure SetValues; override;
1656 TfdB5G6R5us1 = class(TfdUniversalUS1)
1657 procedure SetValues; override;
1660 TfdBGR5X1us1 = class(TfdUniversalUS1)
1661 procedure SetValues; override;
1664 TfdX1BGR5us1 = class(TfdUniversalUS1)
1665 procedure SetValues; override;
1668 TfdBGR8ub3 = class(TfdBGRub3)
1669 procedure SetValues; override;
1672 TfdBGRX8ui1 = class(TfdUniversalUI1)
1673 procedure SetValues; override;
1676 TfdXBGR8ui1 = class(TfdUniversalUI1)
1677 procedure SetValues; override;
1680 TfdBGR10X2ui1 = class(TfdUniversalUI1)
1681 procedure SetValues; override;
1684 TfdX2BGR10ui1 = class(TfdUniversalUI1)
1685 procedure SetValues; override;
1688 TfdBGR16us3 = class(TfdBGRus3)
1689 procedure SetValues; override;
1692 TfdBGRA4us1 = class(TfdUniversalUS1)
1693 procedure SetValues; override;
1696 TfdABGR4us1 = class(TfdUniversalUS1)
1697 procedure SetValues; override;
1700 TfdBGR5A1us1 = class(TfdUniversalUS1)
1701 procedure SetValues; override;
1704 TfdA1BGR5us1 = class(TfdUniversalUS1)
1705 procedure SetValues; override;
1708 TfdBGRA8ui1 = class(TfdUniversalUI1)
1709 procedure SetValues; override;
1712 TfdABGR8ui1 = class(TfdUniversalUI1)
1713 procedure SetValues; override;
1716 TfdBGRA8ub4 = class(TfdBGRAub4)
1717 procedure SetValues; override;
1720 TfdBGR10A2ui1 = class(TfdUniversalUI1)
1721 procedure SetValues; override;
1724 TfdA2BGR10ui1 = class(TfdUniversalUI1)
1725 procedure SetValues; override;
1728 TfdBGRA16us4 = class(TfdBGRAus4)
1729 procedure SetValues; override;
1732 TfdDepth16us1 = class(TfdDepthUS1)
1733 procedure SetValues; override;
1736 TfdDepth24ui1 = class(TfdDepthUI1)
1737 procedure SetValues; override;
1740 TfdDepth32ui1 = class(TfdDepthUI1)
1741 procedure SetValues; override;
1744 TfdS3tcDtx1RGBA = class(TFormatDescriptor)
1745 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1746 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1747 procedure SetValues; override;
1750 TfdS3tcDtx3RGBA = 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 TfdS3tcDtx5RGBA = 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 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1763 TbmpBitfieldFormat = class(TFormatDescriptor)
1765 procedure SetCustomValues(const aBPP: Integer; aMask: TglBitmapRec4ul); overload;
1766 procedure SetCustomValues(const aBBP: Integer; const aPrec, aShift: TglBitmapRec4ub); overload;
1767 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1768 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1771 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1772 TbmpColorTableEnty = packed record
1775 TbmpColorTable = array of TbmpColorTableEnty;
1776 TbmpColorTableFormat = class(TFormatDescriptor)
1778 fBitsPerPixel: Integer;
1779 fColorTable: TbmpColorTable;
1781 procedure SetValues; override;
1783 property ColorTable: TbmpColorTable read fColorTable write fColorTable;
1784 property BitsPerPixel: Integer read fBitsPerPixel write fBitsPerPixel;
1786 procedure SetCustomValues(const aFormat: TglBitmapFormat; const aBPP: Integer; const aPrec, aShift: TglBitmapRec4ub); overload;
1787 procedure CalcValues;
1788 procedure CreateColorTable;
1790 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1791 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1792 destructor Destroy; override;
1796 LUMINANCE_WEIGHT_R = 0.30;
1797 LUMINANCE_WEIGHT_G = 0.59;
1798 LUMINANCE_WEIGHT_B = 0.11;
1800 ALPHA_WEIGHT_R = 0.30;
1801 ALPHA_WEIGHT_G = 0.59;
1802 ALPHA_WEIGHT_B = 0.11;
1804 DEPTH_WEIGHT_R = 0.333333333;
1805 DEPTH_WEIGHT_G = 0.333333333;
1806 DEPTH_WEIGHT_B = 0.333333333;
1808 FORMAT_DESCRIPTOR_CLASSES: array[TglBitmapFormat] of TFormatDescriptorClass = (
1819 TfdLuminance4Alpha4ub2,
1820 TfdLuminance6Alpha2ub2,
1821 TfdLuminance8Alpha8ub2,
1822 TfdLuminance12Alpha4us2,
1823 TfdLuminance16Alpha16us2,
1882 FormatDescriptorCS: TCriticalSection;
1883 FormatDescriptors: array[TglBitmapFormat] of TFormatDescriptor;
1885 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1886 constructor EglBitmapUnsupportedFormat.Create(const aFormat: TglBitmapFormat);
1888 inherited Create('unsupported format: ' + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
1891 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1892 constructor EglBitmapUnsupportedFormat.Create(const aMsg: String; const aFormat: TglBitmapFormat);
1894 inherited Create(aMsg + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
1897 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1898 function glBitmapPosition(X: Integer; Y: Integer): TglBitmapPixelPosition;
1900 result.Fields := [];
1903 result.Fields := result.Fields + [ffX];
1905 result.Fields := result.Fields + [ffY];
1907 result.X := Max(0, X);
1908 result.Y := Max(0, Y);
1911 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1912 function glBitmapRec4ub(const r, g, b, a: Byte): TglBitmapRec4ub;
1920 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1921 function glBitmapRec4ui(const r, g, b, a: Cardinal): TglBitmapRec4ui;
1929 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1930 function glBitmapRec4ul(const r, g, b, a: QWord): TglBitmapRec4ul;
1938 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1939 function glBitmapRec4ubCompare(const r1, r2: TglBitmapRec4ub): Boolean;
1944 for i := 0 to high(r1.arr) do
1945 if (r1.arr[i] <> r2.arr[i]) then
1950 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1951 function glBitmapRec4uiCompare(const r1, r2: TglBitmapRec4ui): Boolean;
1956 for i := 0 to high(r1.arr) do
1957 if (r1.arr[i] <> r2.arr[i]) then
1962 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1963 function glBitmapCreateTestTexture(const aFormat: TglBitmapFormat): TglBitmap2D;
1965 desc: TFormatDescriptor;
1969 px: TglBitmapPixelData;
1972 desc := TFormatDescriptor.Get(aFormat);
1973 if (desc.IsCompressed) or (desc.glFormat = 0) then
1976 p := GetMemory(ceil(25 * desc.BytesPerPixel)); // 5 x 5 pixel
1977 md := desc.CreateMappingData;
1980 desc.PreparePixel(px);
1982 for x := 0 to 4 do begin
1983 px.Data := glBitmapRec4ui(0, 0, 0, 0);
1984 for i := 0 to 3 do begin
1985 if ((y < 3) and (y = i)) or
1986 ((y = 3) and (i < 3)) or
1987 ((y = 4) and (i = 3))
1989 px.Data.arr[i] := Trunc(px.Range.arr[i] / 4 * x)
1990 else if ((y < 4) and (i = 3)) or
1991 ((y = 4) and (i < 3))
1993 px.Data.arr[i] := px.Range.arr[i]
1995 px.Data.arr[i] := 0; //px.Range.arr[i];
1997 desc.Map(px, tmp, md);
2000 desc.FreeMappingData(md);
2003 result := TglBitmap2D.Create(glBitmapPosition(5, 5), aFormat, p);
2004 result.FreeDataOnDestroy := true;
2005 result.FreeDataAfterGenTexture := false;
2006 result.SetFilter(GL_NEAREST, GL_NEAREST);
2009 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2010 function glBitmapShiftRec(const r, g, b, a: Byte): TglBitmapRec4ub;
2018 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2019 function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes;
2025 tfAlpha4ub1, tfAlpha8ub1,
2026 tfLuminance4ub1, tfLuminance8ub1, tfR3G3B2ub1,
2029 tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
2030 tfRGBX4us1, tfXRGB4us1, tfRGB5X1us1, tfX1RGB5us1, tfR5G6B5us1, tfRGB5A1us1, tfA1RGB5us1, tfRGBA4us1, tfARGB4us1,
2031 tfBGRX4us1, tfXBGR4us1, tfBGR5X1us1, tfX1BGR5us1, tfB5G6R5us1, tfBGR5A1us1, tfA1BGR5us1, tfBGRA4us1, tfABGR4us1,
2034 tfBGR8ub3, tfRGB8ub3,
2037 tfRGBX8ui1, tfXRGB8ui1, tfRGB10X2ui1, tfX2RGB10ui1, tfRGBA8ui1, tfARGB8ui1, tfRGBA8ub4, tfRGB10A2ui1, tfA2RGB10ui1,
2038 tfBGRX8ui1, tfXBGR8ui1, tfBGR10X2ui1, tfX2BGR10ui1, tfBGRA8ui1, tfABGR8ui1, tfBGRA8ub4, tfBGR10A2ui1, tfA2BGR10ui1])
2040 result := result + [ ftBMP ];
2044 tfAlpha4ub1, tfAlpha8ub1, tfLuminance4ub1, tfLuminance8ub1,
2047 tfAlpha16us1, tfLuminance16us1,
2048 tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
2049 tfX1RGB5us1, tfARGB4us1, tfA1RGB5us1, tfDepth16us1,
2055 tfX2RGB10ui1, tfARGB8ui1, tfBGRA8ub4, tfA2RGB10ui1,
2056 tfDepth24ui1, tfDepth32ui1])
2058 result := result + [ftTGA];
2060 if not (aFormat in [tfEmpty, tfRGB16us3, tfBGR16us3]) then
2061 result := result + [ftDDS];
2063 {$IFDEF GLB_SUPPORT_PNG_WRITE}
2065 tfAlpha8ub1, tfLuminance8ub1, tfLuminance8Alpha8ub2,
2066 tfRGB8ub3, tfRGBA8ui1,
2067 tfBGR8ub3, tfBGRA8ui1] then
2068 result := result + [ftPNG];
2071 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
2072 if aFormat in [tfAlpha8ub1, tfLuminance8ub1, tfRGB8ub3, tfBGR8ub3] then
2073 result := result + [ftJPEG];
2077 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2078 function IsPowerOfTwo(aNumber: Integer): Boolean;
2080 while (aNumber and 1) = 0 do
2081 aNumber := aNumber shr 1;
2082 result := aNumber = 1;
2085 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2086 function GetTopMostBit(aBitSet: QWord): Integer;
2089 while aBitSet > 0 do begin
2091 aBitSet := aBitSet shr 1;
2095 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2096 function CountSetBits(aBitSet: QWord): Integer;
2099 while aBitSet > 0 do begin
2100 if (aBitSet and 1) = 1 then
2102 aBitSet := aBitSet shr 1;
2106 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2107 function LuminanceWeight(const aPixel: TglBitmapPixelData): Cardinal;
2110 LUMINANCE_WEIGHT_R * aPixel.Data.r +
2111 LUMINANCE_WEIGHT_G * aPixel.Data.g +
2112 LUMINANCE_WEIGHT_B * aPixel.Data.b);
2115 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2116 function DepthWeight(const aPixel: TglBitmapPixelData): Cardinal;
2119 DEPTH_WEIGHT_R * aPixel.Data.r +
2120 DEPTH_WEIGHT_G * aPixel.Data.g +
2121 DEPTH_WEIGHT_B * aPixel.Data.b);
2124 {$IFDEF GLB_NATIVE_OGL}
2125 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2126 //OpenGLInitialization///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2127 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2129 GL_LibHandle: Pointer = nil;
2131 function glbGetProcAddress(aProcName: PAnsiChar; aLibHandle: Pointer = nil; const aRaiseOnErr: Boolean = true): Pointer;
2133 if not Assigned(aLibHandle) then
2134 aLibHandle := GL_LibHandle;
2136 {$IF DEFINED(GLB_WIN)}
2137 result := GetProcAddress({%H-}HMODULE(aLibHandle), aProcName);
2138 if Assigned(result) then
2141 if Assigned(wglGetProcAddress) then
2142 result := wglGetProcAddress(aProcName);
2143 {$ELSEIF DEFINED(GLB_LINUX)}
2144 if Assigned(glXGetProcAddress) then begin
2145 result := glXGetProcAddress(aProcName);
2146 if Assigned(result) then
2150 if Assigned(glXGetProcAddressARB) then begin
2151 result := glXGetProcAddressARB(aProcName);
2152 if Assigned(result) then
2156 result := dlsym(aLibHandle, aProcName);
2158 if not Assigned(result) and aRaiseOnErr then
2159 raise EglBitmap.Create('unable to load procedure form library: ' + aProcName);
2162 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
2164 GLU_LibHandle: Pointer = nil;
2165 OpenGLInitialized: Boolean;
2166 InitOpenGLCS: TCriticalSection;
2168 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2169 procedure glbInitOpenGL;
2171 ////////////////////////////////////////////////////////////////////////////////
2172 function glbLoadLibrary(const aName: PChar): Pointer;
2174 {$IF DEFINED(GLB_WIN)}
2175 result := {%H-}Pointer(LoadLibrary(aName));
2176 {$ELSEIF DEFINED(GLB_LINUX)}
2177 result := dlopen(Name, RTLD_LAZY);
2183 ////////////////////////////////////////////////////////////////////////////////
2184 function glbFreeLibrary(const aLibHandle: Pointer): Boolean;
2187 if not Assigned(aLibHandle) then
2190 {$IF DEFINED(GLB_WIN)}
2191 Result := FreeLibrary({%H-}HINST(aLibHandle));
2192 {$ELSEIF DEFINED(GLB_LINUX)}
2193 Result := dlclose(aLibHandle) = 0;
2198 if Assigned(GL_LibHandle) then
2199 glbFreeLibrary(GL_LibHandle);
2201 if Assigned(GLU_LibHandle) then
2202 glbFreeLibrary(GLU_LibHandle);
2204 GL_LibHandle := glbLoadLibrary(libopengl);
2205 if not Assigned(GL_LibHandle) then
2206 raise EglBitmap.Create('unable to load library: ' + libopengl);
2208 GLU_LibHandle := glbLoadLibrary(libglu);
2209 if not Assigned(GLU_LibHandle) then
2210 raise EglBitmap.Create('unable to load library: ' + libglu);
2212 {$IF DEFINED(GLB_WIN)}
2213 wglGetProcAddress := glbGetProcAddress('wglGetProcAddress');
2214 {$ELSEIF DEFINED(GLB_LINUX)}
2215 glXGetProcAddress := glbGetProcAddress('glXGetProcAddress');
2216 glXGetProcAddressARB := glbGetProcAddress('glXGetProcAddressARB');
2219 glEnable := glbGetProcAddress('glEnable');
2220 glDisable := glbGetProcAddress('glDisable');
2221 glGetString := glbGetProcAddress('glGetString');
2222 glGetIntegerv := glbGetProcAddress('glGetIntegerv');
2223 glTexParameteri := glbGetProcAddress('glTexParameteri');
2224 glTexParameteriv := glbGetProcAddress('glTexParameteriv');
2225 glTexParameterfv := glbGetProcAddress('glTexParameterfv');
2226 glGetTexParameteriv := glbGetProcAddress('glGetTexParameteriv');
2227 glGetTexParameterfv := glbGetProcAddress('glGetTexParameterfv');
2228 glGetTexLevelParameteriv := glbGetProcAddress('glGetTexLevelParameteriv');
2229 glGetTexLevelParameterfv := glbGetProcAddress('glGetTexLevelParameterfv');
2230 glTexGeni := glbGetProcAddress('glTexGeni');
2231 glGenTextures := glbGetProcAddress('glGenTextures');
2232 glBindTexture := glbGetProcAddress('glBindTexture');
2233 glDeleteTextures := glbGetProcAddress('glDeleteTextures');
2234 glAreTexturesResident := glbGetProcAddress('glAreTexturesResident');
2235 glReadPixels := glbGetProcAddress('glReadPixels');
2236 glPixelStorei := glbGetProcAddress('glPixelStorei');
2237 glTexImage1D := glbGetProcAddress('glTexImage1D');
2238 glTexImage2D := glbGetProcAddress('glTexImage2D');
2239 glGetTexImage := glbGetProcAddress('glGetTexImage');
2241 gluBuild1DMipmaps := glbGetProcAddress('gluBuild1DMipmaps', GLU_LibHandle);
2242 gluBuild2DMipmaps := glbGetProcAddress('gluBuild2DMipmaps', GLU_LibHandle);
2246 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2247 procedure glbReadOpenGLExtensions;
2250 MajorVersion, MinorVersion: Integer;
2252 ///////////////////////////////////////////////////////////////////////////////////////////
2253 procedure TrimVersionString(aBuffer: AnsiString; out aMajor, aMinor: Integer);
2260 Separator := Pos(AnsiString('.'), aBuffer);
2261 if (Separator > 1) and (Separator < Length(aBuffer)) and
2262 (aBuffer[Separator - 1] in ['0'..'9']) and
2263 (aBuffer[Separator + 1] in ['0'..'9']) then begin
2266 while (Separator > 0) and (aBuffer[Separator] in ['0'..'9']) do
2269 Delete(aBuffer, 1, Separator);
2270 Separator := Pos(AnsiString('.'), aBuffer) + 1;
2272 while (Separator <= Length(aBuffer)) and (AnsiChar(aBuffer[Separator]) in ['0'..'9']) do
2275 Delete(aBuffer, Separator, 255);
2276 Separator := Pos(AnsiString('.'), aBuffer);
2278 aMajor := StrToInt(Copy(String(aBuffer), 1, Separator - 1));
2279 aMinor := StrToInt(Copy(String(aBuffer), Separator + 1, 1));
2283 ///////////////////////////////////////////////////////////////////////////////////////////
2284 function CheckExtension(const Extension: AnsiString): Boolean;
2288 ExtPos := Pos(Extension, Buffer);
2289 result := ExtPos > 0;
2291 result := ((ExtPos + Length(Extension) - 1) = Length(Buffer)) or not (Buffer[ExtPos + Length(Extension)] in ['_', 'A'..'Z', 'a'..'z']);
2294 ///////////////////////////////////////////////////////////////////////////////////////////
2295 function CheckVersion(const aMajor, aMinor: Integer): Boolean;
2297 result := (MajorVersion > aMajor) or ((MajorVersion = aMajor) and (MinorVersion >= aMinor));
2301 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
2304 if not OpenGLInitialized then begin
2306 OpenGLInitialized := true;
2314 Buffer := glGetString(GL_VERSION);
2315 TrimVersionString(Buffer, MajorVersion, MinorVersion);
2317 GL_VERSION_1_2 := CheckVersion(1, 2);
2318 GL_VERSION_1_3 := CheckVersion(1, 3);
2319 GL_VERSION_1_4 := CheckVersion(1, 4);
2320 GL_VERSION_2_0 := CheckVersion(2, 0);
2321 GL_VERSION_3_3 := CheckVersion(3, 3);
2324 Buffer := glGetString(GL_EXTENSIONS);
2325 GL_ARB_texture_border_clamp := CheckExtension('GL_ARB_texture_border_clamp');
2326 GL_ARB_texture_non_power_of_two := CheckExtension('GL_ARB_texture_non_power_of_two');
2327 GL_ARB_texture_swizzle := CheckExtension('GL_ARB_texture_swizzle');
2328 GL_ARB_texture_cube_map := CheckExtension('GL_ARB_texture_cube_map');
2329 GL_ARB_texture_rectangle := CheckExtension('GL_ARB_texture_rectangle');
2330 GL_ARB_texture_mirrored_repeat := CheckExtension('GL_ARB_texture_mirrored_repeat');
2331 GL_EXT_texture_edge_clamp := CheckExtension('GL_EXT_texture_edge_clamp');
2332 GL_EXT_texture_filter_anisotropic := CheckExtension('GL_EXT_texture_filter_anisotropic');
2333 GL_EXT_texture_rectangle := CheckExtension('GL_EXT_texture_rectangle');
2334 GL_EXT_texture_swizzle := CheckExtension('GL_EXT_texture_swizzle');
2335 GL_EXT_texture_cube_map := CheckExtension('GL_EXT_texture_cube_map');
2336 GL_NV_texture_rectangle := CheckExtension('GL_NV_texture_rectangle');
2337 GL_IBM_texture_mirrored_repeat := CheckExtension('GL_IBM_texture_mirrored_repeat');
2338 GL_SGIS_generate_mipmap := CheckExtension('GL_SGIS_generate_mipmap');
2340 if GL_VERSION_1_3 then begin
2341 glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1D');
2342 glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2D');
2343 glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImage');
2345 glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1DARB', nil, false);
2346 glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2DARB', nil, false);
2347 glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImageARB', nil, false);
2352 {$IFDEF GLB_SDL_IMAGE}
2353 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2354 // SDL Image Helper /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2355 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2356 function glBitmapRWseek(context: PSDL_RWops; offset: Integer; whence: Integer): Integer; cdecl;
2358 result := TStream(context^.unknown.data1).Seek(offset, whence);
2361 function glBitmapRWread(context: PSDL_RWops; Ptr: Pointer; size: Integer; maxnum : Integer): Integer; cdecl;
2363 result := TStream(context^.unknown.data1).Read(Ptr^, size * maxnum);
2366 function glBitmapRWwrite(context: PSDL_RWops; Ptr: Pointer; size: Integer; num: Integer): Integer; cdecl;
2368 result := TStream(context^.unknown.data1).Write(Ptr^, size * num);
2371 function glBitmapRWclose(context: PSDL_RWops): Integer; cdecl;
2376 function glBitmapCreateRWops(Stream: TStream): PSDL_RWops;
2378 result := SDL_AllocRW;
2380 if result = nil then
2381 raise EglBitmap.Create('glBitmapCreateRWops - SDL_AllocRW failed.');
2383 result^.seek := glBitmapRWseek;
2384 result^.read := glBitmapRWread;
2385 result^.write := glBitmapRWwrite;
2386 result^.close := glBitmapRWclose;
2387 result^.unknown.data1 := Stream;
2391 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2392 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
2394 glBitmapDefaultDeleteTextureOnFree := aDeleteTextureOnFree;
2397 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2398 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
2400 glBitmapDefaultFreeDataAfterGenTextures := aFreeData;
2403 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2404 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
2406 glBitmapDefaultMipmap := aValue;
2409 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2410 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
2412 glBitmapDefaultFormat := aFormat;
2415 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2416 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
2418 glBitmapDefaultFilterMin := aMin;
2419 glBitmapDefaultFilterMag := aMag;
2422 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2423 procedure glBitmapSetDefaultWrap(const S: Cardinal = GL_CLAMP_TO_EDGE; const T: Cardinal = GL_CLAMP_TO_EDGE; const R: Cardinal = GL_CLAMP_TO_EDGE);
2425 glBitmapDefaultWrapS := S;
2426 glBitmapDefaultWrapT := T;
2427 glBitmapDefaultWrapR := R;
2430 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2431 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
2432 procedure glBitmapSetDefaultSwizzle(const r: GLenum = GL_RED; g: GLenum = GL_GREEN; b: GLenum = GL_BLUE; a: GLenum = GL_ALPHA);
2434 glDefaultSwizzle[0] := r;
2435 glDefaultSwizzle[1] := g;
2436 glDefaultSwizzle[2] := b;
2437 glDefaultSwizzle[3] := a;
2441 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2442 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
2444 result := glBitmapDefaultDeleteTextureOnFree;
2447 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2448 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
2450 result := glBitmapDefaultFreeDataAfterGenTextures;
2453 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2454 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
2456 result := glBitmapDefaultMipmap;
2459 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2460 function glBitmapGetDefaultFormat: TglBitmapFormat;
2462 result := glBitmapDefaultFormat;
2465 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2466 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
2468 aMin := glBitmapDefaultFilterMin;
2469 aMag := glBitmapDefaultFilterMag;
2472 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2473 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
2475 S := glBitmapDefaultWrapS;
2476 T := glBitmapDefaultWrapT;
2477 R := glBitmapDefaultWrapR;
2481 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2482 procedure glBitmapGetDefaultSwizzle(var r, g, b, a: GLenum);
2484 r := glDefaultSwizzle[0];
2485 g := glDefaultSwizzle[1];
2486 b := glDefaultSwizzle[2];
2487 a := glDefaultSwizzle[3];
2491 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2492 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2493 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2494 function TFormatDescriptor.GetSize(const aSize: TglBitmapPixelPosition): Integer;
2498 if (ffX in aSize.Fields) or (ffY in aSize.Fields) then begin
2499 w := Max(1, aSize.X);
2500 h := Max(1, aSize.Y);
2501 result := GetSize(w, h);
2506 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2507 function TFormatDescriptor.GetSize(const aWidth, aHeight: Integer): Integer;
2510 if (aWidth <= 0) or (aHeight <= 0) then
2512 result := Ceil(aWidth * aHeight * BytesPerPixel);
2515 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2516 function TFormatDescriptor.CreateMappingData: Pointer;
2521 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2522 procedure TFormatDescriptor.FreeMappingData(var aMappingData: Pointer);
2527 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2528 function TFormatDescriptor.IsEmpty: Boolean;
2530 result := (fFormat = tfEmpty);
2533 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2534 function TFormatDescriptor.MaskMatch(const aMask: TglBitmapRec4ul): Boolean;
2540 if (aMask.r = 0) and (aMask.g = 0) and (aMask.b = 0) and (aMask.a = 0) then
2541 raise EglBitmap.Create('FormatCheckFormat - All Masks are 0');
2544 if (aMask.arr[i] <> m.arr[i]) then
2549 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2550 procedure TFormatDescriptor.PreparePixel(out aPixel: TglBitmapPixelData);
2552 FillChar(aPixel{%H-}, SizeOf(aPixel), 0);
2553 aPixel.Data := Range;
2554 aPixel.Format := fFormat;
2555 aPixel.Range := Range;
2558 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2559 constructor TFormatDescriptor.Create;
2564 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2565 //TfdAlpha_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2566 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2567 procedure TfdAlphaUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2569 aData^ := aPixel.Data.a;
2573 procedure TfdAlphaUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2578 aPixel.Data.a := aData^;
2582 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2583 //TfdLuminance_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2584 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2585 procedure TfdLuminanceUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2587 aData^ := LuminanceWeight(aPixel);
2591 procedure TfdLuminanceUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2593 aPixel.Data.r := aData^;
2594 aPixel.Data.g := aData^;
2595 aPixel.Data.b := aData^;
2600 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2601 //TfdUniversal_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2602 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2603 procedure TfdUniversalUB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2609 if (Range.arr[i] > 0) then
2610 aData^ := aData^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
2614 procedure TfdUniversalUB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2619 aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and Range.arr[i];
2623 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2624 //TfdLuminanceAlpha_UB2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2625 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2626 procedure TfdLuminanceAlphaUB2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2628 inherited Map(aPixel, aData, aMapData);
2629 aData^ := aPixel.Data.a;
2633 procedure TfdLuminanceAlphaUB2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2635 inherited Unmap(aData, aPixel, aMapData);
2636 aPixel.Data.a := aData^;
2640 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2641 //TfdRGB_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2642 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2643 procedure TfdRGBub3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2645 aData^ := aPixel.Data.r;
2647 aData^ := aPixel.Data.g;
2649 aData^ := aPixel.Data.b;
2653 procedure TfdRGBub3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2655 aPixel.Data.r := aData^;
2657 aPixel.Data.g := aData^;
2659 aPixel.Data.b := aData^;
2664 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2665 //TfdBGR_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2666 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2667 procedure TfdBGRub3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2669 aData^ := aPixel.Data.b;
2671 aData^ := aPixel.Data.g;
2673 aData^ := aPixel.Data.r;
2677 procedure TfdBGRub3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2679 aPixel.Data.b := aData^;
2681 aPixel.Data.g := aData^;
2683 aPixel.Data.r := aData^;
2688 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2689 //TfdRGBA_UB4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2690 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2691 procedure TfdRGBAub4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2693 inherited Map(aPixel, aData, aMapData);
2694 aData^ := aPixel.Data.a;
2698 procedure TfdRGBAub4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2700 inherited Unmap(aData, aPixel, aMapData);
2701 aPixel.Data.a := aData^;
2705 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2706 //TfdBGRA_UB4//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2707 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2708 procedure TfdBGRAub4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2710 inherited Map(aPixel, aData, aMapData);
2711 aData^ := aPixel.Data.a;
2715 procedure TfdBGRAub4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2717 inherited Unmap(aData, aPixel, aMapData);
2718 aPixel.Data.a := aData^;
2722 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2723 //TfdAlpha_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2724 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2725 procedure TfdAlphaUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2727 PWord(aData)^ := aPixel.Data.a;
2731 procedure TfdAlphaUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2736 aPixel.Data.a := PWord(aData)^;
2740 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2741 //TfdLuminance_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2742 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2743 procedure TfdLuminanceUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2745 PWord(aData)^ := LuminanceWeight(aPixel);
2749 procedure TfdLuminanceUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2751 aPixel.Data.r := PWord(aData)^;
2752 aPixel.Data.g := PWord(aData)^;
2753 aPixel.Data.b := PWord(aData)^;
2758 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2759 //TfdUniversal_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2760 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2761 procedure TfdUniversalUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2767 if (Range.arr[i] > 0) then
2768 PWord(aData)^ := PWord(aData)^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
2772 procedure TfdUniversalUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2777 aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and Range.arr[i];
2781 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2782 //TfdDepth_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2783 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2784 procedure TfdDepthUS1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2786 PWord(aData)^ := DepthWeight(aPixel);
2790 procedure TfdDepthUS1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2792 aPixel.Data.r := PWord(aData)^;
2793 aPixel.Data.g := PWord(aData)^;
2794 aPixel.Data.b := PWord(aData)^;
2795 aPixel.Data.a := PWord(aData)^;;
2799 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2800 //TfdLuminanceAlpha_US2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2801 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2802 procedure TfdLuminanceAlphaUS2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2804 inherited Map(aPixel, aData, aMapData);
2805 PWord(aData)^ := aPixel.Data.a;
2809 procedure TfdLuminanceAlphaUS2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2811 inherited Unmap(aData, aPixel, aMapData);
2812 aPixel.Data.a := PWord(aData)^;
2816 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2817 //TfdRGB_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2818 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2819 procedure TfdRGBus3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2821 PWord(aData)^ := aPixel.Data.r;
2823 PWord(aData)^ := aPixel.Data.g;
2825 PWord(aData)^ := aPixel.Data.b;
2829 procedure TfdRGBus3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2831 aPixel.Data.r := PWord(aData)^;
2833 aPixel.Data.g := PWord(aData)^;
2835 aPixel.Data.b := PWord(aData)^;
2840 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2841 //TfdBGR_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2842 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2843 procedure TfdBGRus3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2845 PWord(aData)^ := aPixel.Data.b;
2847 PWord(aData)^ := aPixel.Data.g;
2849 PWord(aData)^ := aPixel.Data.r;
2853 procedure TfdBGRus3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2855 aPixel.Data.b := PWord(aData)^;
2857 aPixel.Data.g := PWord(aData)^;
2859 aPixel.Data.r := PWord(aData)^;
2864 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2865 //TfdRGBA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2866 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2867 procedure TfdRGBAus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2869 inherited Map(aPixel, aData, aMapData);
2870 PWord(aData)^ := aPixel.Data.a;
2874 procedure TfdRGBAus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2876 inherited Unmap(aData, aPixel, aMapData);
2877 aPixel.Data.a := PWord(aData)^;
2881 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2882 //TfdARGB_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2883 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2884 procedure TfdARGBus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2886 PWord(aData)^ := aPixel.Data.a;
2888 inherited Map(aPixel, aData, aMapData);
2891 procedure TfdARGBus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2893 aPixel.Data.a := PWord(aData)^;
2895 inherited Unmap(aData, aPixel, aMapData);
2898 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2899 //TfdBGRA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2900 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2901 procedure TfdBGRAus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2903 inherited Map(aPixel, aData, aMapData);
2904 PWord(aData)^ := aPixel.Data.a;
2908 procedure TfdBGRAus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2910 inherited Unmap(aData, aPixel, aMapData);
2911 aPixel.Data.a := PWord(aData)^;
2915 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2916 //TfdABGR_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2917 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2918 procedure TfdABGRus4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2920 PWord(aData)^ := aPixel.Data.a;
2922 inherited Map(aPixel, aData, aMapData);
2925 procedure TfdABGRus4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2927 aPixel.Data.a := PWord(aData)^;
2929 inherited Unmap(aData, aPixel, aMapData);
2932 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2933 //TfdUniversal_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2934 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2935 procedure TfdUniversalUI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2939 PCardinal(aData)^ := 0;
2941 if (Range.arr[i] > 0) then
2942 PCardinal(aData)^ := PCardinal(aData)^ or ((aPixel.Data.arr[i] and Range.arr[i]) shl fShift.arr[i]);
2946 procedure TfdUniversalUI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2951 aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and Range.arr[i];
2955 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2956 //TfdDepth_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2957 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2958 procedure TfdDepthUI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2960 PCardinal(aData)^ := DepthWeight(aPixel);
2964 procedure TfdDepthUI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2966 aPixel.Data.r := PCardinal(aData)^;
2967 aPixel.Data.g := PCardinal(aData)^;
2968 aPixel.Data.b := PCardinal(aData)^;
2969 aPixel.Data.a := PCardinal(aData)^;
2973 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2974 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2975 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2976 procedure TfdAlpha4ub1.SetValues;
2978 inherited SetValues;
2980 fFormat := tfAlpha4ub1;
2981 fWithAlpha := tfAlpha4ub1;
2982 fPrecision := glBitmapRec4ub(0, 0, 0, 8);
2983 fShift := glBitmapRec4ub(0, 0, 0, 0);
2985 fOpenGLFormat := tfAlpha4ub1;
2986 fglFormat := GL_ALPHA;
2987 fglInternalFormat := GL_ALPHA4;
2988 fglDataFormat := GL_UNSIGNED_BYTE;
2990 fOpenGLFormat := tfAlpha8ub1;
2994 procedure TfdAlpha8ub1.SetValues;
2996 inherited SetValues;
2998 fFormat := tfAlpha8ub1;
2999 fWithAlpha := tfAlpha8ub1;
3000 fPrecision := glBitmapRec4ub(0, 0, 0, 8);
3001 fShift := glBitmapRec4ub(0, 0, 0, 0);
3002 fOpenGLFormat := tfAlpha8ub1;
3003 fglFormat := GL_ALPHA;
3004 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_ALPHA8{$ELSE}GL_ALPHA{$ENDIF};
3005 fglDataFormat := GL_UNSIGNED_BYTE;
3008 procedure TfdAlpha16us1.SetValues;
3010 inherited SetValues;
3011 fBitsPerPixel := 16;
3012 fFormat := tfAlpha16us1;
3013 fWithAlpha := tfAlpha16us1;
3014 fPrecision := glBitmapRec4ub(0, 0, 0, 16);
3015 fShift := glBitmapRec4ub(0, 0, 0, 0);
3017 fOpenGLFormat := tfAlpha16us1;
3018 fglFormat := GL_ALPHA;
3019 fglInternalFormat := GL_ALPHA16;
3020 fglDataFormat := GL_UNSIGNED_SHORT;
3022 fOpenGLFormat := tfAlpha8ub1;
3026 procedure TfdLuminance4ub1.SetValues;
3028 inherited SetValues;
3030 fFormat := tfLuminance4ub1;
3031 fWithAlpha := tfLuminance4Alpha4ub2;
3032 fWithoutAlpha := tfLuminance4ub1;
3033 fPrecision := glBitmapRec4ub(8, 8, 8, 0);
3034 fShift := glBitmapRec4ub(0, 0, 0, 0);
3036 fOpenGLFormat := tfLuminance4ub1;
3037 fglFormat := GL_LUMINANCE;
3038 fglInternalFormat := GL_LUMINANCE4;
3039 fglDataFormat := GL_UNSIGNED_BYTE;
3041 fOpenGLFormat := tfLuminance8ub1;
3045 procedure TfdLuminance8ub1.SetValues;
3047 inherited SetValues;
3049 fFormat := tfLuminance8ub1;
3050 fWithAlpha := tfLuminance8Alpha8ub2;
3051 fWithoutAlpha := tfLuminance8ub1;
3052 fOpenGLFormat := tfLuminance8ub1;
3053 fPrecision := glBitmapRec4ub(8, 8, 8, 0);
3054 fShift := glBitmapRec4ub(0, 0, 0, 0);
3055 fglFormat := GL_LUMINANCE;
3056 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_LUMINANCE8{$ELSE}GL_LUMINANCE{$ENDIF};
3057 fglDataFormat := GL_UNSIGNED_BYTE;
3060 procedure TfdLuminance16us1.SetValues;
3062 inherited SetValues;
3063 fBitsPerPixel := 16;
3064 fFormat := tfLuminance16us1;
3065 fWithAlpha := tfLuminance16Alpha16us2;
3066 fWithoutAlpha := tfLuminance16us1;
3067 fPrecision := glBitmapRec4ub(16, 16, 16, 0);
3068 fShift := glBitmapRec4ub( 0, 0, 0, 0);
3070 fOpenGLFormat := tfLuminance16us1;
3071 fglFormat := GL_LUMINANCE;
3072 fglInternalFormat := GL_LUMINANCE16;
3073 fglDataFormat := GL_UNSIGNED_SHORT;
3075 fOpenGLFormat := tfLuminance8ub1;
3079 procedure TfdLuminance4Alpha4ub2.SetValues;
3081 inherited SetValues;
3082 fBitsPerPixel := 16;
3083 fFormat := tfLuminance4Alpha4ub2;
3084 fWithAlpha := tfLuminance4Alpha4ub2;
3085 fWithoutAlpha := tfLuminance4ub1;
3086 fPrecision := glBitmapRec4ub(8, 8, 8, 8);
3087 fShift := glBitmapRec4ub(0, 0, 0, 8);
3089 fOpenGLFormat := tfLuminance4Alpha4ub2;
3090 fglFormat := GL_LUMINANCE_ALPHA;
3091 fglInternalFormat := GL_LUMINANCE4_ALPHA4;
3092 fglDataFormat := GL_UNSIGNED_BYTE;
3094 fOpenGLFormat := tfLuminance8Alpha8ub2;
3098 procedure TfdLuminance6Alpha2ub2.SetValues;
3100 inherited SetValues;
3101 fBitsPerPixel := 16;
3102 fFormat := tfLuminance6Alpha2ub2;
3103 fWithAlpha := tfLuminance6Alpha2ub2;
3104 fWithoutAlpha := tfLuminance8ub1;
3105 fPrecision := glBitmapRec4ub(8, 8, 8, 8);
3106 fShift := glBitmapRec4ub(0, 0, 0, 8);
3108 fOpenGLFormat := tfLuminance6Alpha2ub2;
3109 fglFormat := GL_LUMINANCE_ALPHA;
3110 fglInternalFormat := GL_LUMINANCE6_ALPHA2;
3111 fglDataFormat := GL_UNSIGNED_BYTE;
3113 fOpenGLFormat := tfLuminance8Alpha8ub2;
3117 procedure TfdLuminance8Alpha8ub2.SetValues;
3119 inherited SetValues;
3120 fBitsPerPixel := 16;
3121 fFormat := tfLuminance8Alpha8ub2;
3122 fWithAlpha := tfLuminance8Alpha8ub2;
3123 fWithoutAlpha := tfLuminance8ub1;
3124 fOpenGLFormat := tfLuminance8Alpha8ub2;
3125 fPrecision := glBitmapRec4ub(8, 8, 8, 8);
3126 fShift := glBitmapRec4ub(0, 0, 0, 8);
3127 fglFormat := GL_LUMINANCE_ALPHA;
3128 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_LUMINANCE8_ALPHA8{$ELSE}GL_LUMINANCE_ALPHA{$ENDIF};
3129 fglDataFormat := GL_UNSIGNED_BYTE;
3132 procedure TfdLuminance12Alpha4us2.SetValues;
3134 inherited SetValues;
3135 fBitsPerPixel := 32;
3136 fFormat := tfLuminance12Alpha4us2;
3137 fWithAlpha := tfLuminance12Alpha4us2;
3138 fWithoutAlpha := tfLuminance16us1;
3139 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3140 fShift := glBitmapRec4ub( 0, 0, 0, 16);
3142 fOpenGLFormat := tfLuminance12Alpha4us2;
3143 fglFormat := GL_LUMINANCE_ALPHA;
3144 fglInternalFormat := GL_LUMINANCE12_ALPHA4;
3145 fglDataFormat := GL_UNSIGNED_SHORT;
3147 fOpenGLFormat := tfLuminance8Alpha8ub2;
3151 procedure TfdLuminance16Alpha16us2.SetValues;
3153 inherited SetValues;
3154 fBitsPerPixel := 32;
3155 fFormat := tfLuminance16Alpha16us2;
3156 fWithAlpha := tfLuminance16Alpha16us2;
3157 fWithoutAlpha := tfLuminance16us1;
3158 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3159 fShift := glBitmapRec4ub( 0, 0, 0, 16);
3161 fOpenGLFormat := tfLuminance16Alpha16us2;
3162 fglFormat := GL_LUMINANCE_ALPHA;
3163 fglInternalFormat := GL_LUMINANCE16_ALPHA16;
3164 fglDataFormat := GL_UNSIGNED_SHORT;
3166 fOpenGLFormat := tfLuminance8Alpha8ub2;
3170 procedure TfdR3G3B2ub1.SetValues;
3172 inherited SetValues;
3174 fFormat := tfR3G3B2ub1;
3175 fWithAlpha := tfRGBA4us1;
3176 fWithoutAlpha := tfR3G3B2ub1;
3177 fRGBInverted := tfEmpty;
3178 fPrecision := glBitmapRec4ub(3, 3, 2, 0);
3179 fShift := glBitmapRec4ub(5, 2, 0, 0);
3181 fOpenGLFormat := tfR3G3B2ub1;
3182 fglFormat := GL_RGB;
3183 fglInternalFormat := GL_R3_G3_B2;
3184 fglDataFormat := GL_UNSIGNED_BYTE_3_3_2;
3186 fOpenGLFormat := tfR5G6B5us1;
3190 procedure TfdRGBX4us1.SetValues;
3192 inherited SetValues;
3193 fBitsPerPixel := 16;
3194 fFormat := tfRGBX4us1;
3195 fWithAlpha := tfRGBA4us1;
3196 fWithoutAlpha := tfRGBX4us1;
3197 fRGBInverted := tfBGRX4us1;
3198 fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
3199 fShift := glBitmapRec4ub(12, 8, 4, 0);
3201 fOpenGLFormat := tfRGBX4us1;
3202 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3203 fglInternalFormat := GL_RGB4;
3204 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3206 fOpenGLFormat := tfR5G6B5us1;
3210 procedure TfdXRGB4us1.SetValues;
3212 inherited SetValues;
3213 fBitsPerPixel := 16;
3214 fFormat := tfXRGB4us1;
3215 fWithAlpha := tfARGB4us1;
3216 fWithoutAlpha := tfXRGB4us1;
3217 fRGBInverted := tfXBGR4us1;
3218 fPrecision := glBitmapRec4ub(4, 4, 4, 0);
3219 fShift := glBitmapRec4ub(8, 4, 0, 0);
3221 fOpenGLFormat := tfXRGB4us1;
3222 fglFormat := GL_BGRA;
3223 fglInternalFormat := GL_RGB4;
3224 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3226 fOpenGLFormat := tfR5G6B5us1;
3230 procedure TfdR5G6B5us1.SetValues;
3232 inherited SetValues;
3233 fBitsPerPixel := 16;
3234 fFormat := tfR5G6B5us1;
3235 fWithAlpha := tfRGB5A1us1;
3236 fWithoutAlpha := tfR5G6B5us1;
3237 fRGBInverted := tfB5G6R5us1;
3238 fPrecision := glBitmapRec4ub( 5, 6, 5, 0);
3239 fShift := glBitmapRec4ub(11, 5, 0, 0);
3240 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
3241 fOpenGLFormat := tfR5G6B5us1;
3242 fglFormat := GL_RGB;
3243 fglInternalFormat := GL_RGB565;
3244 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5;
3246 fOpenGLFormat := tfRGB8ub3;
3250 procedure TfdRGB5X1us1.SetValues;
3252 inherited SetValues;
3253 fBitsPerPixel := 16;
3254 fFormat := tfRGB5X1us1;
3255 fWithAlpha := tfRGB5A1us1;
3256 fWithoutAlpha := tfRGB5X1us1;
3257 fRGBInverted := tfBGR5X1us1;
3258 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
3259 fShift := glBitmapRec4ub(11, 6, 1, 0);
3261 fOpenGLFormat := tfRGB5X1us1;
3262 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3263 fglInternalFormat := GL_RGB5;
3264 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3266 fOpenGLFormat := tfR5G6B5us1;
3270 procedure TfdX1RGB5us1.SetValues;
3272 inherited SetValues;
3273 fBitsPerPixel := 16;
3274 fFormat := tfX1RGB5us1;
3275 fWithAlpha := tfA1RGB5us1;
3276 fWithoutAlpha := tfX1RGB5us1;
3277 fRGBInverted := tfX1BGR5us1;
3278 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
3279 fShift := glBitmapRec4ub(10, 5, 0, 0);
3281 fOpenGLFormat := tfX1RGB5us1;
3282 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3283 fglInternalFormat := GL_RGB5;
3284 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3286 fOpenGLFormat := tfR5G6B5us1;
3290 procedure TfdRGB8ub3.SetValues;
3292 inherited SetValues;
3293 fBitsPerPixel := 24;
3294 fFormat := tfRGB8ub3;
3295 fWithAlpha := tfRGBA8ub4;
3296 fWithoutAlpha := tfRGB8ub3;
3297 fRGBInverted := tfBGR8ub3;
3298 fPrecision := glBitmapRec4ub(8, 8, 8, 0);
3299 fShift := glBitmapRec4ub(0, 8, 16, 0);
3300 fOpenGLFormat := tfRGB8ub3;
3301 fglFormat := GL_RGB;
3302 fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}GL_RGB8{$ELSE}GL_RGB{$IFEND};
3303 fglDataFormat := GL_UNSIGNED_BYTE;
3306 procedure TfdRGBX8ui1.SetValues;
3308 inherited SetValues;
3309 fBitsPerPixel := 32;
3310 fFormat := tfRGBX8ui1;
3311 fWithAlpha := tfRGBA8ui1;
3312 fWithoutAlpha := tfRGBX8ui1;
3313 fRGBInverted := tfBGRX8ui1;
3314 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3315 fShift := glBitmapRec4ub(24, 16, 8, 0);
3317 fOpenGLFormat := tfRGBX8ui1;
3318 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3319 fglInternalFormat := GL_RGB8;
3320 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3322 fOpenGLFormat := tfRGB8ub3;
3326 procedure TfdXRGB8ui1.SetValues;
3328 inherited SetValues;
3329 fBitsPerPixel := 32;
3330 fFormat := tfXRGB8ui1;
3331 fWithAlpha := tfXRGB8ui1;
3332 fWithoutAlpha := tfXRGB8ui1;
3333 fOpenGLFormat := tfXRGB8ui1;
3334 fRGBInverted := tfXBGR8ui1;
3335 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3336 fShift := glBitmapRec4ub(16, 8, 0, 0);
3338 fOpenGLFormat := tfXRGB8ui1;
3339 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3340 fglInternalFormat := GL_RGB8;
3341 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3343 fOpenGLFormat := tfRGB8ub3;
3347 procedure TfdRGB10X2ui1.SetValues;
3349 inherited SetValues;
3350 fBitsPerPixel := 32;
3351 fFormat := tfRGB10X2ui1;
3352 fWithAlpha := tfRGB10A2ui1;
3353 fWithoutAlpha := tfRGB10X2ui1;
3354 fRGBInverted := tfBGR10X2ui1;
3355 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3356 fShift := glBitmapRec4ub(22, 12, 2, 0);
3358 fOpenGLFormat := tfRGB10X2ui1;
3359 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3360 fglInternalFormat := GL_RGB10;
3361 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3363 fOpenGLFormat := tfRGB16us3;
3367 procedure TfdX2RGB10ui1.SetValues;
3369 inherited SetValues;
3370 fBitsPerPixel := 32;
3371 fFormat := tfX2RGB10ui1;
3372 fWithAlpha := tfA2RGB10ui1;
3373 fWithoutAlpha := tfX2RGB10ui1;
3374 fRGBInverted := tfX2BGR10ui1;
3375 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3376 fShift := glBitmapRec4ub(20, 10, 0, 0);
3378 fOpenGLFormat := tfX2RGB10ui1;
3379 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3380 fglInternalFormat := GL_RGB10;
3381 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3383 fOpenGLFormat := tfRGB16us3;
3387 procedure TfdRGB16us3.SetValues;
3389 inherited SetValues;
3390 fBitsPerPixel := 48;
3391 fFormat := tfRGB16us3;
3392 fWithAlpha := tfRGBA16us4;
3393 fWithoutAlpha := tfRGB16us3;
3394 fRGBInverted := tfBGR16us3;
3395 fPrecision := glBitmapRec4ub(16, 16, 16, 0);
3396 fShift := glBitmapRec4ub( 0, 16, 32, 0);
3397 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
3398 fOpenGLFormat := tfRGB16us3;
3399 fglFormat := GL_RGB;
3400 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_RGB16{$ELSE}GL_RGB16UI{$ENDIF};
3401 fglDataFormat := GL_UNSIGNED_SHORT;
3403 fOpenGLFormat := tfRGB8ub3;
3407 procedure TfdRGBA4us1.SetValues;
3409 inherited SetValues;
3410 fBitsPerPixel := 16;
3411 fFormat := tfRGBA4us1;
3412 fWithAlpha := tfRGBA4us1;
3413 fWithoutAlpha := tfRGBX4us1;
3414 fOpenGLFormat := tfRGBA4us1;
3415 fRGBInverted := tfBGRA4us1;
3416 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3417 fShift := glBitmapRec4ub(12, 8, 4, 0);
3418 fglFormat := GL_RGBA;
3419 fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}GL_RGBA8{$ELSE}GL_RGBA{$IFEND};
3420 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3423 procedure TfdARGB4us1.SetValues;
3425 inherited SetValues;
3426 fBitsPerPixel := 16;
3427 fFormat := tfARGB4us1;
3428 fWithAlpha := tfARGB4us1;
3429 fWithoutAlpha := tfXRGB4us1;
3430 fRGBInverted := tfABGR4us1;
3431 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3432 fShift := glBitmapRec4ub( 8, 4, 0, 12);
3434 fOpenGLFormat := tfARGB4us1;
3435 fglFormat := GL_BGRA;
3436 fglInternalFormat := GL_RGBA4;
3437 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3439 fOpenGLFormat := tfRGBA4us1;
3443 procedure TfdRGB5A1us1.SetValues;
3445 inherited SetValues;
3446 fBitsPerPixel := 16;
3447 fFormat := tfRGB5A1us1;
3448 fWithAlpha := tfRGB5A1us1;
3449 fWithoutAlpha := tfRGB5X1us1;
3450 fOpenGLFormat := tfRGB5A1us1;
3451 fRGBInverted := tfBGR5A1us1;
3452 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3453 fShift := glBitmapRec4ub(11, 6, 1, 0);
3454 fglFormat := GL_RGBA;
3455 fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}GL_RGB5_A1{$ELSE}GL_RGBA{$IFEND};
3456 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3459 procedure TfdA1RGB5us1.SetValues;
3461 inherited SetValues;
3462 fBitsPerPixel := 16;
3463 fFormat := tfA1RGB5us1;
3464 fWithAlpha := tfA1RGB5us1;
3465 fWithoutAlpha := tfX1RGB5us1;
3466 fRGBInverted := tfA1BGR5us1;
3467 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3468 fShift := glBitmapRec4ub(10, 5, 0, 15);
3470 fOpenGLFormat := tfA1RGB5us1;
3471 fglFormat := GL_BGRA;
3472 fglInternalFormat := GL_RGB5_A1;
3473 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3475 fOpenGLFormat := tfRGB5A1us1;
3479 procedure TfdRGBA8ui1.SetValues;
3481 inherited SetValues;
3482 fBitsPerPixel := 32;
3483 fFormat := tfRGBA8ui1;
3484 fWithAlpha := tfRGBA8ui1;
3485 fWithoutAlpha := tfRGBX8ui1;
3486 fRGBInverted := tfBGRA8ui1;
3487 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3488 fShift := glBitmapRec4ub(24, 16, 8, 0);
3490 fOpenGLFormat := tfRGBA8ui1;
3491 fglFormat := GL_RGBA;
3492 fglInternalFormat := GL_RGBA8;
3493 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3495 fOpenGLFormat := tfRGBA8ub4;
3499 procedure TfdARGB8ui1.SetValues;
3501 inherited SetValues;
3502 fBitsPerPixel := 32;
3503 fFormat := tfARGB8ui1;
3504 fWithAlpha := tfARGB8ui1;
3505 fWithoutAlpha := tfXRGB8ui1;
3506 fRGBInverted := tfABGR8ui1;
3507 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3508 fShift := glBitmapRec4ub(16, 8, 0, 24);
3510 fOpenGLFormat := tfARGB8ui1;
3511 fglFormat := GL_BGRA;
3512 fglInternalFormat := GL_RGBA8;
3513 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3515 fOpenGLFormat := tfRGBA8ub4;
3519 procedure TfdRGBA8ub4.SetValues;
3521 inherited SetValues;
3522 fBitsPerPixel := 32;
3523 fFormat := tfRGBA8ub4;
3524 fWithAlpha := tfRGBA8ub4;
3525 fWithoutAlpha := tfRGB8ub3;
3526 fOpenGLFormat := tfRGBA8ub4;
3527 fRGBInverted := tfBGRA8ub4;
3528 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3529 fShift := glBitmapRec4ub( 0, 8, 16, 24);
3530 fglFormat := GL_RGBA;
3531 fglInternalFormat := {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}GL_RGBA8{$ELSE}GL_RGBA{$IFEND};
3532 fglDataFormat := GL_UNSIGNED_BYTE;
3535 procedure TfdRGB10A2ui1.SetValues;
3537 inherited SetValues;
3538 fBitsPerPixel := 32;
3539 fFormat := tfRGB10A2ui1;
3540 fWithAlpha := tfRGB10A2ui1;
3541 fWithoutAlpha := tfRGB10X2ui1;
3542 fRGBInverted := tfBGR10A2ui1;
3543 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3544 fShift := glBitmapRec4ub(22, 12, 2, 0);
3546 fOpenGLFormat := tfRGB10A2ui1;
3547 fglFormat := GL_RGBA;
3548 fglInternalFormat := GL_RGB10_A2;
3549 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3551 fOpenGLFormat := tfA2RGB10ui1;
3555 procedure TfdA2RGB10ui1.SetValues;
3557 inherited SetValues;
3558 fBitsPerPixel := 32;
3559 fFormat := tfA2RGB10ui1;
3560 fWithAlpha := tfA2RGB10ui1;
3561 fWithoutAlpha := tfX2RGB10ui1;
3562 fRGBInverted := tfA2BGR10ui1;
3563 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3564 fShift := glBitmapRec4ub(20, 10, 0, 30);
3565 {$IF NOT DEFINED(OPENGL_ES)}
3566 fOpenGLFormat := tfA2RGB10ui1;
3567 fglFormat := GL_BGRA;
3568 fglInternalFormat := GL_RGB10_A2;
3569 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3570 {$ELSEIF DEFINED(OPENGL_ES_3_0)}
3571 fOpenGLFormat := tfA2RGB10ui1;
3572 fglFormat := GL_RGBA;
3573 fglInternalFormat := GL_RGB10_A2;
3574 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3576 fOpenGLFormat := tfRGBA8ui1;
3580 procedure TfdRGBA16us4.SetValues;
3582 inherited SetValues;
3583 fBitsPerPixel := 64;
3584 fFormat := tfRGBA16us4;
3585 fWithAlpha := tfRGBA16us4;
3586 fWithoutAlpha := tfRGB16us3;
3587 fRGBInverted := tfBGRA16us4;
3588 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
3589 fShift := glBitmapRec4ub( 0, 16, 32, 48);
3590 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
3591 fOpenGLFormat := tfRGBA16us4;
3592 fglFormat := GL_RGBA;
3593 fglInternalFormat := {$IFNDEF OPENGL_ES}GL_RGBA16{$ELSE}GL_RGBA16UI{$ENDIF};
3594 fglDataFormat := GL_UNSIGNED_SHORT;
3596 fOpenGLFormat := tfRGBA8ub4;
3600 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3601 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3602 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3603 procedure TfdBGRX4us1.SetValues;
3605 inherited SetValues;
3606 fBitsPerPixel := 16;
3607 fFormat := tfBGRX4us1;
3608 fWithAlpha := tfBGRA4us1;
3609 fWithoutAlpha := tfBGRX4us1;
3610 fRGBInverted := tfRGBX4us1;
3611 fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
3612 fShift := glBitmapRec4ub( 4, 8, 12, 0);
3614 fOpenGLFormat := tfBGRX4us1;
3615 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3616 fglInternalFormat := GL_RGB4;
3617 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3619 fOpenGLFormat := tfR5G6B5us1;
3623 procedure TfdXBGR4us1.SetValues;
3625 inherited SetValues;
3626 fBitsPerPixel := 16;
3627 fFormat := tfXBGR4us1;
3628 fWithAlpha := tfABGR4us1;
3629 fWithoutAlpha := tfXBGR4us1;
3630 fRGBInverted := tfXRGB4us1;
3631 fPrecision := glBitmapRec4ub( 4, 4, 4, 0);
3632 fShift := glBitmapRec4ub( 0, 4, 8, 0);
3634 fOpenGLFormat := tfXBGR4us1;
3635 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3636 fglInternalFormat := GL_RGB4;
3637 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3639 fOpenGLFormat := tfR5G6B5us1;
3643 procedure TfdB5G6R5us1.SetValues;
3645 inherited SetValues;
3646 fBitsPerPixel := 16;
3647 fFormat := tfB5G6R5us1;
3648 fWithAlpha := tfBGR5A1us1;
3649 fWithoutAlpha := tfB5G6R5us1;
3650 fRGBInverted := tfR5G6B5us1;
3651 fPrecision := glBitmapRec4ub( 5, 6, 5, 0);
3652 fShift := glBitmapRec4ub( 0, 5, 11, 0);
3654 fOpenGLFormat := tfB5G6R5us1;
3655 fglFormat := GL_RGB;
3656 fglInternalFormat := GL_RGB565;
3657 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5_REV;
3659 fOpenGLFormat := tfR5G6B5us1;
3663 procedure TfdBGR5X1us1.SetValues;
3665 inherited SetValues;
3666 fBitsPerPixel := 16;
3667 fFormat := tfBGR5X1us1;
3668 fWithAlpha := tfBGR5A1us1;
3669 fWithoutAlpha := tfBGR5X1us1;
3670 fRGBInverted := tfRGB5X1us1;
3671 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
3672 fShift := glBitmapRec4ub( 1, 6, 11, 0);
3674 fOpenGLFormat := tfBGR5X1us1;
3675 fglFormat := GL_BGRA;
3676 fglInternalFormat := GL_RGB5;
3677 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3679 fOpenGLFormat := tfR5G6B5us1;
3683 procedure TfdX1BGR5us1.SetValues;
3685 inherited SetValues;
3686 fBitsPerPixel := 16;
3687 fFormat := tfX1BGR5us1;
3688 fWithAlpha := tfA1BGR5us1;
3689 fWithoutAlpha := tfX1BGR5us1;
3690 fRGBInverted := tfX1RGB5us1;
3691 fPrecision := glBitmapRec4ub( 5, 5, 5, 0);
3692 fShift := glBitmapRec4ub( 0, 5, 10, 0);
3694 fOpenGLFormat := tfX1BGR5us1;
3695 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3696 fglInternalFormat := GL_RGB5;
3697 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3699 fOpenGLFormat := tfR5G6B5us1;
3703 procedure TfdBGR8ub3.SetValues;
3705 inherited SetValues;
3706 fBitsPerPixel := 24;
3707 fFormat := tfBGR8ub3;
3708 fWithAlpha := tfBGRA8ub4;
3709 fWithoutAlpha := tfBGR8ub3;
3710 fRGBInverted := tfRGB8ub3;
3711 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3712 fShift := glBitmapRec4ub(16, 8, 0, 0);
3714 fOpenGLFormat := tfBGR8ub3;
3715 fglFormat := GL_BGR;
3716 fglInternalFormat := GL_RGB8;
3717 fglDataFormat := GL_UNSIGNED_BYTE;
3719 fOpenGLFormat := tfRGB8ub3;
3723 procedure TfdBGRX8ui1.SetValues;
3725 inherited SetValues;
3726 fBitsPerPixel := 32;
3727 fFormat := tfBGRX8ui1;
3728 fWithAlpha := tfBGRA8ui1;
3729 fWithoutAlpha := tfBGRX8ui1;
3730 fRGBInverted := tfRGBX8ui1;
3731 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3732 fShift := glBitmapRec4ub( 8, 16, 24, 0);
3734 fOpenGLFormat := tfBGRX8ui1;
3735 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3736 fglInternalFormat := GL_RGB8;
3737 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3739 fOpenGLFormat := tfRGB8ub3;
3743 procedure TfdXBGR8ui1.SetValues;
3745 inherited SetValues;
3746 fBitsPerPixel := 32;
3747 fFormat := tfXBGR8ui1;
3748 fWithAlpha := tfABGR8ui1;
3749 fWithoutAlpha := tfXBGR8ui1;
3750 fRGBInverted := tfXRGB8ui1;
3751 fPrecision := glBitmapRec4ub( 8, 8, 8, 0);
3752 fShift := glBitmapRec4ub( 0, 8, 16, 0);
3754 fOpenGLFormat := tfXBGR8ui1;
3755 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3756 fglInternalFormat := GL_RGB8;
3757 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3759 fOpenGLFormat := tfRGB8ub3;
3763 procedure TfdBGR10X2ui1.SetValues;
3765 inherited SetValues;
3766 fBitsPerPixel := 32;
3767 fFormat := tfBGR10X2ui1;
3768 fWithAlpha := tfBGR10A2ui1;
3769 fWithoutAlpha := tfBGR10X2ui1;
3770 fRGBInverted := tfRGB10X2ui1;
3771 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3772 fShift := glBitmapRec4ub( 2, 12, 22, 0);
3774 fOpenGLFormat := tfBGR10X2ui1;
3775 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3776 fglInternalFormat := GL_RGB10;
3777 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3779 fOpenGLFormat := tfRGB16us3;
3783 procedure TfdX2BGR10ui1.SetValues;
3785 inherited SetValues;
3786 fBitsPerPixel := 32;
3787 fFormat := tfX2BGR10ui1;
3788 fWithAlpha := tfA2BGR10ui1;
3789 fWithoutAlpha := tfX2BGR10ui1;
3790 fRGBInverted := tfX2RGB10ui1;
3791 fPrecision := glBitmapRec4ub(10, 10, 10, 0);
3792 fShift := glBitmapRec4ub( 0, 10, 20, 0);
3794 fOpenGLFormat := tfX2BGR10ui1;
3795 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3796 fglInternalFormat := GL_RGB10;
3797 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3799 fOpenGLFormat := tfRGB16us3;
3803 procedure TfdBGR16us3.SetValues;
3805 inherited SetValues;
3806 fBitsPerPixel := 48;
3807 fFormat := tfBGR16us3;
3808 fWithAlpha := tfBGRA16us4;
3809 fWithoutAlpha := tfBGR16us3;
3810 fRGBInverted := tfRGB16us3;
3811 fPrecision := glBitmapRec4ub(16, 16, 16, 0);
3812 fShift := glBitmapRec4ub(32, 16, 0, 0);
3814 fOpenGLFormat := tfBGR16us3;
3815 fglFormat := GL_BGR;
3816 fglInternalFormat := GL_RGB16;
3817 fglDataFormat := GL_UNSIGNED_SHORT;
3819 fOpenGLFormat := tfRGB16us3;
3823 procedure TfdBGRA4us1.SetValues;
3825 inherited SetValues;
3826 fBitsPerPixel := 16;
3827 fFormat := tfBGRA4us1;
3828 fWithAlpha := tfBGRA4us1;
3829 fWithoutAlpha := tfBGRX4us1;
3830 fRGBInverted := tfRGBA4us1;
3831 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3832 fShift := glBitmapRec4ub( 4, 8, 12, 0);
3834 fOpenGLFormat := tfBGRA4us1;
3835 fglFormat := GL_BGRA;
3836 fglInternalFormat := GL_RGBA4;
3837 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3839 fOpenGLFormat := tfRGBA4us1;
3843 procedure TfdABGR4us1.SetValues;
3845 inherited SetValues;
3846 fBitsPerPixel := 16;
3847 fFormat := tfABGR4us1;
3848 fWithAlpha := tfABGR4us1;
3849 fWithoutAlpha := tfXBGR4us1;
3850 fRGBInverted := tfARGB4us1;
3851 fPrecision := glBitmapRec4ub( 4, 4, 4, 4);
3852 fShift := glBitmapRec4ub( 0, 4, 8, 12);
3854 fOpenGLFormat := tfABGR4us1;
3855 fglFormat := GL_RGBA;
3856 fglInternalFormat := GL_RGBA4;
3857 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3859 fOpenGLFormat := tfRGBA4us1;
3863 procedure TfdBGR5A1us1.SetValues;
3865 inherited SetValues;
3866 fBitsPerPixel := 16;
3867 fFormat := tfBGR5A1us1;
3868 fWithAlpha := tfBGR5A1us1;
3869 fWithoutAlpha := tfBGR5X1us1;
3870 fRGBInverted := tfRGB5A1us1;
3871 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3872 fShift := glBitmapRec4ub( 1, 6, 11, 0);
3874 fOpenGLFormat := tfBGR5A1us1;
3875 fglFormat := GL_BGRA;
3876 fglInternalFormat := GL_RGB5_A1;
3877 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3879 fOpenGLFormat := tfRGB5A1us1;
3883 procedure TfdA1BGR5us1.SetValues;
3885 inherited SetValues;
3886 fBitsPerPixel := 16;
3887 fFormat := tfA1BGR5us1;
3888 fWithAlpha := tfA1BGR5us1;
3889 fWithoutAlpha := tfX1BGR5us1;
3890 fRGBInverted := tfA1RGB5us1;
3891 fPrecision := glBitmapRec4ub( 5, 5, 5, 1);
3892 fShift := glBitmapRec4ub( 0, 5, 10, 15);
3894 fOpenGLFormat := tfA1BGR5us1;
3895 fglFormat := GL_RGBA;
3896 fglInternalFormat := GL_RGB5_A1;
3897 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3899 fOpenGLFormat := tfRGB5A1us1;
3903 procedure TfdBGRA8ui1.SetValues;
3905 inherited SetValues;
3906 fBitsPerPixel := 32;
3907 fFormat := tfBGRA8ui1;
3908 fWithAlpha := tfBGRA8ui1;
3909 fWithoutAlpha := tfBGRX8ui1;
3910 fRGBInverted := tfRGBA8ui1;
3911 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3912 fShift := glBitmapRec4ub( 8, 16, 24, 0);
3914 fOpenGLFormat := tfBGRA8ui1;
3915 fglFormat := GL_BGRA;
3916 fglInternalFormat := GL_RGBA8;
3917 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3919 fOpenGLFormat := tfRGBA8ub4;
3923 procedure TfdABGR8ui1.SetValues;
3925 inherited SetValues;
3926 fBitsPerPixel := 32;
3927 fFormat := tfABGR8ui1;
3928 fWithAlpha := tfABGR8ui1;
3929 fWithoutAlpha := tfXBGR8ui1;
3930 fRGBInverted := tfARGB8ui1;
3931 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3932 fShift := glBitmapRec4ub( 0, 8, 16, 24);
3934 fOpenGLFormat := tfABGR8ui1;
3935 fglFormat := GL_RGBA;
3936 fglInternalFormat := GL_RGBA8;
3937 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3939 fOpenGLFormat := tfRGBA8ub4
3943 procedure TfdBGRA8ub4.SetValues;
3945 inherited SetValues;
3946 fBitsPerPixel := 32;
3947 fFormat := tfBGRA8ub4;
3948 fWithAlpha := tfBGRA8ub4;
3949 fWithoutAlpha := tfBGR8ub3;
3950 fRGBInverted := tfRGBA8ub4;
3951 fPrecision := glBitmapRec4ub( 8, 8, 8, 8);
3952 fShift := glBitmapRec4ub(16, 8, 0, 24);
3954 fOpenGLFormat := tfBGRA8ub4;
3955 fglFormat := GL_BGRA;
3956 fglInternalFormat := GL_RGBA8;
3957 fglDataFormat := GL_UNSIGNED_BYTE;
3959 fOpenGLFormat := tfRGBA8ub4;
3963 procedure TfdBGR10A2ui1.SetValues;
3965 inherited SetValues;
3966 fBitsPerPixel := 32;
3967 fFormat := tfBGR10A2ui1;
3968 fWithAlpha := tfBGR10A2ui1;
3969 fWithoutAlpha := tfBGR10X2ui1;
3970 fRGBInverted := tfRGB10A2ui1;
3971 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3972 fShift := glBitmapRec4ub( 2, 12, 22, 0);
3974 fOpenGLFormat := tfBGR10A2ui1;
3975 fglFormat := GL_BGRA;
3976 fglInternalFormat := GL_RGB10_A2;
3977 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3979 fOpenGLFormat := tfA2RGB10ui1;
3983 procedure TfdA2BGR10ui1.SetValues;
3985 inherited SetValues;
3986 fBitsPerPixel := 32;
3987 fFormat := tfA2BGR10ui1;
3988 fWithAlpha := tfA2BGR10ui1;
3989 fWithoutAlpha := tfX2BGR10ui1;
3990 fRGBInverted := tfA2RGB10ui1;
3991 fPrecision := glBitmapRec4ub(10, 10, 10, 2);
3992 fShift := glBitmapRec4ub( 0, 10, 20, 30);
3994 fOpenGLFormat := tfA2BGR10ui1;
3995 fglFormat := GL_RGBA;
3996 fglInternalFormat := GL_RGB10_A2;
3997 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3999 fOpenGLFormat := tfA2RGB10ui1;
4003 procedure TfdBGRA16us4.SetValues;
4005 inherited SetValues;
4006 fBitsPerPixel := 64;
4007 fFormat := tfBGRA16us4;
4008 fWithAlpha := tfBGRA16us4;
4009 fWithoutAlpha := tfBGR16us3;
4010 fRGBInverted := tfRGBA16us4;
4011 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
4012 fShift := glBitmapRec4ub(32, 16, 0, 48);
4014 fOpenGLFormat := tfBGRA16us4;
4015 fglFormat := GL_BGRA;
4016 fglInternalFormat := GL_RGBA16;
4017 fglDataFormat := GL_UNSIGNED_SHORT;
4019 fOpenGLFormat := tfRGBA16us4;
4023 procedure TfdDepth16us1.SetValues;
4025 inherited SetValues;
4026 fBitsPerPixel := 16;
4027 fFormat := tfDepth16us1;
4028 fWithoutAlpha := tfDepth16us1;
4029 fPrecision := glBitmapRec4ub(16, 16, 16, 16);
4030 fShift := glBitmapRec4ub( 0, 0, 0, 0);
4031 {$IF NOT DEFINED (OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
4032 fOpenGLFormat := tfDepth16us1;
4033 fglFormat := GL_DEPTH_COMPONENT;
4034 fglInternalFormat := GL_DEPTH_COMPONENT16;
4035 fglDataFormat := GL_UNSIGNED_SHORT;
4039 procedure TfdDepth24ui1.SetValues;
4041 inherited SetValues;
4042 fBitsPerPixel := 32;
4043 fFormat := tfDepth24ui1;
4044 fWithoutAlpha := tfDepth24ui1;
4045 fOpenGLFormat := tfDepth24ui1;
4046 fPrecision := glBitmapRec4ub(32, 32, 32, 32);
4047 fShift := glBitmapRec4ub( 0, 0, 0, 0);
4048 {$IF NOT DEFINED (OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
4049 fOpenGLFormat := tfDepth24ui1;
4050 fglFormat := GL_DEPTH_COMPONENT;
4051 fglInternalFormat := GL_DEPTH_COMPONENT24;
4052 fglDataFormat := GL_UNSIGNED_INT;
4056 procedure TfdDepth32ui1.SetValues;
4058 inherited SetValues;
4059 fBitsPerPixel := 32;
4060 fFormat := tfDepth32ui1;
4061 fWithoutAlpha := tfDepth32ui1;
4062 fPrecision := glBitmapRec4ub(32, 32, 32, 32);
4063 fShift := glBitmapRec4ub( 0, 0, 0, 0);
4064 {$IF NOT DEFINED(OPENGL_ES)}
4065 fOpenGLFormat := tfDepth32ui1;
4066 fglFormat := GL_DEPTH_COMPONENT;
4067 fglInternalFormat := GL_DEPTH_COMPONENT32;
4068 fglDataFormat := GL_UNSIGNED_INT;
4069 {$ELSEIF DEFINED(OPENGL_ES_3_0)}
4070 fOpenGLFormat := tfDepth24ui1;
4071 {$ELSEIF DEFINED(OPENGL_ES_2_0)}
4072 fOpenGLFormat := tfDepth16us1;
4076 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4077 //TfdS3tcDtx1RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4078 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4079 procedure TfdS3tcDtx1RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4081 raise EglBitmap.Create('mapping for compressed formats is not supported');
4084 procedure TfdS3tcDtx1RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4086 raise EglBitmap.Create('mapping for compressed formats is not supported');
4089 procedure TfdS3tcDtx1RGBA.SetValues;
4091 inherited SetValues;
4092 fFormat := tfS3tcDtx1RGBA;
4093 fWithAlpha := tfS3tcDtx1RGBA;
4094 fUncompressed := tfRGB5A1us1;
4096 fIsCompressed := true;
4098 fOpenGLFormat := tfS3tcDtx1RGBA;
4099 fglFormat := GL_COMPRESSED_RGBA;
4100 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
4101 fglDataFormat := GL_UNSIGNED_BYTE;
4103 fOpenGLFormat := fUncompressed;
4107 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4108 //TfdS3tcDtx3RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4109 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4110 procedure TfdS3tcDtx3RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4112 raise EglBitmap.Create('mapping for compressed formats is not supported');
4115 procedure TfdS3tcDtx3RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4117 raise EglBitmap.Create('mapping for compressed formats is not supported');
4120 procedure TfdS3tcDtx3RGBA.SetValues;
4122 inherited SetValues;
4123 fFormat := tfS3tcDtx3RGBA;
4124 fWithAlpha := tfS3tcDtx3RGBA;
4125 fUncompressed := tfRGBA8ub4;
4127 fIsCompressed := true;
4129 fOpenGLFormat := tfS3tcDtx3RGBA;
4130 fglFormat := GL_COMPRESSED_RGBA;
4131 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
4132 fglDataFormat := GL_UNSIGNED_BYTE;
4134 fOpenGLFormat := fUncompressed;
4138 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4139 //TfdS3tcDtx5RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4140 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4141 procedure TfdS3tcDtx5RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4143 raise EglBitmap.Create('mapping for compressed formats is not supported');
4146 procedure TfdS3tcDtx5RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4148 raise EglBitmap.Create('mapping for compressed formats is not supported');
4151 procedure TfdS3tcDtx5RGBA.SetValues;
4153 inherited SetValues;
4154 fFormat := tfS3tcDtx3RGBA;
4155 fWithAlpha := tfS3tcDtx3RGBA;
4156 fUncompressed := tfRGBA8ub4;
4158 fIsCompressed := true;
4160 fOpenGLFormat := tfS3tcDtx3RGBA;
4161 fglFormat := GL_COMPRESSED_RGBA;
4162 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
4163 fglDataFormat := GL_UNSIGNED_BYTE;
4165 fOpenGLFormat := fUncompressed;
4169 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4170 //TglBitmapFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4171 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4172 function TglBitmapFormatDescriptor.GetHasRed: Boolean;
4174 result := (fPrecision.r > 0);
4177 function TglBitmapFormatDescriptor.GetHasGreen: Boolean;
4179 result := (fPrecision.g > 0);
4182 function TglBitmapFormatDescriptor.GetHasBlue: Boolean;
4184 result := (fPrecision.b > 0);
4187 function TglBitmapFormatDescriptor.GetHasAlpha: Boolean;
4189 result := (fPrecision.a > 0);
4192 function TglBitmapFormatDescriptor.GetHasColor: Boolean;
4194 result := HasRed or HasGreen or HasBlue;
4197 function TglBitmapFormatDescriptor.GetIsGrayscale: Boolean;
4199 result := (Mask.r = Mask.g) and (Mask.g = Mask.b) and (Mask.r > 0);
4202 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4203 procedure TglBitmapFormatDescriptor.SetValues;
4206 fWithAlpha := tfEmpty;
4207 fWithoutAlpha := tfEmpty;
4208 fOpenGLFormat := tfEmpty;
4209 fRGBInverted := tfEmpty;
4210 fUncompressed := tfEmpty;
4213 fIsCompressed := false;
4216 fglInternalFormat := 0;
4219 FillChar(fPrecision, 0, SizeOf(fPrecision));
4220 FillChar(fShift, 0, SizeOf(fShift));
4223 procedure TglBitmapFormatDescriptor.CalcValues;
4227 fBytesPerPixel := fBitsPerPixel / 8;
4229 for i := 0 to 3 do begin
4230 if (fPrecision.arr[i] > 0) then
4232 fRange.arr[i] := (1 shl fPrecision.arr[i]) - 1;
4233 fMask.arr[i] := fRange.arr[i] shl fShift.arr[i];
4237 constructor TglBitmapFormatDescriptor.Create;
4244 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4245 class function TglBitmapFormatDescriptor.GetByFormat(const aInternalFormat: GLenum): TglBitmapFormatDescriptor;
4249 for f := Low(TglBitmapFormat) to High(TglBitmapFormat) do begin
4250 result := TFormatDescriptor.Get(f);
4251 if (result.glInternalFormat = aInternalFormat) then
4254 result := TFormatDescriptor.Get(tfEmpty);
4257 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4258 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4259 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4260 class procedure TFormatDescriptor.Init;
4262 if not Assigned(FormatDescriptorCS) then
4263 FormatDescriptorCS := TCriticalSection.Create;
4266 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4267 class function TFormatDescriptor.Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
4269 FormatDescriptorCS.Enter;
4271 result := FormatDescriptors[aFormat];
4272 if not Assigned(result) then begin
4273 result := FORMAT_DESCRIPTOR_CLASSES[aFormat].Create;
4274 FormatDescriptors[aFormat] := result;
4277 FormatDescriptorCS.Leave;
4281 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4282 class function TFormatDescriptor.GetAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
4284 result := Get(Get(aFormat).WithAlpha);
4287 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4288 class function TFormatDescriptor.GetFromMask(const aMask: TglBitmapRec4ul; const aBitCount: Integer): TFormatDescriptor;
4290 ft: TglBitmapFormat;
4292 // find matching format with OpenGL support
4293 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
4295 if (result.MaskMatch(aMask)) and
4296 (result.glFormat <> 0) and
4297 (result.glInternalFormat <> 0) and
4298 ((aBitCount = 0) or (aBitCount = result.BitsPerPixel))
4303 // find matching format without OpenGL Support
4304 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
4306 if result.MaskMatch(aMask) and ((aBitCount = 0) or (aBitCount = result.BitsPerPixel)) then
4310 result := TFormatDescriptor.Get(tfEmpty);
4313 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4314 class function TFormatDescriptor.GetFromPrecShift(const aPrec, aShift: TglBitmapRec4ub; const aBitCount: Integer): TFormatDescriptor;
4316 ft: TglBitmapFormat;
4318 // find matching format with OpenGL support
4319 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
4321 if glBitmapRec4ubCompare(result.Shift, aShift) and
4322 glBitmapRec4ubCompare(result.Precision, aPrec) and
4323 (result.glFormat <> 0) and
4324 (result.glInternalFormat <> 0) and
4325 ((aBitCount = 0) or (aBitCount = result.BitsPerPixel))
4330 // find matching format without OpenGL Support
4331 for ft := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
4333 if glBitmapRec4ubCompare(result.Shift, aShift) and
4334 glBitmapRec4ubCompare(result.Precision, aPrec) and
4335 ((aBitCount = 0) or (aBitCount = result.BitsPerPixel)) then
4339 result := TFormatDescriptor.Get(tfEmpty);
4342 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4343 class procedure TFormatDescriptor.Clear;
4347 FormatDescriptorCS.Enter;
4349 for f := low(FormatDescriptors) to high(FormatDescriptors) do
4350 FreeAndNil(FormatDescriptors[f]);
4352 FormatDescriptorCS.Leave;
4356 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4357 class procedure TFormatDescriptor.Finalize;
4360 FreeAndNil(FormatDescriptorCS);
4363 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4364 //TBitfieldFormat/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4365 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4366 procedure TbmpBitfieldFormat.SetCustomValues(const aBPP: Integer; aMask: TglBitmapRec4ul);
4370 for i := 0 to 3 do begin
4372 while (aMask.arr[i] > 0) and (aMask.arr[i] and 1 > 0) do begin
4373 aMask.arr[i] := aMask.arr[i] shr 1;
4376 fPrecision.arr[i] := CountSetBits(aMask.arr[i]);
4381 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4382 procedure TbmpBitfieldFormat.SetCustomValues(const aBBP: Integer; const aPrec, aShift: TglBitmapRec4ub);
4384 fBitsPerPixel := aBBP;
4385 fPrecision := aPrec;
4390 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4391 procedure TbmpBitfieldFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4396 ((aPixel.Data.r and Range.r) shl Shift.r) or
4397 ((aPixel.Data.g and Range.g) shl Shift.g) or
4398 ((aPixel.Data.b and Range.b) shl Shift.b) or
4399 ((aPixel.Data.a and Range.a) shl Shift.a);
4400 case BitsPerPixel of
4402 16: PWord(aData)^ := data;
4403 32: PCardinal(aData)^ := data;
4404 64: PQWord(aData)^ := data;
4406 raise EglBitmap.CreateFmt('invalid pixel size: %d', [BitsPerPixel]);
4408 inc(aData, Round(BytesPerPixel));
4411 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4412 procedure TbmpBitfieldFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4417 case BitsPerPixel of
4419 16: data := PWord(aData)^;
4420 32: data := PCardinal(aData)^;
4421 64: data := PQWord(aData)^;
4423 raise EglBitmap.CreateFmt('invalid pixel size: %d', [BitsPerPixel]);
4426 aPixel.Data.arr[i] := (data shr fShift.arr[i]) and Range.arr[i];
4427 inc(aData, Round(BytesPerPixel));
4430 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4431 //TColorTableFormat///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4432 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4433 procedure TbmpColorTableFormat.SetValues;
4435 inherited SetValues;
4436 fShift := glBitmapRec4ub(8, 8, 8, 0);
4439 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4440 procedure TbmpColorTableFormat.SetCustomValues(const aFormat: TglBitmapFormat; const aBPP: Integer; const aPrec, aShift: TglBitmapRec4ub);
4443 fBitsPerPixel := aBPP;
4444 fPrecision := aPrec;
4449 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4450 procedure TbmpColorTableFormat.CalcValues;
4452 inherited CalcValues;
4455 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4456 procedure TbmpColorTableFormat.CreateColorTable;
4460 SetLength(fColorTable, 256);
4461 if not HasColor then begin
4463 for i := 0 to High(fColorTable) do begin
4464 fColorTable[i].r := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
4465 fColorTable[i].g := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
4466 fColorTable[i].b := Round(((i shr Shift.a) and Range.a) / Range.a * 255);
4467 fColorTable[i].a := 0;
4471 for i := 0 to High(fColorTable) do begin
4472 fColorTable[i].r := Round(((i shr Shift.r) and Range.r) / Range.r * 255);
4473 fColorTable[i].g := Round(((i shr Shift.g) and Range.g) / Range.g * 255);
4474 fColorTable[i].b := Round(((i shr Shift.b) and Range.b) / Range.b * 255);
4475 fColorTable[i].a := 0;
4480 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4481 procedure TbmpColorTableFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4483 if (BitsPerPixel <> 8) then
4484 raise EglBitmapUnsupportedFormat.Create('color table are only supported for 8bit formats');
4485 if not HasColor then
4487 aData^ := aPixel.Data.a
4491 ((aPixel.Data.r and Range.r) shl Shift.r) or
4492 ((aPixel.Data.g and Range.g) shl Shift.g) or
4493 ((aPixel.Data.b and Range.b) shl Shift.b));
4497 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4498 procedure TbmpColorTableFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4500 if (BitsPerPixel <> 8) then
4501 raise EglBitmapUnsupportedFormat.Create('color table are only supported for 8bit formats');
4502 with fColorTable[aData^] do begin
4511 destructor TbmpColorTableFormat.Destroy;
4513 SetLength(fColorTable, 0);
4517 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4518 //TglBitmap - Helper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4519 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4520 procedure glBitmapConvertPixel(var aPixel: TglBitmapPixelData; const aSourceFD, aDestFD: TFormatDescriptor);
4524 for i := 0 to 3 do begin
4525 if (aSourceFD.Range.arr[i] <> aDestFD.Range.arr[i]) then begin
4526 if (aSourceFD.Range.arr[i] > 0) then
4527 aPixel.Data.arr[i] := Round(aPixel.Data.arr[i] / aSourceFD.Range.arr[i] * aDestFD.Range.arr[i])
4529 aPixel.Data.arr[i] := 0;
4534 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4535 procedure glBitmapConvertCopyFunc(var aFuncRec: TglBitmapFunctionRec);
4537 with aFuncRec do begin
4538 if (Source.Range.r > 0) then
4539 Dest.Data.r := Source.Data.r;
4540 if (Source.Range.g > 0) then
4541 Dest.Data.g := Source.Data.g;
4542 if (Source.Range.b > 0) then
4543 Dest.Data.b := Source.Data.b;
4544 if (Source.Range.a > 0) then
4545 Dest.Data.a := Source.Data.a;
4549 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4550 procedure glBitmapConvertCalculateRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
4554 with aFuncRec do begin
4556 if (Source.Range.arr[i] > 0) then
4557 Dest.Data.arr[i] := Round(Dest.Range.arr[i] * Source.Data.arr[i] / Source.Range.arr[i]);
4562 TShiftData = packed record
4564 0: (r, g, b, a: SmallInt);
4565 1: (arr: array[0..3] of SmallInt);
4567 PShiftData = ^TShiftData;
4569 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4570 procedure glBitmapConvertShiftRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
4576 if (Source.Range.arr[i] > 0) then
4577 Dest.Data.arr[i] := Source.Data.arr[i] shr PShiftData(Args)^.arr[i];
4580 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4581 procedure glBitmapInvertFunc(var aFuncRec: TglBitmapFunctionRec);
4583 with aFuncRec do begin
4584 Dest.Data := Source.Data;
4585 if ({%H-}PtrUInt(Args) and $1 > 0) then begin
4586 Dest.Data.r := Dest.Data.r xor Dest.Range.r;
4587 Dest.Data.g := Dest.Data.g xor Dest.Range.g;
4588 Dest.Data.b := Dest.Data.b xor Dest.Range.b;
4590 if ({%H-}PtrUInt(Args) and $2 > 0) then begin
4591 Dest.Data.a := Dest.Data.a xor Dest.Range.a;
4596 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4597 procedure glBitmapFillWithColorFunc(var aFuncRec: TglBitmapFunctionRec);
4601 with aFuncRec do begin
4603 Dest.Data.arr[i] := PglBitmapPixelData(Args)^.Data.arr[i];
4607 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4608 procedure glBitmapAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4612 with FuncRec do begin
4613 if (FuncRec.Args = nil) then begin //source has no alpha
4615 Source.Data.r / Source.Range.r * ALPHA_WEIGHT_R +
4616 Source.Data.g / Source.Range.g * ALPHA_WEIGHT_G +
4617 Source.Data.b / Source.Range.b * ALPHA_WEIGHT_B;
4618 Dest.Data.a := Round(Dest.Range.a * Temp);
4620 Dest.Data.a := Round(Source.Data.a / Source.Range.a * Dest.Range.a);
4624 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4625 procedure glBitmapColorKeyAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4627 PglBitmapPixelData = ^TglBitmapPixelData;
4629 with FuncRec do begin
4630 Dest.Data.r := Source.Data.r;
4631 Dest.Data.g := Source.Data.g;
4632 Dest.Data.b := Source.Data.b;
4634 with PglBitmapPixelData(Args)^ do
4635 if ((Dest.Data.r <= Data.r) and (Dest.Data.r >= Range.r) and
4636 (Dest.Data.g <= Data.g) and (Dest.Data.g >= Range.g) and
4637 (Dest.Data.b <= Data.b) and (Dest.Data.b >= Range.b)) then
4640 Dest.Data.a := Dest.Range.a;
4644 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4645 procedure glBitmapValueAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4647 with FuncRec do begin
4648 Dest.Data.r := Source.Data.r;
4649 Dest.Data.g := Source.Data.g;
4650 Dest.Data.b := Source.Data.b;
4651 Dest.Data.a := PCardinal(Args)^;
4655 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4656 procedure SwapRGB(aData: PByte; aWidth: Integer; const aHasAlpha: Boolean);
4659 TRGBPix = array [0..2] of byte;
4663 while aWidth > 0 do begin
4664 Temp := PRGBPix(aData)^[0];
4665 PRGBPix(aData)^[0] := PRGBPix(aData)^[2];
4666 PRGBPix(aData)^[2] := Temp;
4676 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4677 //TglBitmap - PROTECTED///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4678 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4679 function TglBitmap.GetFormatDesc: TglBitmapFormatDescriptor;
4681 result := TFormatDescriptor.Get(Format);
4684 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4685 function TglBitmap.GetWidth: Integer;
4687 if (ffX in fDimension.Fields) then
4688 result := fDimension.X
4693 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4694 function TglBitmap.GetHeight: Integer;
4696 if (ffY in fDimension.Fields) then
4697 result := fDimension.Y
4702 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4703 function TglBitmap.GetFileWidth: Integer;
4705 result := Max(1, Width);
4708 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4709 function TglBitmap.GetFileHeight: Integer;
4711 result := Max(1, Height);
4714 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4715 procedure TglBitmap.SetCustomData(const aValue: Pointer);
4717 if fCustomData = aValue then
4719 fCustomData := aValue;
4722 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4723 procedure TglBitmap.SetCustomName(const aValue: String);
4725 if fCustomName = aValue then
4727 fCustomName := aValue;
4730 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4731 procedure TglBitmap.SetCustomNameW(const aValue: WideString);
4733 if fCustomNameW = aValue then
4735 fCustomNameW := aValue;
4738 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4739 procedure TglBitmap.SetFreeDataOnDestroy(const aValue: Boolean);
4741 if fFreeDataOnDestroy = aValue then
4743 fFreeDataOnDestroy := aValue;
4746 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4747 procedure TglBitmap.SetDeleteTextureOnFree(const aValue: Boolean);
4749 if fDeleteTextureOnFree = aValue then
4751 fDeleteTextureOnFree := aValue;
4754 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4755 procedure TglBitmap.SetFormat(const aValue: TglBitmapFormat);
4757 if fFormat = aValue then
4759 if TFormatDescriptor.Get(Format).BitsPerPixel <> TFormatDescriptor.Get(aValue).BitsPerPixel then
4760 raise EglBitmapUnsupportedFormat.Create(Format);
4761 SetDataPointer(fData, aValue, Width, Height); //be careful, Data could be freed by this method
4764 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4765 procedure TglBitmap.SetFreeDataAfterGenTexture(const aValue: Boolean);
4767 if fFreeDataAfterGenTexture = aValue then
4769 fFreeDataAfterGenTexture := aValue;
4772 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4773 procedure TglBitmap.SetID(const aValue: Cardinal);
4775 if fID = aValue then
4780 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4781 procedure TglBitmap.SetMipMap(const aValue: TglBitmapMipMap);
4783 if fMipMap = aValue then
4788 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4789 procedure TglBitmap.SetTarget(const aValue: Cardinal);
4791 if fTarget = aValue then
4796 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4797 procedure TglBitmap.SetAnisotropic(const aValue: Integer);
4798 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_EXT)}
4800 MaxAnisotropic: Integer;
4803 fAnisotropic := aValue;
4804 if (ID > 0) then begin
4805 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_EXT)}
4806 if GL_EXT_texture_filter_anisotropic then begin
4807 if fAnisotropic > 0 then begin
4809 glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @MaxAnisotropic);
4810 if aValue > MaxAnisotropic then
4811 fAnisotropic := MaxAnisotropic;
4812 glTexParameteri(Target, GL_TEXTURE_MAX_ANISOTROPY_EXT, fAnisotropic);
4823 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4824 procedure TglBitmap.CreateID;
4827 glDeleteTextures(1, @fID);
4828 glGenTextures(1, @fID);
4832 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4833 procedure TglBitmap.SetupParameters({$IFNDEF OPENGL_ES}out aBuildWithGlu: Boolean{$ENDIF});
4835 // Set Up Parameters
4836 SetWrap(fWrapS, fWrapT, fWrapR);
4837 SetFilter(fFilterMin, fFilterMag);
4838 SetAnisotropic(fAnisotropic);
4841 SetBorderColor(fBorderColor[0], fBorderColor[1], fBorderColor[2], fBorderColor[3]);
4842 if (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
4843 SetSwizzle(fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
4847 // Mip Maps Generation Mode
4848 aBuildWithGlu := false;
4849 if (MipMap = mmMipmap) then begin
4850 if (GL_VERSION_1_4 or GL_SGIS_generate_mipmap) then
4851 glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE)
4853 aBuildWithGlu := true;
4854 end else if (MipMap = mmMipmapGlu) then
4855 aBuildWithGlu := true;
4857 if (MipMap = mmMipmap) then
4858 glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE);
4862 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4863 procedure TglBitmap.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
4864 const aWidth: Integer; const aHeight: Integer);
4868 if (Data <> aData) then begin
4869 if (Assigned(Data)) then
4874 if not Assigned(fData) then begin
4878 FillChar(fDimension, SizeOf(fDimension), 0);
4879 if aWidth <> -1 then begin
4880 fDimension.Fields := fDimension.Fields + [ffX];
4881 fDimension.X := aWidth;
4884 if aHeight <> -1 then begin
4885 fDimension.Fields := fDimension.Fields + [ffY];
4886 fDimension.Y := aHeight;
4889 s := TFormatDescriptor.Get(aFormat).BytesPerPixel;
4891 fPixelSize := Ceil(s);
4892 fRowSize := Ceil(s * aWidth);
4896 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4897 function TglBitmap.FlipHorz: Boolean;
4902 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4903 function TglBitmap.FlipVert: Boolean;
4908 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4909 //TglBitmap - PUBLIC//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4910 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4911 procedure TglBitmap.AfterConstruction;
4913 inherited AfterConstruction;
4918 fIsResident := false;
4921 fMipMap := glBitmapDefaultMipmap;
4922 fFreeDataAfterGenTexture := glBitmapGetDefaultFreeDataAfterGenTexture;
4923 fDeleteTextureOnFree := glBitmapGetDefaultDeleteTextureOnFree;
4925 glBitmapGetDefaultFilter (fFilterMin, fFilterMag);
4926 glBitmapGetDefaultTextureWrap(fWrapS, fWrapT, fWrapR);
4928 glBitmapGetDefaultSwizzle (fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
4932 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4933 procedure TglBitmap.BeforeDestruction;
4937 if fFreeDataOnDestroy then begin
4939 SetDataPointer(NewData, tfEmpty); //be careful, Data could be freed by this method
4941 if (fID > 0) and fDeleteTextureOnFree then
4942 glDeleteTextures(1, @fID);
4943 inherited BeforeDestruction;
4946 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4947 procedure TglBitmap.PrepareResType(var aResource: String; var aResType: PChar);
4951 if not Assigned(aResType) then begin
4952 TempPos := Pos('.', aResource);
4953 aResType := PChar(UpperCase(Copy(aResource, TempPos + 1, Length(aResource) - TempPos)));
4954 aResource := UpperCase(Copy(aResource, 0, TempPos -1));
4958 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4959 procedure TglBitmap.LoadFromFile(const aFilename: String);
4963 if not FileExists(aFilename) then
4964 raise EglBitmap.Create('file does not exist: ' + aFilename);
4965 fFilename := aFilename;
4966 fs := TFileStream.Create(fFilename, fmOpenRead);
4975 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4976 procedure TglBitmap.LoadFromStream(const aStream: TStream);
4978 {$IFDEF GLB_SUPPORT_PNG_READ}
4979 if not LoadPNG(aStream) then
4981 {$IFDEF GLB_SUPPORT_JPEG_READ}
4982 if not LoadJPEG(aStream) then
4984 if not LoadDDS(aStream) then
4985 if not LoadTGA(aStream) then
4986 if not LoadBMP(aStream) then
4987 if not LoadRAW(aStream) then
4988 raise EglBitmap.Create('LoadFromStream - Couldn''t load Stream. It''s possible to be an unknow Streamtype.');
4991 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4992 procedure TglBitmap.LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
4993 const aFormat: TglBitmapFormat; const aArgs: Pointer);
4998 size := TFormatDescriptor.Get(aFormat).GetSize(aSize);
4999 GetMem(tmpData, size);
5001 FillChar(tmpData^, size, #$FF);
5002 SetDataPointer(tmpData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
5004 if Assigned(tmpData) then
5008 AddFunc(Self, aFunc, false, aFormat, aArgs);
5011 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5012 procedure TglBitmap.LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar);
5014 rs: TResourceStream;
5016 PrepareResType(aResource, aResType);
5017 rs := TResourceStream.Create(aInstance, aResource, aResType);
5025 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5026 procedure TglBitmap.LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
5028 rs: TResourceStream;
5030 rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
5038 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5039 procedure TglBitmap.SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
5043 fs := TFileStream.Create(aFileName, fmCreate);
5046 SaveToStream(fs, aFileType);
5052 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5053 procedure TglBitmap.SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType);
5056 {$IFDEF GLB_SUPPORT_PNG_WRITE}
5057 ftPNG: SavePNG(aStream);
5059 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
5060 ftJPEG: SaveJPEG(aStream);
5062 ftDDS: SaveDDS(aStream);
5063 ftTGA: SaveTGA(aStream);
5064 ftBMP: SaveBMP(aStream);
5065 ftRAW: SaveRAW(aStream);
5069 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5070 function TglBitmap.AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer): Boolean;
5072 result := AddFunc(Self, aFunc, aCreateTemp, Format, aArgs);
5075 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5076 function TglBitmap.AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
5077 const aFormat: TglBitmapFormat; const aArgs: Pointer): Boolean;
5079 DestData, TmpData, SourceData: pByte;
5080 TempHeight, TempWidth: Integer;
5081 SourceFD, DestFD: TFormatDescriptor;
5082 SourceMD, DestMD: Pointer;
5084 FuncRec: TglBitmapFunctionRec;
5086 Assert(Assigned(Data));
5087 Assert(Assigned(aSource));
5088 Assert(Assigned(aSource.Data));
5091 if Assigned(aSource.Data) and ((aSource.Height > 0) or (aSource.Width > 0)) then begin
5092 SourceFD := TFormatDescriptor.Get(aSource.Format);
5093 DestFD := TFormatDescriptor.Get(aFormat);
5095 if (SourceFD.IsCompressed) then
5096 raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', SourceFD.Format);
5097 if (DestFD.IsCompressed) then
5098 raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', DestFD.Format);
5100 // inkompatible Formats so CreateTemp
5101 if (SourceFD.BitsPerPixel <> DestFD.BitsPerPixel) then
5102 aCreateTemp := true;
5105 TempHeight := Max(1, aSource.Height);
5106 TempWidth := Max(1, aSource.Width);
5108 FuncRec.Sender := Self;
5109 FuncRec.Args := aArgs;
5112 if aCreateTemp then begin
5113 GetMem(TmpData, DestFD.GetSize(TempWidth, TempHeight));
5114 DestData := TmpData;
5119 SourceFD.PreparePixel(FuncRec.Source);
5120 DestFD.PreparePixel (FuncRec.Dest);
5122 SourceMD := SourceFD.CreateMappingData;
5123 DestMD := DestFD.CreateMappingData;
5125 FuncRec.Size := aSource.Dimension;
5126 FuncRec.Position.Fields := FuncRec.Size.Fields;
5129 SourceData := aSource.Data;
5130 FuncRec.Position.Y := 0;
5131 while FuncRec.Position.Y < TempHeight do begin
5132 FuncRec.Position.X := 0;
5133 while FuncRec.Position.X < TempWidth do begin
5134 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
5136 DestFD.Map(FuncRec.Dest, DestData, DestMD);
5137 inc(FuncRec.Position.X);
5139 inc(FuncRec.Position.Y);
5142 // Updating Image or InternalFormat
5144 SetDataPointer(TmpData, aFormat, aSource.Width, aSource.Height) //be careful, Data could be freed by this method
5145 else if (aFormat <> fFormat) then
5150 SourceFD.FreeMappingData(SourceMD);
5151 DestFD.FreeMappingData(DestMD);
5154 if aCreateTemp and Assigned(TmpData) then
5162 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5163 function TglBitmap.AssignToSurface(out aSurface: PSDL_Surface): Boolean;
5165 Row, RowSize: Integer;
5166 SourceData, TmpData: PByte;
5168 FormatDesc: TFormatDescriptor;
5170 function GetRowPointer(Row: Integer): pByte;
5172 result := aSurface.pixels;
5173 Inc(result, Row * RowSize);
5179 FormatDesc := TFormatDescriptor.Get(Format);
5180 if FormatDesc.IsCompressed then
5181 raise EglBitmapUnsupportedFormat.Create(Format);
5183 if Assigned(Data) then begin
5184 case Trunc(FormatDesc.PixelSize) of
5190 raise EglBitmapUnsupportedFormat.Create(Format);
5193 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, TempDepth,
5194 FormatDesc.RedMask, FormatDesc.GreenMask, FormatDesc.BlueMask, FormatDesc.AlphaMask);
5196 RowSize := FormatDesc.GetSize(FileWidth, 1);
5198 for Row := 0 to FileHeight-1 do begin
5199 TmpData := GetRowPointer(Row);
5200 if Assigned(TmpData) then begin
5201 Move(SourceData^, TmpData^, RowSize);
5202 inc(SourceData, RowSize);
5209 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5210 function TglBitmap.AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
5212 pSource, pData, pTempData: PByte;
5213 Row, RowSize, TempWidth, TempHeight: Integer;
5214 IntFormat: TglBitmapFormat;
5215 fd: TFormatDescriptor;
5216 Mask: TglBitmapMask;
5218 function GetRowPointer(Row: Integer): pByte;
5220 result := aSurface^.pixels;
5221 Inc(result, Row * RowSize);
5226 if (Assigned(aSurface)) then begin
5227 with aSurface^.format^ do begin
5232 IntFormat := TFormatDescriptor.GetFromMask(Mask).Format;
5233 if (IntFormat = tfEmpty) then
5234 raise EglBitmap.Create('AssignFromSurface - Invalid Pixelformat.');
5237 fd := TFormatDescriptor.Get(IntFormat);
5238 TempWidth := aSurface^.w;
5239 TempHeight := aSurface^.h;
5240 RowSize := fd.GetSize(TempWidth, 1);
5241 GetMem(pData, TempHeight * RowSize);
5244 for Row := 0 to TempHeight -1 do begin
5245 pSource := GetRowPointer(Row);
5246 if (Assigned(pSource)) then begin
5247 Move(pSource^, pTempData^, RowSize);
5248 Inc(pTempData, RowSize);
5251 SetDataPointer(pData, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
5254 if Assigned(pData) then
5261 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5262 function TglBitmap.AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
5264 Row, Col, AlphaInterleave: Integer;
5265 pSource, pDest: PByte;
5267 function GetRowPointer(Row: Integer): pByte;
5269 result := aSurface.pixels;
5270 Inc(result, Row * Width);
5275 if Assigned(Data) then begin
5276 if Format in [tfAlpha8ub1, tfLuminance8Alpha8ub2, tfBGRA8ub4, tfRGBA8ub4] then begin
5277 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, 8, $FF, $FF, $FF, 0);
5279 AlphaInterleave := 0;
5281 tfLuminance8Alpha8ub2:
5282 AlphaInterleave := 1;
5283 tfBGRA8ub4, tfRGBA8ub4:
5284 AlphaInterleave := 3;
5288 for Row := 0 to Height -1 do begin
5289 pDest := GetRowPointer(Row);
5290 if Assigned(pDest) then begin
5291 for Col := 0 to Width -1 do begin
5292 Inc(pSource, AlphaInterleave);
5304 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5305 function TglBitmap.AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
5309 bmp := TglBitmap2D.Create;
5311 bmp.AssignFromSurface(aSurface);
5312 result := AddAlphaFromGlBitmap(bmp, aFunc, aArgs);
5320 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5321 function CreateGrayPalette: HPALETTE;
5326 GetMem(Pal, SizeOf(TLogPalette) + (SizeOf(TPaletteEntry) * 256));
5328 Pal.palVersion := $300;
5329 Pal.palNumEntries := 256;
5331 for Idx := 0 to Pal.palNumEntries - 1 do begin
5332 Pal.palPalEntry[Idx].peRed := Idx;
5333 Pal.palPalEntry[Idx].peGreen := Idx;
5334 Pal.palPalEntry[Idx].peBlue := Idx;
5335 Pal.palPalEntry[Idx].peFlags := 0;
5337 Result := CreatePalette(Pal^);
5341 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5342 function TglBitmap.AssignToBitmap(const aBitmap: TBitmap): Boolean;
5345 pSource, pData: PByte;
5348 if Assigned(Data) then begin
5349 if Assigned(aBitmap) then begin
5350 aBitmap.Width := Width;
5351 aBitmap.Height := Height;
5354 tfAlpha8ub1, tfLuminance8ub1: begin
5355 aBitmap.PixelFormat := pf8bit;
5356 aBitmap.Palette := CreateGrayPalette;
5359 aBitmap.PixelFormat := pf15bit;
5361 aBitmap.PixelFormat := pf16bit;
5362 tfRGB8ub3, tfBGR8ub3:
5363 aBitmap.PixelFormat := pf24bit;
5364 tfRGBA8ub4, tfBGRA8ub4:
5365 aBitmap.PixelFormat := pf32bit;
5367 raise EglBitmap.Create('AssignToBitmap - Invalid Pixelformat.');
5371 for Row := 0 to FileHeight -1 do begin
5372 pData := aBitmap.Scanline[Row];
5373 Move(pSource^, pData^, fRowSize);
5374 Inc(pSource, fRowSize);
5375 if (Format in [tfRGB8ub3, tfRGBA8ub4]) then // swap RGB(A) to BGR(A)
5376 SwapRGB(pData, FileWidth, Format = tfRGBA8ub4);
5383 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5384 function TglBitmap.AssignFromBitmap(const aBitmap: TBitmap): Boolean;
5386 pSource, pData, pTempData: PByte;
5387 Row, RowSize, TempWidth, TempHeight: Integer;
5388 IntFormat: TglBitmapFormat;
5392 if (Assigned(aBitmap)) then begin
5393 case aBitmap.PixelFormat of
5395 IntFormat := tfLuminance8ub1;
5397 IntFormat := tfRGB5A1us1;
5399 IntFormat := tfR5G6B5us1;
5401 IntFormat := tfBGR8ub3;
5403 IntFormat := tfBGRA8ub4;
5405 raise EglBitmap.Create('AssignFromBitmap - Invalid Pixelformat.');
5408 TempWidth := aBitmap.Width;
5409 TempHeight := aBitmap.Height;
5410 RowSize := TFormatDescriptor.Get(IntFormat).GetSize(TempWidth, 1);
5411 GetMem(pData, TempHeight * RowSize);
5414 for Row := 0 to TempHeight -1 do begin
5415 pSource := aBitmap.Scanline[Row];
5416 if (Assigned(pSource)) then begin
5417 Move(pSource^, pTempData^, RowSize);
5418 Inc(pTempData, RowSize);
5421 SetDataPointer(pData, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
5424 if Assigned(pData) then
5431 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5432 function TglBitmap.AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
5434 Row, Col, AlphaInterleave: Integer;
5435 pSource, pDest: PByte;
5439 if Assigned(Data) then begin
5440 if (Format in [tfAlpha8ub1, tfLuminance8Alpha8ub2, tfRGBA8ub4, tfBGRA8ub4]) then begin
5441 if Assigned(aBitmap) then begin
5442 aBitmap.PixelFormat := pf8bit;
5443 aBitmap.Palette := CreateGrayPalette;
5444 aBitmap.Width := Width;
5445 aBitmap.Height := Height;
5448 tfLuminance8Alpha8ub2:
5449 AlphaInterleave := 1;
5450 tfRGBA8ub4, tfBGRA8ub4:
5451 AlphaInterleave := 3;
5453 AlphaInterleave := 0;
5459 for Row := 0 to Height -1 do begin
5460 pDest := aBitmap.Scanline[Row];
5461 if Assigned(pDest) then begin
5462 for Col := 0 to Width -1 do begin
5463 Inc(pSource, AlphaInterleave);
5476 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5477 function TglBitmap.AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5481 tex := TglBitmap2D.Create;
5483 tex.AssignFromBitmap(ABitmap);
5484 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
5491 {$IFDEF GLB_LAZARUS}
5492 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5493 function TglBitmap.AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
5495 rid: TRawImageDescription;
5496 FormatDesc: TFormatDescriptor;
5498 if not Assigned(Data) then
5499 raise EglBitmap.Create('no pixel data assigned. load data before save');
5502 if not Assigned(aImage) or (Format = tfEmpty) then
5504 FormatDesc := TFormatDescriptor.Get(Format);
5505 if FormatDesc.IsCompressed then
5508 FillChar(rid{%H-}, SizeOf(rid), 0);
5509 if FormatDesc.IsGrayscale then
5510 rid.Format := ricfGray
5512 rid.Format := ricfRGBA;
5515 rid.Height := Height;
5516 rid.Depth := FormatDesc.BitsPerPixel;
5517 rid.BitOrder := riboBitsInOrder;
5518 rid.ByteOrder := riboLSBFirst;
5519 rid.LineOrder := riloTopToBottom;
5520 rid.LineEnd := rileTight;
5521 rid.BitsPerPixel := FormatDesc.BitsPerPixel;
5522 rid.RedPrec := CountSetBits(FormatDesc.Range.r);
5523 rid.GreenPrec := CountSetBits(FormatDesc.Range.g);
5524 rid.BluePrec := CountSetBits(FormatDesc.Range.b);
5525 rid.AlphaPrec := CountSetBits(FormatDesc.Range.a);
5526 rid.RedShift := FormatDesc.Shift.r;
5527 rid.GreenShift := FormatDesc.Shift.g;
5528 rid.BlueShift := FormatDesc.Shift.b;
5529 rid.AlphaShift := FormatDesc.Shift.a;
5531 rid.MaskBitsPerPixel := 0;
5532 rid.PaletteColorCount := 0;
5534 aImage.DataDescription := rid;
5537 if not Assigned(aImage.PixelData) then
5538 raise EglBitmap.Create('error while creating LazIntfImage');
5539 Move(Data^, aImage.PixelData^, FormatDesc.GetSize(Dimension));
5544 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5545 function TglBitmap.AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
5548 FormatDesc: TFormatDescriptor;
5552 Mask: TglBitmapRec4ul;
5554 procedure CopyConvert;
5556 bfFormat: TbmpBitfieldFormat;
5557 pSourceLine, pDestLine: PByte;
5558 pSourceMD, pDestMD: Pointer;
5559 Shift, Prec: TglBitmapRec4ub;
5561 pixel: TglBitmapPixelData;
5563 bfFormat := TbmpBitfieldFormat.Create;
5564 with aImage.DataDescription do begin
5566 Prec.g := GreenPrec;
5568 Prec.a := AlphaPrec;
5569 Shift.r := RedShift;
5570 Shift.g := GreenShift;
5571 Shift.b := BlueShift;
5572 Shift.a := AlphaShift;
5573 bfFormat.SetCustomValues(BitsPerPixel, Prec, Shift);
5575 pSourceMD := bfFormat.CreateMappingData;
5576 pDestMD := FormatDesc.CreateMappingData;
5578 for y := 0 to aImage.Height-1 do begin
5579 pSourceLine := aImage.PixelData + y {%H-}* aImage.DataDescription.BytesPerLine;
5580 pDestLine := ImageData + y * Round(FormatDesc.BytesPerPixel * aImage.Width);
5581 for x := 0 to aImage.Width-1 do begin
5582 bfFormat.Unmap(pSourceLine, pixel, pSourceMD);
5583 FormatDesc.Map(pixel, pDestLine, pDestMD);
5587 FormatDesc.FreeMappingData(pDestMD);
5588 bfFormat.FreeMappingData(pSourceMD);
5595 if not Assigned(aImage) then
5598 with aImage.DataDescription do begin
5599 Mask.r := (QWord(1 shl RedPrec )-1) shl RedShift;
5600 Mask.g := (QWord(1 shl GreenPrec)-1) shl GreenShift;
5601 Mask.b := (QWord(1 shl BluePrec )-1) shl BlueShift;
5602 Mask.a := (QWord(1 shl AlphaPrec)-1) shl AlphaShift;
5604 FormatDesc := TFormatDescriptor.GetFromMask(Mask);
5605 f := FormatDesc.Format;
5606 if (f = tfEmpty) then
5610 (FormatDesc.BitsPerPixel = aImage.DataDescription.Depth) and
5611 (aImage.DataDescription.BitsPerPixel = aImage.DataDescription.Depth);
5613 ImageSize := FormatDesc.GetSize(aImage.Width, aImage.Height);
5614 ImageData := GetMem(ImageSize);
5617 Move(aImage.PixelData^, ImageData^, ImageSize)
5620 SetDataPointer(ImageData, f, aImage.Width, aImage.Height); //be careful, Data could be freed by this method
5622 if Assigned(ImageData) then
5630 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5631 function TglBitmap.AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
5633 rid: TRawImageDescription;
5634 FormatDesc: TFormatDescriptor;
5635 Pixel: TglBitmapPixelData;
5641 if not Assigned(aImage) or (Format = tfEmpty) then
5643 FormatDesc := TFormatDescriptor.Get(Format);
5644 if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
5647 FillChar(rid{%H-}, SizeOf(rid), 0);
5648 rid.Format := ricfGray;
5650 rid.Height := Height;
5651 rid.Depth := CountSetBits(FormatDesc.Range.a);
5652 rid.BitOrder := riboBitsInOrder;
5653 rid.ByteOrder := riboLSBFirst;
5654 rid.LineOrder := riloTopToBottom;
5655 rid.LineEnd := rileTight;
5656 rid.BitsPerPixel := 8 * Ceil(rid.Depth / 8);
5657 rid.RedPrec := CountSetBits(FormatDesc.Range.a);
5662 rid.GreenShift := 0;
5664 rid.AlphaShift := 0;
5666 rid.MaskBitsPerPixel := 0;
5667 rid.PaletteColorCount := 0;
5669 aImage.DataDescription := rid;
5672 srcMD := FormatDesc.CreateMappingData;
5674 FormatDesc.PreparePixel(Pixel);
5676 dst := aImage.PixelData;
5677 for y := 0 to Height-1 do
5678 for x := 0 to Width-1 do begin
5679 FormatDesc.Unmap(src, Pixel, srcMD);
5680 case rid.BitsPerPixel of
5682 dst^ := Pixel.Data.a;
5686 PWord(dst)^ := Pixel.Data.a;
5690 PByteArray(dst)^[0] := PByteArray(@Pixel.Data.a)^[0];
5691 PByteArray(dst)^[1] := PByteArray(@Pixel.Data.a)^[1];
5692 PByteArray(dst)^[2] := PByteArray(@Pixel.Data.a)^[2];
5696 PCardinal(dst)^ := Pixel.Data.a;
5700 raise EglBitmapUnsupportedFormat.Create(Format);
5704 FormatDesc.FreeMappingData(srcMD);
5709 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5710 function TglBitmap.AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5714 tex := TglBitmap2D.Create;
5716 tex.AssignFromLazIntfImage(aImage);
5717 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
5724 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5725 function TglBitmap.AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar;
5726 const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5728 rs: TResourceStream;
5730 PrepareResType(aResource, aResType);
5731 rs := TResourceStream.Create(aInstance, aResource, aResType);
5733 result := AddAlphaFromStream(rs, aFunc, aArgs);
5739 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5740 function TglBitmap.AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
5741 const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5743 rs: TResourceStream;
5745 rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
5747 result := AddAlphaFromStream(rs, aFunc, aArgs);
5753 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5754 function TglBitmap.AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5756 if TFormatDescriptor.Get(Format).IsCompressed then
5757 raise EglBitmapUnsupportedFormat.Create(Format);
5758 result := AddFunc(Self, aFunc, false, TFormatDescriptor.Get(Format).WithAlpha, aArgs);
5761 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5762 function TglBitmap.AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5766 FS := TFileStream.Create(aFileName, fmOpenRead);
5768 result := AddAlphaFromStream(FS, aFunc, aArgs);
5774 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5775 function TglBitmap.AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5779 tex := TglBitmap2D.Create(aStream);
5781 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
5787 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5788 function TglBitmap.AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5790 DestData, DestData2, SourceData: pByte;
5791 TempHeight, TempWidth: Integer;
5792 SourceFD, DestFD: TFormatDescriptor;
5793 SourceMD, DestMD, DestMD2: Pointer;
5795 FuncRec: TglBitmapFunctionRec;
5799 Assert(Assigned(Data));
5800 Assert(Assigned(aBitmap));
5801 Assert(Assigned(aBitmap.Data));
5803 if ((aBitmap.Width = Width) and (aBitmap.Height = Height)) then begin
5804 result := ConvertTo(TFormatDescriptor.Get(Format).WithAlpha);
5806 SourceFD := TFormatDescriptor.Get(aBitmap.Format);
5807 DestFD := TFormatDescriptor.Get(Format);
5809 if not Assigned(aFunc) then begin
5810 aFunc := glBitmapAlphaFunc;
5811 FuncRec.Args := {%H-}Pointer(SourceFD.HasAlpha);
5813 FuncRec.Args := aArgs;
5816 TempHeight := aBitmap.FileHeight;
5817 TempWidth := aBitmap.FileWidth;
5819 FuncRec.Sender := Self;
5820 FuncRec.Size := Dimension;
5821 FuncRec.Position.Fields := FuncRec.Size.Fields;
5825 SourceData := aBitmap.Data;
5828 SourceFD.PreparePixel(FuncRec.Source);
5829 DestFD.PreparePixel (FuncRec.Dest);
5831 SourceMD := SourceFD.CreateMappingData;
5832 DestMD := DestFD.CreateMappingData;
5833 DestMD2 := DestFD.CreateMappingData;
5835 FuncRec.Position.Y := 0;
5836 while FuncRec.Position.Y < TempHeight do begin
5837 FuncRec.Position.X := 0;
5838 while FuncRec.Position.X < TempWidth do begin
5839 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
5840 DestFD.Unmap (DestData, FuncRec.Dest, DestMD);
5842 DestFD.Map(FuncRec.Dest, DestData2, DestMD2);
5843 inc(FuncRec.Position.X);
5845 inc(FuncRec.Position.Y);
5848 SourceFD.FreeMappingData(SourceMD);
5849 DestFD.FreeMappingData(DestMD);
5850 DestFD.FreeMappingData(DestMD2);
5855 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5856 function TglBitmap.AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte): Boolean;
5858 result := AddAlphaFromColorKeyFloat(aRed / $FF, aGreen / $FF, aBlue / $FF, aDeviation / $FF);
5861 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5862 function TglBitmap.AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal): Boolean;
5864 PixelData: TglBitmapPixelData;
5866 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5867 result := AddAlphaFromColorKeyFloat(
5868 aRed / PixelData.Range.r,
5869 aGreen / PixelData.Range.g,
5870 aBlue / PixelData.Range.b,
5871 aDeviation / Max(PixelData.Range.r, Max(PixelData.Range.g, PixelData.Range.b)));
5874 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5875 function TglBitmap.AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single): Boolean;
5877 values: array[0..2] of Single;
5880 PixelData: TglBitmapPixelData;
5882 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5883 with PixelData do begin
5885 values[1] := aGreen;
5888 for i := 0 to 2 do begin
5889 tmp := Trunc(Range.arr[i] * aDeviation);
5890 Data.arr[i] := Min(Range.arr[i], Trunc(Range.arr[i] * values[i] + tmp));
5891 Range.arr[i] := Max(0, Trunc(Range.arr[i] * values[i] - tmp));
5896 result := AddAlphaFromFunc(glBitmapColorKeyAlphaFunc, @PixelData);
5899 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5900 function TglBitmap.AddAlphaFromValue(const aAlpha: Byte): Boolean;
5902 result := AddAlphaFromValueFloat(aAlpha / $FF);
5905 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5906 function TglBitmap.AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
5908 PixelData: TglBitmapPixelData;
5910 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5911 result := AddAlphaFromValueFloat(aAlpha / PixelData.Range.a);
5914 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5915 function TglBitmap.AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
5917 PixelData: TglBitmapPixelData;
5919 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5921 Data.a := Min(Range.a, Max(0, Round(Range.a * aAlpha)));
5922 result := AddAlphaFromFunc(glBitmapValueAlphaFunc, @PixelData.Data.a);
5925 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5926 function TglBitmap.RemoveAlpha: Boolean;
5928 FormatDesc: TFormatDescriptor;
5931 FormatDesc := TFormatDescriptor.Get(Format);
5932 if Assigned(Data) then begin
5933 if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
5934 raise EglBitmapUnsupportedFormat.Create(Format);
5935 result := ConvertTo(FormatDesc.WithoutAlpha);
5939 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5940 function TglBitmap.Clone: TglBitmap;
5947 Temp := (ClassType.Create as TglBitmap);
5949 // copy texture data if assigned
5950 if Assigned(Data) then begin
5951 Size := TFormatDescriptor.Get(Format).GetSize(fDimension);
5952 GetMem(TempPtr, Size);
5954 Move(Data^, TempPtr^, Size);
5955 Temp.SetDataPointer(TempPtr, Format, Width, Height); //be careful, Data could be freed by this method
5957 if Assigned(TempPtr) then
5963 Temp.SetDataPointer(TempPtr, Format, Width, Height); //be careful, Data could be freed by this method
5968 Temp.fTarget := Target;
5969 Temp.fFormat := Format;
5970 Temp.fMipMap := MipMap;
5971 Temp.fAnisotropic := Anisotropic;
5972 Temp.fBorderColor := fBorderColor;
5973 Temp.fDeleteTextureOnFree := DeleteTextureOnFree;
5974 Temp.fFreeDataAfterGenTexture := FreeDataAfterGenTexture;
5975 Temp.fFilterMin := fFilterMin;
5976 Temp.fFilterMag := fFilterMag;
5977 Temp.fWrapS := fWrapS;
5978 Temp.fWrapT := fWrapT;
5979 Temp.fWrapR := fWrapR;
5980 Temp.fFilename := fFilename;
5981 Temp.fCustomName := fCustomName;
5982 Temp.fCustomNameW := fCustomNameW;
5983 Temp.fCustomData := fCustomData;
5992 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5993 function TglBitmap.ConvertTo(const aFormat: TglBitmapFormat): Boolean;
5995 SourceFD, DestFD: TFormatDescriptor;
5996 SourcePD, DestPD: TglBitmapPixelData;
5997 ShiftData: TShiftData;
5999 function DataIsIdentical: Boolean;
6001 result := SourceFD.MaskMatch(DestFD.Mask);
6004 function CanCopyDirect: Boolean;
6007 ((SourcePD.Range.r = DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
6008 ((SourcePD.Range.g = DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
6009 ((SourcePD.Range.b = DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
6010 ((SourcePD.Range.a = DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
6013 function CanShift: Boolean;
6016 ((SourcePD.Range.r >= DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
6017 ((SourcePD.Range.g >= DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
6018 ((SourcePD.Range.b >= DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
6019 ((SourcePD.Range.a >= DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
6022 function GetShift(aSource, aDest: Cardinal) : ShortInt;
6025 while (aSource > aDest) and (aSource > 0) do begin
6027 aSource := aSource shr 1;
6032 if (aFormat <> fFormat) and (aFormat <> tfEmpty) then begin
6033 SourceFD := TFormatDescriptor.Get(Format);
6034 DestFD := TFormatDescriptor.Get(aFormat);
6036 if DataIsIdentical then begin
6042 SourceFD.PreparePixel(SourcePD);
6043 DestFD.PreparePixel (DestPD);
6045 if CanCopyDirect then
6046 result := AddFunc(Self, glBitmapConvertCopyFunc, false, aFormat)
6047 else if CanShift then begin
6048 ShiftData.r := GetShift(SourcePD.Range.r, DestPD.Range.r);
6049 ShiftData.g := GetShift(SourcePD.Range.g, DestPD.Range.g);
6050 ShiftData.b := GetShift(SourcePD.Range.b, DestPD.Range.b);
6051 ShiftData.a := GetShift(SourcePD.Range.a, DestPD.Range.a);
6052 result := AddFunc(Self, glBitmapConvertShiftRGBAFunc, false, aFormat, @ShiftData);
6054 result := AddFunc(Self, glBitmapConvertCalculateRGBAFunc, false, aFormat);
6059 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6060 procedure TglBitmap.Invert(const aUseRGB: Boolean; const aUseAlpha: Boolean);
6062 if aUseRGB or aUseAlpha then
6063 AddFunc(glBitmapInvertFunc, false, {%H-}Pointer(
6064 ((Byte(aUseAlpha) and 1) shl 1) or
6065 (Byte(aUseRGB) and 1) ));
6069 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6070 procedure TglBitmap.SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
6072 fBorderColor[0] := aRed;
6073 fBorderColor[1] := aGreen;
6074 fBorderColor[2] := aBlue;
6075 fBorderColor[3] := aAlpha;
6076 if (ID > 0) then begin
6078 glTexParameterfv(Target, GL_TEXTURE_BORDER_COLOR, @fBorderColor[0]);
6083 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6084 procedure TglBitmap.FreeData;
6089 SetDataPointer(TempPtr, tfEmpty); //be careful, Data could be freed by this method
6092 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6093 procedure TglBitmap.FillWithColor(const aRed, aGreen, aBlue: Byte;
6094 const aAlpha: Byte);
6096 FillWithColorFloat(aRed/$FF, aGreen/$FF, aBlue/$FF, aAlpha/$FF);
6099 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6100 procedure TglBitmap.FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal);
6102 PixelData: TglBitmapPixelData;
6104 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
6106 aRed / PixelData.Range.r,
6107 aGreen / PixelData.Range.g,
6108 aBlue / PixelData.Range.b,
6109 aAlpha / PixelData.Range.a);
6112 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6113 procedure TglBitmap.FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single);
6115 PixelData: TglBitmapPixelData;
6117 TFormatDescriptor.Get(Format).PreparePixel(PixelData);
6118 with PixelData do begin
6119 Data.r := Max(0, Min(Range.r, Trunc(Range.r * aRed)));
6120 Data.g := Max(0, Min(Range.g, Trunc(Range.g * aGreen)));
6121 Data.b := Max(0, Min(Range.b, Trunc(Range.b * aBlue)));
6122 Data.a := Max(0, Min(Range.a, Trunc(Range.a * aAlpha)));
6124 AddFunc(glBitmapFillWithColorFunc, false, @PixelData);
6127 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6128 procedure TglBitmap.SetFilter(const aMin, aMag: GLenum);
6133 fFilterMin := GL_NEAREST;
6135 fFilterMin := GL_LINEAR;
6136 GL_NEAREST_MIPMAP_NEAREST:
6137 fFilterMin := GL_NEAREST_MIPMAP_NEAREST;
6138 GL_LINEAR_MIPMAP_NEAREST:
6139 fFilterMin := GL_LINEAR_MIPMAP_NEAREST;
6140 GL_NEAREST_MIPMAP_LINEAR:
6141 fFilterMin := GL_NEAREST_MIPMAP_LINEAR;
6142 GL_LINEAR_MIPMAP_LINEAR:
6143 fFilterMin := GL_LINEAR_MIPMAP_LINEAR;
6145 raise EglBitmap.Create('SetFilter - Unknow MIN filter.');
6151 fFilterMag := GL_NEAREST;
6153 fFilterMag := GL_LINEAR;
6155 raise EglBitmap.Create('SetFilter - Unknow MAG filter.');
6159 if (ID > 0) then begin
6161 glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, fFilterMag);
6163 if (MipMap = mmNone) {$IFNDEF OPENGL_ES}or (Target = GL_TEXTURE_RECTANGLE){$ENDIF} then begin
6165 GL_NEAREST, GL_LINEAR:
6166 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
6167 GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR:
6168 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6169 GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR:
6170 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6173 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
6177 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6178 procedure TglBitmap.SetWrap(const S: GLenum; const T: GLenum; const R: GLenum);
6180 procedure CheckAndSetWrap(const aValue: Cardinal; var aTarget: Cardinal);
6185 aTarget := GL_CLAMP;
6189 aTarget := GL_REPEAT;
6191 GL_CLAMP_TO_EDGE: begin
6193 if not GL_VERSION_1_2 and not GL_EXT_texture_edge_clamp then
6197 aTarget := GL_CLAMP_TO_EDGE;
6201 GL_CLAMP_TO_BORDER: begin
6202 if GL_VERSION_1_3 or GL_ARB_texture_border_clamp then
6203 aTarget := GL_CLAMP_TO_BORDER
6205 aTarget := GL_CLAMP;
6209 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
6210 GL_MIRRORED_REPEAT: begin
6212 if GL_VERSION_1_4 or GL_ARB_texture_mirrored_repeat or GL_IBM_texture_mirrored_repeat then
6214 if GL_VERSION_2_0 then
6216 aTarget := GL_MIRRORED_REPEAT
6218 raise EglBitmap.Create('SetWrap - Unsupported Texturewrap GL_MIRRORED_REPEAT (S).');
6222 raise EglBitmap.Create('SetWrap - Unknow Texturewrap');
6227 CheckAndSetWrap(S, fWrapS);
6228 CheckAndSetWrap(T, fWrapT);
6229 CheckAndSetWrap(R, fWrapR);
6231 if (ID > 0) then begin
6233 glTexParameteri(Target, GL_TEXTURE_WRAP_S, fWrapS);
6234 glTexParameteri(Target, GL_TEXTURE_WRAP_T, fWrapT);
6235 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
6236 {$IFDEF OPENGL_ES} if GL_VERSION_3_0 then{$ENDIF}
6237 glTexParameteri(Target, GL_TEXTURE_WRAP_R, fWrapR);
6242 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
6243 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6244 procedure TglBitmap.SetSwizzle(const r, g, b, a: GLenum);
6246 procedure CheckAndSetValue(const aValue: GLenum; const aIndex: Integer);
6248 if (aValue = GL_ZERO) or (aValue = GL_ONE) or (aValue = GL_ALPHA) or
6249 (aValue = GL_RED) or (aValue = GL_GREEN) or (aValue = GL_BLUE) then
6250 fSwizzle[aIndex] := aValue
6252 raise EglBitmap.Create('SetSwizzle - Unknow Swizle Value');
6257 if not (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
6258 raise EglBitmapNotSupported.Create('texture swizzle is not supported');
6260 if not GL_VERSION_3_0 then
6261 raise EglBitmapNotSupported.Create('texture swizzle is not supported');
6263 CheckAndSetValue(r, 0);
6264 CheckAndSetValue(g, 1);
6265 CheckAndSetValue(b, 2);
6266 CheckAndSetValue(a, 3);
6268 if (ID > 0) then begin
6271 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_RGBA, PGLint(@fSwizzle[0]));
6273 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_R, PGLint(@fSwizzle[0]));
6274 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_G, PGLint(@fSwizzle[1]));
6275 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_B, PGLint(@fSwizzle[2]));
6276 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_A, PGLint(@fSwizzle[3]));
6282 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6283 procedure TglBitmap.Bind(const aEnableTextureUnit: Boolean);
6285 if aEnableTextureUnit then
6288 glBindTexture(Target, ID);
6291 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6292 procedure TglBitmap.Unbind(const aDisableTextureUnit: Boolean);
6294 if aDisableTextureUnit then
6296 glBindTexture(Target, 0);
6299 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6300 constructor TglBitmap.Create;
6302 if (ClassType = TglBitmap) then
6303 raise EglBitmap.Create('Don''t create TglBitmap directly. Use one of the deviated classes (TglBitmap2D) instead.');
6304 {$IFDEF GLB_NATIVE_OGL}
6305 glbReadOpenGLExtensions;
6308 fFormat := glBitmapGetDefaultFormat;
6309 fFreeDataOnDestroy := true;
6312 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6313 constructor TglBitmap.Create(const aFileName: String);
6316 LoadFromFile(aFileName);
6319 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6320 constructor TglBitmap.Create(const aStream: TStream);
6323 LoadFromStream(aStream);
6326 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6327 constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; aData: PByte);
6332 if not Assigned(aData) then begin
6333 ImageSize := TFormatDescriptor.Get(aFormat).GetSize(aSize);
6334 GetMem(aData, ImageSize);
6336 FillChar(aData^, ImageSize, #$FF);
6337 SetDataPointer(aData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
6339 if Assigned(aData) then
6344 SetDataPointer(aData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
6345 fFreeDataOnDestroy := false;
6349 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6350 constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer);
6353 LoadFromFunc(aSize, aFunc, aFormat, aArgs);
6356 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6357 constructor TglBitmap.Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar);
6360 LoadFromResource(aInstance, aResource, aResType);
6363 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6364 constructor TglBitmap.Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
6367 LoadFromResourceID(aInstance, aResourceID, aResType);
6370 {$IFDEF GLB_SUPPORT_PNG_READ}
6371 {$IF DEFINED(GLB_LAZ_PNG)}
6372 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6373 //PNG/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6374 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6375 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6378 PNG_MAGIC: String[MAGIC_LEN] = #$89#$50#$4E#$47#$0D#$0A#$1A#$0A;
6380 reader: TLazReaderPNG;
6381 intf: TLazIntfImage;
6383 magic: String[MAGIC_LEN];
6386 StreamPos := aStream.Position;
6388 SetLength(magic, MAGIC_LEN);
6389 aStream.Read(magic[1], MAGIC_LEN);
6390 aStream.Position := StreamPos;
6391 if (magic <> PNG_MAGIC) then begin
6396 intf := TLazIntfImage.Create(0, 0);
6397 reader := TLazReaderPNG.Create;
6399 reader.UpdateDescription := true;
6400 reader.ImageRead(aStream, intf);
6401 AssignFromLazIntfImage(intf);
6404 aStream.Position := StreamPos;
6413 {$ELSEIF DEFINED(GLB_SDL_IMAGE)}
6414 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6415 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6417 Surface: PSDL_Surface;
6421 RWops := glBitmapCreateRWops(aStream);
6423 if IMG_isPNG(RWops) > 0 then begin
6424 Surface := IMG_LoadPNG_RW(RWops);
6426 AssignFromSurface(Surface);
6429 SDL_FreeSurface(Surface);
6437 {$ELSEIF DEFINED(GLB_LIB_PNG)}
6438 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6439 procedure glBitmap_libPNG_read_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
6441 TStream(png_get_io_ptr(png)).Read(buffer^, size);
6444 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6445 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6448 signature: array [0..7] of byte;
6450 png_info: png_infop;
6452 TempHeight, TempWidth: Integer;
6453 Format: TglBitmapFormat;
6456 png_rows: array of pByte;
6457 Row, LineSize: Integer;
6461 if not init_libPNG then
6462 raise Exception.Create('LoadPNG - unable to initialize libPNG.');
6466 StreamPos := aStream.Position;
6467 aStream.Read(signature{%H-}, 8);
6468 aStream.Position := StreamPos;
6470 if png_check_sig(@signature, 8) <> 0 then begin
6472 png := png_create_read_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
6474 raise EglBitmapException.Create('LoadPng - couldn''t create read struct.');
6477 png_info := png_create_info_struct(png);
6478 if png_info = nil then begin
6479 png_destroy_read_struct(@png, nil, nil);
6480 raise EglBitmapException.Create('LoadPng - couldn''t create info struct.');
6483 // set read callback
6484 png_set_read_fn(png, aStream, glBitmap_libPNG_read_func);
6486 // read informations
6487 png_read_info(png, png_info);
6490 TempHeight := png_get_image_height(png, png_info);
6491 TempWidth := png_get_image_width(png, png_info);
6494 case png_get_color_type(png, png_info) of
6495 PNG_COLOR_TYPE_GRAY:
6496 Format := tfLuminance8ub1;
6497 PNG_COLOR_TYPE_GRAY_ALPHA:
6498 Format := tfLuminance8Alpha8us1;
6500 Format := tfRGB8ub3;
6501 PNG_COLOR_TYPE_RGB_ALPHA:
6502 Format := tfRGBA8ub4;
6504 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
6507 // cut upper 8 bit from 16 bit formats
6508 if png_get_bit_depth(png, png_info) > 8 then
6509 png_set_strip_16(png);
6511 // expand bitdepth smaller than 8
6512 if png_get_bit_depth(png, png_info) < 8 then
6513 png_set_expand(png);
6515 // allocating mem for scanlines
6516 LineSize := png_get_rowbytes(png, png_info);
6517 GetMem(png_data, TempHeight * LineSize);
6519 SetLength(png_rows, TempHeight);
6520 for Row := Low(png_rows) to High(png_rows) do begin
6521 png_rows[Row] := png_data;
6522 Inc(png_rows[Row], Row * LineSize);
6525 // read complete image into scanlines
6526 png_read_image(png, @png_rows[0]);
6529 png_read_end(png, png_info);
6531 // destroy read struct
6532 png_destroy_read_struct(@png, @png_info, nil);
6534 SetLength(png_rows, 0);
6537 SetDataPointer(png_data, Format, TempWidth, TempHeight); //be careful, Data could be freed by this method
6541 if Assigned(png_data) then
6551 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
6552 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6553 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6558 Row, Col, PixSize, LineSize: Integer;
6559 NewImage, pSource, pDest, pAlpha: pByte;
6560 PngFormat: TglBitmapFormat;
6561 FormatDesc: TFormatDescriptor;
6564 PngHeader: String[8] = #137#80#78#71#13#10#26#10;
6569 StreamPos := aStream.Position;
6570 aStream.Read(Header[0], SizeOf(Header));
6571 aStream.Position := StreamPos;
6573 {Test if the header matches}
6574 if Header = PngHeader then begin
6575 Png := TPNGObject.Create;
6577 Png.LoadFromStream(aStream);
6579 case Png.Header.ColorType of
6581 PngFormat := tfLuminance8ub1;
6582 COLOR_GRAYSCALEALPHA:
6583 PngFormat := tfLuminance8Alpha8us1;
6585 PngFormat := tfBGR8ub3;
6587 PngFormat := tfBGRA8ub4;
6589 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
6592 FormatDesc := TFormatDescriptor.Get(PngFormat);
6593 PixSize := Round(FormatDesc.PixelSize);
6594 LineSize := FormatDesc.GetSize(Png.Header.Width, 1);
6596 GetMem(NewImage, LineSize * Integer(Png.Header.Height));
6600 case Png.Header.ColorType of
6601 COLOR_RGB, COLOR_GRAYSCALE:
6603 for Row := 0 to Png.Height -1 do begin
6604 Move (Png.Scanline[Row]^, pDest^, LineSize);
6605 Inc(pDest, LineSize);
6608 COLOR_RGBALPHA, COLOR_GRAYSCALEALPHA:
6610 PixSize := PixSize -1;
6612 for Row := 0 to Png.Height -1 do begin
6613 pSource := Png.Scanline[Row];
6614 pAlpha := pByte(Png.AlphaScanline[Row]);
6616 for Col := 0 to Png.Width -1 do begin
6617 Move (pSource^, pDest^, PixSize);
6618 Inc(pSource, PixSize);
6619 Inc(pDest, PixSize);
6628 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
6631 SetDataPointer(NewImage, PngFormat, Png.Header.Width, Png.Header.Height); //be careful, Data could be freed by this method
6635 if Assigned(NewImage) then
6647 {$IFDEF GLB_SUPPORT_PNG_WRITE}
6648 {$IFDEF GLB_LIB_PNG}
6649 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6650 procedure glBitmap_libPNG_write_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
6652 TStream(png_get_io_ptr(png)).Write(buffer^, size);
6656 {$IF DEFINED(GLB_LAZ_PNG)}
6657 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6658 procedure TglBitmap.SavePNG(const aStream: TStream);
6660 png: TPortableNetworkGraphic;
6661 intf: TLazIntfImage;
6664 png := TPortableNetworkGraphic.Create;
6665 intf := TLazIntfImage.Create(0, 0);
6667 if not AssignToLazIntfImage(intf) then
6668 raise EglBitmap.Create('unable to create LazIntfImage from glBitmap');
6669 intf.GetRawImage(raw);
6670 png.LoadFromRawImage(raw, false);
6671 png.SaveToStream(aStream);
6678 {$ELSEIF DEFINED(GLB_LIB_PNG)}
6679 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6680 procedure TglBitmap.SavePNG(const aStream: TStream);
6683 png_info: png_infop;
6684 png_rows: array of pByte;
6688 FormatDesc: TFormatDescriptor;
6690 if not (ftPNG in FormatGetSupportedFiles(Format)) then
6691 raise EglBitmapUnsupportedFormat.Create(Format);
6693 if not init_libPNG then
6694 raise Exception.Create('unable to initialize libPNG.');
6698 tfAlpha8ub1, tfLuminance8ub1:
6699 ColorType := PNG_COLOR_TYPE_GRAY;
6700 tfLuminance8Alpha8us1:
6701 ColorType := PNG_COLOR_TYPE_GRAY_ALPHA;
6702 tfBGR8ub3, tfRGB8ub3:
6703 ColorType := PNG_COLOR_TYPE_RGB;
6704 tfBGRA8ub4, tfRGBA8ub4:
6705 ColorType := PNG_COLOR_TYPE_RGBA;
6707 raise EglBitmapUnsupportedFormat.Create(Format);
6710 FormatDesc := TFormatDescriptor.Get(Format);
6711 LineSize := FormatDesc.GetSize(Width, 1);
6713 // creating array for scanline
6714 SetLength(png_rows, Height);
6716 for Row := 0 to Height - 1 do begin
6717 png_rows[Row] := Data;
6718 Inc(png_rows[Row], Row * LineSize)
6722 png := png_create_write_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
6724 raise EglBitmapException.Create('SavePng - couldn''t create write struct.');
6727 png_info := png_create_info_struct(png);
6728 if png_info = nil then begin
6729 png_destroy_write_struct(@png, nil);
6730 raise EglBitmapException.Create('SavePng - couldn''t create info struct.');
6733 // set read callback
6734 png_set_write_fn(png, aStream, glBitmap_libPNG_write_func, nil);
6737 png_set_compression_level(png, 6);
6739 if Format in [tfBGR8ub3, tfBGRA8ub4] then
6742 png_set_IHDR(png, png_info, Width, Height, 8, ColorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
6743 png_write_info(png, png_info);
6744 png_write_image(png, @png_rows[0]);
6745 png_write_end(png, png_info);
6746 png_destroy_write_struct(@png, @png_info);
6748 SetLength(png_rows, 0);
6755 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
6756 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6757 procedure TglBitmap.SavePNG(const aStream: TStream);
6761 pSource, pDest: pByte;
6762 X, Y, PixSize: Integer;
6763 ColorType: Cardinal;
6769 if not (ftPNG in FormatGetSupportedFiles (Format)) then
6770 raise EglBitmapUnsupportedFormat.Create(Format);
6773 tfAlpha8ub1, tfLuminance8ub1: begin
6774 ColorType := COLOR_GRAYSCALE;
6778 tfLuminance8Alpha8us1: begin
6779 ColorType := COLOR_GRAYSCALEALPHA;
6783 tfBGR8ub3, tfRGB8ub3: begin
6784 ColorType := COLOR_RGB;
6788 tfBGRA8ub4, tfRGBA8ub4: begin
6789 ColorType := COLOR_RGBALPHA;
6794 raise EglBitmapUnsupportedFormat.Create(Format);
6797 Png := TPNGObject.CreateBlank(ColorType, 8, Width, Height);
6801 for Y := 0 to Height -1 do begin
6802 pDest := png.ScanLine[Y];
6803 for X := 0 to Width -1 do begin
6804 Move(pSource^, pDest^, PixSize);
6805 Inc(pDest, PixSize);
6806 Inc(pSource, PixSize);
6808 png.AlphaScanline[Y]^[X] := pSource^;
6813 // convert RGB line to BGR
6814 if Format in [tfRGB8ub3, tfRGBA8ub4] then begin
6815 pTemp := png.ScanLine[Y];
6816 for X := 0 to Width -1 do begin
6817 Temp := pByteArray(pTemp)^[0];
6818 pByteArray(pTemp)^[0] := pByteArray(pTemp)^[2];
6819 pByteArray(pTemp)^[2] := Temp;
6826 Png.CompressionLevel := 6;
6827 Png.SaveToStream(aStream);
6835 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6836 //JPEG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6837 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6838 {$IFDEF GLB_LIB_JPEG}
6840 glBitmap_libJPEG_source_mgr_ptr = ^glBitmap_libJPEG_source_mgr;
6841 glBitmap_libJPEG_source_mgr = record
6842 pub: jpeg_source_mgr;
6845 SrcBuffer: array [1..4096] of byte;
6848 glBitmap_libJPEG_dest_mgr_ptr = ^glBitmap_libJPEG_dest_mgr;
6849 glBitmap_libJPEG_dest_mgr = record
6850 pub: jpeg_destination_mgr;
6852 DestStream: TStream;
6853 DestBuffer: array [1..4096] of byte;
6856 procedure glBitmap_libJPEG_error_exit(cinfo: j_common_ptr); cdecl;
6862 procedure glBitmap_libJPEG_output_message(cinfo: j_common_ptr); cdecl;
6868 procedure glBitmap_libJPEG_init_source(cinfo: j_decompress_ptr); cdecl;
6873 procedure glBitmap_libJPEG_term_source(cinfo: j_decompress_ptr); cdecl;
6879 procedure glBitmap_libJPEG_init_destination(cinfo: j_compress_ptr); cdecl;
6885 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6886 function glBitmap_libJPEG_fill_input_buffer(cinfo: j_decompress_ptr): boolean; cdecl;
6888 src: glBitmap_libJPEG_source_mgr_ptr;
6891 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
6893 bytes := src^.SrcStream.Read(src^.SrcBuffer[1], 4096);
6894 if (bytes <= 0) then begin
6895 src^.SrcBuffer[1] := $FF;
6896 src^.SrcBuffer[2] := JPEG_EOI;
6900 src^.pub.next_input_byte := @(src^.SrcBuffer[1]);
6901 src^.pub.bytes_in_buffer := bytes;
6906 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6907 procedure glBitmap_libJPEG_skip_input_data(cinfo: j_decompress_ptr; num_bytes: Longint); cdecl;
6909 src: glBitmap_libJPEG_source_mgr_ptr;
6911 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
6913 if num_bytes > 0 then begin
6914 // wanted byte isn't in buffer so set stream position and read buffer
6915 if num_bytes > src^.pub.bytes_in_buffer then begin
6916 src^.SrcStream.Position := src^.SrcStream.Position + num_bytes - src^.pub.bytes_in_buffer;
6917 src^.pub.fill_input_buffer(cinfo);
6919 // wanted byte is in buffer so only skip
6920 inc(src^.pub.next_input_byte, num_bytes);
6921 dec(src^.pub.bytes_in_buffer, num_bytes);
6926 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6927 function glBitmap_libJPEG_empty_output_buffer(cinfo: j_compress_ptr): boolean; cdecl;
6929 dest: glBitmap_libJPEG_dest_mgr_ptr;
6931 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
6933 if dest^.pub.free_in_buffer < Cardinal(Length(dest^.DestBuffer)) then begin
6934 // write complete buffer
6935 dest^.DestStream.Write(dest^.DestBuffer[1], SizeOf(dest^.DestBuffer));
6938 dest^.pub.next_output_byte := @dest^.DestBuffer[1];
6939 dest^.pub.free_in_buffer := Length(dest^.DestBuffer);
6945 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6946 procedure glBitmap_libJPEG_term_destination(cinfo: j_compress_ptr); cdecl;
6949 dest: glBitmap_libJPEG_dest_mgr_ptr;
6951 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
6953 for Idx := Low(dest^.DestBuffer) to High(dest^.DestBuffer) do begin
6954 // check for endblock
6955 if (Idx < High(dest^.DestBuffer)) and (dest^.DestBuffer[Idx] = $FF) and (dest^.DestBuffer[Idx +1] = JPEG_EOI) then begin
6957 dest^.DestStream.Write(dest^.DestBuffer[Idx], 2);
6962 dest^.DestStream.Write(dest^.DestBuffer[Idx], 1);
6967 {$IFDEF GLB_SUPPORT_JPEG_READ}
6968 {$IF DEFINED(GLB_LAZ_JPEG)}
6969 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6970 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6973 JPEG_MAGIC: String[MAGIC_LEN] = #$FF#$D8;
6975 intf: TLazIntfImage;
6976 reader: TFPReaderJPEG;
6978 magic: String[MAGIC_LEN];
6981 StreamPos := aStream.Position;
6983 SetLength(magic, MAGIC_LEN);
6984 aStream.Read(magic[1], MAGIC_LEN);
6985 aStream.Position := StreamPos;
6986 if (magic <> JPEG_MAGIC) then begin
6991 reader := TFPReaderJPEG.Create;
6992 intf := TLazIntfImage.Create(0, 0);
6994 intf.DataDescription := GetDescriptionFromDevice(0, 0, 0);
6995 reader.ImageRead(aStream, intf);
6996 AssignFromLazIntfImage(intf);
6999 aStream.Position := StreamPos;
7008 {$ELSEIF DEFINED(GLB_SDL_IMAGE)}
7009 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7010 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
7012 Surface: PSDL_Surface;
7017 RWops := glBitmapCreateRWops(aStream);
7019 if IMG_isJPG(RWops) > 0 then begin
7020 Surface := IMG_LoadJPG_RW(RWops);
7022 AssignFromSurface(Surface);
7025 SDL_FreeSurface(Surface);
7033 {$ELSEIF DEFINED(GLB_LIB_JPEG)}
7034 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7035 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
7038 Temp: array[0..1]of Byte;
7040 jpeg: jpeg_decompress_struct;
7041 jpeg_err: jpeg_error_mgr;
7043 IntFormat: TglBitmapFormat;
7045 TempHeight, TempWidth: Integer;
7050 FormatDesc: TFormatDescriptor;
7054 if not init_libJPEG then
7055 raise Exception.Create('LoadJPG - unable to initialize libJPEG.');
7058 // reading first two bytes to test file and set cursor back to begin
7059 StreamPos := aStream.Position;
7060 aStream.Read({%H-}Temp[0], 2);
7061 aStream.Position := StreamPos;
7063 // if Bitmap then read file.
7064 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
7065 FillChar(jpeg{%H-}, SizeOf(jpeg_decompress_struct), $00);
7066 FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
7069 jpeg.err := jpeg_std_error(@jpeg_err);
7070 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
7071 jpeg_err.output_message := glBitmap_libJPEG_output_message;
7073 // decompression struct
7074 jpeg_create_decompress(@jpeg);
7076 // allocation space for streaming methods
7077 jpeg.src := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_source_mgr));
7079 // seeting up custom functions
7080 with glBitmap_libJPEG_source_mgr_ptr(jpeg.src)^ do begin
7081 pub.init_source := glBitmap_libJPEG_init_source;
7082 pub.fill_input_buffer := glBitmap_libJPEG_fill_input_buffer;
7083 pub.skip_input_data := glBitmap_libJPEG_skip_input_data;
7084 pub.resync_to_restart := jpeg_resync_to_restart; // use default method
7085 pub.term_source := glBitmap_libJPEG_term_source;
7087 pub.bytes_in_buffer := 0; // forces fill_input_buffer on first read
7088 pub.next_input_byte := nil; // until buffer loaded
7090 SrcStream := aStream;
7093 // set global decoding state
7094 jpeg.global_state := DSTATE_START;
7096 // read header of jpeg
7097 jpeg_read_header(@jpeg, false);
7099 // setting output parameter
7100 case jpeg.jpeg_color_space of
7103 jpeg.out_color_space := JCS_GRAYSCALE;
7104 IntFormat := tfLuminance8ub1;
7107 jpeg.out_color_space := JCS_RGB;
7108 IntFormat := tfRGB8ub3;
7112 jpeg_start_decompress(@jpeg);
7114 TempHeight := jpeg.output_height;
7115 TempWidth := jpeg.output_width;
7117 FormatDesc := TFormatDescriptor.Get(IntFormat);
7119 // creating new image
7120 GetMem(pImage, FormatDesc.GetSize(TempWidth, TempHeight));
7124 for Row := 0 to TempHeight -1 do begin
7125 jpeg_read_scanlines(@jpeg, @pTemp, 1);
7126 Inc(pTemp, FormatDesc.GetSize(TempWidth, 1));
7129 // finish decompression
7130 jpeg_finish_decompress(@jpeg);
7132 // destroy decompression
7133 jpeg_destroy_decompress(@jpeg);
7135 SetDataPointer(pImage, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
7139 if Assigned(pImage) then
7149 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
7150 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7151 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
7156 Temp: array[0..1]of Byte;
7160 // reading first two bytes to test file and set cursor back to begin
7161 StreamPos := aStream.Position;
7162 aStream.Read(Temp[0], 2);
7163 aStream.Position := StreamPos;
7165 // if Bitmap then read file.
7166 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
7167 bmp := TBitmap.Create;
7169 jpg := TJPEGImage.Create;
7171 jpg.LoadFromStream(aStream);
7173 result := AssignFromBitmap(bmp);
7185 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
7186 {$IF DEFINED(GLB_LAZ_JPEG)}
7187 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7188 procedure TglBitmap.SaveJPEG(const aStream: TStream);
7191 intf: TLazIntfImage;
7194 jpeg := TJPEGImage.Create;
7195 intf := TLazIntfImage.Create(0, 0);
7197 if not AssignToLazIntfImage(intf) then
7198 raise EglBitmap.Create('unable to create LazIntfImage from glBitmap');
7199 intf.GetRawImage(raw);
7200 jpeg.LoadFromRawImage(raw, false);
7201 jpeg.SaveToStream(aStream);
7208 {$ELSEIF DEFINED(GLB_LIB_JPEG)}
7209 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7210 procedure TglBitmap.SaveJPEG(const aStream: TStream);
7212 jpeg: jpeg_compress_struct;
7213 jpeg_err: jpeg_error_mgr;
7215 pTemp, pTemp2: pByte;
7217 procedure CopyRow(pDest, pSource: pByte);
7221 for X := 0 to Width - 1 do begin
7222 pByteArray(pDest)^[0] := pByteArray(pSource)^[2];
7223 pByteArray(pDest)^[1] := pByteArray(pSource)^[1];
7224 pByteArray(pDest)^[2] := pByteArray(pSource)^[0];
7231 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
7232 raise EglBitmapUnsupportedFormat.Create(Format);
7234 if not init_libJPEG then
7235 raise Exception.Create('SaveJPG - unable to initialize libJPEG.');
7238 FillChar(jpeg{%H-}, SizeOf(jpeg_compress_struct), $00);
7239 FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
7242 jpeg.err := jpeg_std_error(@jpeg_err);
7243 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
7244 jpeg_err.output_message := glBitmap_libJPEG_output_message;
7246 // compression struct
7247 jpeg_create_compress(@jpeg);
7249 // allocation space for streaming methods
7250 jpeg.dest := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_dest_mgr));
7252 // seeting up custom functions
7253 with glBitmap_libJPEG_dest_mgr_ptr(jpeg.dest)^ do begin
7254 pub.init_destination := glBitmap_libJPEG_init_destination;
7255 pub.empty_output_buffer := glBitmap_libJPEG_empty_output_buffer;
7256 pub.term_destination := glBitmap_libJPEG_term_destination;
7258 pub.next_output_byte := @DestBuffer[1];
7259 pub.free_in_buffer := Length(DestBuffer);
7261 DestStream := aStream;
7264 // very important state
7265 jpeg.global_state := CSTATE_START;
7266 jpeg.image_width := Width;
7267 jpeg.image_height := Height;
7269 tfAlpha8ub1, tfLuminance8ub1: begin
7270 jpeg.input_components := 1;
7271 jpeg.in_color_space := JCS_GRAYSCALE;
7273 tfRGB8ub3, tfBGR8ub3: begin
7274 jpeg.input_components := 3;
7275 jpeg.in_color_space := JCS_RGB;
7279 jpeg_set_defaults(@jpeg);
7280 jpeg_set_quality(@jpeg, 95, true);
7281 jpeg_start_compress(@jpeg, true);
7284 if Format = tfBGR8ub3 then
7285 GetMem(pTemp2, fRowSize)
7290 for Row := 0 to jpeg.image_height -1 do begin
7292 if Format = tfBGR8ub3 then
7293 CopyRow(pTemp2, pTemp)
7298 jpeg_write_scanlines(@jpeg, @pTemp2, 1);
7299 inc(pTemp, fRowSize);
7303 if Format = tfBGR8ub3 then
7306 jpeg_finish_compress(@jpeg);
7307 jpeg_destroy_compress(@jpeg);
7313 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
7314 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7315 procedure TglBitmap.SaveJPEG(const aStream: TStream);
7320 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
7321 raise EglBitmapUnsupportedFormat.Create(Format);
7323 Bmp := TBitmap.Create;
7325 Jpg := TJPEGImage.Create;
7327 AssignToBitmap(Bmp);
7328 if (Format in [tfAlpha8ub1, tfLuminance8ub1]) then begin
7329 Jpg.Grayscale := true;
7330 Jpg.PixelFormat := jf8Bit;
7333 Jpg.SaveToStream(aStream);
7344 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7345 //RAW/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7346 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7348 RawHeader = packed record
7354 BitsPerPixel: Integer;
7355 Precision: TglBitmapRec4ub;
7356 Shift: TglBitmapRec4ub;
7359 function TglBitmap.LoadRAW(const aStream: TStream): Boolean;
7363 fd: TFormatDescriptor;
7367 StartPos := aStream.Position;
7368 aStream.Read(header{%H-}, SizeOf(header));
7369 if (header.Magic <> 'glBMP') then begin
7370 aStream.Position := StartPos;
7374 fd := TFormatDescriptor.GetFromPrecShift(header.Precision, header.Shift, header.BitsPerPixel);
7375 if (fd.Format = tfEmpty) then
7376 raise EglBitmapUnsupportedFormat.Create('no supported format found');
7378 buf := GetMemory(header.DataSize);
7379 aStream.Read(buf^, header.DataSize);
7380 SetDataPointer(buf, fd.Format, header.Width, header.Height);
7385 procedure TglBitmap.SaveRAW(const aStream: TStream);
7388 fd: TFormatDescriptor;
7390 fd := TFormatDescriptor.Get(Format);
7391 header.Magic := 'glBMP';
7392 header.Version := 1;
7393 header.Width := Width;
7394 header.Height := Height;
7395 header.DataSize := fd.GetSize(fDimension);
7396 header.BitsPerPixel := fd.BitsPerPixel;
7397 header.Precision := fd.Precision;
7398 header.Shift := fd.Shift;
7399 aStream.Write(header, SizeOf(header));
7400 aStream.Write(Data^, header.DataSize);
7403 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7404 //BMP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7405 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7412 BMP_COMP_BITFIELDS = 3;
7415 TBMPHeader = packed record
7420 bfOffBits: Cardinal;
7423 TBMPInfo = packed record
7429 biCompression: Cardinal;
7430 biSizeImage: Cardinal;
7431 biXPelsPerMeter: Longint;
7432 biYPelsPerMeter: Longint;
7433 biClrUsed: Cardinal;
7434 biClrImportant: Cardinal;
7437 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7438 function TglBitmap.LoadBMP(const aStream: TStream): Boolean;
7440 //////////////////////////////////////////////////////////////////////////////////////////////////
7441 function ReadInfo(out aInfo: TBMPInfo; out aMask: TglBitmapRec4ul): TglBitmapFormat;
7444 aStream.Read(aInfo{%H-}, SizeOf(aInfo));
7445 FillChar(aMask{%H-}, SizeOf(aMask), 0);
7448 case aInfo.biCompression of
7450 BMP_COMP_RLE8: begin
7451 raise EglBitmap.Create('RLE compression is not supported');
7453 BMP_COMP_BITFIELDS: begin
7454 if (aInfo.biBitCount = 16) or (aInfo.biBitCount = 32) then begin
7455 aStream.Read(aMask.r, SizeOf(aMask.r));
7456 aStream.Read(aMask.g, SizeOf(aMask.g));
7457 aStream.Read(aMask.b, SizeOf(aMask.b));
7458 aStream.Read(aMask.a, SizeOf(aMask.a));
7460 raise EglBitmap.Create('Bitfields are only supported for 16bit and 32bit formats');
7464 //get suitable format
7465 case aInfo.biBitCount of
7466 8: result := tfLuminance8ub1;
7467 16: result := tfX1RGB5us1;
7468 24: result := tfBGR8ub3;
7469 32: result := tfXRGB8ui1;
7473 function ReadColorTable(var aFormat: TglBitmapFormat; const aInfo: TBMPInfo): TbmpColorTableFormat;
7476 ColorTable: TbmpColorTable;
7479 if (aInfo.biBitCount >= 16) then
7481 aFormat := tfLuminance8ub1;
7482 c := aInfo.biClrUsed;
7484 c := 1 shl aInfo.biBitCount;
7485 SetLength(ColorTable, c);
7486 for i := 0 to c-1 do begin
7487 aStream.Read(ColorTable[i], SizeOf(TbmpColorTableEnty));
7488 if (ColorTable[i].r <> ColorTable[i].g) or (ColorTable[i].g <> ColorTable[i].b) then
7489 aFormat := tfRGB8ub3;
7492 result := TbmpColorTableFormat.Create;
7493 result.BitsPerPixel := aInfo.biBitCount;
7494 result.ColorTable := ColorTable;
7498 //////////////////////////////////////////////////////////////////////////////////////////////////
7499 function CheckBitfields(var aFormat: TglBitmapFormat; const aMask: TglBitmapRec4ul; const aInfo: TBMPInfo): TbmpBitfieldFormat;
7501 FormatDesc: TFormatDescriptor;
7504 if (aMask.r <> 0) or (aMask.g <> 0) or (aMask.b <> 0) or (aMask.a <> 0) then begin
7505 FormatDesc := TFormatDescriptor.GetFromMask(aMask);
7506 if (FormatDesc.Format = tfEmpty) then
7508 aFormat := FormatDesc.Format;
7509 if (aMask.a = 0) and TFormatDescriptor.Get(aFormat).HasAlpha then
7510 aFormat := TFormatDescriptor.Get(aFormat).WithoutAlpha;
7511 if (aMask.a <> 0) and not TFormatDescriptor.Get(aFormat).HasAlpha then
7512 aFormat := TFormatDescriptor.Get(aFormat).WithAlpha;
7514 result := TbmpBitfieldFormat.Create;
7515 result.SetCustomValues(aInfo.biBitCount, aMask);
7522 ImageSize, rbLineSize, wbLineSize, Padding, i: Integer;
7523 PaddingBuff: Cardinal;
7524 LineBuf, ImageData, TmpData: PByte;
7525 SourceMD, DestMD: Pointer;
7526 BmpFormat: TglBitmapFormat;
7529 Mask: TglBitmapRec4ul;
7534 SpecialFormat: TFormatDescriptor;
7535 FormatDesc: TFormatDescriptor;
7537 //////////////////////////////////////////////////////////////////////////////////////////////////
7538 procedure SpecialFormatReadLine(aData: PByte; aLineBuf: PByte);
7541 Pixel: TglBitmapPixelData;
7543 aStream.Read(aLineBuf^, rbLineSize);
7544 SpecialFormat.PreparePixel(Pixel);
7545 for i := 0 to Info.biWidth-1 do begin
7546 SpecialFormat.Unmap(aLineBuf, Pixel, SourceMD);
7547 glBitmapConvertPixel(Pixel, SpecialFormat, FormatDesc);
7548 FormatDesc.Map(Pixel, aData, DestMD);
7554 BmpFormat := tfEmpty;
7555 SpecialFormat := nil;
7561 StartPos := aStream.Position;
7562 aStream.Read(Header{%H-}, SizeOf(Header));
7564 if Header.bfType = BMP_MAGIC then begin
7566 BmpFormat := ReadInfo(Info, Mask);
7567 SpecialFormat := ReadColorTable(BmpFormat, Info);
7568 if not Assigned(SpecialFormat) then
7569 SpecialFormat := CheckBitfields(BmpFormat, Mask, Info);
7570 aStream.Position := StartPos + Header.bfOffBits;
7572 if (BmpFormat <> tfEmpty) then begin
7573 FormatDesc := TFormatDescriptor.Get(BmpFormat);
7574 rbLineSize := Round(Info.biWidth * Info.biBitCount / 8); //ReadBuffer LineSize
7575 wbLineSize := Trunc(Info.biWidth * FormatDesc.BytesPerPixel);
7576 Padding := (((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3) - rbLineSize;
7579 DestMD := FormatDesc.CreateMappingData;
7580 ImageSize := FormatDesc.GetSize(Info.biWidth, abs(Info.biHeight));
7581 GetMem(ImageData, ImageSize);
7582 if Assigned(SpecialFormat) then begin
7583 GetMem(LineBuf, rbLineSize); //tmp Memory for converting Bitfields
7584 SourceMD := SpecialFormat.CreateMappingData;
7589 FillChar(ImageData^, ImageSize, $FF);
7590 TmpData := ImageData;
7591 if (Info.biHeight > 0) then
7592 Inc(TmpData, wbLineSize * (Info.biHeight-1));
7593 for i := 0 to Abs(Info.biHeight)-1 do begin
7594 if Assigned(SpecialFormat) then
7595 SpecialFormatReadLine(TmpData, LineBuf) //if is special format read and convert data
7597 aStream.Read(TmpData^, wbLineSize); //else only read data
7598 if (Info.biHeight > 0) then
7599 dec(TmpData, wbLineSize)
7601 inc(TmpData, wbLineSize);
7602 aStream.Read(PaddingBuff{%H-}, Padding);
7604 SetDataPointer(ImageData, BmpFormat, Info.biWidth, abs(Info.biHeight)); //be careful, Data could be freed by this method
7607 if Assigned(LineBuf) then
7609 if Assigned(SourceMD) then
7610 SpecialFormat.FreeMappingData(SourceMD);
7611 FormatDesc.FreeMappingData(DestMD);
7614 if Assigned(ImageData) then
7619 raise EglBitmap.Create('LoadBMP - No suitable format found');
7621 aStream.Position := StartPos;
7625 FreeAndNil(SpecialFormat);
7628 else aStream.Position := StartPos;
7631 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7632 procedure TglBitmap.SaveBMP(const aStream: TStream);
7636 Converter: TFormatDescriptor;
7637 FormatDesc: TFormatDescriptor;
7638 SourceFD, DestFD: Pointer;
7639 pData, srcData, dstData, ConvertBuffer: pByte;
7641 Pixel: TglBitmapPixelData;
7642 ImageSize, wbLineSize, rbLineSize, Padding, LineIdx, PixelIdx: Integer;
7643 RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
7645 PaddingBuff: Cardinal;
7647 function GetLineWidth : Integer;
7649 result := ((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3;
7653 if not (ftBMP in FormatGetSupportedFiles(Format)) then
7654 raise EglBitmapUnsupportedFormat.Create(Format);
7657 FormatDesc := TFormatDescriptor.Get(Format);
7658 ImageSize := FormatDesc.GetSize(Dimension);
7660 FillChar(Header{%H-}, SizeOf(Header), 0);
7661 Header.bfType := BMP_MAGIC;
7662 Header.bfSize := SizeOf(Header) + SizeOf(Info) + ImageSize;
7663 Header.bfReserved1 := 0;
7664 Header.bfReserved2 := 0;
7665 Header.bfOffBits := SizeOf(Header) + SizeOf(Info);
7667 FillChar(Info{%H-}, SizeOf(Info), 0);
7668 Info.biSize := SizeOf(Info);
7669 Info.biWidth := Width;
7670 Info.biHeight := Height;
7672 Info.biCompression := BMP_COMP_RGB;
7673 Info.biSizeImage := ImageSize;
7677 tfAlpha4ub1, tfAlpha8ub1, tfLuminance4ub1, tfLuminance8ub1, tfR3G3B2ub1:
7679 Info.biBitCount := 8;
7680 Header.bfSize := Header.bfSize + 256 * SizeOf(Cardinal);
7681 Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal); //256 ColorTable entries
7682 Converter := TbmpColorTableFormat.Create;
7683 with (Converter as TbmpColorTableFormat) do begin
7684 SetCustomValues(fFormat, 1, FormatDesc.Precision, FormatDesc.Shift);
7689 tfLuminance4Alpha4ub2, tfLuminance6Alpha2ub2, tfLuminance8Alpha8ub2,
7690 tfRGBX4us1, tfXRGB4us1, tfRGB5X1us1, tfX1RGB5us1, tfR5G6B5us1, tfRGB5A1us1, tfA1RGB5us1, tfRGBA4us1, tfARGB4us1,
7691 tfBGRX4us1, tfXBGR4us1, tfBGR5X1us1, tfX1BGR5us1, tfB5G6R5us1, tfBGR5A1us1, tfA1BGR5us1, tfBGRA4us1, tfABGR4us1:
7693 Info.biBitCount := 16;
7694 Info.biCompression := BMP_COMP_BITFIELDS;
7697 tfBGR8ub3, tfRGB8ub3:
7699 Info.biBitCount := 24;
7700 if (Format = tfRGB8ub3) then
7701 Converter := TfdBGR8ub3.Create; //use BGR8 Format Descriptor to Swap RGB Values
7704 tfRGBX8ui1, tfXRGB8ui1, tfRGB10X2ui1, tfX2RGB10ui1, tfRGBA8ui1, tfARGB8ui1, tfRGBA8ub4, tfRGB10A2ui1, tfA2RGB10ui1,
7705 tfBGRX8ui1, tfXBGR8ui1, tfBGR10X2ui1, tfX2BGR10ui1, tfBGRA8ui1, tfABGR8ui1, tfBGRA8ub4, tfBGR10A2ui1, tfA2BGR10ui1:
7707 Info.biBitCount := 32;
7708 Info.biCompression := BMP_COMP_BITFIELDS;
7711 raise EglBitmapUnsupportedFormat.Create(Format);
7713 Info.biXPelsPerMeter := 2835;
7714 Info.biYPelsPerMeter := 2835;
7717 if Info.biCompression = BMP_COMP_BITFIELDS then begin
7718 Header.bfSize := Header.bfSize + 4 * SizeOf(Cardinal);
7719 Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal);
7721 RedMask := FormatDesc.Mask.r;
7722 GreenMask := FormatDesc.Mask.g;
7723 BlueMask := FormatDesc.Mask.b;
7724 AlphaMask := FormatDesc.Mask.a;
7728 aStream.Write(Header, SizeOf(Header));
7729 aStream.Write(Info, SizeOf(Info));
7732 if Assigned(Converter) and (Converter is TbmpColorTableFormat) then
7733 with (Converter as TbmpColorTableFormat) do
7734 aStream.Write(ColorTable[0].b,
7735 SizeOf(TbmpColorTableEnty) * Length(ColorTable));
7738 if Info.biCompression = BMP_COMP_BITFIELDS then begin
7739 aStream.Write(RedMask, SizeOf(Cardinal));
7740 aStream.Write(GreenMask, SizeOf(Cardinal));
7741 aStream.Write(BlueMask, SizeOf(Cardinal));
7742 aStream.Write(AlphaMask, SizeOf(Cardinal));
7746 rbLineSize := Round(Info.biWidth * FormatDesc.BytesPerPixel);
7747 wbLineSize := Round(Info.biWidth * Info.biBitCount / 8);
7748 Padding := GetLineWidth - wbLineSize;
7752 inc(pData, (Height-1) * rbLineSize);
7754 // prepare row buffer. But only for RGB because RGBA supports color masks
7755 // so it's possible to change color within the image.
7756 if Assigned(Converter) then begin
7757 FormatDesc.PreparePixel(Pixel);
7758 GetMem(ConvertBuffer, wbLineSize);
7759 SourceFD := FormatDesc.CreateMappingData;
7760 DestFD := Converter.CreateMappingData;
7762 ConvertBuffer := nil;
7765 for LineIdx := 0 to Height - 1 do begin
7767 if Assigned(Converter) then begin
7769 dstData := ConvertBuffer;
7770 for PixelIdx := 0 to Info.biWidth-1 do begin
7771 FormatDesc.Unmap(srcData, Pixel, SourceFD);
7772 glBitmapConvertPixel(Pixel, FormatDesc, Converter);
7773 Converter.Map(Pixel, dstData, DestFD);
7775 aStream.Write(ConvertBuffer^, wbLineSize);
7777 aStream.Write(pData^, rbLineSize);
7779 dec(pData, rbLineSize);
7780 if (Padding > 0) then
7781 aStream.Write(PaddingBuff, Padding);
7784 // destroy row buffer
7785 if Assigned(ConvertBuffer) then begin
7786 FormatDesc.FreeMappingData(SourceFD);
7787 Converter.FreeMappingData(DestFD);
7788 FreeMem(ConvertBuffer);
7792 if Assigned(Converter) then
7797 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7798 //TGA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7799 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7801 TTGAHeader = packed record
7805 //ColorMapSpec: Array[0..4] of Byte;
7806 ColorMapStart: Word;
7807 ColorMapLength: Word;
7808 ColorMapEntrySize: Byte;
7818 TGA_UNCOMPRESSED_RGB = 2;
7819 TGA_UNCOMPRESSED_GRAY = 3;
7820 TGA_COMPRESSED_RGB = 10;
7821 TGA_COMPRESSED_GRAY = 11;
7823 TGA_NONE_COLOR_TABLE = 0;
7825 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7826 function TglBitmap.LoadTGA(const aStream: TStream): Boolean;
7829 ImageData: System.PByte;
7830 StartPosition: Int64;
7831 PixelSize, LineSize: Integer;
7832 tgaFormat: TglBitmapFormat;
7833 FormatDesc: TFormatDescriptor;
7834 Counter: packed record
7836 low, high, dir: Integer;
7843 ////////////////////////////////////////////////////////////////////////////////////////
7844 procedure ReadUncompressed;
7847 buf, tmp1, tmp2: System.PByte;
7850 if (Counter.X.dir < 0) then
7851 GetMem(buf, LineSize);
7853 while (Counter.Y.low <> Counter.Y.high + counter.Y.dir) do begin
7855 inc(tmp1, (Counter.Y.low * LineSize)); //pointer to LineStart
7856 if (Counter.X.dir < 0) then begin //flip X
7857 aStream.Read(buf^, LineSize);
7859 inc(tmp2, LineSize - PixelSize); //pointer to last pixel in line
7860 for i := 0 to Header.Width-1 do begin //for all pixels in line
7861 for j := 0 to PixelSize-1 do begin //for all bytes in pixel
7866 dec(tmp2, 2*PixelSize); //move 2 backwards, because j-loop moved 1 forward
7869 aStream.Read(tmp1^, LineSize);
7870 inc(Counter.Y.low, Counter.Y.dir); //move to next line index
7873 if Assigned(buf) then
7878 ////////////////////////////////////////////////////////////////////////////////////////
7879 procedure ReadCompressed;
7881 /////////////////////////////////////////////////////////////////
7883 TmpData: System.PByte;
7884 LinePixelsRead: Integer;
7885 procedure CheckLine;
7887 if (LinePixelsRead >= Header.Width) then begin
7888 LinePixelsRead := 0;
7889 inc(Counter.Y.low, Counter.Y.dir); //next line index
7890 TmpData := ImageData;
7891 inc(TmpData, Counter.Y.low * LineSize); //set line
7892 if (Counter.X.dir < 0) then //if x flipped then
7893 inc(TmpData, LineSize - PixelSize); //set last pixel
7897 /////////////////////////////////////////////////////////////////
7900 CacheSize, CachePos: Integer;
7901 procedure CachedRead(out Buffer; Count: Integer);
7905 if (CachePos + Count > CacheSize) then begin
7906 //if buffer overflow save non read bytes
7908 if (CacheSize - CachePos > 0) then begin
7909 BytesRead := CacheSize - CachePos;
7910 Move(PByteArray(Cache)^[CachePos], Buffer{%H-}, BytesRead);
7911 inc(CachePos, BytesRead);
7914 //load cache from file
7915 CacheSize := Min(CACHE_SIZE, aStream.Size - aStream.Position);
7916 aStream.Read(Cache^, CacheSize);
7919 //read rest of requested bytes
7920 if (Count - BytesRead > 0) then begin
7921 Move(PByteArray(Cache)^[CachePos], TByteArray(Buffer)[BytesRead], Count - BytesRead);
7922 inc(CachePos, Count - BytesRead);
7925 //if no buffer overflow just read the data
7926 Move(PByteArray(Cache)^[CachePos], Buffer, Count);
7927 inc(CachePos, Count);
7931 procedure PixelToBuffer(const aData: PByte; var aBuffer: PByte);
7936 inc(aBuffer, Counter.X.dir);
7939 PWord(aBuffer)^ := PWord(aData)^;
7940 inc(aBuffer, 2 * Counter.X.dir);
7943 PByteArray(aBuffer)^[0] := PByteArray(aData)^[0];
7944 PByteArray(aBuffer)^[1] := PByteArray(aData)^[1];
7945 PByteArray(aBuffer)^[2] := PByteArray(aData)^[2];
7946 inc(aBuffer, 3 * Counter.X.dir);
7949 PCardinal(aBuffer)^ := PCardinal(aData)^;
7950 inc(aBuffer, 4 * Counter.X.dir);
7956 TotalPixelsToRead, TotalPixelsRead: Integer;
7958 buf: array [0..3] of Byte; //1 pixel is max 32bit long
7959 PixelRepeat: Boolean;
7960 PixelsToRead, PixelCount: Integer;
7965 TotalPixelsToRead := Header.Width * Header.Height;
7966 TotalPixelsRead := 0;
7967 LinePixelsRead := 0;
7969 GetMem(Cache, CACHE_SIZE);
7971 TmpData := ImageData;
7972 inc(TmpData, Counter.Y.low * LineSize); //set line
7973 if (Counter.X.dir < 0) then //if x flipped then
7974 inc(TmpData, LineSize - PixelSize); //set last pixel
7978 CachedRead(Temp, 1);
7979 PixelRepeat := (Temp and $80) > 0;
7980 PixelsToRead := (Temp and $7F) + 1;
7981 inc(TotalPixelsRead, PixelsToRead);
7984 CachedRead(buf[0], PixelSize);
7985 while (PixelsToRead > 0) do begin
7987 PixelCount := Min(Header.Width - LinePixelsRead, PixelsToRead); //max read to EOL or EOF
7988 while (PixelCount > 0) do begin
7989 if not PixelRepeat then
7990 CachedRead(buf[0], PixelSize);
7991 PixelToBuffer(@buf[0], TmpData);
7992 inc(LinePixelsRead);
7997 until (TotalPixelsRead >= TotalPixelsToRead);
8003 function IsGrayFormat: Boolean;
8005 result := Header.ImageType in [TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_GRAY];
8011 // reading header to test file and set cursor back to begin
8012 StartPosition := aStream.Position;
8013 aStream.Read(Header{%H-}, SizeOf(Header));
8015 // no colormapped files
8016 if (Header.ColorMapType = TGA_NONE_COLOR_TABLE) and (Header.ImageType in [
8017 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY]) then
8020 if Header.ImageID <> 0 then // skip image ID
8021 aStream.Position := aStream.Position + Header.ImageID;
8023 tgaFormat := tfEmpty;
8025 8: if IsGrayFormat then case (Header.ImageDesc and $F) of
8026 0: tgaFormat := tfLuminance8ub1;
8027 8: tgaFormat := tfAlpha8ub1;
8030 16: if IsGrayFormat then case (Header.ImageDesc and $F) of
8031 0: tgaFormat := tfLuminance16us1;
8032 8: tgaFormat := tfLuminance8Alpha8ub2;
8033 end else case (Header.ImageDesc and $F) of
8034 0: tgaFormat := tfX1RGB5us1;
8035 1: tgaFormat := tfA1RGB5us1;
8036 4: tgaFormat := tfARGB4us1;
8039 24: if not IsGrayFormat then case (Header.ImageDesc and $F) of
8040 0: tgaFormat := tfBGR8ub3;
8043 32: if IsGrayFormat then case (Header.ImageDesc and $F) of
8044 0: tgaFormat := tfDepth32ui1;
8045 end else case (Header.ImageDesc and $F) of
8046 0: tgaFormat := tfX2RGB10ui1;
8047 2: tgaFormat := tfA2RGB10ui1;
8048 8: tgaFormat := tfARGB8ui1;
8052 if (tgaFormat = tfEmpty) then
8053 raise EglBitmap.Create('LoadTga - unsupported format');
8055 FormatDesc := TFormatDescriptor.Get(tgaFormat);
8056 PixelSize := FormatDesc.GetSize(1, 1);
8057 LineSize := FormatDesc.GetSize(Header.Width, 1);
8059 GetMem(ImageData, LineSize * Header.Height);
8062 if ((Header.ImageDesc and (1 shl 4)) > 0) then begin
8063 Counter.X.low := Header.Height-1;;
8064 Counter.X.high := 0;
8065 Counter.X.dir := -1;
8068 Counter.X.high := Header.Height-1;
8073 if ((Header.ImageDesc and (1 shl 5)) > 0) then begin
8075 Counter.Y.high := Header.Height-1;
8078 Counter.Y.low := Header.Height-1;;
8079 Counter.Y.high := 0;
8080 Counter.Y.dir := -1;
8084 case Header.ImageType of
8085 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY:
8087 TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY:
8091 SetDataPointer(ImageData, tgaFormat, Header.Width, Header.Height); //be careful, Data could be freed by this method
8094 if Assigned(ImageData) then
8099 aStream.Position := StartPosition;
8102 else aStream.Position := StartPosition;
8105 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8106 procedure TglBitmap.SaveTGA(const aStream: TStream);
8110 FormatDesc: TFormatDescriptor;
8112 if not (ftTGA in FormatGetSupportedFiles(Format)) then
8113 raise EglBitmapUnsupportedFormat.Create(Format);
8116 FormatDesc := TFormatDescriptor.Get(Format);
8117 FillChar(Header{%H-}, SizeOf(Header), 0);
8118 Header.ImageDesc := CountSetBits(FormatDesc.Range.a) and $F;
8119 Header.Bpp := FormatDesc.BitsPerPixel;
8120 Header.Width := Width;
8121 Header.Height := Height;
8122 Header.ImageDesc := Header.ImageDesc or $20; //flip y
8123 if FormatDesc.IsGrayscale or (not FormatDesc.IsGrayscale and not FormatDesc.HasRed and FormatDesc.HasAlpha) then
8124 Header.ImageType := TGA_UNCOMPRESSED_GRAY
8126 Header.ImageType := TGA_UNCOMPRESSED_RGB;
8127 aStream.Write(Header, SizeOf(Header));
8130 Size := FormatDesc.GetSize(Dimension);
8131 aStream.Write(Data^, Size);
8134 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8135 //DDS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8136 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8138 DDS_MAGIC: Cardinal = $20534444;
8140 // DDS_header.dwFlags
8141 DDSD_CAPS = $00000001;
8142 DDSD_HEIGHT = $00000002;
8143 DDSD_WIDTH = $00000004;
8144 DDSD_PIXELFORMAT = $00001000;
8146 // DDS_header.sPixelFormat.dwFlags
8147 DDPF_ALPHAPIXELS = $00000001;
8148 DDPF_ALPHA = $00000002;
8149 DDPF_FOURCC = $00000004;
8150 DDPF_RGB = $00000040;
8151 DDPF_LUMINANCE = $00020000;
8153 // DDS_header.sCaps.dwCaps1
8154 DDSCAPS_TEXTURE = $00001000;
8156 // DDS_header.sCaps.dwCaps2
8157 DDSCAPS2_CUBEMAP = $00000200;
8159 D3DFMT_DXT1 = $31545844;
8160 D3DFMT_DXT3 = $33545844;
8161 D3DFMT_DXT5 = $35545844;
8164 TDDSPixelFormat = packed record
8168 dwRGBBitCount: Cardinal;
8169 dwRBitMask: Cardinal;
8170 dwGBitMask: Cardinal;
8171 dwBBitMask: Cardinal;
8172 dwABitMask: Cardinal;
8175 TDDSCaps = packed record
8179 dwReserved: Cardinal;
8182 TDDSHeader = packed record
8187 dwPitchOrLinearSize: Cardinal;
8189 dwMipMapCount: Cardinal;
8190 dwReserved: array[0..10] of Cardinal;
8191 PixelFormat: TDDSPixelFormat;
8193 dwReserved2: Cardinal;
8196 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8197 function TglBitmap.LoadDDS(const aStream: TStream): Boolean;
8200 Converter: TbmpBitfieldFormat;
8202 function GetDDSFormat: TglBitmapFormat;
8204 fd: TFormatDescriptor;
8206 Mask: TglBitmapRec4ul;
8207 Range: TglBitmapRec4ui;
8211 with Header.PixelFormat do begin
8213 if ((dwFlags and DDPF_FOURCC) > 0) then begin
8214 case Header.PixelFormat.dwFourCC of
8215 D3DFMT_DXT1: result := tfS3tcDtx1RGBA;
8216 D3DFMT_DXT3: result := tfS3tcDtx3RGBA;
8217 D3DFMT_DXT5: result := tfS3tcDtx5RGBA;
8219 end else if ((dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE or DDPF_ALPHA)) > 0) then begin
8221 if ((dwFlags and DDPF_LUMINANCE) = 0) then begin
8222 Mask.r := dwRBitMask;
8223 Mask.g := dwGBitMask;
8224 Mask.b := dwBBitMask;
8226 Mask.r := dwRBitMask;
8227 Mask.g := dwRBitMask;
8228 Mask.b := dwRBitMask;
8230 if (dwFlags and DDPF_ALPHAPIXELS > 0) then
8231 Mask.a := dwABitMask
8235 //find matching format
8236 fd := TFormatDescriptor.GetFromMask(Mask, dwRGBBitCount);
8237 result := fd.Format;
8238 if (result <> tfEmpty) then
8241 //find format with same Range
8243 Range.arr[i] := (2 shl CountSetBits(Mask.arr[i])) - 1;
8244 for result := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
8245 fd := TFormatDescriptor.Get(result);
8248 if (fd.Range.arr[i] <> Range.arr[i]) then begin
8256 //no format with same range found -> use default
8257 if (result = tfEmpty) then begin
8258 if (dwABitMask > 0) then
8259 result := tfRGBA8ui1
8261 result := tfRGB8ub3;
8264 Converter := TbmpBitfieldFormat.Create;
8265 Converter.SetCustomValues(dwRGBBitCount, glBitmapRec4ul(dwRBitMask, dwGBitMask, dwBBitMask, dwABitMask));
8272 x, y, LineSize, RowSize, Magic: Cardinal;
8273 NewImage, TmpData, RowData, SrcData: System.PByte;
8274 SourceMD, DestMD: Pointer;
8275 Pixel: TglBitmapPixelData;
8276 ddsFormat: TglBitmapFormat;
8277 FormatDesc: TFormatDescriptor;
8282 StreamPos := aStream.Position;
8285 aStream.Read(Magic{%H-}, sizeof(Magic));
8286 if (Magic <> DDS_MAGIC) then begin
8287 aStream.Position := StreamPos;
8292 aStream.Read(Header{%H-}, sizeof(Header));
8293 if (Header.dwSize <> SizeOf(Header)) or
8294 ((Header.dwFlags and (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) <>
8295 (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) then
8297 aStream.Position := StreamPos;
8301 if ((Header.Caps.dwCaps1 and DDSCAPS2_CUBEMAP) > 0) then
8302 raise EglBitmap.Create('LoadDDS - CubeMaps are not supported');
8304 ddsFormat := GetDDSFormat;
8306 if (ddsFormat = tfEmpty) then
8307 raise EglBitmap.Create('LoadDDS - unsupported Pixelformat found.');
8309 FormatDesc := TFormatDescriptor.Get(ddsFormat);
8310 LineSize := Trunc(Header.dwWidth * FormatDesc.BytesPerPixel);
8311 GetMem(NewImage, Header.dwHeight * LineSize);
8313 TmpData := NewImage;
8316 if Assigned(Converter) then begin
8317 RowSize := Round(Header.dwWidth * Header.PixelFormat.dwRGBBitCount / 8);
8318 GetMem(RowData, RowSize);
8319 SourceMD := Converter.CreateMappingData;
8320 DestMD := FormatDesc.CreateMappingData;
8322 for y := 0 to Header.dwHeight-1 do begin
8323 TmpData := NewImage;
8324 inc(TmpData, y * LineSize);
8326 aStream.Read(SrcData^, RowSize);
8327 for x := 0 to Header.dwWidth-1 do begin
8328 Converter.Unmap(SrcData, Pixel, SourceMD);
8329 glBitmapConvertPixel(Pixel, Converter, FormatDesc);
8330 FormatDesc.Map(Pixel, TmpData, DestMD);
8334 Converter.FreeMappingData(SourceMD);
8335 FormatDesc.FreeMappingData(DestMD);
8341 if ((Header.PixelFormat.dwFlags and DDPF_FOURCC) > 0) then begin
8342 RowSize := Header.dwPitchOrLinearSize div Header.dwWidth;
8343 for Y := 0 to Header.dwHeight-1 do begin
8344 aStream.Read(TmpData^, RowSize);
8345 Inc(TmpData, LineSize);
8350 if (Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE)) > 0 then begin
8351 RowSize := (Header.PixelFormat.dwRGBBitCount * Header.dwWidth) shr 3;
8352 for Y := 0 to Header.dwHeight-1 do begin
8353 aStream.Read(TmpData^, RowSize);
8354 Inc(TmpData, LineSize);
8357 raise EglBitmap.Create('LoadDDS - unsupported Pixelformat found.');
8359 SetDataPointer(NewImage, ddsFormat, Header.dwWidth, Header.dwHeight); //be careful, Data could be freed by this method
8362 if Assigned(NewImage) then
8367 FreeAndNil(Converter);
8371 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8372 procedure TglBitmap.SaveDDS(const aStream: TStream);
8375 FormatDesc: TFormatDescriptor;
8377 if not (ftDDS in FormatGetSupportedFiles(Format)) then
8378 raise EglBitmapUnsupportedFormat.Create(Format);
8380 FormatDesc := TFormatDescriptor.Get(Format);
8383 FillChar(Header{%H-}, SizeOf(Header), 0);
8384 Header.dwSize := SizeOf(Header);
8385 Header.dwFlags := DDSD_WIDTH or DDSD_HEIGHT or DDSD_CAPS or DDSD_PIXELFORMAT;
8387 Header.dwWidth := Max(1, Width);
8388 Header.dwHeight := Max(1, Height);
8391 Header.Caps.dwCaps1 := DDSCAPS_TEXTURE;
8394 Header.PixelFormat.dwSize := sizeof(Header);
8395 if (FormatDesc.IsCompressed) then begin
8396 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_FOURCC;
8398 tfS3tcDtx1RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT1;
8399 tfS3tcDtx3RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT3;
8400 tfS3tcDtx5RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT5;
8402 end else if not FormatDesc.HasColor and FormatDesc.HasAlpha then begin
8403 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHA;
8404 Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
8405 Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
8406 end else if FormatDesc.IsGrayscale then begin
8407 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_LUMINANCE;
8408 Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
8409 Header.PixelFormat.dwRBitMask := FormatDesc.Mask.r;
8410 Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
8412 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_RGB;
8413 Header.PixelFormat.dwRGBBitCount := FormatDesc.BitsPerPixel;
8414 Header.PixelFormat.dwRBitMask := FormatDesc.Mask.r;
8415 Header.PixelFormat.dwGBitMask := FormatDesc.Mask.g;
8416 Header.PixelFormat.dwBBitMask := FormatDesc.Mask.b;
8417 Header.PixelFormat.dwABitMask := FormatDesc.Mask.a;
8420 if (FormatDesc.HasAlpha) then
8421 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHAPIXELS;
8423 aStream.Write(DDS_MAGIC, sizeof(DDS_MAGIC));
8424 aStream.Write(Header, SizeOf(Header));
8425 aStream.Write(Data^, FormatDesc.GetSize(Dimension));
8429 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8430 //TglBitmap1D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8431 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8432 procedure TglBitmap1D.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
8433 const aWidth: Integer; const aHeight: Integer);
8438 if (aHeight > 1) then begin
8439 Size := TFormatDescriptor.Get(aFormat).GetSize(aWidth, 1);
8440 GetMem(pTemp, Size);
8442 Move(aData^, pTemp^, Size);
8451 inherited SetDataPointer(pTemp, aFormat, aWidth);
8454 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8455 function TglBitmap1D.FlipHorz: Boolean;
8458 pTempDest, pDest, pSource: PByte;
8460 result := inherited FlipHorz;
8461 if Assigned(Data) and not TFormatDescriptor.Get(Format).IsCompressed then begin
8463 GetMem(pDest, fRowSize);
8466 Inc(pTempDest, fRowSize);
8467 for Col := 0 to Width-1 do begin
8468 dec(pTempDest, fPixelSize); //dec before, because ptr is behind last byte of data
8469 Move(pSource^, pTempDest^, fPixelSize);
8470 Inc(pSource, fPixelSize);
8472 SetDataPointer(pDest, Format, Width); //be careful, Data could be freed by this method
8475 if Assigned(pDest) then
8482 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8483 procedure TglBitmap1D.UploadData(const aBuildWithGlu: Boolean);
8485 FormatDesc: TFormatDescriptor;
8488 FormatDesc := TFormatDescriptor.Get(Format);
8489 if (FormatDesc.glInternalFormat = 0) or (FormatDesc.glDataFormat = 0) then
8490 raise EglBitmap.Create('format is not supported by video adapter, please convert before uploading data');
8492 if FormatDesc.IsCompressed then begin
8493 if not Assigned(glCompressedTexImage1D) then
8494 raise EglBitmap.Create('compressed formats not supported by video adapter');
8495 glCompressedTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.GetSize(Width, 1), Data)
8496 end else if aBuildWithGlu then
8497 gluBuild1DMipmaps(Target, FormatDesc.glInternalFormat, Width, FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
8499 glTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
8502 if (FreeDataAfterGenTexture) then
8506 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8507 procedure TglBitmap1D.GenTexture(const aTestTextureSize: Boolean);
8509 BuildWithGlu, TexRec: Boolean;
8512 if Assigned(Data) then begin
8513 // Check Texture Size
8514 if (aTestTextureSize) then begin
8515 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
8517 if (Width > TexSize) then
8518 raise EglBitmapSizeToLarge.Create('TglBitmap1D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
8520 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and
8521 (Target = GL_TEXTURE_RECTANGLE);
8522 if not (IsPowerOfTwo(Width) or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
8523 raise EglBitmapNonPowerOfTwo.Create('TglBitmap1D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8527 SetupParameters(BuildWithGlu);
8528 UploadData(BuildWithGlu);
8529 glAreTexturesResident(1, @fID, @fIsResident);
8533 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8534 procedure TglBitmap1D.AfterConstruction;
8537 Target := GL_TEXTURE_1D;
8541 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8542 //TglBitmap2D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8543 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8544 function TglBitmap2D.GetScanline(const aIndex: Integer): Pointer;
8546 if (aIndex >= Low(fLines)) and (aIndex <= High(fLines)) then
8547 result := fLines[aIndex]
8552 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8553 procedure TglBitmap2D.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
8554 const aWidth: Integer; const aHeight: Integer);
8556 Idx, LineWidth: Integer;
8558 inherited SetDataPointer(aData, aFormat, aWidth, aHeight);
8560 if not TFormatDescriptor.Get(aFormat).IsCompressed then begin
8562 if Assigned(Data) then begin
8563 SetLength(fLines, GetHeight);
8564 LineWidth := Trunc(GetWidth * TFormatDescriptor.Get(Format).BytesPerPixel);
8566 for Idx := 0 to GetHeight-1 do begin
8567 fLines[Idx] := Data;
8568 Inc(fLines[Idx], Idx * LineWidth);
8571 else SetLength(fLines, 0);
8573 SetLength(fLines, 0);
8577 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8578 procedure TglBitmap2D.UploadData(const aTarget: GLenum{$IFNDEF OPENGL_ES}; const aBuildWithGlu: Boolean{$ENDIF});
8580 FormatDesc: TFormatDescriptor;
8582 FormatDesc := TFormatDescriptor.Get(Format);
8583 if (FormatDesc.glInternalFormat = 0) or (FormatDesc.glDataFormat = 0) then
8584 raise EglBitmap.Create('format is not supported by video adapter, please convert before uploading data');
8586 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
8588 if FormatDesc.IsCompressed then begin
8589 if not Assigned(glCompressedTexImage2D) then
8590 raise EglBitmap.Create('compressed formats not supported by video adapter');
8591 glCompressedTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0, FormatDesc.GetSize(fDimension), Data)
8593 end else if aBuildWithGlu then begin
8594 gluBuild2DMipmaps(aTarget, FormatDesc.ChannelCount, Width, Height,
8595 FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
8598 glTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0,
8599 FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
8603 if (FreeDataAfterGenTexture) then
8607 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8608 procedure TglBitmap2D.AfterConstruction;
8611 Target := GL_TEXTURE_2D;
8614 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8615 procedure TglBitmap2D.GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
8618 Size, w, h: Integer;
8619 FormatDesc: TFormatDescriptor;
8621 FormatDesc := TFormatDescriptor.Get(aFormat);
8622 if FormatDesc.IsCompressed then
8623 raise EglBitmapUnsupportedFormat.Create(aFormat);
8625 w := aRight - aLeft;
8626 h := aBottom - aTop;
8627 Size := FormatDesc.GetSize(w, h);
8630 glPixelStorei(GL_PACK_ALIGNMENT, 1);
8631 glReadPixels(aLeft, aTop, w, h, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
8632 SetDataPointer(Temp, aFormat, w, h); //be careful, Data could be freed by this method
8635 if Assigned(Temp) then
8642 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8643 procedure TglBitmap2D.GetDataFromTexture;
8646 TempWidth, TempHeight: Integer;
8647 TempIntFormat: GLint;
8648 IntFormat: TglBitmapFormat;
8649 FormatDesc: TFormatDescriptor;
8654 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_WIDTH, @TempWidth);
8655 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT, @TempHeight);
8656 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat);
8658 FormatDesc := (TglBitmapFormatDescriptor.GetByFormat(TempIntFormat) as TFormatDescriptor);
8659 IntFormat := FormatDesc.Format;
8661 // Getting data from OpenGL
8662 FormatDesc := TFormatDescriptor.Get(IntFormat);
8663 GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight));
8665 if FormatDesc.IsCompressed then begin
8666 if not Assigned(glGetCompressedTexImage) then
8667 raise EglBitmap.Create('compressed formats not supported by video adapter');
8668 glGetCompressedTexImage(Target, 0, Temp)
8670 glGetTexImage(Target, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
8671 SetDataPointer(Temp, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
8673 if Assigned(Temp) then
8680 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8681 procedure TglBitmap2D.GenTexture(const aTestTextureSize: Boolean);
8684 BuildWithGlu, TexRec: Boolean;
8689 if Assigned(Data) then begin
8690 // Check Texture Size
8691 if (aTestTextureSize) then begin
8692 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
8694 if ((Height > TexSize) or (Width > TexSize)) then
8695 raise EglBitmapSizeToLarge.Create('TglBitmap2D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
8697 PotTex := IsPowerOfTwo(Height) and IsPowerOfTwo(Width);
8698 {$IF NOT DEFINED(OPENGL_ES)}
8699 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and (Target = GL_TEXTURE_RECTANGLE);
8700 if not (PotTex or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
8701 raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8702 {$ELSEIF DEFINED(OPENGL_ES_EXT)}
8703 if not PotTex and not GL_OES_texture_npot then
8704 raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8707 raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8712 SetupParameters({$IFNDEF OPENGL_ES}BuildWithGlu{$ENDIF});
8713 UploadData(Target{$IFNDEF OPENGL_ES}, BuildWithGlu{$ENDIF});
8715 glAreTexturesResident(1, @fID, @fIsResident);
8720 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8721 function TglBitmap2D.FlipHorz: Boolean;
8724 TempDestData, DestData, SourceData: PByte;
8727 result := inherited FlipHorz;
8728 if Assigned(Data) then begin
8730 ImgSize := Height * fRowSize;
8731 GetMem(DestData, ImgSize);
8733 TempDestData := DestData;
8734 Dec(TempDestData, fRowSize + fPixelSize);
8735 for Row := 0 to Height -1 do begin
8736 Inc(TempDestData, fRowSize * 2);
8737 for Col := 0 to Width -1 do begin
8738 Move(SourceData^, TempDestData^, fPixelSize);
8739 Inc(SourceData, fPixelSize);
8740 Dec(TempDestData, fPixelSize);
8743 SetDataPointer(DestData, Format, Width, Height); //be careful, Data could be freed by this method
8746 if Assigned(DestData) then
8753 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8754 function TglBitmap2D.FlipVert: Boolean;
8757 TempDestData, DestData, SourceData: PByte;
8759 result := inherited FlipVert;
8760 if Assigned(Data) then begin
8762 GetMem(DestData, Height * fRowSize);
8764 TempDestData := DestData;
8765 Inc(TempDestData, Width * (Height -1) * fPixelSize);
8766 for Row := 0 to Height -1 do begin
8767 Move(SourceData^, TempDestData^, fRowSize);
8768 Dec(TempDestData, fRowSize);
8769 Inc(SourceData, fRowSize);
8771 SetDataPointer(DestData, Format, Width, Height); //be careful, Data could be freed by this method
8774 if Assigned(DestData) then
8781 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8782 //TglBitmap2D - ToNormalMap///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8783 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8785 TMatrixItem = record
8790 PglBitmapToNormalMapRec = ^TglBitmapToNormalMapRec;
8791 TglBitmapToNormalMapRec = Record
8793 Heights: array of Single;
8794 MatrixU : array of TMatrixItem;
8795 MatrixV : array of TMatrixItem;
8799 ONE_OVER_255 = 1 / 255;
8801 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8802 procedure glBitmapToNormalMapPrepareFunc(var FuncRec: TglBitmapFunctionRec);
8806 with FuncRec do begin
8808 Source.Data.r * LUMINANCE_WEIGHT_R +
8809 Source.Data.g * LUMINANCE_WEIGHT_G +
8810 Source.Data.b * LUMINANCE_WEIGHT_B;
8811 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Val * ONE_OVER_255;
8815 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8816 procedure glBitmapToNormalMapPrepareAlphaFunc(var FuncRec: TglBitmapFunctionRec);
8819 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Source.Data.a * ONE_OVER_255;
8822 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8823 procedure glBitmapToNormalMapFunc (var FuncRec: TglBitmapFunctionRec);
8825 TVec = Array[0..2] of Single;
8832 function GetHeight(X, Y: Integer): Single;
8834 with FuncRec do begin
8835 X := Max(0, Min(Size.X -1, X));
8836 Y := Max(0, Min(Size.Y -1, Y));
8837 result := PglBitmapToNormalMapRec(Args)^.Heights[Y * Size.X + X];
8842 with FuncRec do begin
8843 with PglBitmapToNormalMapRec(Args)^ do begin
8845 for Idx := Low(MatrixU) to High(MatrixU) do
8846 du := du + GetHeight(Position.X + MatrixU[Idx].X, Position.Y + MatrixU[Idx].Y) * MatrixU[Idx].W;
8849 for Idx := Low(MatrixU) to High(MatrixU) do
8850 dv := dv + GetHeight(Position.X + MatrixV[Idx].X, Position.Y + MatrixV[Idx].Y) * MatrixV[Idx].W;
8852 Vec[0] := -du * Scale;
8853 Vec[1] := -dv * Scale;
8858 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
8859 if Len <> 0 then begin
8860 Vec[0] := Vec[0] * Len;
8861 Vec[1] := Vec[1] * Len;
8862 Vec[2] := Vec[2] * Len;
8866 Dest.Data.r := Trunc((Vec[0] + 1) * 127.5);
8867 Dest.Data.g := Trunc((Vec[1] + 1) * 127.5);
8868 Dest.Data.b := Trunc((Vec[2] + 1) * 127.5);
8872 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8873 procedure TglBitmap2D.ToNormalMap(const aFunc: TglBitmapNormalMapFunc; const aScale: Single; const aUseAlpha: Boolean);
8875 Rec: TglBitmapToNormalMapRec;
8877 procedure SetEntry (var Matrix: array of TMatrixItem; Index, X, Y: Integer; W: Single);
8879 if (Index >= Low(Matrix)) and (Index <= High(Matrix)) then begin
8880 Matrix[Index].X := X;
8881 Matrix[Index].Y := Y;
8882 Matrix[Index].W := W;
8887 if TFormatDescriptor.Get(Format).IsCompressed then
8888 raise EglBitmapUnsupportedFormat.Create(Format);
8890 if aScale > 100 then
8892 else if aScale < -100 then
8895 Rec.Scale := aScale;
8897 SetLength(Rec.Heights, Width * Height);
8901 SetLength(Rec.MatrixU, 2);
8902 SetEntry(Rec.MatrixU, 0, -1, 0, -0.5);
8903 SetEntry(Rec.MatrixU, 1, 1, 0, 0.5);
8905 SetLength(Rec.MatrixV, 2);
8906 SetEntry(Rec.MatrixV, 0, 0, 1, 0.5);
8907 SetEntry(Rec.MatrixV, 1, 0, -1, -0.5);
8911 SetLength(Rec.MatrixU, 6);
8912 SetEntry(Rec.MatrixU, 0, -1, 1, -1.0);
8913 SetEntry(Rec.MatrixU, 1, -1, 0, -2.0);
8914 SetEntry(Rec.MatrixU, 2, -1, -1, -1.0);
8915 SetEntry(Rec.MatrixU, 3, 1, 1, 1.0);
8916 SetEntry(Rec.MatrixU, 4, 1, 0, 2.0);
8917 SetEntry(Rec.MatrixU, 5, 1, -1, 1.0);
8919 SetLength(Rec.MatrixV, 6);
8920 SetEntry(Rec.MatrixV, 0, -1, 1, 1.0);
8921 SetEntry(Rec.MatrixV, 1, 0, 1, 2.0);
8922 SetEntry(Rec.MatrixV, 2, 1, 1, 1.0);
8923 SetEntry(Rec.MatrixV, 3, -1, -1, -1.0);
8924 SetEntry(Rec.MatrixV, 4, 0, -1, -2.0);
8925 SetEntry(Rec.MatrixV, 5, 1, -1, -1.0);
8929 SetLength(Rec.MatrixU, 6);
8930 SetEntry(Rec.MatrixU, 0, -1, 1, -1/6);
8931 SetEntry(Rec.MatrixU, 1, -1, 0, -1/6);
8932 SetEntry(Rec.MatrixU, 2, -1, -1, -1/6);
8933 SetEntry(Rec.MatrixU, 3, 1, 1, 1/6);
8934 SetEntry(Rec.MatrixU, 4, 1, 0, 1/6);
8935 SetEntry(Rec.MatrixU, 5, 1, -1, 1/6);
8937 SetLength(Rec.MatrixV, 6);
8938 SetEntry(Rec.MatrixV, 0, -1, 1, 1/6);
8939 SetEntry(Rec.MatrixV, 1, 0, 1, 1/6);
8940 SetEntry(Rec.MatrixV, 2, 1, 1, 1/6);
8941 SetEntry(Rec.MatrixV, 3, -1, -1, -1/6);
8942 SetEntry(Rec.MatrixV, 4, 0, -1, -1/6);
8943 SetEntry(Rec.MatrixV, 5, 1, -1, -1/6);
8947 SetLength(Rec.MatrixU, 20);
8948 SetEntry(Rec.MatrixU, 0, -2, 2, -1 / 16);
8949 SetEntry(Rec.MatrixU, 1, -1, 2, -1 / 10);
8950 SetEntry(Rec.MatrixU, 2, 1, 2, 1 / 10);
8951 SetEntry(Rec.MatrixU, 3, 2, 2, 1 / 16);
8952 SetEntry(Rec.MatrixU, 4, -2, 1, -1 / 10);
8953 SetEntry(Rec.MatrixU, 5, -1, 1, -1 / 8);
8954 SetEntry(Rec.MatrixU, 6, 1, 1, 1 / 8);
8955 SetEntry(Rec.MatrixU, 7, 2, 1, 1 / 10);
8956 SetEntry(Rec.MatrixU, 8, -2, 0, -1 / 2.8);
8957 SetEntry(Rec.MatrixU, 9, -1, 0, -0.5);
8958 SetEntry(Rec.MatrixU, 10, 1, 0, 0.5);
8959 SetEntry(Rec.MatrixU, 11, 2, 0, 1 / 2.8);
8960 SetEntry(Rec.MatrixU, 12, -2, -1, -1 / 10);
8961 SetEntry(Rec.MatrixU, 13, -1, -1, -1 / 8);
8962 SetEntry(Rec.MatrixU, 14, 1, -1, 1 / 8);
8963 SetEntry(Rec.MatrixU, 15, 2, -1, 1 / 10);
8964 SetEntry(Rec.MatrixU, 16, -2, -2, -1 / 16);
8965 SetEntry(Rec.MatrixU, 17, -1, -2, -1 / 10);
8966 SetEntry(Rec.MatrixU, 18, 1, -2, 1 / 10);
8967 SetEntry(Rec.MatrixU, 19, 2, -2, 1 / 16);
8969 SetLength(Rec.MatrixV, 20);
8970 SetEntry(Rec.MatrixV, 0, -2, 2, 1 / 16);
8971 SetEntry(Rec.MatrixV, 1, -1, 2, 1 / 10);
8972 SetEntry(Rec.MatrixV, 2, 0, 2, 0.25);
8973 SetEntry(Rec.MatrixV, 3, 1, 2, 1 / 10);
8974 SetEntry(Rec.MatrixV, 4, 2, 2, 1 / 16);
8975 SetEntry(Rec.MatrixV, 5, -2, 1, 1 / 10);
8976 SetEntry(Rec.MatrixV, 6, -1, 1, 1 / 8);
8977 SetEntry(Rec.MatrixV, 7, 0, 1, 0.5);
8978 SetEntry(Rec.MatrixV, 8, 1, 1, 1 / 8);
8979 SetEntry(Rec.MatrixV, 9, 2, 1, 1 / 16);
8980 SetEntry(Rec.MatrixV, 10, -2, -1, -1 / 16);
8981 SetEntry(Rec.MatrixV, 11, -1, -1, -1 / 8);
8982 SetEntry(Rec.MatrixV, 12, 0, -1, -0.5);
8983 SetEntry(Rec.MatrixV, 13, 1, -1, -1 / 8);
8984 SetEntry(Rec.MatrixV, 14, 2, -1, -1 / 10);
8985 SetEntry(Rec.MatrixV, 15, -2, -2, -1 / 16);
8986 SetEntry(Rec.MatrixV, 16, -1, -2, -1 / 10);
8987 SetEntry(Rec.MatrixV, 17, 0, -2, -0.25);
8988 SetEntry(Rec.MatrixV, 18, 1, -2, -1 / 10);
8989 SetEntry(Rec.MatrixV, 19, 2, -2, -1 / 16);
8994 if aUseAlpha and TFormatDescriptor.Get(Format).HasAlpha then
8995 AddFunc(glBitmapToNormalMapPrepareAlphaFunc, false, @Rec)
8997 AddFunc(glBitmapToNormalMapPrepareFunc, false, @Rec);
8998 AddFunc(glBitmapToNormalMapFunc, false, @Rec);
9000 SetLength(Rec.Heights, 0);
9004 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
9005 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9006 //TglBitmapCubeMap////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9007 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9008 procedure TglBitmapCubeMap.GenTexture(const aTestTextureSize: Boolean);
9010 Assert(false, 'TglBitmapCubeMap.GenTexture - Don''t call GenTextures directly.');
9013 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9014 procedure TglBitmapCubeMap.AfterConstruction;
9019 if not (GL_VERSION_1_3 or GL_ARB_texture_cube_map or GL_EXT_texture_cube_map) then
9020 raise EglBitmap.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
9022 if not (GL_VERSION_2_0) then
9023 raise EglBitmap.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
9027 Target := GL_TEXTURE_CUBE_MAP;
9029 fGenMode := GL_REFLECTION_MAP;
9033 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9034 procedure TglBitmapCubeMap.GenerateCubeMap(const aCubeTarget: Cardinal; const aTestTextureSize: Boolean);
9037 BuildWithGlu: Boolean;
9041 if (aTestTextureSize) then begin
9042 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, @TexSize);
9044 if (Height > TexSize) or (Width > TexSize) then
9045 raise EglBitmapSizeToLarge.Create('TglBitmapCubeMap.GenerateCubeMap - The size for the Cubemap is to large. It''s may be not conform with the Hardware.');
9047 {$IF NOT DEFINED(OPENGL_ES)}
9048 if not ((IsPowerOfTwo(Height) and IsPowerOfTwo(Width)) or GL_VERSION_2_0 or GL_ARB_texture_non_power_of_two) then
9049 raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenerateCubeMap - Cubemaps dosn''t support non power of two texture.');
9050 {$ELSEIF DEFINED(OPENGL_ES_EXT)}
9051 if not (IsPowerOfTwo(Height) and IsPowerOfTwo(Width)) and not GL_OES_texture_npot then
9052 raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenerateCubeMap - Cubemaps dosn''t support non power of two texture.');
9054 if not (IsPowerOfTwo(Height) and IsPowerOfTwo(Width)) then
9055 raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenerateCubeMap - Cubemaps dosn''t support non power of two texture.');
9061 SetupParameters({$IFNDEF OPENGL_ES}BuildWithGlu{$ENDIF});
9062 UploadData(aCubeTarget{$IFNDEF OPENGL_ES}, BuildWithGlu{$ENDIF});
9065 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9066 procedure TglBitmapCubeMap.Bind({$IFNDEF OPENGL_ES}const aEnableTexCoordsGen: Boolean;{$ENDIF} const aEnableTextureUnit: Boolean);
9068 inherited Bind (aEnableTextureUnit);
9070 if aEnableTexCoordsGen then begin
9071 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, fGenMode);
9072 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, fGenMode);
9073 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, fGenMode);
9074 glEnable(GL_TEXTURE_GEN_S);
9075 glEnable(GL_TEXTURE_GEN_T);
9076 glEnable(GL_TEXTURE_GEN_R);
9081 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9082 procedure TglBitmapCubeMap.Unbind({$IFNDEF OPENGL_ES}const aDisableTexCoordsGen: Boolean;{$ENDIF} const aDisableTextureUnit: Boolean);
9084 inherited Unbind(aDisableTextureUnit);
9086 if aDisableTexCoordsGen then begin
9087 glDisable(GL_TEXTURE_GEN_S);
9088 glDisable(GL_TEXTURE_GEN_T);
9089 glDisable(GL_TEXTURE_GEN_R);
9095 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_2_0)}
9096 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9097 //TglBitmapNormalMap//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9098 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9100 TVec = Array[0..2] of Single;
9101 TglBitmapNormalMapGetVectorFunc = procedure (out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
9103 PglBitmapNormalMapRec = ^TglBitmapNormalMapRec;
9104 TglBitmapNormalMapRec = record
9106 Func: TglBitmapNormalMapGetVectorFunc;
9109 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9110 procedure glBitmapNormalMapPosX(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
9112 aVec[0] := aHalfSize;
9113 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
9114 aVec[2] := - (aPosition.X + 0.5 - aHalfSize);
9117 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9118 procedure glBitmapNormalMapNegX(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
9120 aVec[0] := - aHalfSize;
9121 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
9122 aVec[2] := aPosition.X + 0.5 - aHalfSize;
9125 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9126 procedure glBitmapNormalMapPosY(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
9128 aVec[0] := aPosition.X + 0.5 - aHalfSize;
9129 aVec[1] := aHalfSize;
9130 aVec[2] := aPosition.Y + 0.5 - aHalfSize;
9133 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9134 procedure glBitmapNormalMapNegY(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
9136 aVec[0] := aPosition.X + 0.5 - aHalfSize;
9137 aVec[1] := - aHalfSize;
9138 aVec[2] := - (aPosition.Y + 0.5 - aHalfSize);
9141 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9142 procedure glBitmapNormalMapPosZ(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
9144 aVec[0] := aPosition.X + 0.5 - aHalfSize;
9145 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
9146 aVec[2] := aHalfSize;
9149 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9150 procedure glBitmapNormalMapNegZ(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
9152 aVec[0] := - (aPosition.X + 0.5 - aHalfSize);
9153 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
9154 aVec[2] := - aHalfSize;
9157 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9158 procedure glBitmapNormalMapFunc(var FuncRec: TglBitmapFunctionRec);
9164 with FuncRec do begin
9165 with PglBitmapNormalMapRec(Args)^ do begin
9166 Func(Vec, Position, HalfSize);
9169 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
9170 if Len <> 0 then begin
9171 Vec[0] := Vec[0] * Len;
9172 Vec[1] := Vec[1] * Len;
9173 Vec[2] := Vec[2] * Len;
9176 // Scale Vector and AddVectro
9177 Vec[0] := Vec[0] * 0.5 + 0.5;
9178 Vec[1] := Vec[1] * 0.5 + 0.5;
9179 Vec[2] := Vec[2] * 0.5 + 0.5;
9184 Dest.Data.arr[i] := Round(Vec[i] * 255);
9188 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9189 procedure TglBitmapNormalMap.AfterConstruction;
9193 fGenMode := GL_NORMAL_MAP;
9197 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9198 procedure TglBitmapNormalMap.GenerateNormalMap(const aSize: Integer; const aTestTextureSize: Boolean);
9200 Rec: TglBitmapNormalMapRec;
9201 SizeRec: TglBitmapPixelPosition;
9203 Rec.HalfSize := aSize div 2;
9204 FreeDataAfterGenTexture := false;
9206 SizeRec.Fields := [ffX, ffY];
9211 Rec.Func := glBitmapNormalMapPosX;
9212 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
9213 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X, aTestTextureSize);
9216 Rec.Func := glBitmapNormalMapNegX;
9217 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
9218 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, aTestTextureSize);
9221 Rec.Func := glBitmapNormalMapPosY;
9222 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
9223 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, aTestTextureSize);
9226 Rec.Func := glBitmapNormalMapNegY;
9227 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
9228 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, aTestTextureSize);
9231 Rec.Func := glBitmapNormalMapPosZ;
9232 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
9233 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, aTestTextureSize);
9236 Rec.Func := glBitmapNormalMapNegZ;
9237 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8ub3, @Rec);
9238 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, aTestTextureSize);
9243 glBitmapSetDefaultFormat (tfEmpty);
9244 glBitmapSetDefaultMipmap (mmMipmap);
9245 glBitmapSetDefaultFilter (GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
9246 glBitmapSetDefaultWrap (GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
9247 {$IF NOT DEFINED(OPENGL_ES) OR DEFINED(OPENGL_ES_3_0)}
9248 glBitmapSetDefaultSwizzle(GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA);
9251 glBitmapSetDefaultFreeDataAfterGenTexture(true);
9252 glBitmapSetDefaultDeleteTextureOnFree (true);
9254 TFormatDescriptor.Init;
9256 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
9257 OpenGLInitialized := false;
9258 InitOpenGLCS := TCriticalSection.Create;
9262 TFormatDescriptor.Finalize;
9264 {$IFDEF GLB_NATIVE_OGL}
9265 if Assigned(GL_LibHandle) then
9266 glbFreeLibrary(GL_LibHandle);
9268 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
9269 if Assigned(GLU_LibHandle) then
9270 glbFreeLibrary(GLU_LibHandle);
9271 FreeAndNil(InitOpenGLCS);