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 // activate to enable build-in OpenGL support with statically linked methods
230 // use dglOpenGL.pas if not enabled
231 {.$DEFINE GLB_NATIVE_OGL_STATIC}
233 // activate to enable build-in OpenGL support with dynamically linked methods
234 // use dglOpenGL.pas if not enabled
235 {.$DEFINE GLB_NATIVE_OGL_DYNAMIC}
238 // activate to enable the support for SDL_surfaces
241 // activate to enable the support for Delphi (including support for Delphi's (not Lazarus') TBitmap)
242 {.$DEFINE GLB_DELPHI}
244 // activate to enable the support for TLazIntfImage from Lazarus
245 {$DEFINE GLB_LAZARUS}
249 // activate to enable the support of SDL_image to load files. (READ ONLY)
250 // If you enable SDL_image all other libraries will be ignored!
251 {.$DEFINE GLB_SDL_IMAGE}
255 // activate to enable Lazarus TPortableNetworkGraphic support
256 // if you enable this pngImage and libPNG will be ignored
257 {$DEFINE GLB_LAZ_PNG}
259 // activate to enable png support with the unit pngimage -> http://pngdelphi.sourceforge.net/
260 // if you enable pngimage the libPNG will be ignored
261 {.$DEFINE GLB_PNGIMAGE}
263 // activate to use the libPNG -> http://www.libpng.org/
264 // You will need an aditional header -> http://www.opengl24.de/index.php?cat=header&file=libpng
265 {.$DEFINE GLB_LIB_PNG}
269 // activate to enable Lazarus TJPEGImage support
270 // if you enable this delphi jpegs and libJPEG will be ignored
271 {$DEFINE GLB_LAZ_JPEG}
273 // if you enable delphi jpegs the libJPEG will be ignored
274 {.$DEFINE GLB_DELPHI_JPEG}
276 // activate to use the libJPEG -> http://www.ijg.org/
277 // You will need an aditional header -> http://www.opengl24.de/index.php?cat=header&file=libjpeg
278 {.$DEFINE GLB_LIB_JPEG}
281 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
282 // PRIVATE: do not change anything! //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
283 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
299 {$IF DEFINED(WIN32) or DEFINED(WIN64) or DEFINED(WINDOWS)}
301 {$ELSEIF DEFINED(LINUX)}
305 // native OpenGL Support
306 {$IF DEFINED(GLB_NATIVE_OGL_STATIC) OR DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
307 {$DEFINE GLB_NATIVE_OGL}
310 // checking define combinations
312 {$IFDEF GLB_SDL_IMAGE}
314 {$MESSAGE warn 'SDL_image won''t work without SDL. SDL will be activated.'}
319 {$MESSAGE warn 'The Lazarus TPortableNetworkGraphics will be ignored because you are using SDL_image.'}
323 {$IFDEF GLB_PNGIMAGE}
324 {$MESSAGE warn 'The unit pngimage will be ignored because you are using SDL_image.'}
325 {$undef GLB_PNGIMAGE}
328 {$IFDEF GLB_LAZ_JPEG}
329 {$MESSAGE warn 'The Lazarus TJPEGImage will be ignored because you are using SDL_image.'}
330 {$undef GLB_LAZ_JPEG}
333 {$IFDEF GLB_DELPHI_JPEG}
334 {$MESSAGE warn 'The unit JPEG will be ignored because you are using SDL_image.'}
335 {$undef GLB_DELPHI_JPEG}
339 {$MESSAGE warn 'The library libPNG will be ignored because you are using SDL_image.'}
343 {$IFDEF GLB_LIB_JPEG}
344 {$MESSAGE warn 'The library libJPEG will be ignored because you are using SDL_image.'}
345 {$undef GLB_LIB_JPEG}
348 {$DEFINE GLB_SUPPORT_PNG_READ}
349 {$DEFINE GLB_SUPPORT_JPEG_READ}
352 // Lazarus TPortableNetworkGraphic
354 {$IFNDEF GLB_LAZARUS}
355 {$MESSAGE warn 'Lazarus TPortableNetworkGraphic won''t work without Lazarus. Lazarus will be activated.'}
356 {$DEFINE GLB_LAZARUS}
359 {$IFDEF GLB_PNGIMAGE}
360 {$MESSAGE warn 'The pngimage will be ignored if you are using Lazarus TPortableNetworkGraphic.'}
361 {$undef GLB_PNGIMAGE}
365 {$MESSAGE warn 'The library libPNG will be ignored if you are using Lazarus TPortableNetworkGraphic.'}
369 {$DEFINE GLB_SUPPORT_PNG_READ}
370 {$DEFINE GLB_SUPPORT_PNG_WRITE}
374 {$IFDEF GLB_PNGIMAGE}
376 {$MESSAGE warn 'The library libPNG will be ignored if you are using pngimage.'}
380 {$DEFINE GLB_SUPPORT_PNG_READ}
381 {$DEFINE GLB_SUPPORT_PNG_WRITE}
386 {$DEFINE GLB_SUPPORT_PNG_READ}
387 {$DEFINE GLB_SUPPORT_PNG_WRITE}
390 // Lazarus TJPEGImage
391 {$IFDEF GLB_LAZ_JPEG}
392 {$IFNDEF GLB_LAZARUS}
393 {$MESSAGE warn 'Lazarus TJPEGImage won''t work without Lazarus. Lazarus will be activated.'}
394 {$DEFINE GLB_LAZARUS}
397 {$IFDEF GLB_DELPHI_JPEG}
398 {$MESSAGE warn 'The Delphi JPEGImage will be ignored if you are using the Lazarus TJPEGImage.'}
399 {$undef GLB_DELPHI_JPEG}
402 {$IFDEF GLB_LIB_JPEG}
403 {$MESSAGE warn 'The library libJPEG will be ignored if you are using the Lazarus TJPEGImage.'}
404 {$undef GLB_LIB_JPEG}
407 {$DEFINE GLB_SUPPORT_JPEG_READ}
408 {$DEFINE GLB_SUPPORT_JPEG_WRITE}
412 {$IFDEF GLB_DELPHI_JPEG}
413 {$IFDEF GLB_LIB_JPEG}
414 {$MESSAGE warn 'The library libJPEG will be ignored if you are using the unit JPEG.'}
415 {$undef GLB_LIB_JPEG}
418 {$DEFINE GLB_SUPPORT_JPEG_READ}
419 {$DEFINE GLB_SUPPORT_JPEG_WRITE}
423 {$IFDEF GLB_LIB_JPEG}
424 {$DEFINE GLB_SUPPORT_JPEG_READ}
425 {$DEFINE GLB_SUPPORT_JPEG_WRITE}
429 {$IF DEFINED(GLB_NATIVE_OGL_STATIC) AND DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
430 {$MESSAGE warn 'GLB_NATIVE_OGL_STATIC will be ignored because you enabled GLB_NATIVE_OGL_DYNAMIC'}
444 {$IFNDEF GLB_NATIVE_OGL} dglOpenGL, {$ENDIF}
445 {$IF DEFINED(GLB_WIN) AND
446 (DEFINED(GLB_NATIVE_OGL) OR
447 DEFINED(GLB_DELPHI))} windows, {$IFEND}
449 {$IFDEF GLB_SDL} SDL, {$ENDIF}
450 {$IFDEF GLB_LAZARUS} IntfGraphics, GraphType, Graphics, {$ENDIF}
451 {$IFDEF GLB_DELPHI} Dialogs, Graphics, Types, {$ENDIF}
453 {$IFDEF GLB_SDL_IMAGE} SDL_image, {$ENDIF}
454 {$IFDEF GLB_PNGIMAGE} pngimage, {$ENDIF}
455 {$IFDEF GLB_LIB_PNG} libPNG, {$ENDIF}
456 {$IFDEF GLB_DELPHI_JPEG} JPEG, {$ENDIF}
457 {$IFDEF GLB_LIB_JPEG} libJPEG, {$ENDIF}
461 {$IFDEF GLB_NATIVE_OGL}
470 GL_EXTENSIONS = $1F03;
472 GL_TEXTURE_1D = $0DE0;
473 GL_TEXTURE_2D = $0DE1;
474 GL_TEXTURE_RECTANGLE = $84F5;
476 GL_NORMAL_MAP = $8511;
477 GL_TEXTURE_CUBE_MAP = $8513;
478 GL_REFLECTION_MAP = $8512;
479 GL_TEXTURE_CUBE_MAP_POSITIVE_X = $8515;
480 GL_TEXTURE_CUBE_MAP_NEGATIVE_X = $8516;
481 GL_TEXTURE_CUBE_MAP_POSITIVE_Y = $8517;
482 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y = $8518;
483 GL_TEXTURE_CUBE_MAP_POSITIVE_Z = $8519;
484 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z = $851A;
486 GL_TEXTURE_WIDTH = $1000;
487 GL_TEXTURE_HEIGHT = $1001;
488 GL_TEXTURE_INTERNAL_FORMAT = $1003;
489 GL_TEXTURE_SWIZZLE_RGBA = $8E46;
496 GL_TEXTURE_GEN_S = $0C60;
497 GL_TEXTURE_GEN_T = $0C61;
498 GL_TEXTURE_GEN_R = $0C62;
499 GL_TEXTURE_GEN_Q = $0C63;
511 GL_LUMINANCE = $1909;
512 GL_LUMINANCE4 = $803F;
513 GL_LUMINANCE8 = $8040;
514 GL_LUMINANCE12 = $8041;
515 GL_LUMINANCE16 = $8042;
517 GL_LUMINANCE_ALPHA = $190A;
518 GL_LUMINANCE4_ALPHA4 = $8043;
519 GL_LUMINANCE6_ALPHA2 = $8044;
520 GL_LUMINANCE8_ALPHA8 = $8045;
521 GL_LUMINANCE12_ALPHA4 = $8046;
522 GL_LUMINANCE12_ALPHA12 = $8047;
523 GL_LUMINANCE16_ALPHA16 = $8048;
546 GL_DEPTH_COMPONENT = $1902;
547 GL_DEPTH_COMPONENT16 = $81A5;
548 GL_DEPTH_COMPONENT24 = $81A6;
549 GL_DEPTH_COMPONENT32 = $81A7;
551 GL_COMPRESSED_RGB = $84ED;
552 GL_COMPRESSED_RGBA = $84EE;
553 GL_COMPRESSED_RGB_S3TC_DXT1_EXT = $83F0;
554 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = $83F1;
555 GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = $83F2;
556 GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = $83F3;
558 GL_UNSIGNED_BYTE = $1401;
559 GL_UNSIGNED_BYTE_3_3_2 = $8032;
560 GL_UNSIGNED_BYTE_2_3_3_REV = $8362;
562 GL_UNSIGNED_SHORT = $1403;
563 GL_UNSIGNED_SHORT_5_6_5 = $8363;
564 GL_UNSIGNED_SHORT_4_4_4_4 = $8033;
565 GL_UNSIGNED_SHORT_5_5_5_1 = $8034;
566 GL_UNSIGNED_SHORT_5_6_5_REV = $8364;
567 GL_UNSIGNED_SHORT_4_4_4_4_REV = $8365;
568 GL_UNSIGNED_SHORT_1_5_5_5_REV = $8366;
570 GL_UNSIGNED_INT = $1405;
571 GL_UNSIGNED_INT_8_8_8_8 = $8035;
572 GL_UNSIGNED_INT_10_10_10_2 = $8036;
573 GL_UNSIGNED_INT_8_8_8_8_REV = $8367;
574 GL_UNSIGNED_INT_2_10_10_10_REV = $8368;
577 GL_TEXTURE_MAG_FILTER = $2800;
578 GL_TEXTURE_MIN_FILTER = $2801;
580 GL_NEAREST_MIPMAP_NEAREST = $2700;
581 GL_NEAREST_MIPMAP_LINEAR = $2702;
583 GL_LINEAR_MIPMAP_NEAREST = $2701;
584 GL_LINEAR_MIPMAP_LINEAR = $2703;
587 GL_TEXTURE_WRAP_S = $2802;
588 GL_TEXTURE_WRAP_T = $2803;
589 GL_TEXTURE_WRAP_R = $8072;
592 GL_CLAMP_TO_EDGE = $812F;
593 GL_CLAMP_TO_BORDER = $812D;
594 GL_MIRRORED_REPEAT = $8370;
597 GL_GENERATE_MIPMAP = $8191;
598 GL_TEXTURE_BORDER_COLOR = $1004;
599 GL_MAX_TEXTURE_SIZE = $0D33;
600 GL_PACK_ALIGNMENT = $0D05;
601 GL_UNPACK_ALIGNMENT = $0CF5;
603 GL_TEXTURE_MAX_ANISOTROPY_EXT = $84FE;
604 GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = $84FF;
605 GL_MAX_CUBE_MAP_TEXTURE_SIZE = $851C;
606 GL_TEXTURE_GEN_MODE = $2500;
608 {$IF DEFINED(GLB_WIN)}
609 libglu = 'glu32.dll';
610 libopengl = 'opengl32.dll';
611 {$ELSEIF DEFINED(GLB_LINUX)}
612 libglu = 'libGLU.so.1';
613 libopengl = 'libGL.so.1';
617 GLboolean = BYTEBOOL;
625 PGLboolean = ^GLboolean;
630 TglCompressedTexImage1D = procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
631 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}
632 TglGetCompressedTexImage = procedure(target: GLenum; level: GLint; img: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
634 {$IF DEFINED(GLB_WIN)}
635 TwglGetProcAddress = function (ProcName: PAnsiChar): Pointer; stdcall;
636 {$ELSEIF DEFINED(GLB_LINUX)}
637 TglXGetProcAddress = function(ProcName: PAnsiChar): Pointer; cdecl;
638 TglXGetProcAddressARB = function(const name: PAnsiChar): pointer; cdecl;
641 {$IF DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
642 TglEnable = procedure(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
643 TglDisable = procedure(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
645 TglGetString = function(name: GLenum): PAnsiChar; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
646 TglGetIntegerv = procedure(pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
648 TglTexParameteri = procedure(target: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
649 TglTexParameteriv = procedure(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
650 TglTexParameterfv = procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
651 TglGetTexParameteriv = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
652 TglGetTexParameterfv = procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
653 TglGetTexLevelParameteriv = procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
654 TglGetTexLevelParameterfv = procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
656 TglTexGeni = procedure(coord: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
657 TglGenTextures = procedure(n: GLsizei; textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
658 TglBindTexture = procedure(target: GLenum; texture: GLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
659 TglDeleteTextures = procedure(n: GLsizei; const textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
661 TglAreTexturesResident = function(n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
662 TglReadPixels = procedure(x: GLint; y: GLint; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
663 TglPixelStorei = procedure(pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
665 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}
666 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}
667 TglGetTexImage = procedure(target: GLenum; level: GLint; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
669 TgluBuild1DMipmaps = function(target: GLEnum; components, width: GLint; format, atype: GLEnum; const data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
670 TgluBuild2DMipmaps = function(target: GLEnum; components, width, height: GLint; format, atype: GLEnum; const Data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
672 {$ELSEIF DEFINED(GLB_NATIVE_OGL_STATIC)}
673 procedure glEnable(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
674 procedure glDisable(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
676 function glGetString(name: GLenum): PAnsiChar; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
677 procedure glGetIntegerv(pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
679 procedure glTexParameteri(target: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
680 procedure glTexParameteriv(target: GLenum; pname: GLenum; const params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
681 procedure glTexParameterfv(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
682 procedure glGetTexParameteriv(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
683 procedure glGetTexParameterfv(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
684 procedure glGetTexLevelParameteriv(target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
685 procedure glGetTexLevelParameterfv(target: GLenum; level: GLint; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
687 procedure glTexGeni(coord: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
688 procedure glGenTextures(n: GLsizei; textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
689 procedure glBindTexture(target: GLenum; texture: GLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
690 procedure glDeleteTextures(n: GLsizei; const textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
692 function glAreTexturesResident(n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
693 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;
694 procedure glPixelStorei(pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
696 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;
697 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;
698 procedure glGetTexImage(target: GLenum; level: GLint; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
700 function gluBuild1DMipmaps(target: GLEnum; components, width: GLint; format, atype: GLEnum; const data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libglu;
701 function gluBuild2DMipmaps(target: GLEnum; components, width, height: GLint; format, atype: GLEnum; const Data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libglu;
711 GL_SGIS_generate_mipmap,
713 GL_ARB_texture_border_clamp,
714 GL_ARB_texture_mirrored_repeat,
715 GL_ARB_texture_rectangle,
716 GL_ARB_texture_non_power_of_two,
717 GL_ARB_texture_swizzle,
718 GL_ARB_texture_cube_map,
720 GL_IBM_texture_mirrored_repeat,
722 GL_NV_texture_rectangle,
724 GL_EXT_texture_edge_clamp,
725 GL_EXT_texture_rectangle,
726 GL_EXT_texture_swizzle,
727 GL_EXT_texture_cube_map,
728 GL_EXT_texture_filter_anisotropic: Boolean;
730 glCompressedTexImage1D: TglCompressedTexImage1D;
731 glCompressedTexImage2D: TglCompressedTexImage2D;
732 glGetCompressedTexImage: TglGetCompressedTexImage;
734 {$IF DEFINED(GLB_WIN)}
735 wglGetProcAddress: TwglGetProcAddress;
736 {$ELSEIF DEFINED(GLB_LINUX)}
737 glXGetProcAddress: TglXGetProcAddress;
738 glXGetProcAddressARB: TglXGetProcAddress;
741 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
743 glDisable: TglDisable;
745 glGetString: TglGetString;
746 glGetIntegerv: TglGetIntegerv;
748 glTexParameteri: TglTexParameteri;
749 glTexParameteriv: TglTexParameteriv;
750 glTexParameterfv: TglTexParameterfv;
751 glGetTexParameteriv: TglGetTexParameteriv;
752 glGetTexParameterfv: TglGetTexParameterfv;
753 glGetTexLevelParameteriv: TglGetTexLevelParameteriv;
754 glGetTexLevelParameterfv: TglGetTexLevelParameterfv;
756 glTexGeni: TglTexGeni;
757 glGenTextures: TglGenTextures;
758 glBindTexture: TglBindTexture;
759 glDeleteTextures: TglDeleteTextures;
761 glAreTexturesResident: TglAreTexturesResident;
762 glReadPixels: TglReadPixels;
763 glPixelStorei: TglPixelStorei;
765 glTexImage1D: TglTexImage1D;
766 glTexImage2D: TglTexImage2D;
767 glGetTexImage: TglGetTexImage;
769 gluBuild1DMipmaps: TgluBuild1DMipmaps;
770 gluBuild2DMipmaps: TgluBuild2DMipmaps;
775 ////////////////////////////////////////////////////////////////////////////////////////////////////
777 tfEmpty = 0, //must be smallest value!
791 tfLuminance16Alpha16,
847 TglBitmapFileType = (
848 {$IFDEF GLB_SUPPORT_PNG_WRITE} ftPNG, {$ENDIF}
849 {$IFDEF GLB_SUPPORT_JPEG_WRITE}ftJPEG, {$ENDIF}
853 TglBitmapFileTypes = set of TglBitmapFileType;
860 TglBitmapNormalMapFunc = (
866 ////////////////////////////////////////////////////////////////////////////////////////////////////
867 EglBitmap = class(Exception);
868 EglBitmapNotSupported = class(Exception);
869 EglBitmapSizeToLarge = class(EglBitmap);
870 EglBitmapNonPowerOfTwo = class(EglBitmap);
871 EglBitmapUnsupportedFormat = class(EglBitmap)
873 constructor Create(const aFormat: TglBitmapFormat); overload;
874 constructor Create(const aMsg: String; const aFormat: TglBitmapFormat); overload;
877 ////////////////////////////////////////////////////////////////////////////////////////////////////
878 TglBitmapColorRec = packed record
880 0: (r, g, b, a: Cardinal);
881 1: (arr: array[0..3] of Cardinal);
884 TglBitmapPixelData = packed record
885 Data, Range: TglBitmapColorRec;
886 Format: TglBitmapFormat;
888 PglBitmapPixelData = ^TglBitmapPixelData;
890 ////////////////////////////////////////////////////////////////////////////////////////////////////
891 TglBitmapPixelPositionFields = set of (ffX, ffY);
892 TglBitmapPixelPosition = record
893 Fields : TglBitmapPixelPositionFields;
898 TglBitmapFormatDescriptor = class(TObject)
900 function GetIsCompressed: Boolean; virtual; abstract;
901 function GetHasRed: Boolean; virtual; abstract;
902 function GetHasGreen: Boolean; virtual; abstract;
903 function GetHasBlue: Boolean; virtual; abstract;
904 function GetHasAlpha: Boolean; virtual; abstract;
906 function GetRGBInverted: TglBitmapFormat; virtual; abstract;
907 function GetWithAlpha: TglBitmapFormat; virtual; abstract;
908 function GetWithoutAlpha: TglBitmapFormat; virtual; abstract;
909 function GetOpenGLFormat: TglBitmapFormat; virtual; abstract;
910 function GetUncompressed: TglBitmapFormat; virtual; abstract;
912 function GetglDataFormat: GLenum; virtual; abstract;
913 function GetglFormat: GLenum; virtual; abstract;
914 function GetglInternalFormat: GLenum; virtual; abstract;
916 property IsCompressed: Boolean read GetIsCompressed;
917 property HasRed: Boolean read GetHasRed;
918 property HasGreen: Boolean read GetHasGreen;
919 property HasBlue: Boolean read GetHasBlue;
920 property HasAlpha: Boolean read GetHasAlpha;
922 property RGBInverted: TglBitmapFormat read GetRGBInverted;
923 property WithAlpha: TglBitmapFormat read GetWithAlpha;
924 property WithoutAlpha: TglBitmapFormat read GetWithoutAlpha;
925 property OpenGLFormat: TglBitmapFormat read GetOpenGLFormat;
926 property Uncompressed: TglBitmapFormat read GetUncompressed;
928 property glFormat: GLenum read GetglFormat;
929 property glInternalFormat: GLenum read GetglInternalFormat;
930 property glDataFormat: GLenum read GetglDataFormat;
932 class function GetByFormat(const aInternalFormat: GLenum): TglBitmapFormatDescriptor;
935 ////////////////////////////////////////////////////////////////////////////////////////////////////
937 TglBitmapFunctionRec = record
939 Size: TglBitmapPixelPosition;
940 Position: TglBitmapPixelPosition;
941 Source: TglBitmapPixelData;
942 Dest: TglBitmapPixelData;
945 TglBitmapFunction = procedure(var FuncRec: TglBitmapFunctionRec);
947 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
950 function GetFormatDesc: TglBitmapFormatDescriptor;
954 fAnisotropic: Integer;
955 fDeleteTextureOnFree: Boolean;
956 fFreeDataOnDestroy: Boolean;
957 fFreeDataAfterGenTexture: Boolean;
959 fIsResident: GLboolean;
960 fBorderColor: array[0..3] of Single;
962 fDimension: TglBitmapPixelPosition;
963 fMipMap: TglBitmapMipMap;
964 fFormat: TglBitmapFormat;
980 fSwizzle: array[0..3] of GLenum;
985 fCustomNameW: WideString;
986 fCustomData: Pointer;
989 function GetWidth: Integer; virtual;
990 function GetHeight: Integer; virtual;
992 function GetFileWidth: Integer; virtual;
993 function GetFileHeight: Integer; virtual;
996 procedure SetCustomData(const aValue: Pointer);
997 procedure SetCustomName(const aValue: String);
998 procedure SetCustomNameW(const aValue: WideString);
999 procedure SetFreeDataOnDestroy(const aValue: Boolean);
1000 procedure SetDeleteTextureOnFree(const aValue: Boolean);
1001 procedure SetFormat(const aValue: TglBitmapFormat);
1002 procedure SetFreeDataAfterGenTexture(const aValue: Boolean);
1003 procedure SetID(const aValue: Cardinal);
1004 procedure SetMipMap(const aValue: TglBitmapMipMap);
1005 procedure SetTarget(const aValue: Cardinal);
1006 procedure SetAnisotropic(const aValue: Integer);
1009 procedure SetupParameters(out aBuildWithGlu: Boolean);
1010 procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
1011 const aWidth: Integer = -1; const aHeight: Integer = -1); virtual; //be careful, aData could be freed by this method
1012 procedure GenTexture(const aTestTextureSize: Boolean = true); virtual; abstract;
1014 function FlipHorz: Boolean; virtual;
1015 function FlipVert: Boolean; virtual;
1017 property Width: Integer read GetWidth;
1018 property Height: Integer read GetHeight;
1020 property FileWidth: Integer read GetFileWidth;
1021 property FileHeight: Integer read GetFileHeight;
1024 property ID: Cardinal read fID write SetID;
1025 property Target: Cardinal read fTarget write SetTarget;
1026 property Format: TglBitmapFormat read fFormat write SetFormat;
1027 property MipMap: TglBitmapMipMap read fMipMap write SetMipMap;
1028 property Anisotropic: Integer read fAnisotropic write SetAnisotropic;
1030 property FormatDesc: TglBitmapFormatDescriptor read GetFormatDesc;
1032 property Filename: String read fFilename;
1033 property CustomName: String read fCustomName write SetCustomName;
1034 property CustomNameW: WideString read fCustomNameW write SetCustomNameW;
1035 property CustomData: Pointer read fCustomData write SetCustomData;
1037 property DeleteTextureOnFree: Boolean read fDeleteTextureOnFree write SetDeleteTextureOnFree;
1038 property FreeDataOnDestroy: Boolean read fFreeDataOnDestroy write SetFreeDataOnDestroy;
1039 property FreeDataAfterGenTexture: Boolean read fFreeDataAfterGenTexture write SetFreeDataAfterGenTexture;
1041 property Dimension: TglBitmapPixelPosition read fDimension;
1042 property Data: PByte read fData;
1043 property IsResident: GLboolean read fIsResident;
1045 procedure AfterConstruction; override;
1046 procedure BeforeDestruction; override;
1048 procedure PrepareResType(var aResource: String; var aResType: PChar);
1051 procedure LoadFromFile(const aFilename: String);
1052 procedure LoadFromStream(const aStream: TStream); virtual;
1053 procedure LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
1054 const aFormat: TglBitmapFormat; const aArgs: Pointer = nil);
1055 procedure LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil);
1056 procedure LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
1059 procedure SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
1060 procedure SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType); virtual;
1063 function AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer = nil): Boolean; overload;
1064 function AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
1065 const aFormat: TglBitmapFormat; const aArgs: Pointer = nil): Boolean; overload;
1069 function AssignToSurface(out aSurface: PSDL_Surface): Boolean;
1070 function AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
1071 function AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
1072 function AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil;
1073 const aArgs: Pointer = nil): Boolean;
1077 function AssignToBitmap(const aBitmap: TBitmap): Boolean;
1078 function AssignFromBitmap(const aBitmap: TBitmap): Boolean;
1079 function AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
1080 function AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction = nil;
1081 const aArgs: Pointer = nil): Boolean;
1084 {$IFDEF GLB_LAZARUS}
1085 function AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
1086 function AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
1087 function AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
1088 function AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction = nil;
1089 const aArgs: Pointer = nil): Boolean;
1092 function AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil;
1093 const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1094 function AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
1095 const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1097 function AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer = nil): Boolean; virtual;
1098 function AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1099 function AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1100 function AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
1102 function AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte = 0): Boolean;
1103 function AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal = 0): Boolean;
1104 function AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single = 0): Boolean;
1106 function AddAlphaFromValue(const aAlpha: Byte): Boolean;
1107 function AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
1108 function AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
1110 function RemoveAlpha: Boolean; virtual;
1113 function Clone: TglBitmap;
1114 function ConvertTo(const aFormat: TglBitmapFormat): Boolean; virtual;
1115 procedure Invert(const aUseRGB: Boolean = true; const aUseAlpha: Boolean = false);
1116 procedure SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
1120 procedure FillWithColor(const aRed, aGreen, aBlue: Byte; const aAlpha: Byte = 255);
1121 procedure FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal = $FFFFFFFF);
1122 procedure FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha : Single = 1);
1125 procedure SetFilter(const aMin, aMag: GLenum);
1127 const S: GLenum = GL_CLAMP_TO_EDGE;
1128 const T: GLenum = GL_CLAMP_TO_EDGE;
1129 const R: GLenum = GL_CLAMP_TO_EDGE);
1130 procedure SetSwizzle(const r, g, b, a: GLenum);
1132 procedure Bind(const aEnableTextureUnit: Boolean = true); virtual;
1133 procedure Unbind(const aDisableTextureUnit: Boolean = true); virtual;
1136 constructor Create; overload;
1137 constructor Create(const aFileName: String); overload;
1138 constructor Create(const aStream: TStream); overload;
1139 constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; aData: PByte = nil); overload;
1140 constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer = nil); overload;
1141 constructor Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil); overload;
1142 constructor Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar); overload;
1144 {$IFDEF GLB_SUPPORT_PNG_READ} function LoadPNG(const aStream: TStream): Boolean; virtual; {$ENDIF}
1145 {$ifdef GLB_SUPPORT_PNG_WRITE} procedure SavePNG(const aStream: TStream); virtual; {$ENDIF}
1147 {$IFDEF GLB_SUPPORT_JPEG_READ} function LoadJPEG(const aStream: TStream): Boolean; virtual; {$ENDIF}
1148 {$IFDEF GLB_SUPPORT_JPEG_WRITE} procedure SaveJPEG(const aStream: TStream); virtual; {$ENDIF}
1150 function LoadBMP(const aStream: TStream): Boolean; virtual;
1151 procedure SaveBMP(const aStream: TStream); virtual;
1153 function LoadTGA(const aStream: TStream): Boolean; virtual;
1154 procedure SaveTGA(const aStream: TStream); virtual;
1156 function LoadDDS(const aStream: TStream): Boolean; virtual;
1157 procedure SaveDDS(const aStream: TStream); virtual;
1160 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1161 TglBitmap1D = class(TglBitmap)
1163 procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
1164 const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
1165 procedure UploadData(const aBuildWithGlu: Boolean);
1168 procedure AfterConstruction; override;
1169 function FlipHorz: Boolean; override;
1170 procedure GenTexture(const aTestTextureSize: Boolean = true); override;
1173 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1174 TglBitmap2D = class(TglBitmap)
1176 fLines: array of PByte;
1177 function GetScanline(const aIndex: Integer): Pointer;
1178 procedure SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
1179 const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
1180 procedure UploadData(const aTarget: GLenum; const aBuildWithGlu: Boolean);
1184 property Scanline[const aIndex: Integer]: Pointer read GetScanline;
1186 procedure AfterConstruction; override;
1188 procedure GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
1189 procedure GetDataFromTexture;
1190 procedure GenTexture(const aTestTextureSize: Boolean = true); override;
1192 function FlipHorz: Boolean; override;
1193 function FlipVert: Boolean; override;
1195 procedure ToNormalMap(const aFunc: TglBitmapNormalMapFunc = nm3x3;
1196 const aScale: Single = 2; const aUseAlpha: Boolean = false);
1199 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1200 TglBitmapCubeMap = class(TglBitmap2D)
1203 procedure GenTexture(const aTestTextureSize: Boolean = true); reintroduce;
1205 procedure AfterConstruction; override;
1206 procedure GenerateCubeMap(const aCubeTarget: Cardinal; const aTestTextureSize: Boolean = true);
1207 procedure Bind(const aEnableTexCoordsGen: Boolean = true; const aEnableTextureUnit: Boolean = true); reintroduce; virtual;
1208 procedure Unbind(const aDisableTexCoordsGen: Boolean = true; const aDisableTextureUnit: Boolean = true); reintroduce; virtual;
1211 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1212 TglBitmapNormalMap = class(TglBitmapCubeMap)
1214 procedure AfterConstruction; override;
1215 procedure GenerateNormalMap(const aSize: Integer = 32; const aTestTextureSize: Boolean = true);
1218 TglcBitmapFormat = TglBitmapFormat;
1219 TglcBitmap1D = TglBitmap1D;
1220 TglcBitmap2D = TglBitmap2D;
1221 TglcBitmapCubeMap = TglBitmapCubeMap;
1222 TglcBitmapNormalMap = TglBitmapNormalMap;
1225 NULL_SIZE: TglBitmapPixelPosition = (Fields: []; X: 0; Y: 0);
1227 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
1228 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
1229 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
1230 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
1231 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
1232 procedure glBitmapSetDefaultWrap(
1233 const S: Cardinal = GL_CLAMP_TO_EDGE;
1234 const T: Cardinal = GL_CLAMP_TO_EDGE;
1235 const R: Cardinal = GL_CLAMP_TO_EDGE);
1237 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
1238 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
1239 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
1240 function glBitmapGetDefaultFormat: TglBitmapFormat;
1241 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
1242 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
1244 function glBitmapPosition(X: Integer = -1; Y: Integer = -1): TglBitmapPixelPosition;
1245 function glBitmapColorRec(const r, g, b, a: Cardinal): TglBitmapColorRec;
1246 function glBitmapColorRecCmp(const r1, r2: TglBitmapColorRec): Boolean;
1249 glBitmapDefaultDeleteTextureOnFree: Boolean;
1250 glBitmapDefaultFreeDataAfterGenTextures: Boolean;
1251 glBitmapDefaultFormat: TglBitmapFormat;
1252 glBitmapDefaultMipmap: TglBitmapMipMap;
1253 glBitmapDefaultFilterMin: Cardinal;
1254 glBitmapDefaultFilterMag: Cardinal;
1255 glBitmapDefaultWrapS: Cardinal;
1256 glBitmapDefaultWrapT: Cardinal;
1257 glBitmapDefaultWrapR: Cardinal;
1258 glDefaultSwizzle: array[0..3] of GLenum;
1261 function CreateGrayPalette: HPALETTE;
1267 Math, syncobjs, typinfo
1268 {$IF DEFINED(GLB_SUPPORT_JPEG_READ) AND DEFINED(GLB_LAZ_JPEG)}, FPReadJPEG{$IFEND};
1272 QWord = System.UInt64;
1279 ////////////////////////////////////////////////////////////////////////////////////////////////////
1280 TShiftRec = packed record
1282 0: (r, g, b, a: Byte);
1283 1: (arr: array[0..3] of Byte);
1286 TFormatDescriptor = class(TglBitmapFormatDescriptor)
1288 function GetRedMask: QWord;
1289 function GetGreenMask: QWord;
1290 function GetBlueMask: QWord;
1291 function GetAlphaMask: QWord;
1293 fFormat: TglBitmapFormat;
1294 fWithAlpha: TglBitmapFormat;
1295 fWithoutAlpha: TglBitmapFormat;
1296 fOpenGLFormat: TglBitmapFormat;
1297 fRGBInverted: TglBitmapFormat;
1298 fUncompressed: TglBitmapFormat;
1301 fIsCompressed: Boolean;
1303 fRange: TglBitmapColorRec;
1307 fglInternalFormat: GLenum;
1308 fglDataFormat: GLenum;
1310 function GetIsCompressed: Boolean; override;
1311 function GetHasRed: Boolean; override;
1312 function GetHasGreen: Boolean; override;
1313 function GetHasBlue: Boolean; override;
1314 function GetHasAlpha: Boolean; override;
1316 function GetRGBInverted: TglBitmapFormat; override;
1317 function GetWithAlpha: TglBitmapFormat; override;
1318 function GetWithoutAlpha: TglBitmapFormat; override;
1319 function GetOpenGLFormat: TglBitmapFormat; override;
1320 function GetUncompressed: TglBitmapFormat; override;
1322 function GetglFormat: GLenum; override;
1323 function GetglInternalFormat: GLenum; override;
1324 function GetglDataFormat: GLenum; override;
1326 function GetComponents: Integer; virtual;
1328 property Format: TglBitmapFormat read fFormat;
1329 property Components: Integer read GetComponents;
1330 property PixelSize: Single read fPixelSize;
1332 property Range: TglBitmapColorRec read fRange;
1333 property Shift: TShiftRec read fShift;
1335 property RedMask: QWord read GetRedMask;
1336 property GreenMask: QWord read GetGreenMask;
1337 property BlueMask: QWord read GetBlueMask;
1338 property AlphaMask: QWord read GetAlphaMask;
1340 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); virtual; abstract;
1341 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); virtual; abstract;
1343 function GetSize(const aSize: TglBitmapPixelPosition): Integer; overload; virtual;
1344 function GetSize(const aWidth, aHeight: Integer): Integer; overload; virtual;
1346 function CreateMappingData: Pointer; virtual;
1347 procedure FreeMappingData(var aMappingData: Pointer); virtual;
1349 function IsEmpty: Boolean; virtual;
1350 function MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: QWord): Boolean; virtual;
1352 procedure PreparePixel(out aPixel: TglBitmapPixelData); virtual;
1354 constructor Create; virtual;
1356 class procedure Init;
1357 class function Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
1358 class function GetAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
1359 class procedure Clear;
1360 class procedure Finalize;
1362 TFormatDescriptorClass = class of TFormatDescriptor;
1364 TfdEmpty = class(TFormatDescriptor);
1366 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1367 TfdAlpha_UB1 = class(TFormatDescriptor) //1* unsigned byte
1368 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1369 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1372 TfdLuminance_UB1 = class(TFormatDescriptor) //1* unsigned byte
1373 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1374 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1377 TfdUniversal_UB1 = class(TFormatDescriptor) //1* unsigned byte
1378 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1379 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1382 TfdLuminanceAlpha_UB2 = class(TfdLuminance_UB1) //2* unsigned byte
1383 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1384 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1387 TfdRGB_UB3 = class(TFormatDescriptor) //3* unsigned byte
1388 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1389 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1392 TfdBGR_UB3 = class(TFormatDescriptor) //3* unsigned byte (inverse)
1393 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1394 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1397 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1398 TfdAlpha_US1 = class(TFormatDescriptor) //1* unsigned short
1399 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1400 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1403 TfdLuminance_US1 = class(TFormatDescriptor) //1* unsigned short
1404 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1405 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1408 TfdUniversal_US1 = class(TFormatDescriptor) //1* unsigned short
1409 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1410 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1413 TfdDepth_US1 = class(TFormatDescriptor) //1* unsigned short
1414 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1415 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1418 TfdLuminanceAlpha_US2 = class(TfdLuminance_US1) //2* unsigned short
1419 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1420 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1423 TfdRGB_US3 = class(TFormatDescriptor) //3* unsigned short
1424 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1425 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1428 TfdBGR_US3 = class(TFormatDescriptor) //3* unsigned short (inverse)
1429 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1430 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1433 TfdRGBA_US4 = class(TfdRGB_US3) //4* unsigned short
1434 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1435 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1438 TfdARGB_US4 = class(TfdRGB_US3) //4* unsigned short
1439 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1440 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1443 TfdBGRA_US4 = class(TfdBGR_US3) //4* unsigned short (inverse)
1444 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1445 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1448 TfdABGR_US4 = class(TfdBGR_US3) //4* unsigned short (inverse)
1449 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1450 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1453 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1454 TfdUniversal_UI1 = class(TFormatDescriptor) //1* unsigned int
1455 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1456 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1459 TfdDepth_UI1 = class(TFormatDescriptor) //1* unsigned int
1460 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1461 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1464 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1465 TfdAlpha4 = class(TfdAlpha_UB1)
1466 constructor Create; override;
1469 TfdAlpha8 = class(TfdAlpha_UB1)
1470 constructor Create; override;
1473 TfdAlpha16 = class(TfdAlpha_US1)
1474 constructor Create; override;
1477 TfdLuminance4 = class(TfdLuminance_UB1)
1478 constructor Create; override;
1481 TfdLuminance8 = class(TfdLuminance_UB1)
1482 constructor Create; override;
1485 TfdLuminance16 = class(TfdLuminance_US1)
1486 constructor Create; override;
1489 TfdLuminance4Alpha4 = class(TfdLuminanceAlpha_UB2)
1490 constructor Create; override;
1493 TfdLuminance6Alpha2 = class(TfdLuminanceAlpha_UB2)
1494 constructor Create; override;
1497 TfdLuminance8Alpha8 = class(TfdLuminanceAlpha_UB2)
1498 constructor Create; override;
1501 TfdLuminance12Alpha4 = class(TfdLuminanceAlpha_US2)
1502 constructor Create; override;
1505 TfdLuminance16Alpha16 = class(TfdLuminanceAlpha_US2)
1506 constructor Create; override;
1509 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1510 TfdR3G3B2 = class(TfdUniversal_UB1)
1511 constructor Create; override;
1514 TfdRGBX4 = class(TfdUniversal_US1)
1515 constructor Create; override;
1518 TfdXRGB4 = class(TfdUniversal_US1)
1519 constructor Create; override;
1522 TfdR5G6B5 = class(TfdUniversal_US1)
1523 constructor Create; override;
1526 TfdRGB5X1 = class(TfdUniversal_US1)
1527 constructor Create; override;
1530 TfdX1RGB5 = class(TfdUniversal_US1)
1531 constructor Create; override;
1534 TfdRGB8 = class(TfdRGB_UB3)
1535 constructor Create; override;
1538 TfdRGBX8 = class(TfdUniversal_UI1)
1539 constructor Create; override;
1542 TfdXRGB8 = class(TfdUniversal_UI1)
1543 constructor Create; override;
1546 TfdRGB10X2 = class(TfdUniversal_UI1)
1547 constructor Create; override;
1550 TfdX2RGB10 = class(TfdUniversal_UI1)
1551 constructor Create; override;
1554 TfdRGB16 = class(TfdRGB_US3)
1555 constructor Create; override;
1558 TfdRGBA4 = class(TfdUniversal_US1)
1559 constructor Create; override;
1562 TfdARGB4 = class(TfdUniversal_US1)
1563 constructor Create; override;
1566 TfdRGB5A1 = class(TfdUniversal_US1)
1567 constructor Create; override;
1570 TfdA1RGB5 = class(TfdUniversal_US1)
1571 constructor Create; override;
1574 TfdRGBA8 = class(TfdUniversal_UI1)
1575 constructor Create; override;
1578 TfdARGB8 = class(TfdUniversal_UI1)
1579 constructor Create; override;
1582 TfdRGB10A2 = class(TfdUniversal_UI1)
1583 constructor Create; override;
1586 TfdA2RGB10 = class(TfdUniversal_UI1)
1587 constructor Create; override;
1590 TfdRGBA16 = class(TfdUniversal_UI1)
1591 constructor Create; override;
1594 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1595 TfdBGRX4 = class(TfdUniversal_US1)
1596 constructor Create; override;
1599 TfdXBGR4 = class(TfdUniversal_US1)
1600 constructor Create; override;
1603 TfdB5G6R5 = class(TfdUniversal_US1)
1604 constructor Create; override;
1607 TfdBGR5X1 = class(TfdUniversal_US1)
1608 constructor Create; override;
1611 TfdX1BGR5 = class(TfdUniversal_US1)
1612 constructor Create; override;
1615 TfdBGR8 = class(TfdBGR_UB3)
1616 constructor Create; override;
1619 TfdBGRX8 = class(TfdUniversal_UI1)
1620 constructor Create; override;
1623 TfdXBGR8 = class(TfdUniversal_UI1)
1624 constructor Create; override;
1627 TfdBGR10X2 = class(TfdUniversal_UI1)
1628 constructor Create; override;
1631 TfdX2BGR10 = class(TfdUniversal_UI1)
1632 constructor Create; override;
1635 TfdBGR16 = class(TfdBGR_US3)
1636 constructor Create; override;
1639 TfdBGRA4 = class(TfdUniversal_US1)
1640 constructor Create; override;
1643 TfdABGR4 = class(TfdUniversal_US1)
1644 constructor Create; override;
1647 TfdBGR5A1 = class(TfdUniversal_US1)
1648 constructor Create; override;
1651 TfdA1BGR5 = class(TfdUniversal_US1)
1652 constructor Create; override;
1655 TfdBGRA8 = class(TfdUniversal_UI1)
1656 constructor Create; override;
1659 TfdABGR8 = class(TfdUniversal_UI1)
1660 constructor Create; override;
1663 TfdBGR10A2 = class(TfdUniversal_UI1)
1664 constructor Create; override;
1667 TfdA2BGR10 = class(TfdUniversal_UI1)
1668 constructor Create; override;
1671 TfdBGRA16 = class(TfdBGRA_US4)
1672 constructor Create; override;
1675 TfdDepth16 = class(TfdDepth_US1)
1676 constructor Create; override;
1679 TfdDepth24 = class(TfdDepth_UI1)
1680 constructor Create; override;
1683 TfdDepth32 = class(TfdDepth_UI1)
1684 constructor Create; override;
1687 TfdS3tcDtx1RGBA = class(TFormatDescriptor)
1688 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1689 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1690 constructor Create; override;
1693 TfdS3tcDtx3RGBA = class(TFormatDescriptor)
1694 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1695 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1696 constructor Create; override;
1699 TfdS3tcDtx5RGBA = class(TFormatDescriptor)
1700 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1701 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1702 constructor Create; override;
1705 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1706 TbmpBitfieldFormat = class(TFormatDescriptor)
1708 procedure SetRedMask (const aValue: QWord);
1709 procedure SetGreenMask(const aValue: QWord);
1710 procedure SetBlueMask (const aValue: QWord);
1711 procedure SetAlphaMask(const aValue: QWord);
1713 procedure Update(aMask: QWord; out aRange: Cardinal; out aShift: Byte);
1715 property RedMask: QWord read GetRedMask write SetRedMask;
1716 property GreenMask: QWord read GetGreenMask write SetGreenMask;
1717 property BlueMask: QWord read GetBlueMask write SetBlueMask;
1718 property AlphaMask: QWord read GetAlphaMask write SetAlphaMask;
1720 property PixelSize: Single read fPixelSize write fPixelSize;
1722 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1723 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1726 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1727 TbmpColorTableEnty = packed record
1730 TbmpColorTable = array of TbmpColorTableEnty;
1731 TbmpColorTableFormat = class(TFormatDescriptor)
1733 fColorTable: TbmpColorTable;
1735 property PixelSize: Single read fPixelSize write fPixelSize;
1736 property ColorTable: TbmpColorTable read fColorTable write fColorTable;
1737 property Range: TglBitmapColorRec read fRange write fRange;
1738 property Shift: TShiftRec read fShift write fShift;
1739 property Format: TglBitmapFormat read fFormat write fFormat;
1741 procedure CreateColorTable;
1743 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1744 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1745 destructor Destroy; override;
1749 LUMINANCE_WEIGHT_R = 0.30;
1750 LUMINANCE_WEIGHT_G = 0.59;
1751 LUMINANCE_WEIGHT_B = 0.11;
1753 ALPHA_WEIGHT_R = 0.30;
1754 ALPHA_WEIGHT_G = 0.59;
1755 ALPHA_WEIGHT_B = 0.11;
1757 DEPTH_WEIGHT_R = 0.333333333;
1758 DEPTH_WEIGHT_G = 0.333333333;
1759 DEPTH_WEIGHT_B = 0.333333333;
1761 UNSUPPORTED_FORMAT = 'the given format isn''t supported by this function.';
1763 FORMAT_DESCRIPTOR_CLASSES: array[TglBitmapFormat] of TFormatDescriptorClass = (
1774 TfdLuminance4Alpha4,
1775 TfdLuminance6Alpha2,
1776 TfdLuminance8Alpha8,
1777 TfdLuminance12Alpha4,
1778 TfdLuminance16Alpha16,
1835 FormatDescriptorCS: TCriticalSection;
1836 FormatDescriptors: array[TglBitmapFormat] of TFormatDescriptor;
1838 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1839 constructor EglBitmapUnsupportedFormat.Create(const aFormat: TglBitmapFormat);
1841 inherited Create('unsupported format: ' + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
1844 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1845 constructor EglBitmapUnsupportedFormat.Create(const aMsg: String; const aFormat: TglBitmapFormat);
1847 inherited Create(aMsg + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
1850 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1851 function glBitmapPosition(X, Y: Integer): TglBitmapPixelPosition;
1853 result.Fields := [];
1856 result.Fields := result.Fields + [ffX];
1858 result.Fields := result.Fields + [ffY];
1860 result.X := Max(0, X);
1861 result.Y := Max(0, Y);
1864 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1865 function glBitmapColorRec(const r, g, b, a: Cardinal): TglBitmapColorRec;
1873 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1874 function glBitmapColorRecCmp(const r1, r2: TglBitmapColorRec): Boolean;
1879 for i := 0 to high(r1.arr) do
1880 if (r1.arr[i] <> r2.arr[i]) then
1885 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1886 function glBitmapShiftRec(const r, g, b, a: Byte): TShiftRec;
1894 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1895 function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes;
1904 tfR3G3B2, tfLuminance8,
1907 tfRGBX4, tfXRGB4, tfRGB5X1, tfX1RGB5, tfR5G6B5, tfRGB5A1, tfA1RGB5, tfRGBA4, tfARGB4,
1908 tfBGRX4, tfXBGR4, tfBGR5X1, tfX1BGR5, tfB5G6R5, tfBGR5A1, tfA1BGR5, tfBGRA4, tfABGR4,
1914 tfRGB10X2, tfX2RGB10, tfRGB10A2, tfA2RGB10, tfRGBA8, tfARGB8,
1915 tfBGR10X2, tfX2BGR10, tfBGR10A2, tfA2BGR10, tfBGRA8, tfABGR8]) then
1916 result := result + [ftBMP];
1920 tfLuminance8, tfAlpha8,
1923 tfLuminance16, tfLuminance8Alpha8,
1924 tfRGB5X1, tfX1RGB5, tfRGB5A1, tfA1RGB5, tfRGBA4, tfARGB4,
1925 tfBGR5X1, tfX1BGR5, tfBGR5A1, tfA1BGR5, tfBGRA4, tfABGR4,
1931 tfRGB10A2, tfRGBA8, tfBGR10A2, tfBGRA8]) then
1932 result := result + [ftTGA];
1936 tfAlpha8, tfLuminance8, tfLuminance4Alpha4, tfLuminance6Alpha2,
1940 tfAlpha16, tfLuminance16, tfLuminance8Alpha8, tfLuminance12Alpha4,
1941 tfRGBX4, tfXRGB4, tfR5G6B5, tfRGB5X1, tfX1RGB5, tfRGBA4, tfARGB4, tfRGB5A1, tfA1RGB5,
1942 tfBGRX4, tfXBGR4, tfB5G6R5, tfBGR5X1, tfX1BGR5, tfBGRA4, tfABGR4, tfBGR5A1, tfA1BGR5,
1948 tfLuminance16Alpha16,
1953 tfS3tcDtx1RGBA, tfS3tcDtx3RGBA, tfS3tcDtx5RGBA]) then
1954 result := result + [ftDDS];
1956 {$IFDEF GLB_SUPPORT_PNG_WRITE}
1958 tfAlpha8, tfLuminance8, tfLuminance8Alpha8,
1960 tfBGR8, tfBGRA8] then
1961 result := result + [ftPNG];
1964 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
1965 if aFormat in [tfAlpha8, tfLuminance8, tfRGB8, tfBGR8] then
1966 result := result + [ftJPEG];
1970 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1971 function IsPowerOfTwo(aNumber: Integer): Boolean;
1973 while (aNumber and 1) = 0 do
1974 aNumber := aNumber shr 1;
1975 result := aNumber = 1;
1978 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1979 function GetTopMostBit(aBitSet: QWord): Integer;
1982 while aBitSet > 0 do begin
1984 aBitSet := aBitSet shr 1;
1988 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1989 function CountSetBits(aBitSet: QWord): Integer;
1992 while aBitSet > 0 do begin
1993 if (aBitSet and 1) = 1 then
1995 aBitSet := aBitSet shr 1;
1999 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2000 function LuminanceWeight(const aPixel: TglBitmapPixelData): Cardinal;
2003 LUMINANCE_WEIGHT_R * aPixel.Data.r +
2004 LUMINANCE_WEIGHT_G * aPixel.Data.g +
2005 LUMINANCE_WEIGHT_B * aPixel.Data.b);
2008 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2009 function DepthWeight(const aPixel: TglBitmapPixelData): Cardinal;
2012 DEPTH_WEIGHT_R * aPixel.Data.r +
2013 DEPTH_WEIGHT_G * aPixel.Data.g +
2014 DEPTH_WEIGHT_B * aPixel.Data.b);
2017 {$IFDEF GLB_NATIVE_OGL}
2018 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2019 //OpenGLInitialization///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2020 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2022 GL_LibHandle: Pointer = nil;
2024 function glbGetProcAddress(aProcName: PAnsiChar; aLibHandle: Pointer = nil; const aRaiseOnErr: Boolean = true): Pointer;
2026 if not Assigned(aLibHandle) then
2027 aLibHandle := GL_LibHandle;
2029 {$IF DEFINED(GLB_WIN)}
2030 result := GetProcAddress({%H-}HMODULE(aLibHandle), aProcName);
2031 if Assigned(result) then
2034 if Assigned(wglGetProcAddress) then
2035 result := wglGetProcAddress(aProcName);
2036 {$ELSEIF DEFINED(GLB_LINUX)}
2037 if Assigned(glXGetProcAddress) then begin
2038 result := glXGetProcAddress(aProcName);
2039 if Assigned(result) then
2043 if Assigned(glXGetProcAddressARB) then begin
2044 result := glXGetProcAddressARB(aProcName);
2045 if Assigned(result) then
2049 result := dlsym(aLibHandle, aProcName);
2051 if not Assigned(result) and aRaiseOnErr then
2052 raise EglBitmap.Create('unable to load procedure form library: ' + aProcName);
2055 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
2057 GLU_LibHandle: Pointer = nil;
2058 OpenGLInitialized: Boolean;
2059 InitOpenGLCS: TCriticalSection;
2061 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2062 procedure glbInitOpenGL;
2064 ////////////////////////////////////////////////////////////////////////////////
2065 function glbLoadLibrary(const aName: PChar): Pointer;
2067 {$IF DEFINED(GLB_WIN)}
2068 result := {%H-}Pointer(LoadLibrary(aName));
2069 {$ELSEIF DEFINED(GLB_LINUX)}
2070 result := dlopen(Name, RTLD_LAZY);
2076 ////////////////////////////////////////////////////////////////////////////////
2077 function glbFreeLibrary(const aLibHandle: Pointer): Boolean;
2080 if not Assigned(aLibHandle) then
2083 {$IF DEFINED(GLB_WIN)}
2084 Result := FreeLibrary({%H-}HINST(aLibHandle));
2085 {$ELSEIF DEFINED(GLB_LINUX)}
2086 Result := dlclose(aLibHandle) = 0;
2091 if Assigned(GL_LibHandle) then
2092 glbFreeLibrary(GL_LibHandle);
2094 if Assigned(GLU_LibHandle) then
2095 glbFreeLibrary(GLU_LibHandle);
2097 GL_LibHandle := glbLoadLibrary(libopengl);
2098 if not Assigned(GL_LibHandle) then
2099 raise EglBitmap.Create('unable to load library: ' + libopengl);
2101 GLU_LibHandle := glbLoadLibrary(libglu);
2102 if not Assigned(GLU_LibHandle) then
2103 raise EglBitmap.Create('unable to load library: ' + libglu);
2105 {$IF DEFINED(GLB_WIN)}
2106 wglGetProcAddress := glbGetProcAddress('wglGetProcAddress');
2107 {$ELSEIF DEFINED(GLB_LINUX)}
2108 glXGetProcAddress := glbGetProcAddress('glXGetProcAddress');
2109 glXGetProcAddressARB := glbGetProcAddress('glXGetProcAddressARB');
2112 glEnable := glbGetProcAddress('glEnable');
2113 glDisable := glbGetProcAddress('glDisable');
2114 glGetString := glbGetProcAddress('glGetString');
2115 glGetIntegerv := glbGetProcAddress('glGetIntegerv');
2116 glTexParameteri := glbGetProcAddress('glTexParameteri');
2117 glTexParameteriv := glbGetProcAddress('glTexParameteriv');
2118 glTexParameterfv := glbGetProcAddress('glTexParameterfv');
2119 glGetTexParameteriv := glbGetProcAddress('glGetTexParameteriv');
2120 glGetTexParameterfv := glbGetProcAddress('glGetTexParameterfv');
2121 glGetTexLevelParameteriv := glbGetProcAddress('glGetTexLevelParameteriv');
2122 glGetTexLevelParameterfv := glbGetProcAddress('glGetTexLevelParameterfv');
2123 glTexGeni := glbGetProcAddress('glTexGeni');
2124 glGenTextures := glbGetProcAddress('glGenTextures');
2125 glBindTexture := glbGetProcAddress('glBindTexture');
2126 glDeleteTextures := glbGetProcAddress('glDeleteTextures');
2127 glAreTexturesResident := glbGetProcAddress('glAreTexturesResident');
2128 glReadPixels := glbGetProcAddress('glReadPixels');
2129 glPixelStorei := glbGetProcAddress('glPixelStorei');
2130 glTexImage1D := glbGetProcAddress('glTexImage1D');
2131 glTexImage2D := glbGetProcAddress('glTexImage2D');
2132 glGetTexImage := glbGetProcAddress('glGetTexImage');
2134 gluBuild1DMipmaps := glbGetProcAddress('gluBuild1DMipmaps', GLU_LibHandle);
2135 gluBuild2DMipmaps := glbGetProcAddress('gluBuild2DMipmaps', GLU_LibHandle);
2139 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2140 procedure glbReadOpenGLExtensions;
2143 MajorVersion, MinorVersion: Integer;
2145 ///////////////////////////////////////////////////////////////////////////////////////////
2146 procedure TrimVersionString(aBuffer: AnsiString; out aMajor, aMinor: Integer);
2153 Separator := Pos(AnsiString('.'), aBuffer);
2154 if (Separator > 1) and (Separator < Length(aBuffer)) and
2155 (aBuffer[Separator - 1] in ['0'..'9']) and
2156 (aBuffer[Separator + 1] in ['0'..'9']) then begin
2159 while (Separator > 0) and (aBuffer[Separator] in ['0'..'9']) do
2162 Delete(aBuffer, 1, Separator);
2163 Separator := Pos(AnsiString('.'), aBuffer) + 1;
2165 while (Separator <= Length(aBuffer)) and (AnsiChar(aBuffer[Separator]) in ['0'..'9']) do
2168 Delete(aBuffer, Separator, 255);
2169 Separator := Pos(AnsiString('.'), aBuffer);
2171 aMajor := StrToInt(Copy(String(aBuffer), 1, Separator - 1));
2172 aMinor := StrToInt(Copy(String(aBuffer), Separator + 1, 1));
2176 ///////////////////////////////////////////////////////////////////////////////////////////
2177 function CheckExtension(const Extension: AnsiString): Boolean;
2181 ExtPos := Pos(Extension, Buffer);
2182 result := ExtPos > 0;
2184 result := ((ExtPos + Length(Extension) - 1) = Length(Buffer)) or not (Buffer[ExtPos + Length(Extension)] in ['_', 'A'..'Z', 'a'..'z']);
2187 ///////////////////////////////////////////////////////////////////////////////////////////
2188 function CheckVersion(const aMajor, aMinor: Integer): Boolean;
2190 result := (MajorVersion > aMajor) or ((MajorVersion = aMajor) and (MinorVersion >= aMinor));
2194 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
2197 if not OpenGLInitialized then begin
2199 OpenGLInitialized := true;
2207 Buffer := glGetString(GL_VERSION);
2208 TrimVersionString(Buffer, MajorVersion, MinorVersion);
2210 GL_VERSION_1_2 := CheckVersion(1, 2);
2211 GL_VERSION_1_3 := CheckVersion(1, 3);
2212 GL_VERSION_1_4 := CheckVersion(1, 4);
2213 GL_VERSION_2_0 := CheckVersion(2, 0);
2214 GL_VERSION_3_3 := CheckVersion(3, 3);
2217 Buffer := glGetString(GL_EXTENSIONS);
2218 GL_ARB_texture_border_clamp := CheckExtension('GL_ARB_texture_border_clamp');
2219 GL_ARB_texture_non_power_of_two := CheckExtension('GL_ARB_texture_non_power_of_two');
2220 GL_ARB_texture_swizzle := CheckExtension('GL_ARB_texture_swizzle');
2221 GL_ARB_texture_cube_map := CheckExtension('GL_ARB_texture_cube_map');
2222 GL_ARB_texture_rectangle := CheckExtension('GL_ARB_texture_rectangle');
2223 GL_ARB_texture_mirrored_repeat := CheckExtension('GL_ARB_texture_mirrored_repeat');
2224 GL_EXT_texture_edge_clamp := CheckExtension('GL_EXT_texture_edge_clamp');
2225 GL_EXT_texture_filter_anisotropic := CheckExtension('GL_EXT_texture_filter_anisotropic');
2226 GL_EXT_texture_rectangle := CheckExtension('GL_EXT_texture_rectangle');
2227 GL_EXT_texture_swizzle := CheckExtension('GL_EXT_texture_swizzle');
2228 GL_EXT_texture_cube_map := CheckExtension('GL_EXT_texture_cube_map');
2229 GL_NV_texture_rectangle := CheckExtension('GL_NV_texture_rectangle');
2230 GL_IBM_texture_mirrored_repeat := CheckExtension('GL_IBM_texture_mirrored_repeat');
2231 GL_SGIS_generate_mipmap := CheckExtension('GL_SGIS_generate_mipmap');
2233 if GL_VERSION_1_3 then begin
2234 glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1D');
2235 glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2D');
2236 glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImage');
2238 glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1DARB', nil, false);
2239 glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2DARB', nil, false);
2240 glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImageARB', nil, false);
2245 {$IFDEF GLB_SDL_IMAGE}
2246 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2247 // SDL Image Helper /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2248 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2249 function glBitmapRWseek(context: PSDL_RWops; offset: Integer; whence: Integer): Integer; cdecl;
2251 result := TStream(context^.unknown.data1).Seek(offset, whence);
2254 function glBitmapRWread(context: PSDL_RWops; Ptr: Pointer; size: Integer; maxnum : Integer): Integer; cdecl;
2256 result := TStream(context^.unknown.data1).Read(Ptr^, size * maxnum);
2259 function glBitmapRWwrite(context: PSDL_RWops; Ptr: Pointer; size: Integer; num: Integer): Integer; cdecl;
2261 result := TStream(context^.unknown.data1).Write(Ptr^, size * num);
2264 function glBitmapRWclose(context: PSDL_RWops): Integer; cdecl;
2269 function glBitmapCreateRWops(Stream: TStream): PSDL_RWops;
2271 result := SDL_AllocRW;
2273 if result = nil then
2274 raise EglBitmapException.Create('glBitmapCreateRWops - SDL_AllocRW failed.');
2276 result^.seek := glBitmapRWseek;
2277 result^.read := glBitmapRWread;
2278 result^.write := glBitmapRWwrite;
2279 result^.close := glBitmapRWclose;
2280 result^.unknown.data1 := Stream;
2284 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2285 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
2287 glBitmapDefaultDeleteTextureOnFree := aDeleteTextureOnFree;
2290 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2291 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
2293 glBitmapDefaultFreeDataAfterGenTextures := aFreeData;
2296 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2297 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
2299 glBitmapDefaultMipmap := aValue;
2302 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2303 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
2305 glBitmapDefaultFormat := aFormat;
2308 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2309 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
2311 glBitmapDefaultFilterMin := aMin;
2312 glBitmapDefaultFilterMag := aMag;
2315 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2316 procedure glBitmapSetDefaultWrap(const S: Cardinal = GL_CLAMP_TO_EDGE; const T: Cardinal = GL_CLAMP_TO_EDGE; const R: Cardinal = GL_CLAMP_TO_EDGE);
2318 glBitmapDefaultWrapS := S;
2319 glBitmapDefaultWrapT := T;
2320 glBitmapDefaultWrapR := R;
2323 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2324 procedure glBitmapSetDefaultSwizzle(const r: GLenum = GL_RED; g: GLenum = GL_GREEN; b: GLenum = GL_BLUE; a: GLenum = GL_ALPHA);
2326 glDefaultSwizzle[0] := r;
2327 glDefaultSwizzle[1] := g;
2328 glDefaultSwizzle[2] := b;
2329 glDefaultSwizzle[3] := a;
2332 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2333 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
2335 result := glBitmapDefaultDeleteTextureOnFree;
2338 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2339 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
2341 result := glBitmapDefaultFreeDataAfterGenTextures;
2344 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2345 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
2347 result := glBitmapDefaultMipmap;
2350 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2351 function glBitmapGetDefaultFormat: TglBitmapFormat;
2353 result := glBitmapDefaultFormat;
2356 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2357 procedure glBitmapGetDefaultFilter(var aMin, aMag: GLenum);
2359 aMin := glBitmapDefaultFilterMin;
2360 aMag := glBitmapDefaultFilterMag;
2363 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2364 procedure glBitmapGetDefaultTextureWrap(var S, T, R: GLenum);
2366 S := glBitmapDefaultWrapS;
2367 T := glBitmapDefaultWrapT;
2368 R := glBitmapDefaultWrapR;
2371 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2372 procedure glBitmapGetDefaultSwizzle(var r, g, b, a: GLenum);
2374 r := glDefaultSwizzle[0];
2375 g := glDefaultSwizzle[1];
2376 b := glDefaultSwizzle[2];
2377 a := glDefaultSwizzle[3];
2380 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2381 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2382 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2383 function TFormatDescriptor.GetRedMask: QWord;
2385 result := fRange.r shl fShift.r;
2388 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2389 function TFormatDescriptor.GetGreenMask: QWord;
2391 result := fRange.g shl fShift.g;
2394 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2395 function TFormatDescriptor.GetBlueMask: QWord;
2397 result := fRange.b shl fShift.b;
2400 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2401 function TFormatDescriptor.GetAlphaMask: QWord;
2403 result := fRange.a shl fShift.a;
2406 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2407 function TFormatDescriptor.GetIsCompressed: Boolean;
2409 result := fIsCompressed;
2412 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2413 function TFormatDescriptor.GetHasRed: Boolean;
2415 result := (fRange.r > 0);
2418 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2419 function TFormatDescriptor.GetHasGreen: Boolean;
2421 result := (fRange.g > 0);
2424 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2425 function TFormatDescriptor.GetHasBlue: Boolean;
2427 result := (fRange.b > 0);
2430 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2431 function TFormatDescriptor.GetHasAlpha: Boolean;
2433 result := (fRange.a > 0);
2436 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2437 function TFormatDescriptor.GetRGBInverted: TglBitmapFormat;
2439 result := fRGBInverted;
2442 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2443 function TFormatDescriptor.GetWithAlpha: TglBitmapFormat;
2445 result := fWithAlpha;
2448 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2449 function TFormatDescriptor.GetWithoutAlpha: TglBitmapFormat;
2451 result := fWithoutAlpha;
2454 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2455 function TFormatDescriptor.GetOpenGLFormat: TglBitmapFormat;
2457 result := fOpenGLFormat;
2460 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2461 function TFormatDescriptor.GetUncompressed: TglBitmapFormat;
2463 result := fUncompressed;
2466 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2467 function TFormatDescriptor.GetglFormat: GLenum;
2469 result := fglFormat;
2472 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2473 function TFormatDescriptor.GetglInternalFormat: GLenum;
2475 result := fglInternalFormat;
2478 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2479 function TFormatDescriptor.GetglDataFormat: GLenum;
2481 result := fglDataFormat;
2484 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2485 function TFormatDescriptor.GetComponents: Integer;
2491 if (fRange.arr[i] > 0) then
2495 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2496 function TFormatDescriptor.GetSize(const aSize: TglBitmapPixelPosition): Integer;
2500 if (ffX in aSize.Fields) or (ffY in aSize.Fields) then begin
2501 w := Max(1, aSize.X);
2502 h := Max(1, aSize.Y);
2503 result := GetSize(w, h);
2508 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2509 function TFormatDescriptor.GetSize(const aWidth, aHeight: Integer): Integer;
2512 if (aWidth <= 0) or (aHeight <= 0) then
2514 result := Ceil(aWidth * aHeight * fPixelSize);
2517 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2518 function TFormatDescriptor.CreateMappingData: Pointer;
2523 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2524 procedure TFormatDescriptor.FreeMappingData(var aMappingData: Pointer);
2529 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2530 function TFormatDescriptor.IsEmpty: Boolean;
2532 result := (fFormat = tfEmpty);
2535 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2536 function TFormatDescriptor.MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: QWord): Boolean;
2539 if (aRedMask = 0) and (aGreenMask = 0) and (aBlueMask = 0) and (aAlphaMask = 0) then
2540 raise EglBitmap.Create('FormatCheckFormat - All Masks are 0');
2541 if (aRedMask <> RedMask) then
2543 if (aGreenMask <> GreenMask) then
2545 if (aBlueMask <> BlueMask) then
2547 if (aAlphaMask <> AlphaMask) then
2552 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2553 procedure TFormatDescriptor.PreparePixel(out aPixel: TglBitmapPixelData);
2555 FillChar(aPixel{%H-}, SizeOf(aPixel), 0);
2556 aPixel.Data := fRange;
2557 aPixel.Range := fRange;
2558 aPixel.Format := fFormat;
2561 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2562 constructor TFormatDescriptor.Create;
2567 fWithAlpha := tfEmpty;
2568 fWithoutAlpha := tfEmpty;
2569 fOpenGLFormat := tfEmpty;
2570 fRGBInverted := tfEmpty;
2571 fUncompressed := tfEmpty;
2574 fIsCompressed := false;
2577 fglInternalFormat := 0;
2580 FillChar(fRange, 0, SizeOf(fRange));
2581 FillChar(fShift, 0, SizeOf(fShift));
2584 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2585 //TfdAlpha_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2586 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2587 procedure TfdAlpha_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2589 aData^ := aPixel.Data.a;
2593 procedure TfdAlpha_UB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2598 aPixel.Data.a := aData^;
2602 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2603 //TfdLuminance_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2604 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2605 procedure TfdLuminance_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2607 aData^ := LuminanceWeight(aPixel);
2611 procedure TfdLuminance_UB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2613 aPixel.Data.r := aData^;
2614 aPixel.Data.g := aData^;
2615 aPixel.Data.b := aData^;
2620 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2621 //TfdUniversal_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2622 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2623 procedure TfdUniversal_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2629 if (fRange.arr[i] > 0) then
2630 aData^ := aData^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
2634 procedure TfdUniversal_UB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2639 aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and fRange.arr[i];
2643 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2644 //TfdLuminanceAlpha_UB2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2645 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2646 procedure TfdLuminanceAlpha_UB2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2648 inherited Map(aPixel, aData, aMapData);
2649 aData^ := aPixel.Data.a;
2653 procedure TfdLuminanceAlpha_UB2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2655 inherited Unmap(aData, aPixel, aMapData);
2656 aPixel.Data.a := aData^;
2660 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2661 //TfdRGB_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2662 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2663 procedure TfdRGB_UB3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2665 aData^ := aPixel.Data.b;
2667 aData^ := aPixel.Data.g;
2669 aData^ := aPixel.Data.r;
2673 procedure TfdRGB_UB3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2675 aPixel.Data.b := aData^;
2677 aPixel.Data.g := aData^;
2679 aPixel.Data.r := aData^;
2684 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2685 //TfdBGR_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2686 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2687 procedure TfdBGR_UB3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2689 aData^ := aPixel.Data.r;
2691 aData^ := aPixel.Data.g;
2693 aData^ := aPixel.Data.b;
2697 procedure TfdBGR_UB3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2699 aPixel.Data.r := aData^;
2701 aPixel.Data.g := aData^;
2703 aPixel.Data.b := aData^;
2708 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2709 //TfdAlpha_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2710 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2711 procedure TfdAlpha_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2713 PWord(aData)^ := aPixel.Data.a;
2717 procedure TfdAlpha_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2722 aPixel.Data.a := PWord(aData)^;
2726 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2727 //TfdLuminance_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2728 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2729 procedure TfdLuminance_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2731 PWord(aData)^ := LuminanceWeight(aPixel);
2735 procedure TfdLuminance_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2737 aPixel.Data.r := PWord(aData)^;
2738 aPixel.Data.g := PWord(aData)^;
2739 aPixel.Data.b := PWord(aData)^;
2744 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2745 //TfdUniversal_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2746 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2747 procedure TfdUniversal_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2753 if (fRange.arr[i] > 0) then
2754 PWord(aData)^ := PWord(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
2758 procedure TfdUniversal_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2763 aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and fRange.arr[i];
2767 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2768 //TfdDepth_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2769 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2770 procedure TfdDepth_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2772 PWord(aData)^ := DepthWeight(aPixel);
2776 procedure TfdDepth_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2778 aPixel.Data.r := PWord(aData)^;
2779 aPixel.Data.g := PWord(aData)^;
2780 aPixel.Data.b := PWord(aData)^;
2781 aPixel.Data.a := PWord(aData)^;;
2785 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2786 //TfdLuminanceAlpha_US2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2787 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2788 procedure TfdLuminanceAlpha_US2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2790 inherited Map(aPixel, aData, aMapData);
2791 PWord(aData)^ := aPixel.Data.a;
2795 procedure TfdLuminanceAlpha_US2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2797 inherited Unmap(aData, aPixel, aMapData);
2798 aPixel.Data.a := PWord(aData)^;
2802 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2803 //TfdRGB_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2804 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2805 procedure TfdRGB_US3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2807 PWord(aData)^ := aPixel.Data.b;
2809 PWord(aData)^ := aPixel.Data.g;
2811 PWord(aData)^ := aPixel.Data.r;
2815 procedure TfdRGB_US3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2817 aPixel.Data.b := PWord(aData)^;
2819 aPixel.Data.g := PWord(aData)^;
2821 aPixel.Data.r := PWord(aData)^;
2826 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2827 //TfdBGR_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2828 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2829 procedure TfdBGR_US3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2831 PWord(aData)^ := aPixel.Data.r;
2833 PWord(aData)^ := aPixel.Data.g;
2835 PWord(aData)^ := aPixel.Data.b;
2839 procedure TfdBGR_US3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2841 aPixel.Data.r := PWord(aData)^;
2843 aPixel.Data.g := PWord(aData)^;
2845 aPixel.Data.b := PWord(aData)^;
2850 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2851 //TfdRGBA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2852 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2853 procedure TfdRGBA_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2855 PWord(aData)^ := aPixel.Data.a;
2857 inherited Map(aPixel, aData, aMapData);
2860 procedure TfdRGBA_US4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2862 aPixel.Data.a := PWord(aData)^;
2864 inherited Unmap(aData, aPixel, aMapData);
2867 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2868 //TfdARGB_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2869 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2870 procedure TfdARGB_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2872 inherited Map(aPixel, aData, aMapData);
2873 PWord(aData)^ := aPixel.Data.a;
2877 procedure TfdARGB_US4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2879 inherited Unmap(aData, aPixel, aMapData);
2880 aPixel.Data.a := PWord(aData)^;
2884 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2885 //TfdBGRA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2886 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2887 procedure TfdBGRA_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2889 PWord(aData)^ := aPixel.Data.a;
2891 inherited Map(aPixel, aData, aMapData);
2894 procedure TfdBGRA_US4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2896 aPixel.Data.a := PWord(aData)^;
2898 inherited Unmap(aData, aPixel, aMapData);
2901 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2902 //TfdABGR_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2903 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2904 procedure TfdABGR_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2906 inherited Map(aPixel, aData, aMapData);
2907 PWord(aData)^ := aPixel.Data.a;
2911 procedure TfdABGR_US4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2913 inherited Unmap(aData, aPixel, aMapData);
2914 aPixel.Data.a := PWord(aData)^;
2918 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2919 //TfdUniversal_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2920 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2921 procedure TfdUniversal_UI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2925 PCardinal(aData)^ := 0;
2927 if (fRange.arr[i] > 0) then
2928 PCardinal(aData)^ := PCardinal(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
2932 procedure TfdUniversal_UI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2937 aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and fRange.arr[i];
2941 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2942 //TfdDepth_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2943 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2944 procedure TfdDepth_UI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2946 PCardinal(aData)^ := DepthWeight(aPixel);
2950 procedure TfdDepth_UI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2952 aPixel.Data.r := PCardinal(aData)^;
2953 aPixel.Data.g := PCardinal(aData)^;
2954 aPixel.Data.b := PCardinal(aData)^;
2959 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2960 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2961 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2962 constructor TfdAlpha4.Create;
2966 fFormat := tfAlpha4;
2967 fWithAlpha := tfAlpha4;
2968 fOpenGLFormat := tfAlpha4;
2970 fglFormat := GL_ALPHA;
2971 fglInternalFormat := GL_ALPHA4;
2972 fglDataFormat := GL_UNSIGNED_BYTE;
2975 constructor TfdAlpha8.Create;
2979 fFormat := tfAlpha8;
2980 fWithAlpha := tfAlpha8;
2981 fOpenGLFormat := tfAlpha8;
2983 fglFormat := GL_ALPHA;
2984 fglInternalFormat := GL_ALPHA8;
2985 fglDataFormat := GL_UNSIGNED_BYTE;
2988 constructor TfdAlpha16.Create;
2992 fFormat := tfAlpha16;
2993 fWithAlpha := tfAlpha16;
2994 fOpenGLFormat := tfAlpha16;
2996 fglFormat := GL_ALPHA;
2997 fglInternalFormat := GL_ALPHA16;
2998 fglDataFormat := GL_UNSIGNED_SHORT;
3001 constructor TfdLuminance4.Create;
3005 fFormat := tfLuminance4;
3006 fWithAlpha := tfLuminance4Alpha4;
3007 fWithoutAlpha := tfLuminance4;
3008 fOpenGLFormat := tfLuminance4;
3012 fglFormat := GL_LUMINANCE;
3013 fglInternalFormat := GL_LUMINANCE4;
3014 fglDataFormat := GL_UNSIGNED_BYTE;
3017 constructor TfdLuminance8.Create;
3021 fFormat := tfLuminance8;
3022 fWithAlpha := tfLuminance8Alpha8;
3023 fWithoutAlpha := tfLuminance8;
3024 fOpenGLFormat := tfLuminance8;
3028 fglFormat := GL_LUMINANCE;
3029 fglInternalFormat := GL_LUMINANCE8;
3030 fglDataFormat := GL_UNSIGNED_BYTE;
3033 constructor TfdLuminance16.Create;
3037 fFormat := tfLuminance16;
3038 fWithAlpha := tfLuminance16Alpha16;
3039 fWithoutAlpha := tfLuminance16;
3040 fOpenGLFormat := tfLuminance16;
3044 fglFormat := GL_LUMINANCE;
3045 fglInternalFormat := GL_LUMINANCE16;
3046 fglDataFormat := GL_UNSIGNED_SHORT;
3049 constructor TfdLuminance4Alpha4.Create;
3053 fFormat := tfLuminance4Alpha4;
3054 fWithAlpha := tfLuminance4Alpha4;
3055 fWithoutAlpha := tfLuminance4;
3056 fOpenGLFormat := tfLuminance4Alpha4;
3065 fglFormat := GL_LUMINANCE_ALPHA;
3066 fglInternalFormat := GL_LUMINANCE4_ALPHA4;
3067 fglDataFormat := GL_UNSIGNED_BYTE;
3070 constructor TfdLuminance6Alpha2.Create;
3074 fFormat := tfLuminance6Alpha2;
3075 fWithAlpha := tfLuminance6Alpha2;
3076 fWithoutAlpha := tfLuminance8;
3077 fOpenGLFormat := tfLuminance6Alpha2;
3086 fglFormat := GL_LUMINANCE_ALPHA;
3087 fglInternalFormat := GL_LUMINANCE6_ALPHA2;
3088 fglDataFormat := GL_UNSIGNED_BYTE;
3091 constructor TfdLuminance8Alpha8.Create;
3095 fFormat := tfLuminance8Alpha8;
3096 fWithAlpha := tfLuminance8Alpha8;
3097 fWithoutAlpha := tfLuminance8;
3098 fOpenGLFormat := tfLuminance8Alpha8;
3107 fglFormat := GL_LUMINANCE_ALPHA;
3108 fglInternalFormat := GL_LUMINANCE8_ALPHA8;
3109 fglDataFormat := GL_UNSIGNED_BYTE;
3112 constructor TfdLuminance12Alpha4.Create;
3116 fFormat := tfLuminance12Alpha4;
3117 fWithAlpha := tfLuminance12Alpha4;
3118 fWithoutAlpha := tfLuminance16;
3119 fOpenGLFormat := tfLuminance12Alpha4;
3128 fglFormat := GL_LUMINANCE_ALPHA;
3129 fglInternalFormat := GL_LUMINANCE12_ALPHA4;
3130 fglDataFormat := GL_UNSIGNED_SHORT;
3133 constructor TfdLuminance16Alpha16.Create;
3137 fFormat := tfLuminance16Alpha16;
3138 fWithAlpha := tfLuminance16Alpha16;
3139 fWithoutAlpha := tfLuminance16;
3140 fOpenGLFormat := tfLuminance16Alpha16;
3149 fglFormat := GL_LUMINANCE_ALPHA;
3150 fglInternalFormat := GL_LUMINANCE16_ALPHA16;
3151 fglDataFormat := GL_UNSIGNED_SHORT;
3154 constructor TfdR3G3B2.Create;
3158 fFormat := tfR3G3B2;
3159 fWithAlpha := tfRGBA4;
3160 fWithoutAlpha := tfR3G3B2;
3161 fOpenGLFormat := tfR3G3B2;
3162 fRGBInverted := tfEmpty;
3169 fglFormat := GL_RGB;
3170 fglInternalFormat := GL_R3_G3_B2;
3171 fglDataFormat := GL_UNSIGNED_BYTE_3_3_2;
3174 constructor TfdRGBX4.Create;
3179 fWithAlpha := tfRGBA4;
3180 fWithoutAlpha := tfRGBX4;
3181 fOpenGLFormat := tfRGBX4;
3182 fRGBInverted := tfBGRX4;
3190 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3191 fglInternalFormat := GL_RGB4;
3192 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3195 constructor TfdXRGB4.Create;
3200 fWithAlpha := tfARGB4;
3201 fWithoutAlpha := tfXRGB4;
3202 fOpenGLFormat := tfXRGB4;
3203 fRGBInverted := tfXBGR4;
3210 fglFormat := GL_BGRA;
3211 fglInternalFormat := GL_RGB4;
3212 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3215 constructor TfdR5G6B5.Create;
3219 fFormat := tfR5G6B5;
3220 fWithAlpha := tfRGB5A1;
3221 fWithoutAlpha := tfR5G6B5;
3222 fOpenGLFormat := tfR5G6B5;
3223 fRGBInverted := tfB5G6R5;
3230 fglFormat := GL_RGB;
3231 fglInternalFormat := GL_RGB565;
3232 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5;
3235 constructor TfdRGB5X1.Create;
3239 fFormat := tfRGB5X1;
3240 fWithAlpha := tfRGB5A1;
3241 fWithoutAlpha := tfRGB5X1;
3242 fOpenGLFormat := tfRGB5X1;
3243 fRGBInverted := tfBGR5X1;
3250 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3251 fglInternalFormat := GL_RGB5;
3252 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3255 constructor TfdX1RGB5.Create;
3259 fFormat := tfX1RGB5;
3260 fWithAlpha := tfA1RGB5;
3261 fWithoutAlpha := tfX1RGB5;
3262 fOpenGLFormat := tfX1RGB5;
3263 fRGBInverted := tfX1BGR5;
3270 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3271 fglInternalFormat := GL_RGB5;
3272 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3275 constructor TfdRGB8.Create;
3280 fWithAlpha := tfRGBA8;
3281 fWithoutAlpha := tfRGB8;
3282 fOpenGLFormat := tfRGB8;
3283 fRGBInverted := tfBGR8;
3290 fglFormat := GL_BGR; // reverse byte order to match little endianess
3291 fglInternalFormat := GL_RGB8; // as if u interpret the 3 bytes as unsigned integer
3292 fglDataFormat := GL_UNSIGNED_BYTE;
3295 constructor TfdRGBX8.Create;
3300 fWithAlpha := tfRGBA8;
3301 fWithoutAlpha := tfRGBX8;
3302 fOpenGLFormat := tfRGB8;
3303 fRGBInverted := tfBGRX8;
3310 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3311 fglInternalFormat := GL_RGB8;
3312 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3315 constructor TfdXRGB8.Create;
3320 fWithAlpha := tfXRGB8;
3321 fWithoutAlpha := tfXRGB8;
3322 fOpenGLFormat := tfRGB8;
3323 fRGBInverted := tfXBGR8;
3330 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3331 fglInternalFormat := GL_RGB8;
3332 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3335 constructor TfdRGB10X2.Create;
3339 fFormat := tfRGB10X2;
3340 fWithAlpha := tfRGB10A2;
3341 fWithoutAlpha := tfRGB10X2;
3342 fOpenGLFormat := tfRGB10X2;
3343 fRGBInverted := tfBGR10X2;
3350 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3351 fglInternalFormat := GL_RGB10;
3352 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3355 constructor TfdX2RGB10.Create;
3359 fFormat := tfX2RGB10;
3360 fWithAlpha := tfA2RGB10;
3361 fWithoutAlpha := tfX2RGB10;
3362 fOpenGLFormat := tfX2RGB10;
3363 fRGBInverted := tfX2BGR10;
3370 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3371 fglInternalFormat := GL_RGB10;
3372 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3375 constructor TfdRGB16.Create;
3380 fWithAlpha := tfRGBA16;
3381 fWithoutAlpha := tfRGB16;
3382 fOpenGLFormat := tfRGB16;
3383 fRGBInverted := tfBGR16;
3390 fglFormat := GL_BGR; // reverse byte order to match little endianess
3391 fglInternalFormat := GL_RGB16; // as if u interpret the 3 bytes as unsigned integer
3392 fglDataFormat := GL_UNSIGNED_SHORT;
3395 constructor TfdRGBA4.Create;
3400 fWithAlpha := tfRGBA4;
3401 fWithoutAlpha := tfRGBX4;
3402 fOpenGLFormat := tfRGBA4;
3403 fRGBInverted := tfBGRA4;
3412 fglFormat := GL_RGBA;
3413 fglInternalFormat := GL_RGBA4;
3414 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3417 constructor TfdARGB4.Create;
3422 fWithAlpha := tfARGB4;
3423 fWithoutAlpha := tfXRGB4;
3424 fOpenGLFormat := tfARGB4;
3425 fRGBInverted := tfABGR4;
3434 fglFormat := GL_BGRA;
3435 fglInternalFormat := GL_RGBA4;
3436 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3439 constructor TfdRGB5A1.Create;
3443 fFormat := tfRGB5A1;
3444 fWithAlpha := tfRGB5A1;
3445 fWithoutAlpha := tfRGB5X1;
3446 fOpenGLFormat := tfRGB5A1;
3447 fRGBInverted := tfBGR5A1;
3456 fglFormat := GL_RGBA;
3457 fglInternalFormat := GL_RGB5_A1;
3458 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3461 constructor TfdA1RGB5.Create;
3465 fFormat := tfA1RGB5;
3466 fWithAlpha := tfA1RGB5;
3467 fWithoutAlpha := tfX1RGB5;
3468 fOpenGLFormat := tfA1RGB5;
3469 fRGBInverted := tfA1BGR5;
3478 fglFormat := GL_BGRA;
3479 fglInternalFormat := GL_RGB5_A1;
3480 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3483 constructor TfdRGBA8.Create;
3488 fWithAlpha := tfRGBA8;
3489 fWithoutAlpha := tfRGB8;
3490 fOpenGLFormat := tfRGBA8;
3491 fRGBInverted := tfBGRA8;
3500 fglFormat := GL_RGBA;
3501 fglInternalFormat := GL_RGBA8;
3502 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3505 constructor TfdARGB8.Create;
3510 fWithAlpha := tfARGB8;
3511 fWithoutAlpha := tfRGB8;
3512 fOpenGLFormat := tfARGB8;
3513 fRGBInverted := tfABGR8;
3522 fglFormat := GL_BGRA;
3523 fglInternalFormat := GL_RGBA8;
3524 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3527 constructor TfdRGB10A2.Create;
3531 fFormat := tfRGB10A2;
3532 fWithAlpha := tfRGB10A2;
3533 fWithoutAlpha := tfRGB10X2;
3534 fOpenGLFormat := tfRGB10A2;
3535 fRGBInverted := tfBGR10A2;
3544 fglFormat := GL_RGBA;
3545 fglInternalFormat := GL_RGB10_A2;
3546 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3549 constructor TfdA2RGB10.Create;
3553 fFormat := tfA2RGB10;
3554 fWithAlpha := tfA2RGB10;
3555 fWithoutAlpha := tfX2RGB10;
3556 fOpenGLFormat := tfA2RGB10;
3557 fRGBInverted := tfA2BGR10;
3566 fglFormat := GL_BGRA;
3567 fglInternalFormat := GL_RGB10_A2;
3568 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3571 constructor TfdRGBA16.Create;
3575 fFormat := tfRGBA16;
3576 fWithAlpha := tfRGBA16;
3577 fWithoutAlpha := tfRGB16;
3578 fOpenGLFormat := tfRGBA16;
3579 fRGBInverted := tfBGRA16;
3588 fglFormat := GL_BGRA; // reverse byte order to match little endianess
3589 fglInternalFormat := GL_RGBA16; // as if u interpret the 3 bytes as unsigned integer
3590 fglDataFormat := GL_UNSIGNED_SHORT;
3593 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3594 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3595 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3596 constructor TfdBGRX4.Create;
3601 fWithAlpha := tfBGRA4;
3602 fWithoutAlpha := tfBGRX4;
3603 fOpenGLFormat := tfBGRX4;
3604 fRGBInverted := tfRGBX4;
3611 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3612 fglInternalFormat := GL_RGB4;
3613 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3616 constructor TfdXBGR4.Create;
3621 fWithAlpha := tfABGR4;
3622 fWithoutAlpha := tfXBGR4;
3623 fOpenGLFormat := tfXBGR4;
3624 fRGBInverted := tfXRGB4;
3632 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3633 fglInternalFormat := GL_RGB4;
3634 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3637 constructor TfdB5G6R5.Create;
3641 fFormat := tfB5G6R5;
3642 fWithAlpha := tfBGR5A1;
3643 fWithoutAlpha := tfB5G6R5;
3644 fOpenGLFormat := tfB5G6R5;
3645 fRGBInverted := tfR5G6B5;
3652 fglFormat := GL_RGB;
3653 fglInternalFormat := GL_RGB565;
3654 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5_REV;
3657 constructor TfdBGR5X1.Create;
3661 fFormat := tfBGR5X1;
3662 fWithAlpha := tfBGR5A1;
3663 fWithoutAlpha := tfBGR5X1;
3664 fOpenGLFormat := tfBGR5X1;
3665 fRGBInverted := tfRGB5X1;
3672 fglFormat := GL_BGRA;
3673 fglInternalFormat := GL_RGB5;
3674 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3677 constructor TfdX1BGR5.Create;
3681 fFormat := tfX1BGR5;
3682 fWithAlpha := tfA1BGR5;
3683 fWithoutAlpha := tfX1BGR5;
3684 fOpenGLFormat := tfX1BGR5;
3685 fRGBInverted := tfX1RGB5;
3692 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3693 fglInternalFormat := GL_RGB5;
3694 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3697 constructor TfdBGR8.Create;
3702 fWithAlpha := tfBGRA8;
3703 fWithoutAlpha := tfBGR8;
3704 fOpenGLFormat := tfBGR8;
3705 fRGBInverted := tfRGB8;
3712 fglFormat := GL_RGB; // reverse byte order to match little endianess
3713 fglInternalFormat := GL_RGB8; // as if u interpret the 3 bytes as unsigned integer
3714 fglDataFormat := GL_UNSIGNED_BYTE;
3717 constructor TfdBGRX8.Create;
3722 fWithAlpha := tfBGRA8;
3723 fWithoutAlpha := tfBGRX8;
3724 fOpenGLFormat := tfBGRX8;
3725 fRGBInverted := tfRGBX8;
3732 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3733 fglInternalFormat := GL_RGB8;
3734 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3737 constructor TfdXBGR8.Create;
3742 fWithAlpha := tfABGR8;
3743 fWithoutAlpha := tfXBGR8;
3744 fOpenGLFormat := tfXBGR8;
3745 fRGBInverted := tfXRGB8;
3752 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3753 fglInternalFormat := GL_RGB8;
3754 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3757 constructor TfdBGR10X2.Create;
3761 fFormat := tfBGR10X2;
3762 fWithAlpha := tfBGR10A2;
3763 fWithoutAlpha := tfBGR10X2;
3764 fOpenGLFormat := tfBGR10X2;
3765 fRGBInverted := tfRGB10X2;
3772 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3773 fglInternalFormat := GL_RGB10;
3774 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3777 constructor TfdX2BGR10.Create;
3781 fFormat := tfX2BGR10;
3782 fWithAlpha := tfA2BGR10;
3783 fWithoutAlpha := tfX2BGR10;
3784 fOpenGLFormat := tfX2BGR10;
3785 fRGBInverted := tfX2RGB10;
3792 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3793 fglInternalFormat := GL_RGB10;
3794 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3797 constructor TfdBGR16.Create;
3802 fWithAlpha := tfBGRA16;
3803 fWithoutAlpha := tfBGR16;
3804 fOpenGLFormat := tfBGR16;
3805 fRGBInverted := tfRGB16;
3812 fglFormat := GL_RGB; // reverse byte order to match little endianess
3813 fglInternalFormat := GL_RGB16; // as if u interpret the 3 bytes as unsigned integer
3814 fglDataFormat := GL_UNSIGNED_SHORT;
3817 constructor TfdBGRA4.Create;
3822 fWithAlpha := tfBGRA4;
3823 fWithoutAlpha := tfBGRX4;
3824 fOpenGLFormat := tfBGRA4;
3825 fRGBInverted := tfRGBA4;
3834 fglFormat := GL_BGRA;
3835 fglInternalFormat := GL_RGBA4;
3836 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3839 constructor TfdABGR4.Create;
3844 fWithAlpha := tfABGR4;
3845 fWithoutAlpha := tfXBGR4;
3846 fOpenGLFormat := tfABGR4;
3847 fRGBInverted := tfARGB4;
3856 fglFormat := GL_RGBA;
3857 fglInternalFormat := GL_RGBA4;
3858 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3861 constructor TfdBGR5A1.Create;
3865 fFormat := tfBGR5A1;
3866 fWithAlpha := tfBGR5A1;
3867 fWithoutAlpha := tfBGR5X1;
3868 fOpenGLFormat := tfBGR5A1;
3869 fRGBInverted := tfRGB5A1;
3878 fglFormat := GL_BGRA;
3879 fglInternalFormat := GL_RGB5_A1;
3880 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3883 constructor TfdA1BGR5.Create;
3887 fFormat := tfA1BGR5;
3888 fWithAlpha := tfA1BGR5;
3889 fWithoutAlpha := tfX1BGR5;
3890 fOpenGLFormat := tfA1BGR5;
3891 fRGBInverted := tfA1RGB5;
3900 fglFormat := GL_RGBA;
3901 fglInternalFormat := GL_RGB5_A1;
3902 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3905 constructor TfdBGRA8.Create;
3910 fWithAlpha := tfBGRA8;
3911 fWithoutAlpha := tfBGR8;
3912 fOpenGLFormat := tfBGRA8;
3913 fRGBInverted := tfRGBA8;
3922 fglFormat := GL_BGRA;
3923 fglInternalFormat := GL_RGBA8;
3924 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3927 constructor TfdABGR8.Create;
3932 fWithAlpha := tfABGR8;
3933 fWithoutAlpha := tfBGR8;
3934 fOpenGLFormat := tfABGR8;
3935 fRGBInverted := tfARGB8;
3944 fglFormat := GL_RGBA;
3945 fglInternalFormat := GL_RGBA8;
3946 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3949 constructor TfdBGR10A2.Create;
3953 fFormat := tfBGR10A2;
3954 fWithAlpha := tfBGR10A2;
3955 fWithoutAlpha := tfBGR10X2;
3956 fOpenGLFormat := tfBGR10A2;
3957 fRGBInverted := tfRGB10A2;
3966 fglFormat := GL_BGRA;
3967 fglInternalFormat := GL_RGB10_A2;
3968 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3971 constructor TfdA2BGR10.Create;
3975 fFormat := tfA2BGR10;
3976 fWithAlpha := tfA2BGR10;
3977 fWithoutAlpha := tfX2BGR10;
3978 fOpenGLFormat := tfA2BGR10;
3979 fRGBInverted := tfA2RGB10;
3988 fglFormat := GL_RGBA;
3989 fglInternalFormat := GL_RGB10_A2;
3990 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3993 constructor TfdBGRA16.Create;
3997 fFormat := tfBGRA16;
3998 fWithAlpha := tfBGRA16;
3999 fWithoutAlpha := tfBGR16;
4000 fOpenGLFormat := tfBGRA16;
4001 fRGBInverted := tfRGBA16;
4010 fglFormat := GL_RGBA; // reverse byte order to match little endianess
4011 fglInternalFormat := GL_RGBA16; // as if u interpret the 3 bytes as unsigned integer
4012 fglDataFormat := GL_UNSIGNED_SHORT;
4015 constructor TfdDepth16.Create;
4019 fFormat := tfDepth16;
4020 fWithoutAlpha := tfDepth16;
4021 fOpenGLFormat := tfDepth16;
4026 fglFormat := GL_DEPTH_COMPONENT;
4027 fglInternalFormat := GL_DEPTH_COMPONENT16;
4028 fglDataFormat := GL_UNSIGNED_SHORT;
4031 constructor TfdDepth24.Create;
4035 fFormat := tfDepth24;
4036 fWithoutAlpha := tfDepth24;
4037 fOpenGLFormat := tfDepth24;
4038 fRange.r := $FFFFFF;
4039 fRange.g := $FFFFFF;
4040 fRange.b := $FFFFFF;
4041 fRange.a := $FFFFFF;
4042 fglFormat := GL_DEPTH_COMPONENT;
4043 fglInternalFormat := GL_DEPTH_COMPONENT24;
4044 fglDataFormat := GL_UNSIGNED_INT;
4047 constructor TfdDepth32.Create;
4051 fFormat := tfDepth32;
4052 fWithoutAlpha := tfDepth32;
4053 fOpenGLFormat := tfDepth32;
4054 fRange.r := $FFFFFFFF;
4055 fRange.g := $FFFFFFFF;
4056 fRange.b := $FFFFFFFF;
4057 fRange.a := $FFFFFFFF;
4058 fglFormat := GL_DEPTH_COMPONENT;
4059 fglInternalFormat := GL_DEPTH_COMPONENT32;
4060 fglDataFormat := GL_UNSIGNED_INT;
4063 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4064 //TfdS3tcDtx1RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4065 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4066 procedure TfdS3tcDtx1RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4068 raise EglBitmap.Create('mapping for compressed formats is not supported');
4071 procedure TfdS3tcDtx1RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4073 raise EglBitmap.Create('mapping for compressed formats is not supported');
4076 constructor TfdS3tcDtx1RGBA.Create;
4079 fFormat := tfS3tcDtx1RGBA;
4080 fWithAlpha := tfS3tcDtx1RGBA;
4081 fOpenGLFormat := tfS3tcDtx1RGBA;
4082 fUncompressed := tfRGB5A1;
4084 fIsCompressed := true;
4085 fglFormat := GL_COMPRESSED_RGBA;
4086 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
4087 fglDataFormat := GL_UNSIGNED_BYTE;
4090 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4091 //TfdS3tcDtx3RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4092 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4093 procedure TfdS3tcDtx3RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4095 raise EglBitmap.Create('mapping for compressed formats is not supported');
4098 procedure TfdS3tcDtx3RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4100 raise EglBitmap.Create('mapping for compressed formats is not supported');
4103 constructor TfdS3tcDtx3RGBA.Create;
4106 fFormat := tfS3tcDtx3RGBA;
4107 fWithAlpha := tfS3tcDtx3RGBA;
4108 fOpenGLFormat := tfS3tcDtx3RGBA;
4109 fUncompressed := tfRGBA8;
4111 fIsCompressed := true;
4112 fglFormat := GL_COMPRESSED_RGBA;
4113 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
4114 fglDataFormat := GL_UNSIGNED_BYTE;
4117 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4118 //TfdS3tcDtx5RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4119 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4120 procedure TfdS3tcDtx5RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4122 raise EglBitmap.Create('mapping for compressed formats is not supported');
4125 procedure TfdS3tcDtx5RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4127 raise EglBitmap.Create('mapping for compressed formats is not supported');
4130 constructor TfdS3tcDtx5RGBA.Create;
4133 fFormat := tfS3tcDtx3RGBA;
4134 fWithAlpha := tfS3tcDtx3RGBA;
4135 fOpenGLFormat := tfS3tcDtx3RGBA;
4136 fUncompressed := tfRGBA8;
4138 fIsCompressed := true;
4139 fglFormat := GL_COMPRESSED_RGBA;
4140 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
4141 fglDataFormat := GL_UNSIGNED_BYTE;
4144 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4145 //TglBitmapFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4146 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4147 class function TglBitmapFormatDescriptor.GetByFormat(const aInternalFormat: GLenum): TglBitmapFormatDescriptor;
4151 for f := Low(TglBitmapFormat) to High(TglBitmapFormat) do begin
4152 result := TFormatDescriptor.Get(f);
4153 if (result.glInternalFormat = aInternalFormat) then
4156 result := TFormatDescriptor.Get(tfEmpty);
4159 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4160 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4161 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4162 class procedure TFormatDescriptor.Init;
4164 if not Assigned(FormatDescriptorCS) then
4165 FormatDescriptorCS := TCriticalSection.Create;
4168 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4169 class function TFormatDescriptor.Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
4171 FormatDescriptorCS.Enter;
4173 result := FormatDescriptors[aFormat];
4174 if not Assigned(result) then begin
4175 result := FORMAT_DESCRIPTOR_CLASSES[aFormat].Create;
4176 FormatDescriptors[aFormat] := result;
4179 FormatDescriptorCS.Leave;
4183 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4184 class function TFormatDescriptor.GetAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
4186 result := Get(Get(aFormat).WithAlpha);
4189 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4190 class procedure TFormatDescriptor.Clear;
4194 FormatDescriptorCS.Enter;
4196 for f := low(FormatDescriptors) to high(FormatDescriptors) do
4197 FreeAndNil(FormatDescriptors[f]);
4199 FormatDescriptorCS.Leave;
4203 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4204 class procedure TFormatDescriptor.Finalize;
4207 FreeAndNil(FormatDescriptorCS);
4210 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4211 //TBitfieldFormat/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4212 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4213 procedure TbmpBitfieldFormat.SetRedMask(const aValue: QWord);
4215 Update(aValue, fRange.r, fShift.r);
4218 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4219 procedure TbmpBitfieldFormat.SetGreenMask(const aValue: QWord);
4221 Update(aValue, fRange.g, fShift.g);
4224 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4225 procedure TbmpBitfieldFormat.SetBlueMask(const aValue: QWord);
4227 Update(aValue, fRange.b, fShift.b);
4230 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4231 procedure TbmpBitfieldFormat.SetAlphaMask(const aValue: QWord);
4233 Update(aValue, fRange.a, fShift.a);
4236 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4237 procedure TbmpBitfieldFormat.Update(aMask: QWord; out aRange: Cardinal; out
4244 while (aMask > 0) and ((aMask and 1) = 0) do begin
4246 aMask := aMask shr 1;
4249 while (aMask > 0) do begin
4250 aRange := aRange shl 1;
4251 aMask := aMask shr 1;
4255 fPixelSize := Round(GetTopMostBit(RedMask or GreenMask or BlueMask or AlphaMask) / 8);
4258 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4259 procedure TbmpBitfieldFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4265 ((aPixel.Data.r and fRange.r) shl fShift.r) or
4266 ((aPixel.Data.g and fRange.g) shl fShift.g) or
4267 ((aPixel.Data.b and fRange.b) shl fShift.b) or
4268 ((aPixel.Data.a and fRange.a) shl fShift.a);
4269 s := Round(fPixelSize);
4272 2: PWord(aData)^ := data;
4273 4: PCardinal(aData)^ := data;
4274 8: PQWord(aData)^ := data;
4276 raise EglBitmap.CreateFmt('invalid pixel size: %.1f', [fPixelSize]);
4281 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4282 procedure TbmpBitfieldFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4287 s := Round(fPixelSize);
4290 2: data := PWord(aData)^;
4291 4: data := PCardinal(aData)^;
4292 8: data := PQWord(aData)^;
4294 raise EglBitmap.CreateFmt('invalid pixel size: %.1f', [fPixelSize]);
4297 aPixel.Data.arr[i] := (data shr fShift.arr[i]) and fRange.arr[i];
4301 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4302 //TColorTableFormat///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4303 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4304 procedure TbmpColorTableFormat.CreateColorTable;
4308 if not (Format in [tfLuminance4, tfLuminance8, tfR3G3B2]) then
4309 raise EglBitmap.Create(UNSUPPORTED_FORMAT);
4311 if (Format = tfLuminance4) then
4312 SetLength(fColorTable, 16)
4314 SetLength(fColorTable, 256);
4318 for i := 0 to High(fColorTable) do begin
4319 fColorTable[i].r := 16 * i;
4320 fColorTable[i].g := 16 * i;
4321 fColorTable[i].b := 16 * i;
4322 fColorTable[i].a := 0;
4327 for i := 0 to High(fColorTable) do begin
4328 fColorTable[i].r := i;
4329 fColorTable[i].g := i;
4330 fColorTable[i].b := i;
4331 fColorTable[i].a := 0;
4336 for i := 0 to High(fColorTable) do begin
4337 fColorTable[i].r := Round(((i shr Shift.r) and Range.r) / Range.r * 255);
4338 fColorTable[i].g := Round(((i shr Shift.g) and Range.g) / Range.g * 255);
4339 fColorTable[i].b := Round(((i shr Shift.b) and Range.b) / Range.b * 255);
4340 fColorTable[i].a := 0;
4346 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4347 procedure TbmpColorTableFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4351 if not (Format in [tfLuminance4, tfLuminance8, tfR3G3B2]) then
4352 raise EglBitmap.Create(UNSUPPORTED_FORMAT);
4356 if (aMapData = nil) then
4358 d := LuminanceWeight(aPixel) and Range.r;
4359 aData^ := aData^ or (d shl (4 - {%H-}PtrUInt(aMapData)));
4360 inc(PByte(aMapData), 4);
4361 if ({%H-}PtrUInt(aMapData) >= 8) then begin
4368 aData^ := LuminanceWeight(aPixel) and Range.r;
4374 ((aPixel.Data.r and Range.r) shl Shift.r) or
4375 ((aPixel.Data.g and Range.g) shl Shift.g) or
4376 ((aPixel.Data.b and Range.b) shl Shift.b));
4382 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4383 procedure TbmpColorTableFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4390 s := Trunc(fPixelSize);
4391 f := fPixelSize - s;
4392 bits := Round(8 * f);
4394 0: idx := (aData^ shr (8 - bits - {%H-}PtrInt(aMapData))) and ((1 shl bits) - 1);
4396 2: idx := PWord(aData)^;
4397 4: idx := PCardinal(aData)^;
4398 8: idx := PQWord(aData)^;
4400 raise EglBitmap.CreateFmt('invalid pixel size: %.3f', [fPixelSize]);
4402 if (idx >= Length(fColorTable)) then
4403 raise EglBitmap.CreateFmt('invalid color index: %d', [idx]);
4404 with fColorTable[idx] do begin
4410 inc(PByte(aMapData), bits);
4411 if ({%H-}PtrUInt(aMapData) >= 8) then begin
4413 dec(PByte(aMapData), 8);
4418 destructor TbmpColorTableFormat.Destroy;
4420 SetLength(fColorTable, 0);
4424 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4425 //TglBitmap - Helper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4426 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4427 procedure glBitmapConvertPixel(var aPixel: TglBitmapPixelData; const aSourceFD, aDestFD: TFormatDescriptor);
4431 for i := 0 to 3 do begin
4432 if (aSourceFD.Range.arr[i] <> aDestFD.Range.arr[i]) then begin
4433 if (aSourceFD.Range.arr[i] > 0) then
4434 aPixel.Data.arr[i] := Round(aPixel.Data.arr[i] / aSourceFD.Range.arr[i] * aDestFD.Range.arr[i])
4436 aPixel.Data.arr[i] := 0;
4441 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4442 procedure glBitmapConvertCopyFunc(var aFuncRec: TglBitmapFunctionRec);
4444 with aFuncRec do begin
4445 if (Source.Range.r > 0) then
4446 Dest.Data.r := Source.Data.r;
4447 if (Source.Range.g > 0) then
4448 Dest.Data.g := Source.Data.g;
4449 if (Source.Range.b > 0) then
4450 Dest.Data.b := Source.Data.b;
4451 if (Source.Range.a > 0) then
4452 Dest.Data.a := Source.Data.a;
4456 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4457 procedure glBitmapConvertCalculateRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
4461 with aFuncRec do begin
4463 if (Source.Range.arr[i] > 0) then
4464 Dest.Data.arr[i] := Round(Dest.Range.arr[i] * Source.Data.arr[i] / Source.Range.arr[i]);
4469 TShiftData = packed record
4471 0: (r, g, b, a: SmallInt);
4472 1: (arr: array[0..3] of SmallInt);
4474 PShiftData = ^TShiftData;
4476 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4477 procedure glBitmapConvertShiftRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
4483 if (Source.Range.arr[i] > 0) then
4484 Dest.Data.arr[i] := Source.Data.arr[i] shr PShiftData(Args)^.arr[i];
4487 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4488 procedure glBitmapInvertFunc(var aFuncRec: TglBitmapFunctionRec);
4490 with aFuncRec do begin
4491 Dest.Data := Source.Data;
4492 if ({%H-}PtrUInt(Args) and $1 > 0) then begin
4493 Dest.Data.r := Dest.Data.r xor Dest.Range.r;
4494 Dest.Data.g := Dest.Data.g xor Dest.Range.g;
4495 Dest.Data.b := Dest.Data.b xor Dest.Range.b;
4497 if ({%H-}PtrUInt(Args) and $2 > 0) then begin
4498 Dest.Data.a := Dest.Data.a xor Dest.Range.a;
4503 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4504 procedure glBitmapFillWithColorFunc(var aFuncRec: TglBitmapFunctionRec);
4508 with aFuncRec do begin
4510 Dest.Data.arr[i] := PglBitmapPixelData(Args)^.Data.arr[i];
4514 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4515 procedure glBitmapAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4519 with FuncRec do begin
4520 if (FuncRec.Args = nil) then begin //source has no alpha
4522 Source.Data.r / Source.Range.r * ALPHA_WEIGHT_R +
4523 Source.Data.g / Source.Range.g * ALPHA_WEIGHT_G +
4524 Source.Data.b / Source.Range.b * ALPHA_WEIGHT_B;
4525 Dest.Data.a := Round(Dest.Range.a * Temp);
4527 Dest.Data.a := Round(Source.Data.a / Source.Range.a * Dest.Range.a);
4531 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4532 procedure glBitmapColorKeyAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4534 PglBitmapPixelData = ^TglBitmapPixelData;
4536 with FuncRec do begin
4537 Dest.Data.r := Source.Data.r;
4538 Dest.Data.g := Source.Data.g;
4539 Dest.Data.b := Source.Data.b;
4541 with PglBitmapPixelData(Args)^ do
4542 if ((Dest.Data.r <= Data.r) and (Dest.Data.r >= Range.r) and
4543 (Dest.Data.g <= Data.g) and (Dest.Data.g >= Range.g) and
4544 (Dest.Data.b <= Data.b) and (Dest.Data.b >= Range.b)) then
4547 Dest.Data.a := Dest.Range.a;
4551 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4552 procedure glBitmapValueAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4554 with FuncRec do begin
4555 Dest.Data.r := Source.Data.r;
4556 Dest.Data.g := Source.Data.g;
4557 Dest.Data.b := Source.Data.b;
4558 Dest.Data.a := PCardinal(Args)^;
4562 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4563 procedure SwapRGB(aData: PByte; aWidth: Integer; const aHasAlpha: Boolean);
4566 TRGBPix = array [0..2] of byte;
4570 while aWidth > 0 do begin
4571 Temp := PRGBPix(aData)^[0];
4572 PRGBPix(aData)^[0] := PRGBPix(aData)^[2];
4573 PRGBPix(aData)^[2] := Temp;
4583 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4584 //TglBitmap - PROTECTED///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4585 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4586 function TglBitmap.GetFormatDesc: TglBitmapFormatDescriptor;
4588 result := TFormatDescriptor.Get(Format);
4591 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4592 function TglBitmap.GetWidth: Integer;
4594 if (ffX in fDimension.Fields) then
4595 result := fDimension.X
4600 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4601 function TglBitmap.GetHeight: Integer;
4603 if (ffY in fDimension.Fields) then
4604 result := fDimension.Y
4609 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4610 function TglBitmap.GetFileWidth: Integer;
4612 result := Max(1, Width);
4615 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4616 function TglBitmap.GetFileHeight: Integer;
4618 result := Max(1, Height);
4621 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4622 procedure TglBitmap.SetCustomData(const aValue: Pointer);
4624 if fCustomData = aValue then
4626 fCustomData := aValue;
4629 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4630 procedure TglBitmap.SetCustomName(const aValue: String);
4632 if fCustomName = aValue then
4634 fCustomName := aValue;
4637 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4638 procedure TglBitmap.SetCustomNameW(const aValue: WideString);
4640 if fCustomNameW = aValue then
4642 fCustomNameW := aValue;
4645 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4646 procedure TglBitmap.SetFreeDataOnDestroy(const aValue: Boolean);
4648 if fFreeDataOnDestroy = aValue then
4650 fFreeDataOnDestroy := aValue;
4653 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4654 procedure TglBitmap.SetDeleteTextureOnFree(const aValue: Boolean);
4656 if fDeleteTextureOnFree = aValue then
4658 fDeleteTextureOnFree := aValue;
4661 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4662 procedure TglBitmap.SetFormat(const aValue: TglBitmapFormat);
4664 if fFormat = aValue then
4666 if TFormatDescriptor.Get(Format).PixelSize <> TFormatDescriptor.Get(aValue).PixelSize then
4667 raise EglBitmapUnsupportedFormat.Create(Format);
4668 SetDataPointer(fData, aValue, Width, Height); //be careful, Data could be freed by this method
4671 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4672 procedure TglBitmap.SetFreeDataAfterGenTexture(const aValue: Boolean);
4674 if fFreeDataAfterGenTexture = aValue then
4676 fFreeDataAfterGenTexture := aValue;
4679 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4680 procedure TglBitmap.SetID(const aValue: Cardinal);
4682 if fID = aValue then
4687 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4688 procedure TglBitmap.SetMipMap(const aValue: TglBitmapMipMap);
4690 if fMipMap = aValue then
4695 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4696 procedure TglBitmap.SetTarget(const aValue: Cardinal);
4698 if fTarget = aValue then
4703 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4704 procedure TglBitmap.SetAnisotropic(const aValue: Integer);
4706 MaxAnisotropic: Integer;
4708 fAnisotropic := aValue;
4709 if (ID > 0) then begin
4710 if GL_EXT_texture_filter_anisotropic then begin
4711 if fAnisotropic > 0 then begin
4713 glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @MaxAnisotropic);
4714 if aValue > MaxAnisotropic then
4715 fAnisotropic := MaxAnisotropic;
4716 glTexParameteri(Target, GL_TEXTURE_MAX_ANISOTROPY_EXT, fAnisotropic);
4724 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4725 procedure TglBitmap.CreateID;
4728 glDeleteTextures(1, @fID);
4729 glGenTextures(1, @fID);
4733 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4734 procedure TglBitmap.SetupParameters(out aBuildWithGlu: Boolean);
4736 // Set Up Parameters
4737 SetWrap(fWrapS, fWrapT, fWrapR);
4738 SetFilter(fFilterMin, fFilterMag);
4739 SetAnisotropic(fAnisotropic);
4740 SetBorderColor(fBorderColor[0], fBorderColor[1], fBorderColor[2], fBorderColor[3]);
4742 if (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
4743 SetSwizzle(fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
4745 // Mip Maps Generation Mode
4746 aBuildWithGlu := false;
4747 if (MipMap = mmMipmap) then begin
4748 if (GL_VERSION_1_4 or GL_SGIS_generate_mipmap) then
4749 glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE)
4751 aBuildWithGlu := true;
4752 end else if (MipMap = mmMipmapGlu) then
4753 aBuildWithGlu := true;
4756 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4757 procedure TglBitmap.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
4758 const aWidth: Integer; const aHeight: Integer);
4762 if (Data <> aData) then begin
4763 if (Assigned(Data)) then
4768 if not Assigned(fData) then begin
4772 FillChar(fDimension, SizeOf(fDimension), 0);
4773 if aWidth <> -1 then begin
4774 fDimension.Fields := fDimension.Fields + [ffX];
4775 fDimension.X := aWidth;
4778 if aHeight <> -1 then begin
4779 fDimension.Fields := fDimension.Fields + [ffY];
4780 fDimension.Y := aHeight;
4783 s := TFormatDescriptor.Get(aFormat).PixelSize;
4785 fPixelSize := Ceil(s);
4786 fRowSize := Ceil(s * aWidth);
4790 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4791 function TglBitmap.FlipHorz: Boolean;
4796 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4797 function TglBitmap.FlipVert: Boolean;
4802 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4803 //TglBitmap - PUBLIC//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4804 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4805 procedure TglBitmap.AfterConstruction;
4807 inherited AfterConstruction;
4811 fIsResident := false;
4813 fMipMap := glBitmapDefaultMipmap;
4814 fFreeDataAfterGenTexture := glBitmapGetDefaultFreeDataAfterGenTexture;
4815 fDeleteTextureOnFree := glBitmapGetDefaultDeleteTextureOnFree;
4817 glBitmapGetDefaultFilter (fFilterMin, fFilterMag);
4818 glBitmapGetDefaultTextureWrap(fWrapS, fWrapT, fWrapR);
4819 glBitmapGetDefaultSwizzle (fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
4822 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4823 procedure TglBitmap.BeforeDestruction;
4827 if fFreeDataOnDestroy then begin
4829 SetDataPointer(NewData, tfEmpty); //be careful, Data could be freed by this method
4831 if (fID > 0) and fDeleteTextureOnFree then
4832 glDeleteTextures(1, @fID);
4833 inherited BeforeDestruction;
4836 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4837 procedure TglBitmap.PrepareResType(var aResource: String; var aResType: PChar);
4841 if not Assigned(aResType) then begin
4842 TempPos := Pos('.', aResource);
4843 aResType := PChar(UpperCase(Copy(aResource, TempPos + 1, Length(aResource) - TempPos)));
4844 aResource := UpperCase(Copy(aResource, 0, TempPos -1));
4848 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4849 procedure TglBitmap.LoadFromFile(const aFilename: String);
4853 if not FileExists(aFilename) then
4854 raise EglBitmap.Create('file does not exist: ' + aFilename);
4855 fFilename := aFilename;
4856 fs := TFileStream.Create(fFilename, fmOpenRead);
4865 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4866 procedure TglBitmap.LoadFromStream(const aStream: TStream);
4868 {$IFDEF GLB_SUPPORT_PNG_READ}
4869 if not LoadPNG(aStream) then
4871 {$IFDEF GLB_SUPPORT_JPEG_READ}
4872 if not LoadJPEG(aStream) then
4874 if not LoadDDS(aStream) then
4875 if not LoadTGA(aStream) then
4876 if not LoadBMP(aStream) then
4877 raise EglBitmap.Create('LoadFromStream - Couldn''t load Stream. It''s possible to be an unknow Streamtype.');
4880 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4881 procedure TglBitmap.LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
4882 const aFormat: TglBitmapFormat; const aArgs: Pointer);
4887 size := TFormatDescriptor.Get(aFormat).GetSize(aSize);
4888 GetMem(tmpData, size);
4890 FillChar(tmpData^, size, #$FF);
4891 SetDataPointer(tmpData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
4893 if Assigned(tmpData) then
4897 AddFunc(Self, aFunc, false, aFormat, aArgs);
4900 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4901 procedure TglBitmap.LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar);
4903 rs: TResourceStream;
4905 PrepareResType(aResource, aResType);
4906 rs := TResourceStream.Create(aInstance, aResource, aResType);
4914 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4915 procedure TglBitmap.LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
4917 rs: TResourceStream;
4919 rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
4927 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4928 procedure TglBitmap.SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
4932 fs := TFileStream.Create(aFileName, fmCreate);
4935 SaveToStream(fs, aFileType);
4941 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4942 procedure TglBitmap.SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType);
4945 {$IFDEF GLB_SUPPORT_PNG_WRITE}
4946 ftPNG: SavePNG(aStream);
4948 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
4949 ftJPEG: SaveJPEG(aStream);
4951 ftDDS: SaveDDS(aStream);
4952 ftTGA: SaveTGA(aStream);
4953 ftBMP: SaveBMP(aStream);
4957 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4958 function TglBitmap.AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer): Boolean;
4960 result := AddFunc(Self, aFunc, aCreateTemp, Format, aArgs);
4963 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4964 function TglBitmap.AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
4965 const aFormat: TglBitmapFormat; const aArgs: Pointer): Boolean;
4967 DestData, TmpData, SourceData: pByte;
4968 TempHeight, TempWidth: Integer;
4969 SourceFD, DestFD: TFormatDescriptor;
4970 SourceMD, DestMD: Pointer;
4972 FuncRec: TglBitmapFunctionRec;
4974 Assert(Assigned(Data));
4975 Assert(Assigned(aSource));
4976 Assert(Assigned(aSource.Data));
4979 if Assigned(aSource.Data) and ((aSource.Height > 0) or (aSource.Width > 0)) then begin
4980 SourceFD := TFormatDescriptor.Get(aSource.Format);
4981 DestFD := TFormatDescriptor.Get(aFormat);
4983 if (SourceFD.IsCompressed) then
4984 raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', SourceFD.Format);
4985 if (DestFD.IsCompressed) then
4986 raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', DestFD.Format);
4988 // inkompatible Formats so CreateTemp
4989 if (SourceFD.PixelSize <> DestFD.PixelSize) then
4990 aCreateTemp := true;
4993 TempHeight := Max(1, aSource.Height);
4994 TempWidth := Max(1, aSource.Width);
4996 FuncRec.Sender := Self;
4997 FuncRec.Args := aArgs;
5000 if aCreateTemp then begin
5001 GetMem(TmpData, DestFD.GetSize(TempWidth, TempHeight));
5002 DestData := TmpData;
5007 SourceFD.PreparePixel(FuncRec.Source);
5008 DestFD.PreparePixel (FuncRec.Dest);
5010 SourceMD := SourceFD.CreateMappingData;
5011 DestMD := DestFD.CreateMappingData;
5013 FuncRec.Size := aSource.Dimension;
5014 FuncRec.Position.Fields := FuncRec.Size.Fields;
5017 SourceData := aSource.Data;
5018 FuncRec.Position.Y := 0;
5019 while FuncRec.Position.Y < TempHeight do begin
5020 FuncRec.Position.X := 0;
5021 while FuncRec.Position.X < TempWidth do begin
5022 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
5024 DestFD.Map(FuncRec.Dest, DestData, DestMD);
5025 inc(FuncRec.Position.X);
5027 inc(FuncRec.Position.Y);
5030 // Updating Image or InternalFormat
5032 SetDataPointer(TmpData, aFormat, aSource.Width, aSource.Height) //be careful, Data could be freed by this method
5033 else if (aFormat <> fFormat) then
5038 SourceFD.FreeMappingData(SourceMD);
5039 DestFD.FreeMappingData(DestMD);
5042 if aCreateTemp and Assigned(TmpData) then
5050 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5051 function TglBitmap.AssignToSurface(out aSurface: PSDL_Surface): Boolean;
5053 Row, RowSize: Integer;
5054 SourceData, TmpData: PByte;
5056 FormatDesc: TFormatDescriptor;
5058 function GetRowPointer(Row: Integer): pByte;
5060 result := aSurface.pixels;
5061 Inc(result, Row * RowSize);
5067 FormatDesc := TFormatDescriptor.Get(Format);
5068 if FormatDesc.IsCompressed then
5069 raise EglBitmapUnsupportedFormat.Create(Format);
5071 if Assigned(Data) then begin
5072 case Trunc(FormatDesc.PixelSize) of
5078 raise EglBitmapUnsupportedFormat.Create(Format);
5081 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, TempDepth,
5082 FormatDesc.RedMask, FormatDesc.GreenMask, FormatDesc.BlueMask, FormatDesc.AlphaMask);
5084 RowSize := FormatDesc.GetSize(FileWidth, 1);
5086 for Row := 0 to FileHeight-1 do begin
5087 TmpData := GetRowPointer(Row);
5088 if Assigned(TmpData) then begin
5089 Move(SourceData^, TmpData^, RowSize);
5090 inc(SourceData, RowSize);
5097 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5098 function TglBitmap.AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
5100 pSource, pData, pTempData: PByte;
5101 Row, RowSize, TempWidth, TempHeight: Integer;
5102 IntFormat: TglBitmapFormat;
5103 FormatDesc: TFormatDescriptor;
5105 function GetRowPointer(Row: Integer): pByte;
5107 result := aSurface^.pixels;
5108 Inc(result, Row * RowSize);
5113 if (Assigned(aSurface)) then begin
5114 with aSurface^.format^ do begin
5115 for IntFormat := High(TglBitmapFormat) to Low(TglBitmapFormat) do begin
5116 FormatDesc := TFormatDescriptor.Get(IntFormat);
5117 if (FormatDesc.MaskMatch(RMask, GMask, BMask, AMask)) then
5120 if (IntFormat = tfEmpty) then
5121 raise EglBitmapException.Create('AssignFromSurface - Invalid Pixelformat.');
5124 TempWidth := aSurface^.w;
5125 TempHeight := aSurface^.h;
5126 RowSize := FormatDesc.GetSize(TempWidth, 1);
5127 GetMem(pData, TempHeight * RowSize);
5130 for Row := 0 to TempHeight -1 do begin
5131 pSource := GetRowPointer(Row);
5132 if (Assigned(pSource)) then begin
5133 Move(pSource^, pTempData^, RowSize);
5134 Inc(pTempData, RowSize);
5137 SetDataPointer(pData, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
5140 if Assigned(pData) then
5147 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5148 function TglBitmap.AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
5150 Row, Col, AlphaInterleave: Integer;
5151 pSource, pDest: PByte;
5153 function GetRowPointer(Row: Integer): pByte;
5155 result := aSurface.pixels;
5156 Inc(result, Row * Width);
5161 if Assigned(Data) then begin
5162 if Format in [tfAlpha8, tfLuminance8Alpha8, tfBGRA8, tfRGBA8] then begin
5163 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, 8, $FF, $FF, $FF, 0);
5165 AlphaInterleave := 0;
5168 AlphaInterleave := 1;
5170 AlphaInterleave := 3;
5174 for Row := 0 to Height -1 do begin
5175 pDest := GetRowPointer(Row);
5176 if Assigned(pDest) then begin
5177 for Col := 0 to Width -1 do begin
5178 Inc(pSource, AlphaInterleave);
5190 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5191 function TglBitmap.AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
5195 bmp := TglBitmap2D.Create;
5197 bmp.AssignFromSurface(aSurface);
5198 result := AddAlphaFromGlBitmap(bmp, aFunc, aArgs);
5206 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5207 function CreateGrayPalette: HPALETTE;
5212 GetMem(Pal, SizeOf(TLogPalette) + (SizeOf(TPaletteEntry) * 256));
5214 Pal.palVersion := $300;
5215 Pal.palNumEntries := 256;
5217 for Idx := 0 to Pal.palNumEntries - 1 do begin
5218 Pal.palPalEntry[Idx].peRed := Idx;
5219 Pal.palPalEntry[Idx].peGreen := Idx;
5220 Pal.palPalEntry[Idx].peBlue := Idx;
5221 Pal.palPalEntry[Idx].peFlags := 0;
5223 Result := CreatePalette(Pal^);
5227 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5228 function TglBitmap.AssignToBitmap(const aBitmap: TBitmap): Boolean;
5231 pSource, pData: PByte;
5234 if Assigned(Data) then begin
5235 if Assigned(aBitmap) then begin
5236 aBitmap.Width := Width;
5237 aBitmap.Height := Height;
5240 tfAlpha8, tfLuminance8: begin
5241 aBitmap.PixelFormat := pf8bit;
5242 aBitmap.Palette := CreateGrayPalette;
5245 aBitmap.PixelFormat := pf15bit;
5247 aBitmap.PixelFormat := pf16bit;
5249 aBitmap.PixelFormat := pf24bit;
5251 aBitmap.PixelFormat := pf32bit;
5253 raise EglBitmap.Create('AssignToBitmap - Invalid Pixelformat.');
5257 for Row := 0 to FileHeight -1 do begin
5258 pData := aBitmap.Scanline[Row];
5259 Move(pSource^, pData^, fRowSize);
5260 Inc(pSource, fRowSize);
5261 if (Format in [tfRGB8, tfRGBA8]) then // swap RGB(A) to BGR(A)
5262 SwapRGB(pData, FileWidth, Format = tfRGBA8);
5269 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5270 function TglBitmap.AssignFromBitmap(const aBitmap: TBitmap): Boolean;
5272 pSource, pData, pTempData: PByte;
5273 Row, RowSize, TempWidth, TempHeight: Integer;
5274 IntFormat: TglBitmapFormat;
5278 if (Assigned(aBitmap)) then begin
5279 case aBitmap.PixelFormat of
5281 IntFormat := tfLuminance8;
5283 IntFormat := tfRGB5A1;
5285 IntFormat := tfR5G6B5;
5287 IntFormat := tfBGR8;
5289 IntFormat := tfBGRA8;
5291 raise EglBitmap.Create('AssignFromBitmap - Invalid Pixelformat.');
5294 TempWidth := aBitmap.Width;
5295 TempHeight := aBitmap.Height;
5296 RowSize := TFormatDescriptor.Get(IntFormat).GetSize(TempWidth, 1);
5297 GetMem(pData, TempHeight * RowSize);
5300 for Row := 0 to TempHeight -1 do begin
5301 pSource := aBitmap.Scanline[Row];
5302 if (Assigned(pSource)) then begin
5303 Move(pSource^, pTempData^, RowSize);
5304 Inc(pTempData, RowSize);
5307 SetDataPointer(pData, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
5310 if Assigned(pData) then
5317 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5318 function TglBitmap.AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
5320 Row, Col, AlphaInterleave: Integer;
5321 pSource, pDest: PByte;
5325 if Assigned(Data) then begin
5326 if (Format in [tfAlpha8, tfLuminance8Alpha8, tfRGBA8, tfBGRA8]) then begin
5327 if Assigned(aBitmap) then begin
5328 aBitmap.PixelFormat := pf8bit;
5329 aBitmap.Palette := CreateGrayPalette;
5330 aBitmap.Width := Width;
5331 aBitmap.Height := Height;
5335 AlphaInterleave := 1;
5337 AlphaInterleave := 3;
5339 AlphaInterleave := 0;
5345 for Row := 0 to Height -1 do begin
5346 pDest := aBitmap.Scanline[Row];
5347 if Assigned(pDest) then begin
5348 for Col := 0 to Width -1 do begin
5349 Inc(pSource, AlphaInterleave);
5362 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5363 function TglBitmap.AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5367 tex := TglBitmap2D.Create;
5369 tex.AssignFromBitmap(ABitmap);
5370 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
5377 {$IFDEF GLB_LAZARUS}
5378 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5379 function TglBitmap.AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
5381 rid: TRawImageDescription;
5382 FormatDesc: TFormatDescriptor;
5385 if not Assigned(aImage) or (Format = tfEmpty) then
5387 FormatDesc := TFormatDescriptor.Get(Format);
5388 if FormatDesc.IsCompressed then
5391 FillChar(rid{%H-}, SizeOf(rid), 0);
5393 tfAlpha4, tfAlpha8, tfAlpha16,
5394 tfLuminance4, tfLuminance8, tfLuminance16,
5395 tfLuminance4Alpha4, tfLuminance8Alpha8, tfLuminance12Alpha4, tfLuminance16Alpha16]) then
5396 rid.Format := ricfGray
5398 rid.Format := ricfRGBA;
5401 rid.Height := Height;
5402 rid.Depth := CountSetBits(FormatDesc.RedMask or FormatDesc.GreenMask or FormatDesc.BlueMask or FormatDesc.AlphaMask);
5403 rid.BitOrder := riboBitsInOrder;
5404 rid.ByteOrder := riboLSBFirst;
5405 rid.LineOrder := riloTopToBottom;
5406 rid.LineEnd := rileTight;
5407 rid.BitsPerPixel := Round(8 * FormatDesc.PixelSize);
5408 rid.RedPrec := CountSetBits(FormatDesc.Range.r);
5409 rid.GreenPrec := CountSetBits(FormatDesc.Range.g);
5410 rid.BluePrec := CountSetBits(FormatDesc.Range.b);
5411 rid.AlphaPrec := CountSetBits(FormatDesc.Range.a);
5412 rid.RedShift := FormatDesc.Shift.r;
5413 rid.GreenShift := FormatDesc.Shift.g;
5414 rid.BlueShift := FormatDesc.Shift.b;
5415 rid.AlphaShift := FormatDesc.Shift.a;
5417 rid.MaskBitsPerPixel := 0;
5418 rid.PaletteColorCount := 0;
5420 aImage.DataDescription := rid;
5423 Move(Data^, aImage.PixelData^, FormatDesc.GetSize(Dimension));
5428 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5429 function TglBitmap.AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
5432 FormatDesc: TFormatDescriptor;
5437 procedure CopyConvert;
5439 bfFormat: TbmpBitfieldFormat;
5440 pSourceLine, pDestLine: PByte;
5441 pSourceMD, pDestMD: Pointer;
5443 pixel: TglBitmapPixelData;
5445 bfFormat := TbmpBitfieldFormat.Create;
5446 with aImage.DataDescription do begin
5447 bfFormat.RedMask := ((1 shl RedPrec) - 1) shl RedShift;
5448 bfFormat.GreenMask := ((1 shl GreenPrec) - 1) shl GreenShift;
5449 bfFormat.BlueMask := ((1 shl BluePrec) - 1) shl BlueShift;
5450 bfFormat.AlphaMask := ((1 shl AlphaPrec) - 1) shl AlphaShift;
5451 bfFormat.PixelSize := BitsPerPixel / 8;
5453 pSourceMD := bfFormat.CreateMappingData;
5454 pDestMD := FormatDesc.CreateMappingData;
5456 for y := 0 to aImage.Height-1 do begin
5457 pSourceLine := aImage.PixelData + y {%H-}* aImage.DataDescription.BytesPerLine;
5458 pDestLine := ImageData + y * Round(FormatDesc.PixelSize * aImage.Width);
5459 for x := 0 to aImage.Width-1 do begin
5460 bfFormat.Unmap(pSourceLine, pixel, pSourceMD);
5461 FormatDesc.Map(pixel, pDestLine, pDestMD);
5465 FormatDesc.FreeMappingData(pDestMD);
5466 bfFormat.FreeMappingData(pSourceMD);
5473 if not Assigned(aImage) then
5475 for f := High(f) downto Low(f) do begin
5476 FormatDesc := TFormatDescriptor.Get(f);
5477 with aImage.DataDescription do
5478 if FormatDesc.MaskMatch(
5479 (QWord(1 shl RedPrec )-1) shl RedShift,
5480 (QWord(1 shl GreenPrec)-1) shl GreenShift,
5481 (QWord(1 shl BluePrec )-1) shl BlueShift,
5482 (QWord(1 shl AlphaPrec)-1) shl AlphaShift) then
5486 if (f = tfEmpty) then
5490 (Round(FormatDesc.PixelSize * 8) = aImage.DataDescription.Depth) and
5491 (aImage.DataDescription.BitsPerPixel = aImage.DataDescription.Depth);
5493 ImageSize := FormatDesc.GetSize(aImage.Width, aImage.Height);
5494 ImageData := GetMem(ImageSize);
5497 Move(aImage.PixelData^, ImageData^, ImageSize)
5500 SetDataPointer(ImageData, f, aImage.Width, aImage.Height); //be careful, Data could be freed by this method
5502 if Assigned(ImageData) then
5510 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5511 function TglBitmap.AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
5513 rid: TRawImageDescription;
5514 FormatDesc: TFormatDescriptor;
5515 Pixel: TglBitmapPixelData;
5521 if not Assigned(aImage) or (Format = tfEmpty) then
5523 FormatDesc := TFormatDescriptor.Get(Format);
5524 if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
5527 FillChar(rid{%H-}, SizeOf(rid), 0);
5528 rid.Format := ricfGray;
5530 rid.Height := Height;
5531 rid.Depth := CountSetBits(FormatDesc.Range.a);
5532 rid.BitOrder := riboBitsInOrder;
5533 rid.ByteOrder := riboLSBFirst;
5534 rid.LineOrder := riloTopToBottom;
5535 rid.LineEnd := rileTight;
5536 rid.BitsPerPixel := 8 * Ceil(rid.Depth / 8);
5537 rid.RedPrec := CountSetBits(FormatDesc.Range.a);
5542 rid.GreenShift := 0;
5544 rid.AlphaShift := 0;
5546 rid.MaskBitsPerPixel := 0;
5547 rid.PaletteColorCount := 0;
5549 aImage.DataDescription := rid;
5552 srcMD := FormatDesc.CreateMappingData;
5554 FormatDesc.PreparePixel(Pixel);
5556 dst := aImage.PixelData;
5557 for y := 0 to Height-1 do
5558 for x := 0 to Width-1 do begin
5559 FormatDesc.Unmap(src, Pixel, srcMD);
5560 case rid.BitsPerPixel of
5562 dst^ := Pixel.Data.a;
5566 PWord(dst)^ := Pixel.Data.a;
5570 PByteArray(dst)^[0] := PByteArray(@Pixel.Data.a)^[0];
5571 PByteArray(dst)^[1] := PByteArray(@Pixel.Data.a)^[1];
5572 PByteArray(dst)^[2] := PByteArray(@Pixel.Data.a)^[2];
5576 PCardinal(dst)^ := Pixel.Data.a;
5580 raise EglBitmapUnsupportedFormat.Create(Format);
5584 FormatDesc.FreeMappingData(srcMD);
5589 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5590 function TglBitmap.AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5594 tex := TglBitmap2D.Create;
5596 tex.AssignFromLazIntfImage(aImage);
5597 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
5604 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5605 function TglBitmap.AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar;
5606 const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5608 rs: TResourceStream;
5610 PrepareResType(aResource, aResType);
5611 rs := TResourceStream.Create(aInstance, aResource, aResType);
5613 result := AddAlphaFromStream(rs, aFunc, aArgs);
5619 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5620 function TglBitmap.AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
5621 const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5623 rs: TResourceStream;
5625 rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
5627 result := AddAlphaFromStream(rs, aFunc, aArgs);
5633 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5634 function TglBitmap.AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5636 if TFormatDescriptor.Get(Format).IsCompressed then
5637 raise EglBitmapUnsupportedFormat.Create(Format);
5638 result := AddFunc(Self, aFunc, false, TFormatDescriptor.Get(Format).WithAlpha, aArgs);
5641 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5642 function TglBitmap.AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5646 FS := TFileStream.Create(aFileName, fmOpenRead);
5648 result := AddAlphaFromStream(FS, aFunc, aArgs);
5654 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5655 function TglBitmap.AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5659 tex := TglBitmap2D.Create(aStream);
5661 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
5667 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5668 function TglBitmap.AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5670 DestData, DestData2, SourceData: pByte;
5671 TempHeight, TempWidth: Integer;
5672 SourceFD, DestFD: TFormatDescriptor;
5673 SourceMD, DestMD, DestMD2: Pointer;
5675 FuncRec: TglBitmapFunctionRec;
5679 Assert(Assigned(Data));
5680 Assert(Assigned(aBitmap));
5681 Assert(Assigned(aBitmap.Data));
5683 if ((aBitmap.Width = Width) and (aBitmap.Height = Height)) then begin
5684 result := ConvertTo(TFormatDescriptor.Get(Format).WithAlpha);
5686 SourceFD := TFormatDescriptor.Get(aBitmap.Format);
5687 DestFD := TFormatDescriptor.Get(Format);
5689 if not Assigned(aFunc) then begin
5690 aFunc := glBitmapAlphaFunc;
5691 FuncRec.Args := {%H-}Pointer(SourceFD.HasAlpha);
5693 FuncRec.Args := aArgs;
5696 TempHeight := aBitmap.FileHeight;
5697 TempWidth := aBitmap.FileWidth;
5699 FuncRec.Sender := Self;
5700 FuncRec.Size := Dimension;
5701 FuncRec.Position.Fields := FuncRec.Size.Fields;
5705 SourceData := aBitmap.Data;
5708 SourceFD.PreparePixel(FuncRec.Source);
5709 DestFD.PreparePixel (FuncRec.Dest);
5711 SourceMD := SourceFD.CreateMappingData;
5712 DestMD := DestFD.CreateMappingData;
5713 DestMD2 := DestFD.CreateMappingData;
5715 FuncRec.Position.Y := 0;
5716 while FuncRec.Position.Y < TempHeight do begin
5717 FuncRec.Position.X := 0;
5718 while FuncRec.Position.X < TempWidth do begin
5719 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
5720 DestFD.Unmap (DestData, FuncRec.Dest, DestMD);
5722 DestFD.Map(FuncRec.Dest, DestData2, DestMD2);
5723 inc(FuncRec.Position.X);
5725 inc(FuncRec.Position.Y);
5728 SourceFD.FreeMappingData(SourceMD);
5729 DestFD.FreeMappingData(DestMD);
5730 DestFD.FreeMappingData(DestMD2);
5735 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5736 function TglBitmap.AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte): Boolean;
5738 result := AddAlphaFromColorKeyFloat(aRed / $FF, aGreen / $FF, aBlue / $FF, aDeviation / $FF);
5741 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5742 function TglBitmap.AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal): Boolean;
5744 PixelData: TglBitmapPixelData;
5746 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5747 result := AddAlphaFromColorKeyFloat(
5748 aRed / PixelData.Range.r,
5749 aGreen / PixelData.Range.g,
5750 aBlue / PixelData.Range.b,
5751 aDeviation / Max(PixelData.Range.r, Max(PixelData.Range.g, PixelData.Range.b)));
5754 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5755 function TglBitmap.AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single): Boolean;
5757 values: array[0..2] of Single;
5760 PixelData: TglBitmapPixelData;
5762 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5763 with PixelData do begin
5765 values[1] := aGreen;
5768 for i := 0 to 2 do begin
5769 tmp := Trunc(Range.arr[i] * aDeviation);
5770 Data.arr[i] := Min(Range.arr[i], Trunc(Range.arr[i] * values[i] + tmp));
5771 Range.arr[i] := Max(0, Trunc(Range.arr[i] * values[i] - tmp));
5776 result := AddAlphaFromFunc(glBitmapColorKeyAlphaFunc, @PixelData);
5779 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5780 function TglBitmap.AddAlphaFromValue(const aAlpha: Byte): Boolean;
5782 result := AddAlphaFromValueFloat(aAlpha / $FF);
5785 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5786 function TglBitmap.AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
5788 PixelData: TglBitmapPixelData;
5790 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5791 result := AddAlphaFromValueFloat(aAlpha / PixelData.Range.a);
5794 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5795 function TglBitmap.AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
5797 PixelData: TglBitmapPixelData;
5799 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5801 Data.a := Min(Range.a, Max(0, Round(Range.a * aAlpha)));
5802 result := AddAlphaFromFunc(glBitmapValueAlphaFunc, @PixelData.Data.a);
5805 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5806 function TglBitmap.RemoveAlpha: Boolean;
5808 FormatDesc: TFormatDescriptor;
5811 FormatDesc := TFormatDescriptor.Get(Format);
5812 if Assigned(Data) then begin
5813 if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
5814 raise EglBitmapUnsupportedFormat.Create(Format);
5815 result := ConvertTo(FormatDesc.WithoutAlpha);
5819 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5820 function TglBitmap.Clone: TglBitmap;
5827 Temp := (ClassType.Create as TglBitmap);
5829 // copy texture data if assigned
5830 if Assigned(Data) then begin
5831 Size := TFormatDescriptor.Get(Format).GetSize(fDimension);
5832 GetMem(TempPtr, Size);
5834 Move(Data^, TempPtr^, Size);
5835 Temp.SetDataPointer(TempPtr, Format, Width, Height); //be careful, Data could be freed by this method
5837 if Assigned(TempPtr) then
5843 Temp.SetDataPointer(TempPtr, Format, Width, Height); //be careful, Data could be freed by this method
5848 Temp.fTarget := Target;
5849 Temp.fFormat := Format;
5850 Temp.fMipMap := MipMap;
5851 Temp.fAnisotropic := Anisotropic;
5852 Temp.fBorderColor := fBorderColor;
5853 Temp.fDeleteTextureOnFree := DeleteTextureOnFree;
5854 Temp.fFreeDataAfterGenTexture := FreeDataAfterGenTexture;
5855 Temp.fFilterMin := fFilterMin;
5856 Temp.fFilterMag := fFilterMag;
5857 Temp.fWrapS := fWrapS;
5858 Temp.fWrapT := fWrapT;
5859 Temp.fWrapR := fWrapR;
5860 Temp.fFilename := fFilename;
5861 Temp.fCustomName := fCustomName;
5862 Temp.fCustomNameW := fCustomNameW;
5863 Temp.fCustomData := fCustomData;
5872 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5873 function TglBitmap.ConvertTo(const aFormat: TglBitmapFormat): Boolean;
5875 SourceFD, DestFD: TFormatDescriptor;
5876 SourcePD, DestPD: TglBitmapPixelData;
5877 ShiftData: TShiftData;
5879 function DataIsIdentical: Boolean;
5882 (SourceFD.RedMask = DestFD.RedMask) and
5883 (SourceFD.GreenMask = DestFD.GreenMask) and
5884 (SourceFD.BlueMask = DestFD.BlueMask) and
5885 (SourceFD.AlphaMask = DestFD.AlphaMask);
5888 function CanCopyDirect: Boolean;
5891 ((SourcePD.Range.r = DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
5892 ((SourcePD.Range.g = DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
5893 ((SourcePD.Range.b = DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
5894 ((SourcePD.Range.a = DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
5897 function CanShift: Boolean;
5900 ((SourcePD.Range.r >= DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
5901 ((SourcePD.Range.g >= DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
5902 ((SourcePD.Range.b >= DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
5903 ((SourcePD.Range.a >= DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
5906 function GetShift(aSource, aDest: Cardinal) : ShortInt;
5909 while (aSource > aDest) and (aSource > 0) do begin
5911 aSource := aSource shr 1;
5916 if (aFormat <> fFormat) and (aFormat <> tfEmpty) then begin
5917 SourceFD := TFormatDescriptor.Get(Format);
5918 DestFD := TFormatDescriptor.Get(aFormat);
5920 if DataIsIdentical then begin
5926 SourceFD.PreparePixel(SourcePD);
5927 DestFD.PreparePixel (DestPD);
5929 if CanCopyDirect then
5930 result := AddFunc(Self, glBitmapConvertCopyFunc, false, aFormat)
5931 else if CanShift then begin
5932 ShiftData.r := GetShift(SourcePD.Range.r, DestPD.Range.r);
5933 ShiftData.g := GetShift(SourcePD.Range.g, DestPD.Range.g);
5934 ShiftData.b := GetShift(SourcePD.Range.b, DestPD.Range.b);
5935 ShiftData.a := GetShift(SourcePD.Range.a, DestPD.Range.a);
5936 result := AddFunc(Self, glBitmapConvertShiftRGBAFunc, false, aFormat, @ShiftData);
5938 result := AddFunc(Self, glBitmapConvertCalculateRGBAFunc, false, aFormat);
5943 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5944 procedure TglBitmap.Invert(const aUseRGB: Boolean; const aUseAlpha: Boolean);
5946 if aUseRGB or aUseAlpha then
5947 AddFunc(glBitmapInvertFunc, false, {%H-}Pointer(
5948 ((Byte(aUseAlpha) and 1) shl 1) or
5949 (Byte(aUseRGB) and 1) ));
5952 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5953 procedure TglBitmap.SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
5955 fBorderColor[0] := aRed;
5956 fBorderColor[1] := aGreen;
5957 fBorderColor[2] := aBlue;
5958 fBorderColor[3] := aAlpha;
5959 if (ID > 0) then begin
5961 glTexParameterfv(Target, GL_TEXTURE_BORDER_COLOR, @fBorderColor[0]);
5965 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5966 procedure TglBitmap.FreeData;
5971 SetDataPointer(TempPtr, tfEmpty); //be careful, Data could be freed by this method
5974 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5975 procedure TglBitmap.FillWithColor(const aRed, aGreen, aBlue: Byte;
5976 const aAlpha: Byte);
5978 FillWithColorFloat(aRed/$FF, aGreen/$FF, aBlue/$FF, aAlpha/$FF);
5981 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5982 procedure TglBitmap.FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal);
5984 PixelData: TglBitmapPixelData;
5986 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5988 aRed / PixelData.Range.r,
5989 aGreen / PixelData.Range.g,
5990 aBlue / PixelData.Range.b,
5991 aAlpha / PixelData.Range.a);
5994 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5995 procedure TglBitmap.FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single);
5997 PixelData: TglBitmapPixelData;
5999 TFormatDescriptor.Get(Format).PreparePixel(PixelData);
6000 with PixelData do begin
6001 Data.r := Max(0, Min(Range.r, Trunc(Range.r * aRed)));
6002 Data.g := Max(0, Min(Range.g, Trunc(Range.g * aGreen)));
6003 Data.b := Max(0, Min(Range.b, Trunc(Range.b * aBlue)));
6004 Data.a := Max(0, Min(Range.a, Trunc(Range.a * aAlpha)));
6006 AddFunc(glBitmapFillWithColorFunc, false, @PixelData);
6009 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6010 procedure TglBitmap.SetFilter(const aMin, aMag: GLenum);
6015 fFilterMin := GL_NEAREST;
6017 fFilterMin := GL_LINEAR;
6018 GL_NEAREST_MIPMAP_NEAREST:
6019 fFilterMin := GL_NEAREST_MIPMAP_NEAREST;
6020 GL_LINEAR_MIPMAP_NEAREST:
6021 fFilterMin := GL_LINEAR_MIPMAP_NEAREST;
6022 GL_NEAREST_MIPMAP_LINEAR:
6023 fFilterMin := GL_NEAREST_MIPMAP_LINEAR;
6024 GL_LINEAR_MIPMAP_LINEAR:
6025 fFilterMin := GL_LINEAR_MIPMAP_LINEAR;
6027 raise EglBitmap.Create('SetFilter - Unknow MIN filter.');
6033 fFilterMag := GL_NEAREST;
6035 fFilterMag := GL_LINEAR;
6037 raise EglBitmap.Create('SetFilter - Unknow MAG filter.');
6041 if (ID > 0) then begin
6043 glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, fFilterMag);
6045 if (MipMap = mmNone) or (Target = GL_TEXTURE_RECTANGLE) then begin
6047 GL_NEAREST, GL_LINEAR:
6048 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
6049 GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR:
6050 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6051 GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR:
6052 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6055 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
6059 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6060 procedure TglBitmap.SetWrap(const S: GLenum; const T: GLenum; const R: GLenum);
6062 procedure CheckAndSetWrap(const aValue: Cardinal; var aTarget: Cardinal);
6066 aTarget := GL_CLAMP;
6069 aTarget := GL_REPEAT;
6071 GL_CLAMP_TO_EDGE: begin
6072 if GL_VERSION_1_2 or GL_EXT_texture_edge_clamp then
6073 aTarget := GL_CLAMP_TO_EDGE
6075 aTarget := GL_CLAMP;
6078 GL_CLAMP_TO_BORDER: begin
6079 if GL_VERSION_1_3 or GL_ARB_texture_border_clamp then
6080 aTarget := GL_CLAMP_TO_BORDER
6082 aTarget := GL_CLAMP;
6085 GL_MIRRORED_REPEAT: begin
6086 if GL_VERSION_1_4 or GL_ARB_texture_mirrored_repeat or GL_IBM_texture_mirrored_repeat then
6087 aTarget := GL_MIRRORED_REPEAT
6089 raise EglBitmap.Create('SetWrap - Unsupported Texturewrap GL_MIRRORED_REPEAT (S).');
6092 raise EglBitmap.Create('SetWrap - Unknow Texturewrap');
6097 CheckAndSetWrap(S, fWrapS);
6098 CheckAndSetWrap(T, fWrapT);
6099 CheckAndSetWrap(R, fWrapR);
6101 if (ID > 0) then begin
6103 glTexParameteri(Target, GL_TEXTURE_WRAP_S, fWrapS);
6104 glTexParameteri(Target, GL_TEXTURE_WRAP_T, fWrapT);
6105 glTexParameteri(Target, GL_TEXTURE_WRAP_R, fWrapR);
6109 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6110 procedure TglBitmap.SetSwizzle(const r, g, b, a: GLenum);
6112 procedure CheckAndSetValue(const aValue: GLenum; const aIndex: Integer);
6114 if (aValue = GL_ZERO) or (aValue = GL_ONE) or (aValue = GL_ALPHA) or
6115 (aValue = GL_RED) or (aValue = GL_GREEN) or (aValue = GL_BLUE) then
6116 fSwizzle[aIndex] := aValue
6118 raise EglBitmap.Create('SetSwizzle - Unknow Swizle Value');
6122 if not (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
6123 raise EglBitmapNotSupported.Create('texture swizzle is not supported');
6124 CheckAndSetValue(r, 0);
6125 CheckAndSetValue(g, 1);
6126 CheckAndSetValue(b, 2);
6127 CheckAndSetValue(a, 3);
6129 if (ID > 0) then begin
6131 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_RGBA, PGLint(@fSwizzle[0]));
6135 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6136 procedure TglBitmap.Bind(const aEnableTextureUnit: Boolean);
6138 if aEnableTextureUnit then
6141 glBindTexture(Target, ID);
6144 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6145 procedure TglBitmap.Unbind(const aDisableTextureUnit: Boolean);
6147 if aDisableTextureUnit then
6149 glBindTexture(Target, 0);
6152 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6153 constructor TglBitmap.Create;
6155 if (ClassType = TglBitmap) then
6156 raise EglBitmap.Create('Don''t create TglBitmap directly. Use one of the deviated classes (TglBitmap2D) instead.');
6157 {$IFDEF GLB_NATIVE_OGL}
6158 glbReadOpenGLExtensions;
6161 fFormat := glBitmapGetDefaultFormat;
6162 fFreeDataOnDestroy := true;
6165 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6166 constructor TglBitmap.Create(const aFileName: String);
6169 LoadFromFile(aFileName);
6172 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6173 constructor TglBitmap.Create(const aStream: TStream);
6176 LoadFromStream(aStream);
6179 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6180 constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; aData: PByte);
6185 if not Assigned(aData) then begin
6186 ImageSize := TFormatDescriptor.Get(aFormat).GetSize(aSize);
6187 GetMem(aData, ImageSize);
6189 FillChar(aData^, ImageSize, #$FF);
6190 SetDataPointer(aData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
6192 if Assigned(aData) then
6197 SetDataPointer(aData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
6198 fFreeDataOnDestroy := false;
6202 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6203 constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer);
6206 LoadFromFunc(aSize, aFunc, aFormat, aArgs);
6209 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6210 constructor TglBitmap.Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar);
6213 LoadFromResource(aInstance, aResource, aResType);
6216 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6217 constructor TglBitmap.Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
6220 LoadFromResourceID(aInstance, aResourceID, aResType);
6223 {$IFDEF GLB_SUPPORT_PNG_READ}
6224 {$IF DEFINED(GLB_LAZ_PNG)}
6225 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6226 //PNG/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6227 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6228 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6231 PNG_MAGIC: String[MAGIC_LEN] = #$89#$50#$4E#$47#$0D#$0A#$1A#$0A;
6233 reader: TLazReaderPNG;
6234 intf: TLazIntfImage;
6236 magic: String[MAGIC_LEN];
6239 StreamPos := aStream.Position;
6241 SetLength(magic, MAGIC_LEN);
6242 aStream.Read(magic[1], MAGIC_LEN);
6243 aStream.Position := StreamPos;
6244 if (magic <> PNG_MAGIC) then begin
6249 intf := TLazIntfImage.Create(0, 0);
6250 reader := TLazReaderPNG.Create;
6252 reader.UpdateDescription := true;
6253 reader.ImageRead(aStream, intf);
6254 AssignFromLazIntfImage(intf);
6257 aStream.Position := StreamPos;
6266 {$ELSEIF DEFINED(GLB_SDL_IMAGE)}
6267 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6268 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6270 Surface: PSDL_Surface;
6274 RWops := glBitmapCreateRWops(aStream);
6276 if IMG_isPNG(RWops) > 0 then begin
6277 Surface := IMG_LoadPNG_RW(RWops);
6279 AssignFromSurface(Surface);
6282 SDL_FreeSurface(Surface);
6290 {$ELSEIF DEFINED(GLB_LIB_PNG)}
6291 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6292 procedure glBitmap_libPNG_read_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
6294 TStream(png_get_io_ptr(png)).Read(buffer^, size);
6297 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6298 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6301 signature: array [0..7] of byte;
6303 png_info: png_infop;
6305 TempHeight, TempWidth: Integer;
6306 Format: TglBitmapFormat;
6309 png_rows: array of pByte;
6310 Row, LineSize: Integer;
6314 if not init_libPNG then
6315 raise Exception.Create('LoadPNG - unable to initialize libPNG.');
6319 StreamPos := aStream.Position;
6320 aStream.Read(signature{%H-}, 8);
6321 aStream.Position := StreamPos;
6323 if png_check_sig(@signature, 8) <> 0 then begin
6325 png := png_create_read_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
6327 raise EglBitmapException.Create('LoadPng - couldn''t create read struct.');
6330 png_info := png_create_info_struct(png);
6331 if png_info = nil then begin
6332 png_destroy_read_struct(@png, nil, nil);
6333 raise EglBitmapException.Create('LoadPng - couldn''t create info struct.');
6336 // set read callback
6337 png_set_read_fn(png, aStream, glBitmap_libPNG_read_func);
6339 // read informations
6340 png_read_info(png, png_info);
6343 TempHeight := png_get_image_height(png, png_info);
6344 TempWidth := png_get_image_width(png, png_info);
6347 case png_get_color_type(png, png_info) of
6348 PNG_COLOR_TYPE_GRAY:
6349 Format := tfLuminance8;
6350 PNG_COLOR_TYPE_GRAY_ALPHA:
6351 Format := tfLuminance8Alpha8;
6354 PNG_COLOR_TYPE_RGB_ALPHA:
6357 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
6360 // cut upper 8 bit from 16 bit formats
6361 if png_get_bit_depth(png, png_info) > 8 then
6362 png_set_strip_16(png);
6364 // expand bitdepth smaller than 8
6365 if png_get_bit_depth(png, png_info) < 8 then
6366 png_set_expand(png);
6368 // allocating mem for scanlines
6369 LineSize := png_get_rowbytes(png, png_info);
6370 GetMem(png_data, TempHeight * LineSize);
6372 SetLength(png_rows, TempHeight);
6373 for Row := Low(png_rows) to High(png_rows) do begin
6374 png_rows[Row] := png_data;
6375 Inc(png_rows[Row], Row * LineSize);
6378 // read complete image into scanlines
6379 png_read_image(png, @png_rows[0]);
6382 png_read_end(png, png_info);
6384 // destroy read struct
6385 png_destroy_read_struct(@png, @png_info, nil);
6387 SetLength(png_rows, 0);
6390 SetDataPointer(png_data, Format, TempWidth, TempHeight); //be careful, Data could be freed by this method
6394 if Assigned(png_data) then
6404 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
6405 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6406 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6411 Row, Col, PixSize, LineSize: Integer;
6412 NewImage, pSource, pDest, pAlpha: pByte;
6413 PngFormat: TglBitmapFormat;
6414 FormatDesc: TFormatDescriptor;
6417 PngHeader: String[8] = #137#80#78#71#13#10#26#10;
6422 StreamPos := aStream.Position;
6423 aStream.Read(Header[0], SizeOf(Header));
6424 aStream.Position := StreamPos;
6426 {Test if the header matches}
6427 if Header = PngHeader then begin
6428 Png := TPNGObject.Create;
6430 Png.LoadFromStream(aStream);
6432 case Png.Header.ColorType of
6434 PngFormat := tfLuminance8;
6435 COLOR_GRAYSCALEALPHA:
6436 PngFormat := tfLuminance8Alpha8;
6438 PngFormat := tfBGR8;
6440 PngFormat := tfBGRA8;
6442 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
6445 FormatDesc := TFormatDescriptor.Get(PngFormat);
6446 PixSize := Round(FormatDesc.PixelSize);
6447 LineSize := FormatDesc.GetSize(Png.Header.Width, 1);
6449 GetMem(NewImage, LineSize * Integer(Png.Header.Height));
6453 case Png.Header.ColorType of
6454 COLOR_RGB, COLOR_GRAYSCALE:
6456 for Row := 0 to Png.Height -1 do begin
6457 Move (Png.Scanline[Row]^, pDest^, LineSize);
6458 Inc(pDest, LineSize);
6461 COLOR_RGBALPHA, COLOR_GRAYSCALEALPHA:
6463 PixSize := PixSize -1;
6465 for Row := 0 to Png.Height -1 do begin
6466 pSource := Png.Scanline[Row];
6467 pAlpha := pByte(Png.AlphaScanline[Row]);
6469 for Col := 0 to Png.Width -1 do begin
6470 Move (pSource^, pDest^, PixSize);
6471 Inc(pSource, PixSize);
6472 Inc(pDest, PixSize);
6481 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
6484 SetDataPointer(NewImage, PngFormat, Png.Header.Width, Png.Header.Height); //be careful, Data could be freed by this method
6488 if Assigned(NewImage) then
6500 {$IFDEF GLB_SUPPORT_PNG_WRITE}
6501 {$IFDEF GLB_LIB_PNG}
6502 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6503 procedure glBitmap_libPNG_write_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
6505 TStream(png_get_io_ptr(png)).Write(buffer^, size);
6509 {$IF DEFINED(GLB_LAZ_PNG)}
6510 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6511 procedure TglBitmap.SavePNG(const aStream: TStream);
6513 png: TPortableNetworkGraphic;
6514 intf: TLazIntfImage;
6517 png := TPortableNetworkGraphic.Create;
6518 intf := TLazIntfImage.Create(0, 0);
6520 if not AssignToLazIntfImage(intf) then
6521 raise EglBitmap.Create('unable to create LazIntfImage from glBitmap');
6522 intf.GetRawImage(raw);
6523 png.LoadFromRawImage(raw, false);
6524 png.SaveToStream(aStream);
6531 {$ELSEIF DEFINED(GLB_LIB_PNG)}
6532 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6533 procedure TglBitmap.SavePNG(const aStream: TStream);
6536 png_info: png_infop;
6537 png_rows: array of pByte;
6541 FormatDesc: TFormatDescriptor;
6543 if not (ftPNG in FormatGetSupportedFiles(Format)) then
6544 raise EglBitmapUnsupportedFormat.Create(Format);
6546 if not init_libPNG then
6547 raise Exception.Create('unable to initialize libPNG.');
6551 tfAlpha8, tfLuminance8:
6552 ColorType := PNG_COLOR_TYPE_GRAY;
6554 ColorType := PNG_COLOR_TYPE_GRAY_ALPHA;
6556 ColorType := PNG_COLOR_TYPE_RGB;
6558 ColorType := PNG_COLOR_TYPE_RGBA;
6560 raise EglBitmapUnsupportedFormat.Create(Format);
6563 FormatDesc := TFormatDescriptor.Get(Format);
6564 LineSize := FormatDesc.GetSize(Width, 1);
6566 // creating array for scanline
6567 SetLength(png_rows, Height);
6569 for Row := 0 to Height - 1 do begin
6570 png_rows[Row] := Data;
6571 Inc(png_rows[Row], Row * LineSize)
6575 png := png_create_write_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
6577 raise EglBitmapException.Create('SavePng - couldn''t create write struct.');
6580 png_info := png_create_info_struct(png);
6581 if png_info = nil then begin
6582 png_destroy_write_struct(@png, nil);
6583 raise EglBitmapException.Create('SavePng - couldn''t create info struct.');
6586 // set read callback
6587 png_set_write_fn(png, aStream, glBitmap_libPNG_write_func, nil);
6590 png_set_compression_level(png, 6);
6592 if Format in [tfBGR8, tfBGRA8] then
6595 png_set_IHDR(png, png_info, Width, Height, 8, ColorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
6596 png_write_info(png, png_info);
6597 png_write_image(png, @png_rows[0]);
6598 png_write_end(png, png_info);
6599 png_destroy_write_struct(@png, @png_info);
6601 SetLength(png_rows, 0);
6608 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
6609 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6610 procedure TglBitmap.SavePNG(const aStream: TStream);
6614 pSource, pDest: pByte;
6615 X, Y, PixSize: Integer;
6616 ColorType: Cardinal;
6622 if not (ftPNG in FormatGetSupportedFiles (Format)) then
6623 raise EglBitmapUnsupportedFormat.Create(Format);
6626 tfAlpha8, tfLuminance8: begin
6627 ColorType := COLOR_GRAYSCALE;
6631 tfLuminance8Alpha8: begin
6632 ColorType := COLOR_GRAYSCALEALPHA;
6636 tfBGR8, tfRGB8: begin
6637 ColorType := COLOR_RGB;
6641 tfBGRA8, tfRGBA8: begin
6642 ColorType := COLOR_RGBALPHA;
6647 raise EglBitmapUnsupportedFormat.Create(Format);
6650 Png := TPNGObject.CreateBlank(ColorType, 8, Width, Height);
6654 for Y := 0 to Height -1 do begin
6655 pDest := png.ScanLine[Y];
6656 for X := 0 to Width -1 do begin
6657 Move(pSource^, pDest^, PixSize);
6658 Inc(pDest, PixSize);
6659 Inc(pSource, PixSize);
6661 png.AlphaScanline[Y]^[X] := pSource^;
6666 // convert RGB line to BGR
6667 if Format in [tfRGB8, tfRGBA8] then begin
6668 pTemp := png.ScanLine[Y];
6669 for X := 0 to Width -1 do begin
6670 Temp := pByteArray(pTemp)^[0];
6671 pByteArray(pTemp)^[0] := pByteArray(pTemp)^[2];
6672 pByteArray(pTemp)^[2] := Temp;
6679 Png.CompressionLevel := 6;
6680 Png.SaveToStream(aStream);
6688 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6689 //JPEG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6690 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6691 {$IFDEF GLB_LIB_JPEG}
6693 glBitmap_libJPEG_source_mgr_ptr = ^glBitmap_libJPEG_source_mgr;
6694 glBitmap_libJPEG_source_mgr = record
6695 pub: jpeg_source_mgr;
6698 SrcBuffer: array [1..4096] of byte;
6701 glBitmap_libJPEG_dest_mgr_ptr = ^glBitmap_libJPEG_dest_mgr;
6702 glBitmap_libJPEG_dest_mgr = record
6703 pub: jpeg_destination_mgr;
6705 DestStream: TStream;
6706 DestBuffer: array [1..4096] of byte;
6709 procedure glBitmap_libJPEG_error_exit(cinfo: j_common_ptr); cdecl;
6715 procedure glBitmap_libJPEG_output_message(cinfo: j_common_ptr); cdecl;
6721 procedure glBitmap_libJPEG_init_source(cinfo: j_decompress_ptr); cdecl;
6726 procedure glBitmap_libJPEG_term_source(cinfo: j_decompress_ptr); cdecl;
6732 procedure glBitmap_libJPEG_init_destination(cinfo: j_compress_ptr); cdecl;
6738 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6739 function glBitmap_libJPEG_fill_input_buffer(cinfo: j_decompress_ptr): boolean; cdecl;
6741 src: glBitmap_libJPEG_source_mgr_ptr;
6744 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
6746 bytes := src^.SrcStream.Read(src^.SrcBuffer[1], 4096);
6747 if (bytes <= 0) then begin
6748 src^.SrcBuffer[1] := $FF;
6749 src^.SrcBuffer[2] := JPEG_EOI;
6753 src^.pub.next_input_byte := @(src^.SrcBuffer[1]);
6754 src^.pub.bytes_in_buffer := bytes;
6759 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6760 procedure glBitmap_libJPEG_skip_input_data(cinfo: j_decompress_ptr; num_bytes: Longint); cdecl;
6762 src: glBitmap_libJPEG_source_mgr_ptr;
6764 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
6766 if num_bytes > 0 then begin
6767 // wanted byte isn't in buffer so set stream position and read buffer
6768 if num_bytes > src^.pub.bytes_in_buffer then begin
6769 src^.SrcStream.Position := src^.SrcStream.Position + num_bytes - src^.pub.bytes_in_buffer;
6770 src^.pub.fill_input_buffer(cinfo);
6772 // wanted byte is in buffer so only skip
6773 inc(src^.pub.next_input_byte, num_bytes);
6774 dec(src^.pub.bytes_in_buffer, num_bytes);
6779 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6780 function glBitmap_libJPEG_empty_output_buffer(cinfo: j_compress_ptr): boolean; cdecl;
6782 dest: glBitmap_libJPEG_dest_mgr_ptr;
6784 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
6786 if dest^.pub.free_in_buffer < Cardinal(Length(dest^.DestBuffer)) then begin
6787 // write complete buffer
6788 dest^.DestStream.Write(dest^.DestBuffer[1], SizeOf(dest^.DestBuffer));
6791 dest^.pub.next_output_byte := @dest^.DestBuffer[1];
6792 dest^.pub.free_in_buffer := Length(dest^.DestBuffer);
6798 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6799 procedure glBitmap_libJPEG_term_destination(cinfo: j_compress_ptr); cdecl;
6802 dest: glBitmap_libJPEG_dest_mgr_ptr;
6804 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
6806 for Idx := Low(dest^.DestBuffer) to High(dest^.DestBuffer) do begin
6807 // check for endblock
6808 if (Idx < High(dest^.DestBuffer)) and (dest^.DestBuffer[Idx] = $FF) and (dest^.DestBuffer[Idx +1] = JPEG_EOI) then begin
6810 dest^.DestStream.Write(dest^.DestBuffer[Idx], 2);
6815 dest^.DestStream.Write(dest^.DestBuffer[Idx], 1);
6820 {$IFDEF GLB_SUPPORT_JPEG_READ}
6821 {$IF DEFINED(GLB_LAZ_JPEG)}
6822 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6823 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6826 JPEG_MAGIC: String[MAGIC_LEN] = #$FF#$D8;
6828 intf: TLazIntfImage;
6829 reader: TFPReaderJPEG;
6831 magic: String[MAGIC_LEN];
6834 StreamPos := aStream.Position;
6836 SetLength(magic, MAGIC_LEN);
6837 aStream.Read(magic[1], MAGIC_LEN);
6838 aStream.Position := StreamPos;
6839 if (magic <> JPEG_MAGIC) then begin
6844 reader := TFPReaderJPEG.Create;
6845 intf := TLazIntfImage.Create(0, 0);
6847 intf.DataDescription := GetDescriptionFromDevice(0, 0, 0);
6848 reader.ImageRead(aStream, intf);
6849 AssignFromLazIntfImage(intf);
6852 aStream.Position := StreamPos;
6861 {$ELSEIF DEFINED(GLB_SDL_IMAGE)}
6862 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6863 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6865 Surface: PSDL_Surface;
6870 RWops := glBitmapCreateRWops(aStream);
6872 if IMG_isJPG(RWops) > 0 then begin
6873 Surface := IMG_LoadJPG_RW(RWops);
6875 AssignFromSurface(Surface);
6878 SDL_FreeSurface(Surface);
6886 {$ELSEIF DEFINED(GLB_LIB_JPEG)}
6887 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6888 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6891 Temp: array[0..1]of Byte;
6893 jpeg: jpeg_decompress_struct;
6894 jpeg_err: jpeg_error_mgr;
6896 IntFormat: TglBitmapFormat;
6898 TempHeight, TempWidth: Integer;
6903 FormatDesc: TFormatDescriptor;
6907 if not init_libJPEG then
6908 raise Exception.Create('LoadJPG - unable to initialize libJPEG.');
6911 // reading first two bytes to test file and set cursor back to begin
6912 StreamPos := aStream.Position;
6913 aStream.Read({%H-}Temp[0], 2);
6914 aStream.Position := StreamPos;
6916 // if Bitmap then read file.
6917 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
6918 FillChar(jpeg{%H-}, SizeOf(jpeg_decompress_struct), $00);
6919 FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
6922 jpeg.err := jpeg_std_error(@jpeg_err);
6923 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
6924 jpeg_err.output_message := glBitmap_libJPEG_output_message;
6926 // decompression struct
6927 jpeg_create_decompress(@jpeg);
6929 // allocation space for streaming methods
6930 jpeg.src := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_source_mgr));
6932 // seeting up custom functions
6933 with glBitmap_libJPEG_source_mgr_ptr(jpeg.src)^ do begin
6934 pub.init_source := glBitmap_libJPEG_init_source;
6935 pub.fill_input_buffer := glBitmap_libJPEG_fill_input_buffer;
6936 pub.skip_input_data := glBitmap_libJPEG_skip_input_data;
6937 pub.resync_to_restart := jpeg_resync_to_restart; // use default method
6938 pub.term_source := glBitmap_libJPEG_term_source;
6940 pub.bytes_in_buffer := 0; // forces fill_input_buffer on first read
6941 pub.next_input_byte := nil; // until buffer loaded
6943 SrcStream := aStream;
6946 // set global decoding state
6947 jpeg.global_state := DSTATE_START;
6949 // read header of jpeg
6950 jpeg_read_header(@jpeg, false);
6952 // setting output parameter
6953 case jpeg.jpeg_color_space of
6956 jpeg.out_color_space := JCS_GRAYSCALE;
6957 IntFormat := tfLuminance8;
6960 jpeg.out_color_space := JCS_RGB;
6961 IntFormat := tfRGB8;
6965 jpeg_start_decompress(@jpeg);
6967 TempHeight := jpeg.output_height;
6968 TempWidth := jpeg.output_width;
6970 FormatDesc := TFormatDescriptor.Get(IntFormat);
6972 // creating new image
6973 GetMem(pImage, FormatDesc.GetSize(TempWidth, TempHeight));
6977 for Row := 0 to TempHeight -1 do begin
6978 jpeg_read_scanlines(@jpeg, @pTemp, 1);
6979 Inc(pTemp, FormatDesc.GetSize(TempWidth, 1));
6982 // finish decompression
6983 jpeg_finish_decompress(@jpeg);
6985 // destroy decompression
6986 jpeg_destroy_decompress(@jpeg);
6988 SetDataPointer(pImage, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
6992 if Assigned(pImage) then
7002 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
7003 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7004 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
7009 Temp: array[0..1]of Byte;
7013 // reading first two bytes to test file and set cursor back to begin
7014 StreamPos := aStream.Position;
7015 aStream.Read(Temp[0], 2);
7016 aStream.Position := StreamPos;
7018 // if Bitmap then read file.
7019 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
7020 bmp := TBitmap.Create;
7022 jpg := TJPEGImage.Create;
7024 jpg.LoadFromStream(aStream);
7026 result := AssignFromBitmap(bmp);
7038 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
7039 {$IF DEFINED(GLB_LAZ_JPEG)}
7040 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7041 procedure TglBitmap.SaveJPEG(const aStream: TStream);
7044 intf: TLazIntfImage;
7047 jpeg := TJPEGImage.Create;
7048 intf := TLazIntfImage.Create(0, 0);
7050 if not AssignToLazIntfImage(intf) then
7051 raise EglBitmap.Create('unable to create LazIntfImage from glBitmap');
7052 intf.GetRawImage(raw);
7053 jpeg.LoadFromRawImage(raw, false);
7054 jpeg.SaveToStream(aStream);
7061 {$ELSEIF DEFINED(GLB_LIB_JPEG)}
7062 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7063 procedure TglBitmap.SaveJPEG(const aStream: TStream);
7065 jpeg: jpeg_compress_struct;
7066 jpeg_err: jpeg_error_mgr;
7068 pTemp, pTemp2: pByte;
7070 procedure CopyRow(pDest, pSource: pByte);
7074 for X := 0 to Width - 1 do begin
7075 pByteArray(pDest)^[0] := pByteArray(pSource)^[2];
7076 pByteArray(pDest)^[1] := pByteArray(pSource)^[1];
7077 pByteArray(pDest)^[2] := pByteArray(pSource)^[0];
7084 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
7085 raise EglBitmapUnsupportedFormat.Create(Format);
7087 if not init_libJPEG then
7088 raise Exception.Create('SaveJPG - unable to initialize libJPEG.');
7091 FillChar(jpeg{%H-}, SizeOf(jpeg_compress_struct), $00);
7092 FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
7095 jpeg.err := jpeg_std_error(@jpeg_err);
7096 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
7097 jpeg_err.output_message := glBitmap_libJPEG_output_message;
7099 // compression struct
7100 jpeg_create_compress(@jpeg);
7102 // allocation space for streaming methods
7103 jpeg.dest := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_dest_mgr));
7105 // seeting up custom functions
7106 with glBitmap_libJPEG_dest_mgr_ptr(jpeg.dest)^ do begin
7107 pub.init_destination := glBitmap_libJPEG_init_destination;
7108 pub.empty_output_buffer := glBitmap_libJPEG_empty_output_buffer;
7109 pub.term_destination := glBitmap_libJPEG_term_destination;
7111 pub.next_output_byte := @DestBuffer[1];
7112 pub.free_in_buffer := Length(DestBuffer);
7114 DestStream := aStream;
7117 // very important state
7118 jpeg.global_state := CSTATE_START;
7119 jpeg.image_width := Width;
7120 jpeg.image_height := Height;
7122 tfAlpha8, tfLuminance8: begin
7123 jpeg.input_components := 1;
7124 jpeg.in_color_space := JCS_GRAYSCALE;
7126 tfRGB8, tfBGR8: begin
7127 jpeg.input_components := 3;
7128 jpeg.in_color_space := JCS_RGB;
7132 jpeg_set_defaults(@jpeg);
7133 jpeg_set_quality(@jpeg, 95, true);
7134 jpeg_start_compress(@jpeg, true);
7137 if Format = tfBGR8 then
7138 GetMem(pTemp2, fRowSize)
7143 for Row := 0 to jpeg.image_height -1 do begin
7145 if Format = tfBGR8 then
7146 CopyRow(pTemp2, pTemp)
7151 jpeg_write_scanlines(@jpeg, @pTemp2, 1);
7152 inc(pTemp, fRowSize);
7156 if Format = tfBGR8 then
7159 jpeg_finish_compress(@jpeg);
7160 jpeg_destroy_compress(@jpeg);
7166 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
7167 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7168 procedure TglBitmap.SaveJPEG(const aStream: TStream);
7173 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
7174 raise EglBitmapUnsupportedFormat.Create(Format);
7176 Bmp := TBitmap.Create;
7178 Jpg := TJPEGImage.Create;
7180 AssignToBitmap(Bmp);
7181 if (Format in [tfAlpha8, tfLuminance8]) then begin
7182 Jpg.Grayscale := true;
7183 Jpg.PixelFormat := jf8Bit;
7186 Jpg.SaveToStream(aStream);
7197 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7198 //BMP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7199 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7206 BMP_COMP_BITFIELDS = 3;
7209 TBMPHeader = packed record
7214 bfOffBits: Cardinal;
7217 TBMPInfo = packed record
7223 biCompression: Cardinal;
7224 biSizeImage: Cardinal;
7225 biXPelsPerMeter: Longint;
7226 biYPelsPerMeter: Longint;
7227 biClrUsed: Cardinal;
7228 biClrImportant: Cardinal;
7231 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7232 function TglBitmap.LoadBMP(const aStream: TStream): Boolean;
7234 //////////////////////////////////////////////////////////////////////////////////////////////////
7235 function ReadInfo(out aInfo: TBMPInfo; out aMask: TglBitmapColorRec): TglBitmapFormat;
7238 aStream.Read(aInfo{%H-}, SizeOf(aInfo));
7239 FillChar(aMask{%H-}, SizeOf(aMask), 0);
7242 case aInfo.biCompression of
7244 BMP_COMP_RLE8: begin
7245 raise EglBitmap.Create('RLE compression is not supported');
7247 BMP_COMP_BITFIELDS: begin
7248 if (aInfo.biBitCount = 16) or (aInfo.biBitCount = 32) then begin
7249 aStream.Read(aMask.r, SizeOf(aMask.r));
7250 aStream.Read(aMask.g, SizeOf(aMask.g));
7251 aStream.Read(aMask.b, SizeOf(aMask.b));
7252 aStream.Read(aMask.a, SizeOf(aMask.a));
7254 raise EglBitmap.Create('Bitfields are only supported for 16bit and 32bit formats');
7258 //get suitable format
7259 case aInfo.biBitCount of
7260 8: result := tfLuminance8;
7261 16: result := tfX1RGB5;
7262 24: result := tfRGB8;
7263 32: result := tfXRGB8;
7267 function ReadColorTable(var aFormat: TglBitmapFormat; const aInfo: TBMPInfo): TbmpColorTableFormat;
7270 ColorTable: TbmpColorTable;
7273 if (aInfo.biBitCount >= 16) then
7275 aFormat := tfLuminance8;
7276 c := aInfo.biClrUsed;
7278 c := 1 shl aInfo.biBitCount;
7279 SetLength(ColorTable, c);
7280 for i := 0 to c-1 do begin
7281 aStream.Read(ColorTable[i], SizeOf(TbmpColorTableEnty));
7282 if (ColorTable[i].r <> ColorTable[i].g) or (ColorTable[i].g <> ColorTable[i].b) then
7286 result := TbmpColorTableFormat.Create;
7287 result.PixelSize := aInfo.biBitCount / 8;
7288 result.ColorTable := ColorTable;
7289 result.Range := glBitmapColorRec($FF, $FF, $FF, $00);
7292 //////////////////////////////////////////////////////////////////////////////////////////////////
7293 function CheckBitfields(var aFormat: TglBitmapFormat; const aMask: TglBitmapColorRec;
7294 const aInfo: TBMPInfo): TbmpBitfieldFormat;
7296 TmpFormat: TglBitmapFormat;
7297 FormatDesc: TFormatDescriptor;
7300 if (aMask.r <> 0) or (aMask.g <> 0) or (aMask.b <> 0) or (aMask.a <> 0) then begin
7301 for TmpFormat := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
7302 FormatDesc := TFormatDescriptor.Get(TmpFormat);
7303 if FormatDesc.MaskMatch(aMask.r, aMask.g, aMask.b, aMask.a) then begin
7304 aFormat := FormatDesc.Format;
7309 if (aMask.a = 0) and TFormatDescriptor.Get(aFormat).HasAlpha then
7310 aFormat := TFormatDescriptor.Get(aFormat).WithoutAlpha;
7311 if (aMask.a <> 0) and not TFormatDescriptor.Get(aFormat).HasAlpha then
7312 aFormat := TFormatDescriptor.Get(aFormat).WithAlpha;
7314 result := TbmpBitfieldFormat.Create;
7315 result.PixelSize := aInfo.biBitCount / 8;
7316 result.RedMask := aMask.r;
7317 result.GreenMask := aMask.g;
7318 result.BlueMask := aMask.b;
7319 result.AlphaMask := aMask.a;
7326 ImageSize, rbLineSize, wbLineSize, Padding, i: Integer;
7327 PaddingBuff: Cardinal;
7328 LineBuf, ImageData, TmpData: PByte;
7329 SourceMD, DestMD: Pointer;
7330 BmpFormat: TglBitmapFormat;
7333 Mask: TglBitmapColorRec;
7338 SpecialFormat: TFormatDescriptor;
7339 FormatDesc: TFormatDescriptor;
7341 //////////////////////////////////////////////////////////////////////////////////////////////////
7342 procedure SpecialFormatReadLine(aData: PByte; aLineBuf: PByte);
7345 Pixel: TglBitmapPixelData;
7347 aStream.Read(aLineBuf^, rbLineSize);
7348 SpecialFormat.PreparePixel(Pixel);
7349 for i := 0 to Info.biWidth-1 do begin
7350 SpecialFormat.Unmap(aLineBuf, Pixel, SourceMD);
7351 glBitmapConvertPixel(Pixel, SpecialFormat, FormatDesc);
7352 FormatDesc.Map(Pixel, aData, DestMD);
7358 BmpFormat := tfEmpty;
7359 SpecialFormat := nil;
7365 StartPos := aStream.Position;
7366 aStream.Read(Header{%H-}, SizeOf(Header));
7368 if Header.bfType = BMP_MAGIC then begin
7370 BmpFormat := ReadInfo(Info, Mask);
7371 SpecialFormat := ReadColorTable(BmpFormat, Info);
7372 if not Assigned(SpecialFormat) then
7373 SpecialFormat := CheckBitfields(BmpFormat, Mask, Info);
7374 aStream.Position := StartPos + Header.bfOffBits;
7376 if (BmpFormat <> tfEmpty) then begin
7377 FormatDesc := TFormatDescriptor.Get(BmpFormat);
7378 rbLineSize := Round(Info.biWidth * Info.biBitCount / 8); //ReadBuffer LineSize
7379 wbLineSize := Trunc(Info.biWidth * FormatDesc.PixelSize);
7380 Padding := (((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3) - rbLineSize;
7383 DestMD := FormatDesc.CreateMappingData;
7384 ImageSize := FormatDesc.GetSize(Info.biWidth, abs(Info.biHeight));
7385 GetMem(ImageData, ImageSize);
7386 if Assigned(SpecialFormat) then begin
7387 GetMem(LineBuf, rbLineSize); //tmp Memory for converting Bitfields
7388 SourceMD := SpecialFormat.CreateMappingData;
7393 FillChar(ImageData^, ImageSize, $FF);
7394 TmpData := ImageData;
7395 if (Info.biHeight > 0) then
7396 Inc(TmpData, wbLineSize * (Info.biHeight-1));
7397 for i := 0 to Abs(Info.biHeight)-1 do begin
7398 if Assigned(SpecialFormat) then
7399 SpecialFormatReadLine(TmpData, LineBuf) //if is special format read and convert data
7401 aStream.Read(TmpData^, wbLineSize); //else only read data
7402 if (Info.biHeight > 0) then
7403 dec(TmpData, wbLineSize)
7405 inc(TmpData, wbLineSize);
7406 aStream.Read(PaddingBuff{%H-}, Padding);
7408 SetDataPointer(ImageData, BmpFormat, Info.biWidth, abs(Info.biHeight)); //be careful, Data could be freed by this method
7411 if Assigned(LineBuf) then
7413 if Assigned(SourceMD) then
7414 SpecialFormat.FreeMappingData(SourceMD);
7415 FormatDesc.FreeMappingData(DestMD);
7418 if Assigned(ImageData) then
7423 raise EglBitmap.Create('LoadBMP - No suitable format found');
7425 aStream.Position := StartPos;
7429 FreeAndNil(SpecialFormat);
7432 else aStream.Position := StartPos;
7435 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7436 procedure TglBitmap.SaveBMP(const aStream: TStream);
7440 Converter: TFormatDescriptor;
7441 FormatDesc: TFormatDescriptor;
7442 SourceFD, DestFD: Pointer;
7443 pData, srcData, dstData, ConvertBuffer: pByte;
7445 Pixel: TglBitmapPixelData;
7446 ImageSize, wbLineSize, rbLineSize, Padding, LineIdx, PixelIdx: Integer;
7447 RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
7449 PaddingBuff: Cardinal;
7451 function GetLineWidth : Integer;
7453 result := ((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3;
7457 if not (ftBMP in FormatGetSupportedFiles(Format)) then
7458 raise EglBitmapUnsupportedFormat.Create(Format);
7461 FormatDesc := TFormatDescriptor.Get(Format);
7462 ImageSize := FormatDesc.GetSize(Dimension);
7464 FillChar(Header{%H-}, SizeOf(Header), 0);
7465 Header.bfType := BMP_MAGIC;
7466 Header.bfSize := SizeOf(Header) + SizeOf(Info) + ImageSize;
7467 Header.bfReserved1 := 0;
7468 Header.bfReserved2 := 0;
7469 Header.bfOffBits := SizeOf(Header) + SizeOf(Info);
7471 FillChar(Info{%H-}, SizeOf(Info), 0);
7472 Info.biSize := SizeOf(Info);
7473 Info.biWidth := Width;
7474 Info.biHeight := Height;
7476 Info.biCompression := BMP_COMP_RGB;
7477 Info.biSizeImage := ImageSize;
7482 Info.biBitCount := 4;
7483 Header.bfSize := Header.bfSize + 16 * SizeOf(Cardinal);
7484 Header.bfOffBits := Header.bfOffBits + 16 * SizeOf(Cardinal); //16 ColorTable entries
7485 Converter := TbmpColorTableFormat.Create;
7486 with (Converter as TbmpColorTableFormat) do begin
7489 Range := glBitmapColorRec($F, $F, $F, $0);
7494 tfR3G3B2, tfLuminance8: begin
7495 Info.biBitCount := 8;
7496 Header.bfSize := Header.bfSize + 256 * SizeOf(Cardinal);
7497 Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal); //256 ColorTable entries
7498 Converter := TbmpColorTableFormat.Create;
7499 with (Converter as TbmpColorTableFormat) do begin
7502 if (Format = tfR3G3B2) then begin
7503 Range := glBitmapColorRec($7, $7, $3, $0);
7504 Shift := glBitmapShiftRec(0, 3, 6, 0);
7506 Range := glBitmapColorRec($FF, $FF, $FF, $0);
7511 tfRGBX4, tfXRGB4, tfRGB5X1, tfX1RGB5, tfR5G6B5, tfRGB5A1, tfA1RGB5, tfRGBA4, tfARGB4,
7512 tfBGRX4, tfXBGR4, tfBGR5X1, tfX1BGR5, tfB5G6R5, tfBGR5A1, tfA1BGR5, tfBGRA4, tfABGR4: begin
7513 Info.biBitCount := 16;
7514 Info.biCompression := BMP_COMP_BITFIELDS;
7517 tfBGR8, tfRGB8: begin
7518 Info.biBitCount := 24;
7519 if (Format = tfRGB8) then
7520 Converter := TfdBGR8.Create; //use BGR8 Format Descriptor to Swap RGB Values
7523 tfRGB10X2, tfX2RGB10, tfRGB10A2, tfA2RGB10, tfRGBA8, tfARGB8,
7524 tfBGR10X2, tfX2BGR10, tfBGR10A2, tfA2BGR10, tfBGRA8, tfABGR8: begin
7525 Info.biBitCount := 32;
7526 Info.biCompression := BMP_COMP_BITFIELDS;
7529 raise EglBitmapUnsupportedFormat.Create(Format);
7531 Info.biXPelsPerMeter := 2835;
7532 Info.biYPelsPerMeter := 2835;
7535 if Info.biCompression = BMP_COMP_BITFIELDS then begin
7536 Header.bfSize := Header.bfSize + 4 * SizeOf(Cardinal);
7537 Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal);
7539 RedMask := FormatDesc.RedMask;
7540 GreenMask := FormatDesc.GreenMask;
7541 BlueMask := FormatDesc.BlueMask;
7542 AlphaMask := FormatDesc.AlphaMask;
7546 aStream.Write(Header, SizeOf(Header));
7547 aStream.Write(Info, SizeOf(Info));
7550 if Assigned(Converter) and (Converter is TbmpColorTableFormat) then
7551 with (Converter as TbmpColorTableFormat) do
7552 aStream.Write(ColorTable[0].b,
7553 SizeOf(TbmpColorTableEnty) * Length(ColorTable));
7556 if Info.biCompression = BMP_COMP_BITFIELDS then begin
7557 aStream.Write(RedMask, SizeOf(Cardinal));
7558 aStream.Write(GreenMask, SizeOf(Cardinal));
7559 aStream.Write(BlueMask, SizeOf(Cardinal));
7560 aStream.Write(AlphaMask, SizeOf(Cardinal));
7564 rbLineSize := Round(Info.biWidth * FormatDesc.PixelSize);
7565 wbLineSize := Round(Info.biWidth * Info.biBitCount / 8);
7566 Padding := GetLineWidth - wbLineSize;
7570 inc(pData, (Height-1) * rbLineSize);
7572 // prepare row buffer. But only for RGB because RGBA supports color masks
7573 // so it's possible to change color within the image.
7574 if Assigned(Converter) then begin
7575 FormatDesc.PreparePixel(Pixel);
7576 GetMem(ConvertBuffer, wbLineSize);
7577 SourceFD := FormatDesc.CreateMappingData;
7578 DestFD := Converter.CreateMappingData;
7580 ConvertBuffer := nil;
7583 for LineIdx := 0 to Height - 1 do begin
7585 if Assigned(Converter) then begin
7587 dstData := ConvertBuffer;
7588 for PixelIdx := 0 to Info.biWidth-1 do begin
7589 FormatDesc.Unmap(srcData, Pixel, SourceFD);
7590 glBitmapConvertPixel(Pixel, FormatDesc, Converter);
7591 Converter.Map(Pixel, dstData, DestFD);
7593 aStream.Write(ConvertBuffer^, wbLineSize);
7595 aStream.Write(pData^, rbLineSize);
7597 dec(pData, rbLineSize);
7598 if (Padding > 0) then
7599 aStream.Write(PaddingBuff, Padding);
7602 // destroy row buffer
7603 if Assigned(ConvertBuffer) then begin
7604 FormatDesc.FreeMappingData(SourceFD);
7605 Converter.FreeMappingData(DestFD);
7606 FreeMem(ConvertBuffer);
7610 if Assigned(Converter) then
7615 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7616 //TGA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7617 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7619 TTGAHeader = packed record
7623 //ColorMapSpec: Array[0..4] of Byte;
7624 ColorMapStart: Word;
7625 ColorMapLength: Word;
7626 ColorMapEntrySize: Byte;
7636 TGA_UNCOMPRESSED_RGB = 2;
7637 TGA_UNCOMPRESSED_GRAY = 3;
7638 TGA_COMPRESSED_RGB = 10;
7639 TGA_COMPRESSED_GRAY = 11;
7641 TGA_NONE_COLOR_TABLE = 0;
7643 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7644 function TglBitmap.LoadTGA(const aStream: TStream): Boolean;
7647 ImageData: System.PByte;
7648 StartPosition: Int64;
7649 PixelSize, LineSize: Integer;
7650 tgaFormat: TglBitmapFormat;
7651 FormatDesc: TFormatDescriptor;
7652 Counter: packed record
7654 low, high, dir: Integer;
7661 ////////////////////////////////////////////////////////////////////////////////////////
7662 procedure ReadUncompressed;
7665 buf, tmp1, tmp2: System.PByte;
7668 if (Counter.X.dir < 0) then
7669 GetMem(buf, LineSize);
7671 while (Counter.Y.low <> Counter.Y.high + counter.Y.dir) do begin
7673 inc(tmp1, (Counter.Y.low * LineSize)); //pointer to LineStart
7674 if (Counter.X.dir < 0) then begin //flip X
7675 aStream.Read(buf^, LineSize);
7677 inc(tmp2, LineSize - PixelSize); //pointer to last pixel in line
7678 for i := 0 to Header.Width-1 do begin //for all pixels in line
7679 for j := 0 to PixelSize-1 do begin //for all bytes in pixel
7684 dec(tmp2, 2*PixelSize); //move 2 backwards, because j-loop moved 1 forward
7687 aStream.Read(tmp1^, LineSize);
7688 inc(Counter.Y.low, Counter.Y.dir); //move to next line index
7691 if Assigned(buf) then
7696 ////////////////////////////////////////////////////////////////////////////////////////
7697 procedure ReadCompressed;
7699 /////////////////////////////////////////////////////////////////
7701 TmpData: System.PByte;
7702 LinePixelsRead: Integer;
7703 procedure CheckLine;
7705 if (LinePixelsRead >= Header.Width) then begin
7706 LinePixelsRead := 0;
7707 inc(Counter.Y.low, Counter.Y.dir); //next line index
7708 TmpData := ImageData;
7709 inc(TmpData, Counter.Y.low * LineSize); //set line
7710 if (Counter.X.dir < 0) then //if x flipped then
7711 inc(TmpData, LineSize - PixelSize); //set last pixel
7715 /////////////////////////////////////////////////////////////////
7718 CacheSize, CachePos: Integer;
7719 procedure CachedRead(out Buffer; Count: Integer);
7723 if (CachePos + Count > CacheSize) then begin
7724 //if buffer overflow save non read bytes
7726 if (CacheSize - CachePos > 0) then begin
7727 BytesRead := CacheSize - CachePos;
7728 Move(PByteArray(Cache)^[CachePos], Buffer{%H-}, BytesRead);
7729 inc(CachePos, BytesRead);
7732 //load cache from file
7733 CacheSize := Min(CACHE_SIZE, aStream.Size - aStream.Position);
7734 aStream.Read(Cache^, CacheSize);
7737 //read rest of requested bytes
7738 if (Count - BytesRead > 0) then begin
7739 Move(PByteArray(Cache)^[CachePos], TByteArray(Buffer)[BytesRead], Count - BytesRead);
7740 inc(CachePos, Count - BytesRead);
7743 //if no buffer overflow just read the data
7744 Move(PByteArray(Cache)^[CachePos], Buffer, Count);
7745 inc(CachePos, Count);
7749 procedure PixelToBuffer(const aData: PByte; var aBuffer: PByte);
7754 inc(aBuffer, Counter.X.dir);
7757 PWord(aBuffer)^ := PWord(aData)^;
7758 inc(aBuffer, 2 * Counter.X.dir);
7761 PByteArray(aBuffer)^[0] := PByteArray(aData)^[0];
7762 PByteArray(aBuffer)^[1] := PByteArray(aData)^[1];
7763 PByteArray(aBuffer)^[2] := PByteArray(aData)^[2];
7764 inc(aBuffer, 3 * Counter.X.dir);
7767 PCardinal(aBuffer)^ := PCardinal(aData)^;
7768 inc(aBuffer, 4 * Counter.X.dir);
7774 TotalPixelsToRead, TotalPixelsRead: Integer;
7776 buf: array [0..3] of Byte; //1 pixel is max 32bit long
7777 PixelRepeat: Boolean;
7778 PixelsToRead, PixelCount: Integer;
7783 TotalPixelsToRead := Header.Width * Header.Height;
7784 TotalPixelsRead := 0;
7785 LinePixelsRead := 0;
7787 GetMem(Cache, CACHE_SIZE);
7789 TmpData := ImageData;
7790 inc(TmpData, Counter.Y.low * LineSize); //set line
7791 if (Counter.X.dir < 0) then //if x flipped then
7792 inc(TmpData, LineSize - PixelSize); //set last pixel
7796 CachedRead(Temp, 1);
7797 PixelRepeat := (Temp and $80) > 0;
7798 PixelsToRead := (Temp and $7F) + 1;
7799 inc(TotalPixelsRead, PixelsToRead);
7802 CachedRead(buf[0], PixelSize);
7803 while (PixelsToRead > 0) do begin
7805 PixelCount := Min(Header.Width - LinePixelsRead, PixelsToRead); //max read to EOL or EOF
7806 while (PixelCount > 0) do begin
7807 if not PixelRepeat then
7808 CachedRead(buf[0], PixelSize);
7809 PixelToBuffer(@buf[0], TmpData);
7810 inc(LinePixelsRead);
7815 until (TotalPixelsRead >= TotalPixelsToRead);
7821 function IsGrayFormat: Boolean;
7823 result := Header.ImageType in [TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_GRAY];
7829 // reading header to test file and set cursor back to begin
7830 StartPosition := aStream.Position;
7831 aStream.Read(Header{%H-}, SizeOf(Header));
7833 // no colormapped files
7834 if (Header.ColorMapType = TGA_NONE_COLOR_TABLE) and (Header.ImageType in [
7835 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY]) then
7838 if Header.ImageID <> 0 then // skip image ID
7839 aStream.Position := aStream.Position + Header.ImageID;
7841 tgaFormat := tfEmpty;
7843 8: if IsGrayFormat then case (Header.ImageDesc and $F) of
7844 0: tgaFormat := tfLuminance8;
7845 8: tgaFormat := tfAlpha8;
7848 16: if IsGrayFormat then case (Header.ImageDesc and $F) of
7849 0: tgaFormat := tfLuminance16;
7850 8: tgaFormat := tfLuminance8Alpha8;
7851 end else case (Header.ImageDesc and $F) of
7852 0: tgaFormat := tfX1RGB5;
7853 1: tgaFormat := tfA1RGB5;
7854 4: tgaFormat := tfARGB4;
7857 24: if not IsGrayFormat then case (Header.ImageDesc and $F) of
7858 0: tgaFormat := tfRGB8;
7861 32: if not IsGrayFormat then case (Header.ImageDesc and $F) of
7862 2: tgaFormat := tfA2RGB10;
7863 8: tgaFormat := tfARGB8;
7867 if (tgaFormat = tfEmpty) then
7868 raise EglBitmap.Create('LoadTga - unsupported format');
7870 FormatDesc := TFormatDescriptor.Get(tgaFormat);
7871 PixelSize := FormatDesc.GetSize(1, 1);
7872 LineSize := FormatDesc.GetSize(Header.Width, 1);
7874 GetMem(ImageData, LineSize * Header.Height);
7877 if ((Header.ImageDesc and (1 shl 4)) > 0) then begin
7878 Counter.X.low := Header.Height-1;;
7879 Counter.X.high := 0;
7880 Counter.X.dir := -1;
7883 Counter.X.high := Header.Height-1;
7888 if ((Header.ImageDesc and (1 shl 5)) > 0) then begin
7890 Counter.Y.high := Header.Height-1;
7893 Counter.Y.low := Header.Height-1;;
7894 Counter.Y.high := 0;
7895 Counter.Y.dir := -1;
7899 case Header.ImageType of
7900 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY:
7902 TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY:
7906 SetDataPointer(ImageData, tgaFormat, Header.Width, Header.Height); //be careful, Data could be freed by this method
7909 if Assigned(ImageData) then
7914 aStream.Position := StartPosition;
7917 else aStream.Position := StartPosition;
7920 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7921 procedure TglBitmap.SaveTGA(const aStream: TStream);
7924 LineSize, Size, x, y: Integer;
7925 Pixel: TglBitmapPixelData;
7926 LineBuf, SourceData, DestData: PByte;
7927 SourceMD, DestMD: Pointer;
7928 FormatDesc: TFormatDescriptor;
7929 Converter: TFormatDescriptor;
7931 if not (ftTGA in FormatGetSupportedFiles(Format)) then
7932 raise EglBitmapUnsupportedFormat.Create(Format);
7935 FillChar(Header{%H-}, SizeOf(Header), 0);
7938 if (Format in [tfLuminance8, tfLuminance6Alpha2, tfLuminance4Alpha4, tfAlpha8,
7939 tfLuminance16, tfLuminance12Alpha4, tfLuminance8Alpha8]) then
7940 Header.ImageType := TGA_UNCOMPRESSED_GRAY
7942 Header.ImageType := TGA_UNCOMPRESSED_RGB;
7945 if (Format in [tfLuminance8, tfLuminance6Alpha2, tfLuminance4Alpha4, tfAlpha8]) then
7947 else if (Format in [tfLuminance16, tfLuminance12Alpha4, tfLuminance8Alpha8,
7948 tfRGB5X1, tfBGR5X1, tfRGB5A1, tfBGR5A1, tfRGBA4, tfBGRA4]) then
7950 else if (Format in [tfBGR8, tfRGB8]) then
7958 Header.ImageDesc := 1 and $F;
7959 tfRGB10A2, tfBGR10A2:
7960 Header.ImageDesc := 2 and $F;
7962 Header.ImageDesc := 4 and $F;
7963 tfAlpha8, tfLuminance8Alpha8, tfRGBA8, tfBGRA8:
7964 Header.ImageDesc := 8 and $F;
7967 Header.Width := Width;
7968 Header.Height := Height;
7969 Header.ImageDesc := Header.ImageDesc or $20; //flip y
7970 aStream.Write(Header, SizeOf(Header));
7972 // convert RGB(A) to BGR(A)
7974 FormatDesc := TFormatDescriptor.Get(Format);
7975 Size := FormatDesc.GetSize(Dimension);
7976 if Format in [tfRGB5X1, tfRGB5A1, tfRGBA4, tfRGB8, tfRGB10A2, tfRGBA8] then begin
7977 if (FormatDesc.RGBInverted = tfEmpty) then
7978 raise EglBitmap.Create('inverted RGB format is empty');
7979 Converter := TFormatDescriptor.Get(FormatDesc.RGBInverted);
7980 if not glBitmapColorRecCmp(Converter.Range, FormatDesc.Range) or
7981 (Converter.PixelSize <> FormatDesc.PixelSize) then
7982 raise EglBitmap.Create('invalid inverted RGB format');
7985 if Assigned(Converter) then begin
7986 LineSize := FormatDesc.GetSize(Width, 1);
7987 GetMem(LineBuf, LineSize);
7988 SourceMD := FormatDesc.CreateMappingData;
7989 DestMD := Converter.CreateMappingData;
7992 for y := 0 to Height-1 do begin
7993 DestData := LineBuf;
7994 for x := 0 to Width-1 do begin
7995 FormatDesc.Unmap(SourceData, Pixel, SourceMD);
7996 Converter.Map(Pixel, DestData, DestMD);
7998 aStream.Write(LineBuf^, LineSize);
8002 FormatDesc.FreeMappingData(SourceMD);
8003 FormatDesc.FreeMappingData(DestMD);
8006 aStream.Write(Data^, Size);
8009 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8010 //DDS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8011 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8013 DDS_MAGIC: Cardinal = $20534444;
8015 // DDS_header.dwFlags
8016 DDSD_CAPS = $00000001;
8017 DDSD_HEIGHT = $00000002;
8018 DDSD_WIDTH = $00000004;
8019 DDSD_PIXELFORMAT = $00001000;
8021 // DDS_header.sPixelFormat.dwFlags
8022 DDPF_ALPHAPIXELS = $00000001;
8023 DDPF_ALPHA = $00000002;
8024 DDPF_FOURCC = $00000004;
8025 DDPF_RGB = $00000040;
8026 DDPF_LUMINANCE = $00020000;
8028 // DDS_header.sCaps.dwCaps1
8029 DDSCAPS_TEXTURE = $00001000;
8031 // DDS_header.sCaps.dwCaps2
8032 DDSCAPS2_CUBEMAP = $00000200;
8034 D3DFMT_DXT1 = $31545844;
8035 D3DFMT_DXT3 = $33545844;
8036 D3DFMT_DXT5 = $35545844;
8039 TDDSPixelFormat = packed record
8043 dwRGBBitCount: Cardinal;
8044 dwRBitMask: Cardinal;
8045 dwGBitMask: Cardinal;
8046 dwBBitMask: Cardinal;
8047 dwABitMask: Cardinal;
8050 TDDSCaps = packed record
8054 dwReserved: Cardinal;
8057 TDDSHeader = packed record
8062 dwPitchOrLinearSize: Cardinal;
8064 dwMipMapCount: Cardinal;
8065 dwReserved: array[0..10] of Cardinal;
8066 PixelFormat: TDDSPixelFormat;
8068 dwReserved2: Cardinal;
8071 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8072 function TglBitmap.LoadDDS(const aStream: TStream): Boolean;
8075 Converter: TbmpBitfieldFormat;
8077 function GetDDSFormat: TglBitmapFormat;
8079 fd: TFormatDescriptor;
8081 Range: TglBitmapColorRec;
8085 with Header.PixelFormat do begin
8087 if ((dwFlags and DDPF_FOURCC) > 0) then begin
8088 case Header.PixelFormat.dwFourCC of
8089 D3DFMT_DXT1: result := tfS3tcDtx1RGBA;
8090 D3DFMT_DXT3: result := tfS3tcDtx3RGBA;
8091 D3DFMT_DXT5: result := tfS3tcDtx5RGBA;
8093 end else if ((dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE)) > 0) then begin
8095 if ((dwFlags and DDPF_LUMINANCE) = 0) then begin
8096 Range.r := dwRBitMask;
8097 Range.g := dwGBitMask;
8098 Range.b := dwBBitMask;
8100 Range.r := dwRBitMask;
8101 Range.g := dwRBitMask;
8102 Range.b := dwRBitMask;
8104 Range.a := dwABitMask;
8106 //find matching format
8107 for result := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
8108 fd := TFormatDescriptor.Get(result);
8109 if fd.MaskMatch(Range.r, Range.g, Range.b, Range.a) and
8110 (8 * fd.PixelSize = dwRGBBitCount) then
8114 //find format with same Range
8115 for i := 0 to 3 do begin
8116 while ((Range.arr[i] and 1) = 0) and (Range.arr[i] > 0) do
8117 Range.arr[i] := Range.arr[i] shr 1;
8119 for result := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
8120 fd := TFormatDescriptor.Get(result);
8123 if (fd.Range.arr[i] <> Range.arr[i]) then begin
8131 //no format with same range found -> use default
8132 if (result = tfEmpty) then begin
8133 if (dwABitMask > 0) then
8139 Converter := TbmpBitfieldFormat.Create;
8140 Converter.RedMask := dwRBitMask;
8141 Converter.GreenMask := dwGBitMask;
8142 Converter.BlueMask := dwBBitMask;
8143 Converter.AlphaMask := dwABitMask;
8144 Converter.PixelSize := dwRGBBitCount / 8;
8151 x, y, LineSize, RowSize, Magic: Cardinal;
8152 NewImage, TmpData, RowData, SrcData: System.PByte;
8153 SourceMD, DestMD: Pointer;
8154 Pixel: TglBitmapPixelData;
8155 ddsFormat: TglBitmapFormat;
8156 FormatDesc: TFormatDescriptor;
8161 StreamPos := aStream.Position;
8164 aStream.Read(Magic{%H-}, sizeof(Magic));
8165 if (Magic <> DDS_MAGIC) then begin
8166 aStream.Position := StreamPos;
8171 aStream.Read(Header{%H-}, sizeof(Header));
8172 if (Header.dwSize <> SizeOf(Header)) or
8173 ((Header.dwFlags and (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) <>
8174 (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) then
8176 aStream.Position := StreamPos;
8180 if ((Header.Caps.dwCaps1 and DDSCAPS2_CUBEMAP) > 0) then
8181 raise EglBitmap.Create('LoadDDS - CubeMaps are not supported');
8183 ddsFormat := GetDDSFormat;
8185 if (ddsFormat = tfEmpty) then
8186 raise EglBitmap.Create('LoadDDS - unsupported Pixelformat found.');
8188 FormatDesc := TFormatDescriptor.Get(ddsFormat);
8189 LineSize := Trunc(Header.dwWidth * FormatDesc.PixelSize);
8190 GetMem(NewImage, Header.dwHeight * LineSize);
8192 TmpData := NewImage;
8195 if Assigned(Converter) then begin
8196 RowSize := Round(Header.dwWidth * Header.PixelFormat.dwRGBBitCount / 8);
8197 GetMem(RowData, RowSize);
8198 SourceMD := Converter.CreateMappingData;
8199 DestMD := FormatDesc.CreateMappingData;
8201 for y := 0 to Header.dwHeight-1 do begin
8202 TmpData := NewImage;
8203 inc(TmpData, y * LineSize);
8205 aStream.Read(SrcData^, RowSize);
8206 for x := 0 to Header.dwWidth-1 do begin
8207 Converter.Unmap(SrcData, Pixel, SourceMD);
8208 glBitmapConvertPixel(Pixel, Converter, FormatDesc);
8209 FormatDesc.Map(Pixel, TmpData, DestMD);
8213 Converter.FreeMappingData(SourceMD);
8214 FormatDesc.FreeMappingData(DestMD);
8220 if ((Header.PixelFormat.dwFlags and DDPF_FOURCC) > 0) then begin
8221 RowSize := Header.dwPitchOrLinearSize div Header.dwWidth;
8222 for Y := 0 to Header.dwHeight-1 do begin
8223 aStream.Read(TmpData^, RowSize);
8224 Inc(TmpData, LineSize);
8229 if (Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE)) > 0 then begin
8230 RowSize := (Header.PixelFormat.dwRGBBitCount * Header.dwWidth) shr 3;
8231 for Y := 0 to Header.dwHeight-1 do begin
8232 aStream.Read(TmpData^, RowSize);
8233 Inc(TmpData, LineSize);
8236 raise EglBitmap.Create('LoadDDS - unsupported Pixelformat found.');
8238 SetDataPointer(NewImage, ddsFormat, Header.dwWidth, Header.dwHeight); //be careful, Data could be freed by this method
8241 if Assigned(NewImage) then
8246 FreeAndNil(Converter);
8250 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8251 procedure TglBitmap.SaveDDS(const aStream: TStream);
8254 FormatDesc: TFormatDescriptor;
8256 if not (ftDDS in FormatGetSupportedFiles(Format)) then
8257 raise EglBitmapUnsupportedFormat.Create(Format);
8259 FormatDesc := TFormatDescriptor.Get(Format);
8262 FillChar(Header{%H-}, SizeOf(Header), 0);
8263 Header.dwSize := SizeOf(Header);
8264 Header.dwFlags := DDSD_WIDTH or DDSD_HEIGHT or DDSD_CAPS or DDSD_PIXELFORMAT;
8266 Header.dwWidth := Max(1, Width);
8267 Header.dwHeight := Max(1, Height);
8270 Header.Caps.dwCaps1 := DDSCAPS_TEXTURE;
8273 Header.PixelFormat.dwSize := sizeof(Header);
8274 if (FormatDesc.IsCompressed) then begin
8275 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_FOURCC;
8277 tfS3tcDtx1RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT1;
8278 tfS3tcDtx3RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT3;
8279 tfS3tcDtx5RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT5;
8281 end else if (Format in [tfAlpha8, tfAlpha16]) then begin
8282 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHA;
8283 Header.PixelFormat.dwRGBBitCount := Round(FormatDesc.PixelSize * 8);
8284 Header.PixelFormat.dwABitMask := FormatDesc.AlphaMask;
8285 end else if (FormatDesc.RedMask = FormatDesc.GreenMask) and (FormatDesc.GreenMask = FormatDesc.BlueMask) then begin
8286 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_LUMINANCE;
8287 Header.PixelFormat.dwRGBBitCount := Round(FormatDesc.PixelSize * 8);
8288 Header.PixelFormat.dwRBitMask := FormatDesc.RedMask;
8289 Header.PixelFormat.dwABitMask := FormatDesc.AlphaMask;
8291 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_RGB;
8292 Header.PixelFormat.dwRGBBitCount := Round(FormatDesc.PixelSize * 8);
8293 Header.PixelFormat.dwRBitMask := FormatDesc.RedMask;
8294 Header.PixelFormat.dwGBitMask := FormatDesc.GreenMask;
8295 Header.PixelFormat.dwBBitMask := FormatDesc.BlueMask;
8296 Header.PixelFormat.dwABitMask := FormatDesc.AlphaMask;
8299 if (FormatDesc.HasAlpha) then
8300 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHAPIXELS;
8302 aStream.Write(DDS_MAGIC, sizeof(DDS_MAGIC));
8303 aStream.Write(Header, SizeOf(Header));
8304 aStream.Write(Data^, FormatDesc.GetSize(Dimension));
8307 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8308 //TglBitmap1D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8309 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8310 procedure TglBitmap1D.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
8311 const aWidth: Integer; const aHeight: Integer);
8316 if (aHeight > 1) then begin
8317 Size := TFormatDescriptor.Get(aFormat).GetSize(aWidth, 1);
8318 GetMem(pTemp, Size);
8320 Move(aData^, pTemp^, Size);
8329 inherited SetDataPointer(pTemp, aFormat, aWidth);
8332 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8333 function TglBitmap1D.FlipHorz: Boolean;
8336 pTempDest, pDest, pSource: PByte;
8338 result := inherited FlipHorz;
8339 if Assigned(Data) and not TFormatDescriptor.Get(Format).IsCompressed then begin
8341 GetMem(pDest, fRowSize);
8344 Inc(pTempDest, fRowSize);
8345 for Col := 0 to Width-1 do begin
8346 dec(pTempDest, fPixelSize); //dec before, because ptr is behind last byte of data
8347 Move(pSource^, pTempDest^, fPixelSize);
8348 Inc(pSource, fPixelSize);
8350 SetDataPointer(pDest, Format, Width); //be careful, Data could be freed by this method
8353 if Assigned(pDest) then
8360 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8361 procedure TglBitmap1D.UploadData(const aBuildWithGlu: Boolean);
8363 FormatDesc: TFormatDescriptor;
8366 FormatDesc := TFormatDescriptor.Get(Format);
8367 if FormatDesc.IsCompressed then begin
8368 if not Assigned(glCompressedTexImage1D) then
8369 raise EglBitmap.Create('compressed formats not supported by video adapter');
8370 glCompressedTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.GetSize(Width, 1), Data)
8371 end else if aBuildWithGlu then
8372 gluBuild1DMipmaps(Target, FormatDesc.glInternalFormat, Width, FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
8374 glTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
8377 if (FreeDataAfterGenTexture) then
8381 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8382 procedure TglBitmap1D.GenTexture(const aTestTextureSize: Boolean);
8384 BuildWithGlu, TexRec: Boolean;
8387 if Assigned(Data) then begin
8388 // Check Texture Size
8389 if (aTestTextureSize) then begin
8390 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
8392 if (Width > TexSize) then
8393 raise EglBitmapSizeToLarge.Create('TglBitmap1D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
8395 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and
8396 (Target = GL_TEXTURE_RECTANGLE);
8397 if not (IsPowerOfTwo(Width) or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
8398 raise EglBitmapNonPowerOfTwo.Create('TglBitmap1D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8402 SetupParameters(BuildWithGlu);
8403 UploadData(BuildWithGlu);
8404 glAreTexturesResident(1, @fID, @fIsResident);
8408 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8409 procedure TglBitmap1D.AfterConstruction;
8412 Target := GL_TEXTURE_1D;
8415 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8416 //TglBitmap2D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8417 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8418 function TglBitmap2D.GetScanline(const aIndex: Integer): Pointer;
8420 if (aIndex >= Low(fLines)) and (aIndex <= High(fLines)) then
8421 result := fLines[aIndex]
8426 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8427 procedure TglBitmap2D.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
8428 const aWidth: Integer; const aHeight: Integer);
8430 Idx, LineWidth: Integer;
8432 inherited SetDataPointer(aData, aFormat, aWidth, aHeight);
8434 if not TFormatDescriptor.Get(aFormat).IsCompressed then begin
8436 if Assigned(Data) then begin
8437 SetLength(fLines, GetHeight);
8438 LineWidth := Trunc(GetWidth * TFormatDescriptor.Get(Format).PixelSize);
8440 for Idx := 0 to GetHeight-1 do begin
8441 fLines[Idx] := Data;
8442 Inc(fLines[Idx], Idx * LineWidth);
8445 else SetLength(fLines, 0);
8447 SetLength(fLines, 0);
8451 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8452 procedure TglBitmap2D.UploadData(const aTarget: GLenum; const aBuildWithGlu: Boolean);
8454 FormatDesc: TFormatDescriptor;
8456 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
8458 FormatDesc := TFormatDescriptor.Get(Format);
8459 if FormatDesc.IsCompressed then begin
8460 if not Assigned(glCompressedTexImage2D) then
8461 raise EglBitmap.Create('compressed formats not supported by video adapter');
8462 glCompressedTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0, FormatDesc.GetSize(fDimension), Data)
8463 end else if aBuildWithGlu then begin
8464 gluBuild2DMipmaps(aTarget, FormatDesc.Components, Width, Height,
8465 FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
8467 glTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0,
8468 FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
8472 if (FreeDataAfterGenTexture) then
8476 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8477 procedure TglBitmap2D.AfterConstruction;
8480 Target := GL_TEXTURE_2D;
8483 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8484 procedure TglBitmap2D.GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
8487 Size, w, h: Integer;
8488 FormatDesc: TFormatDescriptor;
8490 FormatDesc := TFormatDescriptor.Get(aFormat);
8491 if FormatDesc.IsCompressed then
8492 raise EglBitmapUnsupportedFormat.Create(aFormat);
8494 w := aRight - aLeft;
8495 h := aBottom - aTop;
8496 Size := FormatDesc.GetSize(w, h);
8499 glPixelStorei(GL_PACK_ALIGNMENT, 1);
8500 glReadPixels(aLeft, aTop, w, h, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
8501 SetDataPointer(Temp, aFormat, w, h); //be careful, Data could be freed by this method
8504 if Assigned(Temp) then
8510 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8511 procedure TglBitmap2D.GetDataFromTexture;
8514 TempWidth, TempHeight: Integer;
8515 TempIntFormat: GLint;
8516 IntFormat: TglBitmapFormat;
8517 FormatDesc: TFormatDescriptor;
8522 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_WIDTH, @TempWidth);
8523 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT, @TempHeight);
8524 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat);
8526 IntFormat := tfEmpty;
8527 FormatDesc := (TglBitmapFormatDescriptor.GetByFormat(TempIntFormat) as TFormatDescriptor);
8528 IntFormat := FormatDesc.Format;
8530 // Getting data from OpenGL
8531 FormatDesc := TFormatDescriptor.Get(IntFormat);
8532 GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight));
8534 if FormatDesc.IsCompressed then begin
8535 if not Assigned(glGetCompressedTexImage) then
8536 raise EglBitmap.Create('compressed formats not supported by video adapter');
8537 glGetCompressedTexImage(Target, 0, Temp)
8539 glGetTexImage(Target, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
8540 SetDataPointer(Temp, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
8542 if Assigned(Temp) then
8548 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8549 procedure TglBitmap2D.GenTexture(const aTestTextureSize: Boolean);
8551 BuildWithGlu, PotTex, TexRec: Boolean;
8554 if Assigned(Data) then begin
8555 // Check Texture Size
8556 if (aTestTextureSize) then begin
8557 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
8559 if ((Height > TexSize) or (Width > TexSize)) then
8560 raise EglBitmapSizeToLarge.Create('TglBitmap2D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
8562 PotTex := IsPowerOfTwo(Height) and IsPowerOfTwo(Width);
8563 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and (Target = GL_TEXTURE_RECTANGLE);
8564 if not (PotTex or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
8565 raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8569 SetupParameters(BuildWithGlu);
8570 UploadData(Target, BuildWithGlu);
8571 glAreTexturesResident(1, @fID, @fIsResident);
8575 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8576 function TglBitmap2D.FlipHorz: Boolean;
8579 TempDestData, DestData, SourceData: PByte;
8582 result := inherited FlipHorz;
8583 if Assigned(Data) then begin
8585 ImgSize := Height * fRowSize;
8586 GetMem(DestData, ImgSize);
8588 TempDestData := DestData;
8589 Dec(TempDestData, fRowSize + fPixelSize);
8590 for Row := 0 to Height -1 do begin
8591 Inc(TempDestData, fRowSize * 2);
8592 for Col := 0 to Width -1 do begin
8593 Move(SourceData^, TempDestData^, fPixelSize);
8594 Inc(SourceData, fPixelSize);
8595 Dec(TempDestData, fPixelSize);
8598 SetDataPointer(DestData, Format, Width, Height); //be careful, Data could be freed by this method
8601 if Assigned(DestData) then
8608 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8609 function TglBitmap2D.FlipVert: Boolean;
8612 TempDestData, DestData, SourceData: PByte;
8614 result := inherited FlipVert;
8615 if Assigned(Data) then begin
8617 GetMem(DestData, Height * fRowSize);
8619 TempDestData := DestData;
8620 Inc(TempDestData, Width * (Height -1) * fPixelSize);
8621 for Row := 0 to Height -1 do begin
8622 Move(SourceData^, TempDestData^, fRowSize);
8623 Dec(TempDestData, fRowSize);
8624 Inc(SourceData, fRowSize);
8626 SetDataPointer(DestData, Format, Width, Height); //be careful, Data could be freed by this method
8629 if Assigned(DestData) then
8636 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8637 //TglBitmap2D - ToNormalMap///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8638 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8640 TMatrixItem = record
8645 PglBitmapToNormalMapRec = ^TglBitmapToNormalMapRec;
8646 TglBitmapToNormalMapRec = Record
8648 Heights: array of Single;
8649 MatrixU : array of TMatrixItem;
8650 MatrixV : array of TMatrixItem;
8654 ONE_OVER_255 = 1 / 255;
8656 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8657 procedure glBitmapToNormalMapPrepareFunc(var FuncRec: TglBitmapFunctionRec);
8661 with FuncRec do begin
8663 Source.Data.r * LUMINANCE_WEIGHT_R +
8664 Source.Data.g * LUMINANCE_WEIGHT_G +
8665 Source.Data.b * LUMINANCE_WEIGHT_B;
8666 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Val * ONE_OVER_255;
8670 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8671 procedure glBitmapToNormalMapPrepareAlphaFunc(var FuncRec: TglBitmapFunctionRec);
8674 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Source.Data.a * ONE_OVER_255;
8677 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8678 procedure glBitmapToNormalMapFunc (var FuncRec: TglBitmapFunctionRec);
8680 TVec = Array[0..2] of Single;
8687 function GetHeight(X, Y: Integer): Single;
8689 with FuncRec do begin
8690 X := Max(0, Min(Size.X -1, X));
8691 Y := Max(0, Min(Size.Y -1, Y));
8692 result := PglBitmapToNormalMapRec(Args)^.Heights[Y * Size.X + X];
8697 with FuncRec do begin
8698 with PglBitmapToNormalMapRec(Args)^ do begin
8700 for Idx := Low(MatrixU) to High(MatrixU) do
8701 du := du + GetHeight(Position.X + MatrixU[Idx].X, Position.Y + MatrixU[Idx].Y) * MatrixU[Idx].W;
8704 for Idx := Low(MatrixU) to High(MatrixU) do
8705 dv := dv + GetHeight(Position.X + MatrixV[Idx].X, Position.Y + MatrixV[Idx].Y) * MatrixV[Idx].W;
8707 Vec[0] := -du * Scale;
8708 Vec[1] := -dv * Scale;
8713 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
8714 if Len <> 0 then begin
8715 Vec[0] := Vec[0] * Len;
8716 Vec[1] := Vec[1] * Len;
8717 Vec[2] := Vec[2] * Len;
8721 Dest.Data.r := Trunc((Vec[0] + 1) * 127.5);
8722 Dest.Data.g := Trunc((Vec[1] + 1) * 127.5);
8723 Dest.Data.b := Trunc((Vec[2] + 1) * 127.5);
8727 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8728 procedure TglBitmap2D.ToNormalMap(const aFunc: TglBitmapNormalMapFunc; const aScale: Single; const aUseAlpha: Boolean);
8730 Rec: TglBitmapToNormalMapRec;
8732 procedure SetEntry (var Matrix: array of TMatrixItem; Index, X, Y: Integer; W: Single);
8734 if (Index >= Low(Matrix)) and (Index <= High(Matrix)) then begin
8735 Matrix[Index].X := X;
8736 Matrix[Index].Y := Y;
8737 Matrix[Index].W := W;
8742 if TFormatDescriptor.Get(Format).IsCompressed then
8743 raise EglBitmapUnsupportedFormat.Create(Format);
8745 if aScale > 100 then
8747 else if aScale < -100 then
8750 Rec.Scale := aScale;
8752 SetLength(Rec.Heights, Width * Height);
8756 SetLength(Rec.MatrixU, 2);
8757 SetEntry(Rec.MatrixU, 0, -1, 0, -0.5);
8758 SetEntry(Rec.MatrixU, 1, 1, 0, 0.5);
8760 SetLength(Rec.MatrixV, 2);
8761 SetEntry(Rec.MatrixV, 0, 0, 1, 0.5);
8762 SetEntry(Rec.MatrixV, 1, 0, -1, -0.5);
8766 SetLength(Rec.MatrixU, 6);
8767 SetEntry(Rec.MatrixU, 0, -1, 1, -1.0);
8768 SetEntry(Rec.MatrixU, 1, -1, 0, -2.0);
8769 SetEntry(Rec.MatrixU, 2, -1, -1, -1.0);
8770 SetEntry(Rec.MatrixU, 3, 1, 1, 1.0);
8771 SetEntry(Rec.MatrixU, 4, 1, 0, 2.0);
8772 SetEntry(Rec.MatrixU, 5, 1, -1, 1.0);
8774 SetLength(Rec.MatrixV, 6);
8775 SetEntry(Rec.MatrixV, 0, -1, 1, 1.0);
8776 SetEntry(Rec.MatrixV, 1, 0, 1, 2.0);
8777 SetEntry(Rec.MatrixV, 2, 1, 1, 1.0);
8778 SetEntry(Rec.MatrixV, 3, -1, -1, -1.0);
8779 SetEntry(Rec.MatrixV, 4, 0, -1, -2.0);
8780 SetEntry(Rec.MatrixV, 5, 1, -1, -1.0);
8784 SetLength(Rec.MatrixU, 6);
8785 SetEntry(Rec.MatrixU, 0, -1, 1, -1/6);
8786 SetEntry(Rec.MatrixU, 1, -1, 0, -1/6);
8787 SetEntry(Rec.MatrixU, 2, -1, -1, -1/6);
8788 SetEntry(Rec.MatrixU, 3, 1, 1, 1/6);
8789 SetEntry(Rec.MatrixU, 4, 1, 0, 1/6);
8790 SetEntry(Rec.MatrixU, 5, 1, -1, 1/6);
8792 SetLength(Rec.MatrixV, 6);
8793 SetEntry(Rec.MatrixV, 0, -1, 1, 1/6);
8794 SetEntry(Rec.MatrixV, 1, 0, 1, 1/6);
8795 SetEntry(Rec.MatrixV, 2, 1, 1, 1/6);
8796 SetEntry(Rec.MatrixV, 3, -1, -1, -1/6);
8797 SetEntry(Rec.MatrixV, 4, 0, -1, -1/6);
8798 SetEntry(Rec.MatrixV, 5, 1, -1, -1/6);
8802 SetLength(Rec.MatrixU, 20);
8803 SetEntry(Rec.MatrixU, 0, -2, 2, -1 / 16);
8804 SetEntry(Rec.MatrixU, 1, -1, 2, -1 / 10);
8805 SetEntry(Rec.MatrixU, 2, 1, 2, 1 / 10);
8806 SetEntry(Rec.MatrixU, 3, 2, 2, 1 / 16);
8807 SetEntry(Rec.MatrixU, 4, -2, 1, -1 / 10);
8808 SetEntry(Rec.MatrixU, 5, -1, 1, -1 / 8);
8809 SetEntry(Rec.MatrixU, 6, 1, 1, 1 / 8);
8810 SetEntry(Rec.MatrixU, 7, 2, 1, 1 / 10);
8811 SetEntry(Rec.MatrixU, 8, -2, 0, -1 / 2.8);
8812 SetEntry(Rec.MatrixU, 9, -1, 0, -0.5);
8813 SetEntry(Rec.MatrixU, 10, 1, 0, 0.5);
8814 SetEntry(Rec.MatrixU, 11, 2, 0, 1 / 2.8);
8815 SetEntry(Rec.MatrixU, 12, -2, -1, -1 / 10);
8816 SetEntry(Rec.MatrixU, 13, -1, -1, -1 / 8);
8817 SetEntry(Rec.MatrixU, 14, 1, -1, 1 / 8);
8818 SetEntry(Rec.MatrixU, 15, 2, -1, 1 / 10);
8819 SetEntry(Rec.MatrixU, 16, -2, -2, -1 / 16);
8820 SetEntry(Rec.MatrixU, 17, -1, -2, -1 / 10);
8821 SetEntry(Rec.MatrixU, 18, 1, -2, 1 / 10);
8822 SetEntry(Rec.MatrixU, 19, 2, -2, 1 / 16);
8824 SetLength(Rec.MatrixV, 20);
8825 SetEntry(Rec.MatrixV, 0, -2, 2, 1 / 16);
8826 SetEntry(Rec.MatrixV, 1, -1, 2, 1 / 10);
8827 SetEntry(Rec.MatrixV, 2, 0, 2, 0.25);
8828 SetEntry(Rec.MatrixV, 3, 1, 2, 1 / 10);
8829 SetEntry(Rec.MatrixV, 4, 2, 2, 1 / 16);
8830 SetEntry(Rec.MatrixV, 5, -2, 1, 1 / 10);
8831 SetEntry(Rec.MatrixV, 6, -1, 1, 1 / 8);
8832 SetEntry(Rec.MatrixV, 7, 0, 1, 0.5);
8833 SetEntry(Rec.MatrixV, 8, 1, 1, 1 / 8);
8834 SetEntry(Rec.MatrixV, 9, 2, 1, 1 / 16);
8835 SetEntry(Rec.MatrixV, 10, -2, -1, -1 / 16);
8836 SetEntry(Rec.MatrixV, 11, -1, -1, -1 / 8);
8837 SetEntry(Rec.MatrixV, 12, 0, -1, -0.5);
8838 SetEntry(Rec.MatrixV, 13, 1, -1, -1 / 8);
8839 SetEntry(Rec.MatrixV, 14, 2, -1, -1 / 10);
8840 SetEntry(Rec.MatrixV, 15, -2, -2, -1 / 16);
8841 SetEntry(Rec.MatrixV, 16, -1, -2, -1 / 10);
8842 SetEntry(Rec.MatrixV, 17, 0, -2, -0.25);
8843 SetEntry(Rec.MatrixV, 18, 1, -2, -1 / 10);
8844 SetEntry(Rec.MatrixV, 19, 2, -2, -1 / 16);
8849 if aUseAlpha and TFormatDescriptor.Get(Format).HasAlpha then
8850 AddFunc(glBitmapToNormalMapPrepareAlphaFunc, false, @Rec)
8852 AddFunc(glBitmapToNormalMapPrepareFunc, false, @Rec);
8853 AddFunc(glBitmapToNormalMapFunc, false, @Rec);
8855 SetLength(Rec.Heights, 0);
8859 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8860 //TglBitmapCubeMap////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8861 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8862 procedure TglBitmapCubeMap.GenTexture(const aTestTextureSize: Boolean);
8864 Assert(false, 'TglBitmapCubeMap.GenTexture - Don''t call GenTextures directly.');
8867 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8868 procedure TglBitmapCubeMap.AfterConstruction;
8872 if not (GL_VERSION_1_3 or GL_ARB_texture_cube_map or GL_EXT_texture_cube_map) then
8873 raise EglBitmap.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
8876 Target := GL_TEXTURE_CUBE_MAP;
8877 fGenMode := GL_REFLECTION_MAP;
8880 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8881 procedure TglBitmapCubeMap.GenerateCubeMap(const aCubeTarget: Cardinal; const aTestTextureSize: Boolean);
8883 BuildWithGlu: Boolean;
8886 if (aTestTextureSize) then begin
8887 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, @TexSize);
8889 if (Height > TexSize) or (Width > TexSize) then
8890 raise EglBitmapSizeToLarge.Create('TglBitmapCubeMap.GenTexture - The size for the Cubemap is to large. It''s may be not conform with the Hardware.');
8892 if not ((IsPowerOfTwo(Height) and IsPowerOfTwo(Width)) or GL_VERSION_2_0 or GL_ARB_texture_non_power_of_two) then
8893 raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenTexture - Cubemaps dosn''t support non power of two texture.');
8898 SetupParameters(BuildWithGlu);
8899 UploadData(aCubeTarget, BuildWithGlu);
8902 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8903 procedure TglBitmapCubeMap.Bind(const aEnableTexCoordsGen: Boolean; const aEnableTextureUnit: Boolean);
8905 inherited Bind (aEnableTextureUnit);
8906 if aEnableTexCoordsGen then begin
8907 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, fGenMode);
8908 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, fGenMode);
8909 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, fGenMode);
8910 glEnable(GL_TEXTURE_GEN_S);
8911 glEnable(GL_TEXTURE_GEN_T);
8912 glEnable(GL_TEXTURE_GEN_R);
8916 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8917 procedure TglBitmapCubeMap.Unbind(const aDisableTexCoordsGen: Boolean; const aDisableTextureUnit: Boolean);
8919 inherited Unbind(aDisableTextureUnit);
8920 if aDisableTexCoordsGen then begin
8921 glDisable(GL_TEXTURE_GEN_S);
8922 glDisable(GL_TEXTURE_GEN_T);
8923 glDisable(GL_TEXTURE_GEN_R);
8927 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8928 //TglBitmapNormalMap//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8929 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8931 TVec = Array[0..2] of Single;
8932 TglBitmapNormalMapGetVectorFunc = procedure (out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8934 PglBitmapNormalMapRec = ^TglBitmapNormalMapRec;
8935 TglBitmapNormalMapRec = record
8937 Func: TglBitmapNormalMapGetVectorFunc;
8940 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8941 procedure glBitmapNormalMapPosX(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8943 aVec[0] := aHalfSize;
8944 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8945 aVec[2] := - (aPosition.X + 0.5 - aHalfSize);
8948 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8949 procedure glBitmapNormalMapNegX(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8951 aVec[0] := - aHalfSize;
8952 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8953 aVec[2] := aPosition.X + 0.5 - aHalfSize;
8956 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8957 procedure glBitmapNormalMapPosY(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8959 aVec[0] := aPosition.X + 0.5 - aHalfSize;
8960 aVec[1] := aHalfSize;
8961 aVec[2] := aPosition.Y + 0.5 - aHalfSize;
8964 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8965 procedure glBitmapNormalMapNegY(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8967 aVec[0] := aPosition.X + 0.5 - aHalfSize;
8968 aVec[1] := - aHalfSize;
8969 aVec[2] := - (aPosition.Y + 0.5 - aHalfSize);
8972 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8973 procedure glBitmapNormalMapPosZ(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8975 aVec[0] := aPosition.X + 0.5 - aHalfSize;
8976 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8977 aVec[2] := aHalfSize;
8980 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8981 procedure glBitmapNormalMapNegZ(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8983 aVec[0] := - (aPosition.X + 0.5 - aHalfSize);
8984 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8985 aVec[2] := - aHalfSize;
8988 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8989 procedure glBitmapNormalMapFunc(var FuncRec: TglBitmapFunctionRec);
8995 with FuncRec do begin
8996 with PglBitmapNormalMapRec(Args)^ do begin
8997 Func(Vec, Position, HalfSize);
9000 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
9001 if Len <> 0 then begin
9002 Vec[0] := Vec[0] * Len;
9003 Vec[1] := Vec[1] * Len;
9004 Vec[2] := Vec[2] * Len;
9007 // Scale Vector and AddVectro
9008 Vec[0] := Vec[0] * 0.5 + 0.5;
9009 Vec[1] := Vec[1] * 0.5 + 0.5;
9010 Vec[2] := Vec[2] * 0.5 + 0.5;
9015 Dest.Data.arr[i] := Round(Vec[i] * 255);
9019 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9020 procedure TglBitmapNormalMap.AfterConstruction;
9023 fGenMode := GL_NORMAL_MAP;
9026 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9027 procedure TglBitmapNormalMap.GenerateNormalMap(const aSize: Integer; const aTestTextureSize: Boolean);
9029 Rec: TglBitmapNormalMapRec;
9030 SizeRec: TglBitmapPixelPosition;
9032 Rec.HalfSize := aSize div 2;
9033 FreeDataAfterGenTexture := false;
9035 SizeRec.Fields := [ffX, ffY];
9040 Rec.Func := glBitmapNormalMapPosX;
9041 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8, @Rec);
9042 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X, aTestTextureSize);
9045 Rec.Func := glBitmapNormalMapNegX;
9046 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8, @Rec);
9047 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, aTestTextureSize);
9050 Rec.Func := glBitmapNormalMapPosY;
9051 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8, @Rec);
9052 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, aTestTextureSize);
9055 Rec.Func := glBitmapNormalMapNegY;
9056 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8, @Rec);
9057 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, aTestTextureSize);
9060 Rec.Func := glBitmapNormalMapPosZ;
9061 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8, @Rec);
9062 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, aTestTextureSize);
9065 Rec.Func := glBitmapNormalMapNegZ;
9066 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8, @Rec);
9067 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, aTestTextureSize);
9072 glBitmapSetDefaultFormat (tfEmpty);
9073 glBitmapSetDefaultMipmap (mmMipmap);
9074 glBitmapSetDefaultFilter (GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
9075 glBitmapSetDefaultWrap (GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
9076 glBitmapSetDefaultSwizzle(GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA);
9078 glBitmapSetDefaultFreeDataAfterGenTexture(true);
9079 glBitmapSetDefaultDeleteTextureOnFree (true);
9081 TFormatDescriptor.Init;
9083 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
9084 OpenGLInitialized := false;
9085 InitOpenGLCS := TCriticalSection.Create;
9089 TFormatDescriptor.Finalize;
9091 {$IFDEF GLB_NATIVE_OGL}
9092 if Assigned(GL_LibHandle) then
9093 glbFreeLibrary(GL_LibHandle);
9095 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
9096 if Assigned(GLU_LibHandle) then
9097 glbFreeLibrary(GLU_LibHandle);
9098 FreeAndNil(InitOpenGLCS);