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);
1219 NULL_SIZE: TglBitmapPixelPosition = (Fields: []; X: 0; Y: 0);
1221 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
1222 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
1223 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
1224 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
1225 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
1226 procedure glBitmapSetDefaultWrap(
1227 const S: Cardinal = GL_CLAMP_TO_EDGE;
1228 const T: Cardinal = GL_CLAMP_TO_EDGE;
1229 const R: Cardinal = GL_CLAMP_TO_EDGE);
1231 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
1232 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
1233 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
1234 function glBitmapGetDefaultFormat: TglBitmapFormat;
1235 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
1236 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
1238 function glBitmapPosition(X: Integer = -1; Y: Integer = -1): TglBitmapPixelPosition;
1239 function glBitmapColorRec(const r, g, b, a: Cardinal): TglBitmapColorRec;
1240 function glBitmapColorRecCmp(const r1, r2: TglBitmapColorRec): Boolean;
1243 glBitmapDefaultDeleteTextureOnFree: Boolean;
1244 glBitmapDefaultFreeDataAfterGenTextures: Boolean;
1245 glBitmapDefaultFormat: TglBitmapFormat;
1246 glBitmapDefaultMipmap: TglBitmapMipMap;
1247 glBitmapDefaultFilterMin: Cardinal;
1248 glBitmapDefaultFilterMag: Cardinal;
1249 glBitmapDefaultWrapS: Cardinal;
1250 glBitmapDefaultWrapT: Cardinal;
1251 glBitmapDefaultWrapR: Cardinal;
1252 glDefaultSwizzle: array[0..3] of GLenum;
1255 function CreateGrayPalette: HPALETTE;
1261 Math, syncobjs, typinfo
1262 {$IF DEFINED(GLB_SUPPORT_JPEG_READ) AND DEFINED(GLB_LAZ_JPEG)}, FPReadJPEG{$IFEND};
1266 QWord = System.UInt64;
1273 ////////////////////////////////////////////////////////////////////////////////////////////////////
1274 TShiftRec = packed record
1276 0: (r, g, b, a: Byte);
1277 1: (arr: array[0..3] of Byte);
1280 TFormatDescriptor = class(TglBitmapFormatDescriptor)
1282 function GetRedMask: QWord;
1283 function GetGreenMask: QWord;
1284 function GetBlueMask: QWord;
1285 function GetAlphaMask: QWord;
1287 fFormat: TglBitmapFormat;
1288 fWithAlpha: TglBitmapFormat;
1289 fWithoutAlpha: TglBitmapFormat;
1290 fOpenGLFormat: TglBitmapFormat;
1291 fRGBInverted: TglBitmapFormat;
1292 fUncompressed: TglBitmapFormat;
1295 fIsCompressed: Boolean;
1297 fRange: TglBitmapColorRec;
1301 fglInternalFormat: GLenum;
1302 fglDataFormat: GLenum;
1304 function GetIsCompressed: Boolean; override;
1305 function GetHasRed: Boolean; override;
1306 function GetHasGreen: Boolean; override;
1307 function GetHasBlue: Boolean; override;
1308 function GetHasAlpha: Boolean; override;
1310 function GetRGBInverted: TglBitmapFormat; override;
1311 function GetWithAlpha: TglBitmapFormat; override;
1312 function GetWithoutAlpha: TglBitmapFormat; override;
1313 function GetOpenGLFormat: TglBitmapFormat; override;
1314 function GetUncompressed: TglBitmapFormat; override;
1316 function GetglFormat: GLenum; override;
1317 function GetglInternalFormat: GLenum; override;
1318 function GetglDataFormat: GLenum; override;
1320 function GetComponents: Integer; virtual;
1322 property Format: TglBitmapFormat read fFormat;
1323 property Components: Integer read GetComponents;
1324 property PixelSize: Single read fPixelSize;
1326 property Range: TglBitmapColorRec read fRange;
1327 property Shift: TShiftRec read fShift;
1329 property RedMask: QWord read GetRedMask;
1330 property GreenMask: QWord read GetGreenMask;
1331 property BlueMask: QWord read GetBlueMask;
1332 property AlphaMask: QWord read GetAlphaMask;
1334 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); virtual; abstract;
1335 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); virtual; abstract;
1337 function GetSize(const aSize: TglBitmapPixelPosition): Integer; overload; virtual;
1338 function GetSize(const aWidth, aHeight: Integer): Integer; overload; virtual;
1340 function CreateMappingData: Pointer; virtual;
1341 procedure FreeMappingData(var aMappingData: Pointer); virtual;
1343 function IsEmpty: Boolean; virtual;
1344 function MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: QWord): Boolean; virtual;
1346 procedure PreparePixel(out aPixel: TglBitmapPixelData); virtual;
1348 constructor Create; virtual;
1350 class procedure Init;
1351 class function Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
1352 class function GetAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
1353 class procedure Clear;
1354 class procedure Finalize;
1356 TFormatDescriptorClass = class of TFormatDescriptor;
1358 TfdEmpty = class(TFormatDescriptor);
1360 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1361 TfdAlpha_UB1 = class(TFormatDescriptor) //1* unsigned byte
1362 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1363 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1366 TfdLuminance_UB1 = class(TFormatDescriptor) //1* unsigned byte
1367 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1368 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1371 TfdUniversal_UB1 = class(TFormatDescriptor) //1* unsigned byte
1372 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1373 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1376 TfdLuminanceAlpha_UB2 = class(TfdLuminance_UB1) //2* unsigned byte
1377 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1378 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1381 TfdRGB_UB3 = class(TFormatDescriptor) //3* unsigned byte
1382 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1383 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1386 TfdBGR_UB3 = class(TFormatDescriptor) //3* unsigned byte (inverse)
1387 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1388 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1391 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1392 TfdAlpha_US1 = class(TFormatDescriptor) //1* unsigned short
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 TfdLuminance_US1 = class(TFormatDescriptor) //1* unsigned short
1398 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1399 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1402 TfdUniversal_US1 = class(TFormatDescriptor) //1* unsigned short
1403 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1404 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1407 TfdDepth_US1 = class(TFormatDescriptor) //1* unsigned short
1408 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1409 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1412 TfdLuminanceAlpha_US2 = class(TfdLuminance_US1) //2* unsigned short
1413 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1414 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1417 TfdRGB_US3 = class(TFormatDescriptor) //3* unsigned short
1418 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1419 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1422 TfdBGR_US3 = class(TFormatDescriptor) //3* unsigned short (inverse)
1423 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1424 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1427 TfdRGBA_US4 = class(TfdRGB_US3) //4* unsigned short
1428 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1429 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1432 TfdARGB_US4 = class(TfdRGB_US3) //4* unsigned short
1433 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1434 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1437 TfdBGRA_US4 = class(TfdBGR_US3) //4* unsigned short (inverse)
1438 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1439 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1442 TfdABGR_US4 = class(TfdBGR_US3) //4* unsigned short (inverse)
1443 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1444 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1447 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1448 TfdUniversal_UI1 = class(TFormatDescriptor) //1* unsigned int
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 TfdDepth_UI1 = class(TFormatDescriptor) //1* unsigned int
1454 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1455 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1458 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1459 TfdAlpha4 = class(TfdAlpha_UB1)
1460 constructor Create; override;
1463 TfdAlpha8 = class(TfdAlpha_UB1)
1464 constructor Create; override;
1467 TfdAlpha16 = class(TfdAlpha_US1)
1468 constructor Create; override;
1471 TfdLuminance4 = class(TfdLuminance_UB1)
1472 constructor Create; override;
1475 TfdLuminance8 = class(TfdLuminance_UB1)
1476 constructor Create; override;
1479 TfdLuminance16 = class(TfdLuminance_US1)
1480 constructor Create; override;
1483 TfdLuminance4Alpha4 = class(TfdLuminanceAlpha_UB2)
1484 constructor Create; override;
1487 TfdLuminance6Alpha2 = class(TfdLuminanceAlpha_UB2)
1488 constructor Create; override;
1491 TfdLuminance8Alpha8 = class(TfdLuminanceAlpha_UB2)
1492 constructor Create; override;
1495 TfdLuminance12Alpha4 = class(TfdLuminanceAlpha_US2)
1496 constructor Create; override;
1499 TfdLuminance16Alpha16 = class(TfdLuminanceAlpha_US2)
1500 constructor Create; override;
1503 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1504 TfdR3G3B2 = class(TfdUniversal_UB1)
1505 constructor Create; override;
1508 TfdRGBX4 = class(TfdUniversal_US1)
1509 constructor Create; override;
1512 TfdXRGB4 = class(TfdUniversal_US1)
1513 constructor Create; override;
1516 TfdR5G6B5 = class(TfdUniversal_US1)
1517 constructor Create; override;
1520 TfdRGB5X1 = class(TfdUniversal_US1)
1521 constructor Create; override;
1524 TfdX1RGB5 = class(TfdUniversal_US1)
1525 constructor Create; override;
1528 TfdRGB8 = class(TfdRGB_UB3)
1529 constructor Create; override;
1532 TfdRGBX8 = class(TfdUniversal_UI1)
1533 constructor Create; override;
1536 TfdXRGB8 = class(TfdUniversal_UI1)
1537 constructor Create; override;
1540 TfdRGB10X2 = class(TfdUniversal_UI1)
1541 constructor Create; override;
1544 TfdX2RGB10 = class(TfdUniversal_UI1)
1545 constructor Create; override;
1548 TfdRGB16 = class(TfdRGB_US3)
1549 constructor Create; override;
1552 TfdRGBA4 = class(TfdUniversal_US1)
1553 constructor Create; override;
1556 TfdARGB4 = class(TfdUniversal_US1)
1557 constructor Create; override;
1560 TfdRGB5A1 = class(TfdUniversal_US1)
1561 constructor Create; override;
1564 TfdA1RGB5 = class(TfdUniversal_US1)
1565 constructor Create; override;
1568 TfdRGBA8 = class(TfdUniversal_UI1)
1569 constructor Create; override;
1572 TfdARGB8 = class(TfdUniversal_UI1)
1573 constructor Create; override;
1576 TfdRGB10A2 = class(TfdUniversal_UI1)
1577 constructor Create; override;
1580 TfdA2RGB10 = class(TfdUniversal_UI1)
1581 constructor Create; override;
1584 TfdRGBA16 = class(TfdUniversal_UI1)
1585 constructor Create; override;
1588 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1589 TfdBGRX4 = class(TfdUniversal_US1)
1590 constructor Create; override;
1593 TfdXBGR4 = class(TfdUniversal_US1)
1594 constructor Create; override;
1597 TfdB5G6R5 = class(TfdUniversal_US1)
1598 constructor Create; override;
1601 TfdBGR5X1 = class(TfdUniversal_US1)
1602 constructor Create; override;
1605 TfdX1BGR5 = class(TfdUniversal_US1)
1606 constructor Create; override;
1609 TfdBGR8 = class(TfdBGR_UB3)
1610 constructor Create; override;
1613 TfdBGRX8 = class(TfdUniversal_UI1)
1614 constructor Create; override;
1617 TfdXBGR8 = class(TfdUniversal_UI1)
1618 constructor Create; override;
1621 TfdBGR10X2 = class(TfdUniversal_UI1)
1622 constructor Create; override;
1625 TfdX2BGR10 = class(TfdUniversal_UI1)
1626 constructor Create; override;
1629 TfdBGR16 = class(TfdBGR_US3)
1630 constructor Create; override;
1633 TfdBGRA4 = class(TfdUniversal_US1)
1634 constructor Create; override;
1637 TfdABGR4 = class(TfdUniversal_US1)
1638 constructor Create; override;
1641 TfdBGR5A1 = class(TfdUniversal_US1)
1642 constructor Create; override;
1645 TfdA1BGR5 = class(TfdUniversal_US1)
1646 constructor Create; override;
1649 TfdBGRA8 = class(TfdUniversal_UI1)
1650 constructor Create; override;
1653 TfdABGR8 = class(TfdUniversal_UI1)
1654 constructor Create; override;
1657 TfdBGR10A2 = class(TfdUniversal_UI1)
1658 constructor Create; override;
1661 TfdA2BGR10 = class(TfdUniversal_UI1)
1662 constructor Create; override;
1665 TfdBGRA16 = class(TfdBGRA_US4)
1666 constructor Create; override;
1669 TfdDepth16 = class(TfdDepth_US1)
1670 constructor Create; override;
1673 TfdDepth24 = class(TfdDepth_UI1)
1674 constructor Create; override;
1677 TfdDepth32 = class(TfdDepth_UI1)
1678 constructor Create; override;
1681 TfdS3tcDtx1RGBA = class(TFormatDescriptor)
1682 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1683 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1684 constructor Create; override;
1687 TfdS3tcDtx3RGBA = 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 TfdS3tcDtx5RGBA = 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 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1700 TbmpBitfieldFormat = class(TFormatDescriptor)
1702 procedure SetRedMask (const aValue: QWord);
1703 procedure SetGreenMask(const aValue: QWord);
1704 procedure SetBlueMask (const aValue: QWord);
1705 procedure SetAlphaMask(const aValue: QWord);
1707 procedure Update(aMask: QWord; out aRange: Cardinal; out aShift: Byte);
1709 property RedMask: QWord read GetRedMask write SetRedMask;
1710 property GreenMask: QWord read GetGreenMask write SetGreenMask;
1711 property BlueMask: QWord read GetBlueMask write SetBlueMask;
1712 property AlphaMask: QWord read GetAlphaMask write SetAlphaMask;
1714 property PixelSize: Single read fPixelSize write fPixelSize;
1716 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1717 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1720 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1721 TbmpColorTableEnty = packed record
1724 TbmpColorTable = array of TbmpColorTableEnty;
1725 TbmpColorTableFormat = class(TFormatDescriptor)
1727 fColorTable: TbmpColorTable;
1729 property PixelSize: Single read fPixelSize write fPixelSize;
1730 property ColorTable: TbmpColorTable read fColorTable write fColorTable;
1731 property Range: TglBitmapColorRec read fRange write fRange;
1732 property Shift: TShiftRec read fShift write fShift;
1733 property Format: TglBitmapFormat read fFormat write fFormat;
1735 procedure CreateColorTable;
1737 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1738 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1739 destructor Destroy; override;
1743 LUMINANCE_WEIGHT_R = 0.30;
1744 LUMINANCE_WEIGHT_G = 0.59;
1745 LUMINANCE_WEIGHT_B = 0.11;
1747 ALPHA_WEIGHT_R = 0.30;
1748 ALPHA_WEIGHT_G = 0.59;
1749 ALPHA_WEIGHT_B = 0.11;
1751 DEPTH_WEIGHT_R = 0.333333333;
1752 DEPTH_WEIGHT_G = 0.333333333;
1753 DEPTH_WEIGHT_B = 0.333333333;
1755 UNSUPPORTED_FORMAT = 'the given format isn''t supported by this function.';
1757 FORMAT_DESCRIPTOR_CLASSES: array[TglBitmapFormat] of TFormatDescriptorClass = (
1768 TfdLuminance4Alpha4,
1769 TfdLuminance6Alpha2,
1770 TfdLuminance8Alpha8,
1771 TfdLuminance12Alpha4,
1772 TfdLuminance16Alpha16,
1829 FormatDescriptorCS: TCriticalSection;
1830 FormatDescriptors: array[TglBitmapFormat] of TFormatDescriptor;
1832 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1833 constructor EglBitmapUnsupportedFormat.Create(const aFormat: TglBitmapFormat);
1835 inherited Create('unsupported format: ' + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
1838 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1839 constructor EglBitmapUnsupportedFormat.Create(const aMsg: String; const aFormat: TglBitmapFormat);
1841 inherited Create(aMsg + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
1844 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1845 function glBitmapPosition(X, Y: Integer): TglBitmapPixelPosition;
1847 result.Fields := [];
1850 result.Fields := result.Fields + [ffX];
1852 result.Fields := result.Fields + [ffY];
1854 result.X := Max(0, X);
1855 result.Y := Max(0, Y);
1858 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1859 function glBitmapColorRec(const r, g, b, a: Cardinal): TglBitmapColorRec;
1867 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1868 function glBitmapColorRecCmp(const r1, r2: TglBitmapColorRec): Boolean;
1873 for i := 0 to high(r1.arr) do
1874 if (r1.arr[i] <> r2.arr[i]) then
1879 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1880 function glBitmapShiftRec(const r, g, b, a: Byte): TShiftRec;
1888 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1889 function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes;
1898 tfR3G3B2, tfLuminance8,
1901 tfRGBX4, tfXRGB4, tfRGB5X1, tfX1RGB5, tfR5G6B5, tfRGB5A1, tfA1RGB5, tfRGBA4, tfARGB4,
1902 tfBGRX4, tfXBGR4, tfBGR5X1, tfX1BGR5, tfB5G6R5, tfBGR5A1, tfA1BGR5, tfBGRA4, tfABGR4,
1908 tfRGB10X2, tfX2RGB10, tfRGB10A2, tfA2RGB10, tfRGBA8, tfARGB8,
1909 tfBGR10X2, tfX2BGR10, tfBGR10A2, tfA2BGR10, tfBGRA8, tfABGR8]) then
1910 result := result + [ftBMP];
1914 tfLuminance8, tfAlpha8,
1917 tfLuminance16, tfLuminance8Alpha8,
1918 tfRGB5X1, tfX1RGB5, tfRGB5A1, tfA1RGB5, tfRGBA4, tfARGB4,
1919 tfBGR5X1, tfX1BGR5, tfBGR5A1, tfA1BGR5, tfBGRA4, tfABGR4,
1925 tfRGB10A2, tfRGBA8, tfBGR10A2, tfBGRA8]) then
1926 result := result + [ftTGA];
1930 tfAlpha8, tfLuminance8, tfLuminance4Alpha4, tfLuminance6Alpha2,
1934 tfAlpha16, tfLuminance16, tfLuminance8Alpha8, tfLuminance12Alpha4,
1935 tfRGBX4, tfXRGB4, tfR5G6B5, tfRGB5X1, tfX1RGB5, tfRGBA4, tfARGB4, tfRGB5A1, tfA1RGB5,
1936 tfBGRX4, tfXBGR4, tfB5G6R5, tfBGR5X1, tfX1BGR5, tfBGRA4, tfABGR4, tfBGR5A1, tfA1BGR5,
1942 tfLuminance16Alpha16,
1947 tfS3tcDtx1RGBA, tfS3tcDtx3RGBA, tfS3tcDtx5RGBA]) then
1948 result := result + [ftDDS];
1950 {$IFDEF GLB_SUPPORT_PNG_WRITE}
1952 tfAlpha8, tfLuminance8, tfLuminance8Alpha8,
1954 tfBGR8, tfBGRA8] then
1955 result := result + [ftPNG];
1958 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
1959 if aFormat in [tfAlpha8, tfLuminance8, tfRGB8, tfBGR8] then
1960 result := result + [ftJPEG];
1964 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1965 function IsPowerOfTwo(aNumber: Integer): Boolean;
1967 while (aNumber and 1) = 0 do
1968 aNumber := aNumber shr 1;
1969 result := aNumber = 1;
1972 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1973 function GetTopMostBit(aBitSet: QWord): Integer;
1976 while aBitSet > 0 do begin
1978 aBitSet := aBitSet shr 1;
1982 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1983 function CountSetBits(aBitSet: QWord): Integer;
1986 while aBitSet > 0 do begin
1987 if (aBitSet and 1) = 1 then
1989 aBitSet := aBitSet shr 1;
1993 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1994 function LuminanceWeight(const aPixel: TglBitmapPixelData): Cardinal;
1997 LUMINANCE_WEIGHT_R * aPixel.Data.r +
1998 LUMINANCE_WEIGHT_G * aPixel.Data.g +
1999 LUMINANCE_WEIGHT_B * aPixel.Data.b);
2002 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2003 function DepthWeight(const aPixel: TglBitmapPixelData): Cardinal;
2006 DEPTH_WEIGHT_R * aPixel.Data.r +
2007 DEPTH_WEIGHT_G * aPixel.Data.g +
2008 DEPTH_WEIGHT_B * aPixel.Data.b);
2011 {$IFDEF GLB_NATIVE_OGL}
2012 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2013 //OpenGLInitialization///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2014 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2016 GL_LibHandle: Pointer = nil;
2018 function glbGetProcAddress(aProcName: PAnsiChar; aLibHandle: Pointer = nil; const aRaiseOnErr: Boolean = true): Pointer;
2020 if not Assigned(aLibHandle) then
2021 aLibHandle := GL_LibHandle;
2023 {$IF DEFINED(GLB_WIN)}
2024 result := GetProcAddress({%H-}HMODULE(aLibHandle), aProcName);
2025 if Assigned(result) then
2028 if Assigned(wglGetProcAddress) then
2029 result := wglGetProcAddress(aProcName);
2030 {$ELSEIF DEFINED(GLB_LINUX)}
2031 if Assigned(glXGetProcAddress) then begin
2032 result := glXGetProcAddress(aProcName);
2033 if Assigned(result) then
2037 if Assigned(glXGetProcAddressARB) then begin
2038 result := glXGetProcAddressARB(aProcName);
2039 if Assigned(result) then
2043 result := dlsym(aLibHandle, aProcName);
2045 if not Assigned(result) and aRaiseOnErr then
2046 raise EglBitmap.Create('unable to load procedure form library: ' + aProcName);
2049 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
2051 GLU_LibHandle: Pointer = nil;
2052 OpenGLInitialized: Boolean;
2053 InitOpenGLCS: TCriticalSection;
2055 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2056 procedure glbInitOpenGL;
2058 ////////////////////////////////////////////////////////////////////////////////
2059 function glbLoadLibrary(const aName: PChar): Pointer;
2061 {$IF DEFINED(GLB_WIN)}
2062 result := {%H-}Pointer(LoadLibrary(aName));
2063 {$ELSEIF DEFINED(GLB_LINUX)}
2064 result := dlopen(Name, RTLD_LAZY);
2070 ////////////////////////////////////////////////////////////////////////////////
2071 function glbFreeLibrary(const aLibHandle: Pointer): Boolean;
2074 if not Assigned(aLibHandle) then
2077 {$IF DEFINED(GLB_WIN)}
2078 Result := FreeLibrary({%H-}HINST(aLibHandle));
2079 {$ELSEIF DEFINED(GLB_LINUX)}
2080 Result := dlclose(aLibHandle) = 0;
2085 if Assigned(GL_LibHandle) then
2086 glbFreeLibrary(GL_LibHandle);
2088 if Assigned(GLU_LibHandle) then
2089 glbFreeLibrary(GLU_LibHandle);
2091 GL_LibHandle := glbLoadLibrary(libopengl);
2092 if not Assigned(GL_LibHandle) then
2093 raise EglBitmap.Create('unable to load library: ' + libopengl);
2095 GLU_LibHandle := glbLoadLibrary(libglu);
2096 if not Assigned(GLU_LibHandle) then
2097 raise EglBitmap.Create('unable to load library: ' + libglu);
2099 {$IF DEFINED(GLB_WIN)}
2100 wglGetProcAddress := glbGetProcAddress('wglGetProcAddress');
2101 {$ELSEIF DEFINED(GLB_LINUX)}
2102 glXGetProcAddress := glbGetProcAddress('glXGetProcAddress');
2103 glXGetProcAddressARB := glbGetProcAddress('glXGetProcAddressARB');
2106 glEnable := glbGetProcAddress('glEnable');
2107 glDisable := glbGetProcAddress('glDisable');
2108 glGetString := glbGetProcAddress('glGetString');
2109 glGetIntegerv := glbGetProcAddress('glGetIntegerv');
2110 glTexParameteri := glbGetProcAddress('glTexParameteri');
2111 glTexParameteriv := glbGetProcAddress('glTexParameteriv');
2112 glTexParameterfv := glbGetProcAddress('glTexParameterfv');
2113 glGetTexParameteriv := glbGetProcAddress('glGetTexParameteriv');
2114 glGetTexParameterfv := glbGetProcAddress('glGetTexParameterfv');
2115 glGetTexLevelParameteriv := glbGetProcAddress('glGetTexLevelParameteriv');
2116 glGetTexLevelParameterfv := glbGetProcAddress('glGetTexLevelParameterfv');
2117 glTexGeni := glbGetProcAddress('glTexGeni');
2118 glGenTextures := glbGetProcAddress('glGenTextures');
2119 glBindTexture := glbGetProcAddress('glBindTexture');
2120 glDeleteTextures := glbGetProcAddress('glDeleteTextures');
2121 glAreTexturesResident := glbGetProcAddress('glAreTexturesResident');
2122 glReadPixels := glbGetProcAddress('glReadPixels');
2123 glPixelStorei := glbGetProcAddress('glPixelStorei');
2124 glTexImage1D := glbGetProcAddress('glTexImage1D');
2125 glTexImage2D := glbGetProcAddress('glTexImage2D');
2126 glGetTexImage := glbGetProcAddress('glGetTexImage');
2128 gluBuild1DMipmaps := glbGetProcAddress('gluBuild1DMipmaps', GLU_LibHandle);
2129 gluBuild2DMipmaps := glbGetProcAddress('gluBuild2DMipmaps', GLU_LibHandle);
2133 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2134 procedure glbReadOpenGLExtensions;
2137 MajorVersion, MinorVersion: Integer;
2139 ///////////////////////////////////////////////////////////////////////////////////////////
2140 procedure TrimVersionString(aBuffer: AnsiString; out aMajor, aMinor: Integer);
2147 Separator := Pos(AnsiString('.'), aBuffer);
2148 if (Separator > 1) and (Separator < Length(aBuffer)) and
2149 (aBuffer[Separator - 1] in ['0'..'9']) and
2150 (aBuffer[Separator + 1] in ['0'..'9']) then begin
2153 while (Separator > 0) and (aBuffer[Separator] in ['0'..'9']) do
2156 Delete(aBuffer, 1, Separator);
2157 Separator := Pos(AnsiString('.'), aBuffer) + 1;
2159 while (Separator <= Length(aBuffer)) and (AnsiChar(aBuffer[Separator]) in ['0'..'9']) do
2162 Delete(aBuffer, Separator, 255);
2163 Separator := Pos(AnsiString('.'), aBuffer);
2165 aMajor := StrToInt(Copy(String(aBuffer), 1, Separator - 1));
2166 aMinor := StrToInt(Copy(String(aBuffer), Separator + 1, 1));
2170 ///////////////////////////////////////////////////////////////////////////////////////////
2171 function CheckExtension(const Extension: AnsiString): Boolean;
2175 ExtPos := Pos(Extension, Buffer);
2176 result := ExtPos > 0;
2178 result := ((ExtPos + Length(Extension) - 1) = Length(Buffer)) or not (Buffer[ExtPos + Length(Extension)] in ['_', 'A'..'Z', 'a'..'z']);
2181 ///////////////////////////////////////////////////////////////////////////////////////////
2182 function CheckVersion(const aMajor, aMinor: Integer): Boolean;
2184 result := (MajorVersion > aMajor) or ((MajorVersion = aMajor) and (MinorVersion >= aMinor));
2188 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
2191 if not OpenGLInitialized then begin
2193 OpenGLInitialized := true;
2201 Buffer := glGetString(GL_VERSION);
2202 TrimVersionString(Buffer, MajorVersion, MinorVersion);
2204 GL_VERSION_1_2 := CheckVersion(1, 2);
2205 GL_VERSION_1_3 := CheckVersion(1, 3);
2206 GL_VERSION_1_4 := CheckVersion(1, 4);
2207 GL_VERSION_2_0 := CheckVersion(2, 0);
2208 GL_VERSION_3_3 := CheckVersion(3, 3);
2211 Buffer := glGetString(GL_EXTENSIONS);
2212 GL_ARB_texture_border_clamp := CheckExtension('GL_ARB_texture_border_clamp');
2213 GL_ARB_texture_non_power_of_two := CheckExtension('GL_ARB_texture_non_power_of_two');
2214 GL_ARB_texture_swizzle := CheckExtension('GL_ARB_texture_swizzle');
2215 GL_ARB_texture_cube_map := CheckExtension('GL_ARB_texture_cube_map');
2216 GL_ARB_texture_rectangle := CheckExtension('GL_ARB_texture_rectangle');
2217 GL_ARB_texture_mirrored_repeat := CheckExtension('GL_ARB_texture_mirrored_repeat');
2218 GL_EXT_texture_edge_clamp := CheckExtension('GL_EXT_texture_edge_clamp');
2219 GL_EXT_texture_filter_anisotropic := CheckExtension('GL_EXT_texture_filter_anisotropic');
2220 GL_EXT_texture_rectangle := CheckExtension('GL_EXT_texture_rectangle');
2221 GL_EXT_texture_swizzle := CheckExtension('GL_EXT_texture_swizzle');
2222 GL_EXT_texture_cube_map := CheckExtension('GL_EXT_texture_cube_map');
2223 GL_NV_texture_rectangle := CheckExtension('GL_NV_texture_rectangle');
2224 GL_IBM_texture_mirrored_repeat := CheckExtension('GL_IBM_texture_mirrored_repeat');
2225 GL_SGIS_generate_mipmap := CheckExtension('GL_SGIS_generate_mipmap');
2227 if GL_VERSION_1_3 then begin
2228 glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1D');
2229 glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2D');
2230 glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImage');
2232 glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1DARB', nil, false);
2233 glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2DARB', nil, false);
2234 glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImageARB', nil, false);
2239 {$IFDEF GLB_SDL_IMAGE}
2240 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2241 // SDL Image Helper /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2242 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2243 function glBitmapRWseek(context: PSDL_RWops; offset: Integer; whence: Integer): Integer; cdecl;
2245 result := TStream(context^.unknown.data1).Seek(offset, whence);
2248 function glBitmapRWread(context: PSDL_RWops; Ptr: Pointer; size: Integer; maxnum : Integer): Integer; cdecl;
2250 result := TStream(context^.unknown.data1).Read(Ptr^, size * maxnum);
2253 function glBitmapRWwrite(context: PSDL_RWops; Ptr: Pointer; size: Integer; num: Integer): Integer; cdecl;
2255 result := TStream(context^.unknown.data1).Write(Ptr^, size * num);
2258 function glBitmapRWclose(context: PSDL_RWops): Integer; cdecl;
2263 function glBitmapCreateRWops(Stream: TStream): PSDL_RWops;
2265 result := SDL_AllocRW;
2267 if result = nil then
2268 raise EglBitmapException.Create('glBitmapCreateRWops - SDL_AllocRW failed.');
2270 result^.seek := glBitmapRWseek;
2271 result^.read := glBitmapRWread;
2272 result^.write := glBitmapRWwrite;
2273 result^.close := glBitmapRWclose;
2274 result^.unknown.data1 := Stream;
2278 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2279 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
2281 glBitmapDefaultDeleteTextureOnFree := aDeleteTextureOnFree;
2284 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2285 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
2287 glBitmapDefaultFreeDataAfterGenTextures := aFreeData;
2290 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2291 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
2293 glBitmapDefaultMipmap := aValue;
2296 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2297 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
2299 glBitmapDefaultFormat := aFormat;
2302 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2303 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
2305 glBitmapDefaultFilterMin := aMin;
2306 glBitmapDefaultFilterMag := aMag;
2309 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2310 procedure glBitmapSetDefaultWrap(const S: Cardinal = GL_CLAMP_TO_EDGE; const T: Cardinal = GL_CLAMP_TO_EDGE; const R: Cardinal = GL_CLAMP_TO_EDGE);
2312 glBitmapDefaultWrapS := S;
2313 glBitmapDefaultWrapT := T;
2314 glBitmapDefaultWrapR := R;
2317 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2318 procedure glBitmapSetDefaultSwizzle(const r: GLenum = GL_RED; g: GLenum = GL_GREEN; b: GLenum = GL_BLUE; a: GLenum = GL_ALPHA);
2320 glDefaultSwizzle[0] := r;
2321 glDefaultSwizzle[1] := g;
2322 glDefaultSwizzle[2] := b;
2323 glDefaultSwizzle[3] := a;
2326 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2327 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
2329 result := glBitmapDefaultDeleteTextureOnFree;
2332 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2333 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
2335 result := glBitmapDefaultFreeDataAfterGenTextures;
2338 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2339 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
2341 result := glBitmapDefaultMipmap;
2344 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2345 function glBitmapGetDefaultFormat: TglBitmapFormat;
2347 result := glBitmapDefaultFormat;
2350 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2351 procedure glBitmapGetDefaultFilter(var aMin, aMag: GLenum);
2353 aMin := glBitmapDefaultFilterMin;
2354 aMag := glBitmapDefaultFilterMag;
2357 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2358 procedure glBitmapGetDefaultTextureWrap(var S, T, R: GLenum);
2360 S := glBitmapDefaultWrapS;
2361 T := glBitmapDefaultWrapT;
2362 R := glBitmapDefaultWrapR;
2365 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2366 procedure glBitmapGetDefaultSwizzle(var r, g, b, a: GLenum);
2368 r := glDefaultSwizzle[0];
2369 g := glDefaultSwizzle[1];
2370 b := glDefaultSwizzle[2];
2371 a := glDefaultSwizzle[3];
2374 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2375 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2376 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2377 function TFormatDescriptor.GetRedMask: QWord;
2379 result := fRange.r shl fShift.r;
2382 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2383 function TFormatDescriptor.GetGreenMask: QWord;
2385 result := fRange.g shl fShift.g;
2388 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2389 function TFormatDescriptor.GetBlueMask: QWord;
2391 result := fRange.b shl fShift.b;
2394 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2395 function TFormatDescriptor.GetAlphaMask: QWord;
2397 result := fRange.a shl fShift.a;
2400 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2401 function TFormatDescriptor.GetIsCompressed: Boolean;
2403 result := fIsCompressed;
2406 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2407 function TFormatDescriptor.GetHasRed: Boolean;
2409 result := (fRange.r > 0);
2412 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2413 function TFormatDescriptor.GetHasGreen: Boolean;
2415 result := (fRange.g > 0);
2418 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2419 function TFormatDescriptor.GetHasBlue: Boolean;
2421 result := (fRange.b > 0);
2424 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2425 function TFormatDescriptor.GetHasAlpha: Boolean;
2427 result := (fRange.a > 0);
2430 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2431 function TFormatDescriptor.GetRGBInverted: TglBitmapFormat;
2433 result := fRGBInverted;
2436 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2437 function TFormatDescriptor.GetWithAlpha: TglBitmapFormat;
2439 result := fWithAlpha;
2442 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2443 function TFormatDescriptor.GetWithoutAlpha: TglBitmapFormat;
2445 result := fWithoutAlpha;
2448 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2449 function TFormatDescriptor.GetOpenGLFormat: TglBitmapFormat;
2451 result := fOpenGLFormat;
2454 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2455 function TFormatDescriptor.GetUncompressed: TglBitmapFormat;
2457 result := fUncompressed;
2460 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2461 function TFormatDescriptor.GetglFormat: GLenum;
2463 result := fglFormat;
2466 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2467 function TFormatDescriptor.GetglInternalFormat: GLenum;
2469 result := fglInternalFormat;
2472 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2473 function TFormatDescriptor.GetglDataFormat: GLenum;
2475 result := fglDataFormat;
2478 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2479 function TFormatDescriptor.GetComponents: Integer;
2485 if (fRange.arr[i] > 0) then
2489 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2490 function TFormatDescriptor.GetSize(const aSize: TglBitmapPixelPosition): Integer;
2494 if (ffX in aSize.Fields) or (ffY in aSize.Fields) then begin
2495 w := Max(1, aSize.X);
2496 h := Max(1, aSize.Y);
2497 result := GetSize(w, h);
2502 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2503 function TFormatDescriptor.GetSize(const aWidth, aHeight: Integer): Integer;
2506 if (aWidth <= 0) or (aHeight <= 0) then
2508 result := Ceil(aWidth * aHeight * fPixelSize);
2511 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2512 function TFormatDescriptor.CreateMappingData: Pointer;
2517 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2518 procedure TFormatDescriptor.FreeMappingData(var aMappingData: Pointer);
2523 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2524 function TFormatDescriptor.IsEmpty: Boolean;
2526 result := (fFormat = tfEmpty);
2529 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2530 function TFormatDescriptor.MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: QWord): Boolean;
2533 if (aRedMask = 0) and (aGreenMask = 0) and (aBlueMask = 0) and (aAlphaMask = 0) then
2534 raise EglBitmap.Create('FormatCheckFormat - All Masks are 0');
2535 if (aRedMask <> RedMask) then
2537 if (aGreenMask <> GreenMask) then
2539 if (aBlueMask <> BlueMask) then
2541 if (aAlphaMask <> AlphaMask) then
2546 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2547 procedure TFormatDescriptor.PreparePixel(out aPixel: TglBitmapPixelData);
2549 FillChar(aPixel{%H-}, SizeOf(aPixel), 0);
2550 aPixel.Data := fRange;
2551 aPixel.Range := fRange;
2552 aPixel.Format := fFormat;
2555 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2556 constructor TFormatDescriptor.Create;
2561 fWithAlpha := tfEmpty;
2562 fWithoutAlpha := tfEmpty;
2563 fOpenGLFormat := tfEmpty;
2564 fRGBInverted := tfEmpty;
2565 fUncompressed := tfEmpty;
2568 fIsCompressed := false;
2571 fglInternalFormat := 0;
2574 FillChar(fRange, 0, SizeOf(fRange));
2575 FillChar(fShift, 0, SizeOf(fShift));
2578 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2579 //TfdAlpha_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2580 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2581 procedure TfdAlpha_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2583 aData^ := aPixel.Data.a;
2587 procedure TfdAlpha_UB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2592 aPixel.Data.a := aData^;
2596 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2597 //TfdLuminance_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2598 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2599 procedure TfdLuminance_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2601 aData^ := LuminanceWeight(aPixel);
2605 procedure TfdLuminance_UB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2607 aPixel.Data.r := aData^;
2608 aPixel.Data.g := aData^;
2609 aPixel.Data.b := aData^;
2614 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2615 //TfdUniversal_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2616 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2617 procedure TfdUniversal_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2623 if (fRange.arr[i] > 0) then
2624 aData^ := aData^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
2628 procedure TfdUniversal_UB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2633 aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and fRange.arr[i];
2637 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2638 //TfdLuminanceAlpha_UB2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2639 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2640 procedure TfdLuminanceAlpha_UB2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2642 inherited Map(aPixel, aData, aMapData);
2643 aData^ := aPixel.Data.a;
2647 procedure TfdLuminanceAlpha_UB2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2649 inherited Unmap(aData, aPixel, aMapData);
2650 aPixel.Data.a := aData^;
2654 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2655 //TfdRGB_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2656 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2657 procedure TfdRGB_UB3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2659 aData^ := aPixel.Data.b;
2661 aData^ := aPixel.Data.g;
2663 aData^ := aPixel.Data.r;
2667 procedure TfdRGB_UB3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2669 aPixel.Data.b := aData^;
2671 aPixel.Data.g := aData^;
2673 aPixel.Data.r := aData^;
2678 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2679 //TfdBGR_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2680 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2681 procedure TfdBGR_UB3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2683 aData^ := aPixel.Data.r;
2685 aData^ := aPixel.Data.g;
2687 aData^ := aPixel.Data.b;
2691 procedure TfdBGR_UB3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2693 aPixel.Data.r := aData^;
2695 aPixel.Data.g := aData^;
2697 aPixel.Data.b := aData^;
2702 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2703 //TfdAlpha_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2704 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2705 procedure TfdAlpha_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2707 PWord(aData)^ := aPixel.Data.a;
2711 procedure TfdAlpha_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2716 aPixel.Data.a := PWord(aData)^;
2720 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2721 //TfdLuminance_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2722 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2723 procedure TfdLuminance_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2725 PWord(aData)^ := LuminanceWeight(aPixel);
2729 procedure TfdLuminance_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2731 aPixel.Data.r := PWord(aData)^;
2732 aPixel.Data.g := PWord(aData)^;
2733 aPixel.Data.b := PWord(aData)^;
2738 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2739 //TfdUniversal_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2740 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2741 procedure TfdUniversal_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2747 if (fRange.arr[i] > 0) then
2748 PWord(aData)^ := PWord(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
2752 procedure TfdUniversal_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2757 aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and fRange.arr[i];
2761 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2762 //TfdDepth_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2763 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2764 procedure TfdDepth_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2766 PWord(aData)^ := DepthWeight(aPixel);
2770 procedure TfdDepth_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2772 aPixel.Data.r := PWord(aData)^;
2773 aPixel.Data.g := PWord(aData)^;
2774 aPixel.Data.b := PWord(aData)^;
2775 aPixel.Data.a := PWord(aData)^;;
2779 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2780 //TfdLuminanceAlpha_US2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2781 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2782 procedure TfdLuminanceAlpha_US2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2784 inherited Map(aPixel, aData, aMapData);
2785 PWord(aData)^ := aPixel.Data.a;
2789 procedure TfdLuminanceAlpha_US2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2791 inherited Unmap(aData, aPixel, aMapData);
2792 aPixel.Data.a := PWord(aData)^;
2796 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2797 //TfdRGB_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2798 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2799 procedure TfdRGB_US3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2801 PWord(aData)^ := aPixel.Data.b;
2803 PWord(aData)^ := aPixel.Data.g;
2805 PWord(aData)^ := aPixel.Data.r;
2809 procedure TfdRGB_US3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2811 aPixel.Data.b := PWord(aData)^;
2813 aPixel.Data.g := PWord(aData)^;
2815 aPixel.Data.r := PWord(aData)^;
2820 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2821 //TfdBGR_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2822 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2823 procedure TfdBGR_US3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2825 PWord(aData)^ := aPixel.Data.r;
2827 PWord(aData)^ := aPixel.Data.g;
2829 PWord(aData)^ := aPixel.Data.b;
2833 procedure TfdBGR_US3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2835 aPixel.Data.r := PWord(aData)^;
2837 aPixel.Data.g := PWord(aData)^;
2839 aPixel.Data.b := PWord(aData)^;
2844 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2845 //TfdRGBA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2846 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2847 procedure TfdRGBA_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2849 PWord(aData)^ := aPixel.Data.a;
2851 inherited Map(aPixel, aData, aMapData);
2854 procedure TfdRGBA_US4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2856 aPixel.Data.a := PWord(aData)^;
2858 inherited Unmap(aData, aPixel, aMapData);
2861 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2862 //TfdARGB_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2863 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2864 procedure TfdARGB_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2866 inherited Map(aPixel, aData, aMapData);
2867 PWord(aData)^ := aPixel.Data.a;
2871 procedure TfdARGB_US4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2873 inherited Unmap(aData, aPixel, aMapData);
2874 aPixel.Data.a := PWord(aData)^;
2878 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2879 //TfdBGRA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2880 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2881 procedure TfdBGRA_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2883 PWord(aData)^ := aPixel.Data.a;
2885 inherited Map(aPixel, aData, aMapData);
2888 procedure TfdBGRA_US4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2890 aPixel.Data.a := PWord(aData)^;
2892 inherited Unmap(aData, aPixel, aMapData);
2895 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2896 //TfdABGR_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2897 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2898 procedure TfdABGR_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2900 inherited Map(aPixel, aData, aMapData);
2901 PWord(aData)^ := aPixel.Data.a;
2905 procedure TfdABGR_US4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2907 inherited Unmap(aData, aPixel, aMapData);
2908 aPixel.Data.a := PWord(aData)^;
2912 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2913 //TfdUniversal_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2914 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2915 procedure TfdUniversal_UI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2919 PCardinal(aData)^ := 0;
2921 if (fRange.arr[i] > 0) then
2922 PCardinal(aData)^ := PCardinal(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
2926 procedure TfdUniversal_UI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2931 aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and fRange.arr[i];
2935 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2936 //TfdDepth_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2937 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2938 procedure TfdDepth_UI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2940 PCardinal(aData)^ := DepthWeight(aPixel);
2944 procedure TfdDepth_UI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2946 aPixel.Data.r := PCardinal(aData)^;
2947 aPixel.Data.g := PCardinal(aData)^;
2948 aPixel.Data.b := PCardinal(aData)^;
2953 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2954 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2955 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2956 constructor TfdAlpha4.Create;
2960 fFormat := tfAlpha4;
2961 fWithAlpha := tfAlpha4;
2962 fOpenGLFormat := tfAlpha4;
2964 fglFormat := GL_ALPHA;
2965 fglInternalFormat := GL_ALPHA4;
2966 fglDataFormat := GL_UNSIGNED_BYTE;
2969 constructor TfdAlpha8.Create;
2973 fFormat := tfAlpha8;
2974 fWithAlpha := tfAlpha8;
2975 fOpenGLFormat := tfAlpha8;
2977 fglFormat := GL_ALPHA;
2978 fglInternalFormat := GL_ALPHA8;
2979 fglDataFormat := GL_UNSIGNED_BYTE;
2982 constructor TfdAlpha16.Create;
2986 fFormat := tfAlpha16;
2987 fWithAlpha := tfAlpha16;
2988 fOpenGLFormat := tfAlpha16;
2990 fglFormat := GL_ALPHA;
2991 fglInternalFormat := GL_ALPHA16;
2992 fglDataFormat := GL_UNSIGNED_SHORT;
2995 constructor TfdLuminance4.Create;
2999 fFormat := tfLuminance4;
3000 fWithAlpha := tfLuminance4Alpha4;
3001 fWithoutAlpha := tfLuminance4;
3002 fOpenGLFormat := tfLuminance4;
3006 fglFormat := GL_LUMINANCE;
3007 fglInternalFormat := GL_LUMINANCE4;
3008 fglDataFormat := GL_UNSIGNED_BYTE;
3011 constructor TfdLuminance8.Create;
3015 fFormat := tfLuminance8;
3016 fWithAlpha := tfLuminance8Alpha8;
3017 fWithoutAlpha := tfLuminance8;
3018 fOpenGLFormat := tfLuminance8;
3022 fglFormat := GL_LUMINANCE;
3023 fglInternalFormat := GL_LUMINANCE8;
3024 fglDataFormat := GL_UNSIGNED_BYTE;
3027 constructor TfdLuminance16.Create;
3031 fFormat := tfLuminance16;
3032 fWithAlpha := tfLuminance16Alpha16;
3033 fWithoutAlpha := tfLuminance16;
3034 fOpenGLFormat := tfLuminance16;
3038 fglFormat := GL_LUMINANCE;
3039 fglInternalFormat := GL_LUMINANCE16;
3040 fglDataFormat := GL_UNSIGNED_SHORT;
3043 constructor TfdLuminance4Alpha4.Create;
3047 fFormat := tfLuminance4Alpha4;
3048 fWithAlpha := tfLuminance4Alpha4;
3049 fWithoutAlpha := tfLuminance4;
3050 fOpenGLFormat := tfLuminance4Alpha4;
3059 fglFormat := GL_LUMINANCE_ALPHA;
3060 fglInternalFormat := GL_LUMINANCE4_ALPHA4;
3061 fglDataFormat := GL_UNSIGNED_BYTE;
3064 constructor TfdLuminance6Alpha2.Create;
3068 fFormat := tfLuminance6Alpha2;
3069 fWithAlpha := tfLuminance6Alpha2;
3070 fWithoutAlpha := tfLuminance8;
3071 fOpenGLFormat := tfLuminance6Alpha2;
3080 fglFormat := GL_LUMINANCE_ALPHA;
3081 fglInternalFormat := GL_LUMINANCE6_ALPHA2;
3082 fglDataFormat := GL_UNSIGNED_BYTE;
3085 constructor TfdLuminance8Alpha8.Create;
3089 fFormat := tfLuminance8Alpha8;
3090 fWithAlpha := tfLuminance8Alpha8;
3091 fWithoutAlpha := tfLuminance8;
3092 fOpenGLFormat := tfLuminance8Alpha8;
3101 fglFormat := GL_LUMINANCE_ALPHA;
3102 fglInternalFormat := GL_LUMINANCE8_ALPHA8;
3103 fglDataFormat := GL_UNSIGNED_BYTE;
3106 constructor TfdLuminance12Alpha4.Create;
3110 fFormat := tfLuminance12Alpha4;
3111 fWithAlpha := tfLuminance12Alpha4;
3112 fWithoutAlpha := tfLuminance16;
3113 fOpenGLFormat := tfLuminance12Alpha4;
3122 fglFormat := GL_LUMINANCE_ALPHA;
3123 fglInternalFormat := GL_LUMINANCE12_ALPHA4;
3124 fglDataFormat := GL_UNSIGNED_SHORT;
3127 constructor TfdLuminance16Alpha16.Create;
3131 fFormat := tfLuminance16Alpha16;
3132 fWithAlpha := tfLuminance16Alpha16;
3133 fWithoutAlpha := tfLuminance16;
3134 fOpenGLFormat := tfLuminance16Alpha16;
3143 fglFormat := GL_LUMINANCE_ALPHA;
3144 fglInternalFormat := GL_LUMINANCE16_ALPHA16;
3145 fglDataFormat := GL_UNSIGNED_SHORT;
3148 constructor TfdR3G3B2.Create;
3152 fFormat := tfR3G3B2;
3153 fWithAlpha := tfRGBA4;
3154 fWithoutAlpha := tfR3G3B2;
3155 fOpenGLFormat := tfR3G3B2;
3156 fRGBInverted := tfEmpty;
3163 fglFormat := GL_RGB;
3164 fglInternalFormat := GL_R3_G3_B2;
3165 fglDataFormat := GL_UNSIGNED_BYTE_3_3_2;
3168 constructor TfdRGBX4.Create;
3173 fWithAlpha := tfRGBA4;
3174 fWithoutAlpha := tfRGBX4;
3175 fOpenGLFormat := tfRGBX4;
3176 fRGBInverted := tfBGRX4;
3184 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3185 fglInternalFormat := GL_RGB4;
3186 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3189 constructor TfdXRGB4.Create;
3194 fWithAlpha := tfARGB4;
3195 fWithoutAlpha := tfXRGB4;
3196 fOpenGLFormat := tfXRGB4;
3197 fRGBInverted := tfXBGR4;
3204 fglFormat := GL_BGRA;
3205 fglInternalFormat := GL_RGB4;
3206 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3209 constructor TfdR5G6B5.Create;
3213 fFormat := tfR5G6B5;
3214 fWithAlpha := tfRGB5A1;
3215 fWithoutAlpha := tfR5G6B5;
3216 fOpenGLFormat := tfR5G6B5;
3217 fRGBInverted := tfB5G6R5;
3224 fglFormat := GL_RGB;
3225 fglInternalFormat := GL_RGB565;
3226 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5;
3229 constructor TfdRGB5X1.Create;
3233 fFormat := tfRGB5X1;
3234 fWithAlpha := tfRGB5A1;
3235 fWithoutAlpha := tfRGB5X1;
3236 fOpenGLFormat := tfRGB5X1;
3237 fRGBInverted := tfBGR5X1;
3244 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3245 fglInternalFormat := GL_RGB5;
3246 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3249 constructor TfdX1RGB5.Create;
3253 fFormat := tfX1RGB5;
3254 fWithAlpha := tfA1RGB5;
3255 fWithoutAlpha := tfX1RGB5;
3256 fOpenGLFormat := tfX1RGB5;
3257 fRGBInverted := tfX1BGR5;
3264 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3265 fglInternalFormat := GL_RGB5;
3266 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3269 constructor TfdRGB8.Create;
3274 fWithAlpha := tfRGBA8;
3275 fWithoutAlpha := tfRGB8;
3276 fOpenGLFormat := tfRGB8;
3277 fRGBInverted := tfBGR8;
3284 fglFormat := GL_BGR; // reverse byte order to match little endianess
3285 fglInternalFormat := GL_RGB8; // as if u interpret the 3 bytes as unsigned integer
3286 fglDataFormat := GL_UNSIGNED_BYTE;
3289 constructor TfdRGBX8.Create;
3294 fWithAlpha := tfRGBA8;
3295 fWithoutAlpha := tfRGBX8;
3296 fOpenGLFormat := tfRGB8;
3297 fRGBInverted := tfBGRX8;
3304 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3305 fglInternalFormat := GL_RGB8;
3306 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3309 constructor TfdXRGB8.Create;
3314 fWithAlpha := tfXRGB8;
3315 fWithoutAlpha := tfXRGB8;
3316 fOpenGLFormat := tfRGB8;
3317 fRGBInverted := tfXBGR8;
3324 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3325 fglInternalFormat := GL_RGB8;
3326 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3329 constructor TfdRGB10X2.Create;
3333 fFormat := tfRGB10X2;
3334 fWithAlpha := tfRGB10A2;
3335 fWithoutAlpha := tfRGB10X2;
3336 fOpenGLFormat := tfRGB10X2;
3337 fRGBInverted := tfBGR10X2;
3344 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3345 fglInternalFormat := GL_RGB10;
3346 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3349 constructor TfdX2RGB10.Create;
3353 fFormat := tfX2RGB10;
3354 fWithAlpha := tfA2RGB10;
3355 fWithoutAlpha := tfX2RGB10;
3356 fOpenGLFormat := tfX2RGB10;
3357 fRGBInverted := tfX2BGR10;
3364 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3365 fglInternalFormat := GL_RGB10;
3366 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3369 constructor TfdRGB16.Create;
3374 fWithAlpha := tfRGBA16;
3375 fWithoutAlpha := tfRGB16;
3376 fOpenGLFormat := tfRGB16;
3377 fRGBInverted := tfBGR16;
3384 fglFormat := GL_BGR; // reverse byte order to match little endianess
3385 fglInternalFormat := GL_RGB16; // as if u interpret the 3 bytes as unsigned integer
3386 fglDataFormat := GL_UNSIGNED_SHORT;
3389 constructor TfdRGBA4.Create;
3394 fWithAlpha := tfRGBA4;
3395 fWithoutAlpha := tfRGBX4;
3396 fOpenGLFormat := tfRGBA4;
3397 fRGBInverted := tfBGRA4;
3406 fglFormat := GL_RGBA;
3407 fglInternalFormat := GL_RGBA4;
3408 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3411 constructor TfdARGB4.Create;
3416 fWithAlpha := tfARGB4;
3417 fWithoutAlpha := tfXRGB4;
3418 fOpenGLFormat := tfARGB4;
3419 fRGBInverted := tfABGR4;
3428 fglFormat := GL_BGRA;
3429 fglInternalFormat := GL_RGBA4;
3430 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3433 constructor TfdRGB5A1.Create;
3437 fFormat := tfRGB5A1;
3438 fWithAlpha := tfRGB5A1;
3439 fWithoutAlpha := tfRGB5X1;
3440 fOpenGLFormat := tfRGB5A1;
3441 fRGBInverted := tfBGR5A1;
3450 fglFormat := GL_RGBA;
3451 fglInternalFormat := GL_RGB5_A1;
3452 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3455 constructor TfdA1RGB5.Create;
3459 fFormat := tfA1RGB5;
3460 fWithAlpha := tfA1RGB5;
3461 fWithoutAlpha := tfX1RGB5;
3462 fOpenGLFormat := tfA1RGB5;
3463 fRGBInverted := tfA1BGR5;
3472 fglFormat := GL_BGRA;
3473 fglInternalFormat := GL_RGB5_A1;
3474 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3477 constructor TfdRGBA8.Create;
3482 fWithAlpha := tfRGBA8;
3483 fWithoutAlpha := tfRGB8;
3484 fOpenGLFormat := tfRGBA8;
3485 fRGBInverted := tfBGRA8;
3494 fglFormat := GL_RGBA;
3495 fglInternalFormat := GL_RGBA8;
3496 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3499 constructor TfdARGB8.Create;
3504 fWithAlpha := tfARGB8;
3505 fWithoutAlpha := tfRGB8;
3506 fOpenGLFormat := tfARGB8;
3507 fRGBInverted := tfABGR8;
3516 fglFormat := GL_BGRA;
3517 fglInternalFormat := GL_RGBA8;
3518 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3521 constructor TfdRGB10A2.Create;
3525 fFormat := tfRGB10A2;
3526 fWithAlpha := tfRGB10A2;
3527 fWithoutAlpha := tfRGB10X2;
3528 fOpenGLFormat := tfRGB10A2;
3529 fRGBInverted := tfBGR10A2;
3538 fglFormat := GL_RGBA;
3539 fglInternalFormat := GL_RGB10_A2;
3540 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3543 constructor TfdA2RGB10.Create;
3547 fFormat := tfA2RGB10;
3548 fWithAlpha := tfA2RGB10;
3549 fWithoutAlpha := tfX2RGB10;
3550 fOpenGLFormat := tfA2RGB10;
3551 fRGBInverted := tfA2BGR10;
3560 fglFormat := GL_BGRA;
3561 fglInternalFormat := GL_RGB10_A2;
3562 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3565 constructor TfdRGBA16.Create;
3569 fFormat := tfRGBA16;
3570 fWithAlpha := tfRGBA16;
3571 fWithoutAlpha := tfRGB16;
3572 fOpenGLFormat := tfRGBA16;
3573 fRGBInverted := tfBGRA16;
3582 fglFormat := GL_BGRA; // reverse byte order to match little endianess
3583 fglInternalFormat := GL_RGBA16; // as if u interpret the 3 bytes as unsigned integer
3584 fglDataFormat := GL_UNSIGNED_SHORT;
3587 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3588 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3589 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3590 constructor TfdBGRX4.Create;
3595 fWithAlpha := tfBGRA4;
3596 fWithoutAlpha := tfBGRX4;
3597 fOpenGLFormat := tfBGRX4;
3598 fRGBInverted := tfRGBX4;
3605 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3606 fglInternalFormat := GL_RGB4;
3607 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3610 constructor TfdXBGR4.Create;
3615 fWithAlpha := tfABGR4;
3616 fWithoutAlpha := tfXBGR4;
3617 fOpenGLFormat := tfXBGR4;
3618 fRGBInverted := tfXRGB4;
3626 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3627 fglInternalFormat := GL_RGB4;
3628 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3631 constructor TfdB5G6R5.Create;
3635 fFormat := tfB5G6R5;
3636 fWithAlpha := tfBGR5A1;
3637 fWithoutAlpha := tfB5G6R5;
3638 fOpenGLFormat := tfB5G6R5;
3639 fRGBInverted := tfR5G6B5;
3646 fglFormat := GL_RGB;
3647 fglInternalFormat := GL_RGB565;
3648 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5_REV;
3651 constructor TfdBGR5X1.Create;
3655 fFormat := tfBGR5X1;
3656 fWithAlpha := tfBGR5A1;
3657 fWithoutAlpha := tfBGR5X1;
3658 fOpenGLFormat := tfBGR5X1;
3659 fRGBInverted := tfRGB5X1;
3666 fglFormat := GL_BGRA;
3667 fglInternalFormat := GL_RGB5;
3668 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3671 constructor TfdX1BGR5.Create;
3675 fFormat := tfX1BGR5;
3676 fWithAlpha := tfA1BGR5;
3677 fWithoutAlpha := tfX1BGR5;
3678 fOpenGLFormat := tfX1BGR5;
3679 fRGBInverted := tfX1RGB5;
3686 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3687 fglInternalFormat := GL_RGB5;
3688 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3691 constructor TfdBGR8.Create;
3696 fWithAlpha := tfBGRA8;
3697 fWithoutAlpha := tfBGR8;
3698 fOpenGLFormat := tfBGR8;
3699 fRGBInverted := tfRGB8;
3706 fglFormat := GL_RGB; // reverse byte order to match little endianess
3707 fglInternalFormat := GL_RGB8; // as if u interpret the 3 bytes as unsigned integer
3708 fglDataFormat := GL_UNSIGNED_BYTE;
3711 constructor TfdBGRX8.Create;
3716 fWithAlpha := tfBGRA8;
3717 fWithoutAlpha := tfBGRX8;
3718 fOpenGLFormat := tfBGRX8;
3719 fRGBInverted := tfRGBX8;
3726 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3727 fglInternalFormat := GL_RGB8;
3728 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3731 constructor TfdXBGR8.Create;
3736 fWithAlpha := tfABGR8;
3737 fWithoutAlpha := tfXBGR8;
3738 fOpenGLFormat := tfXBGR8;
3739 fRGBInverted := tfXRGB8;
3746 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3747 fglInternalFormat := GL_RGB8;
3748 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3751 constructor TfdBGR10X2.Create;
3755 fFormat := tfBGR10X2;
3756 fWithAlpha := tfBGR10A2;
3757 fWithoutAlpha := tfBGR10X2;
3758 fOpenGLFormat := tfBGR10X2;
3759 fRGBInverted := tfRGB10X2;
3766 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3767 fglInternalFormat := GL_RGB10;
3768 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3771 constructor TfdX2BGR10.Create;
3775 fFormat := tfX2BGR10;
3776 fWithAlpha := tfA2BGR10;
3777 fWithoutAlpha := tfX2BGR10;
3778 fOpenGLFormat := tfX2BGR10;
3779 fRGBInverted := tfX2RGB10;
3786 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3787 fglInternalFormat := GL_RGB10;
3788 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3791 constructor TfdBGR16.Create;
3796 fWithAlpha := tfBGRA16;
3797 fWithoutAlpha := tfBGR16;
3798 fOpenGLFormat := tfBGR16;
3799 fRGBInverted := tfRGB16;
3806 fglFormat := GL_RGB; // reverse byte order to match little endianess
3807 fglInternalFormat := GL_RGB16; // as if u interpret the 3 bytes as unsigned integer
3808 fglDataFormat := GL_UNSIGNED_SHORT;
3811 constructor TfdBGRA4.Create;
3816 fWithAlpha := tfBGRA4;
3817 fWithoutAlpha := tfBGRX4;
3818 fOpenGLFormat := tfBGRA4;
3819 fRGBInverted := tfRGBA4;
3828 fglFormat := GL_BGRA;
3829 fglInternalFormat := GL_RGBA4;
3830 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4;
3833 constructor TfdABGR4.Create;
3838 fWithAlpha := tfABGR4;
3839 fWithoutAlpha := tfXBGR4;
3840 fOpenGLFormat := tfABGR4;
3841 fRGBInverted := tfARGB4;
3850 fglFormat := GL_RGBA;
3851 fglInternalFormat := GL_RGBA4;
3852 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3855 constructor TfdBGR5A1.Create;
3859 fFormat := tfBGR5A1;
3860 fWithAlpha := tfBGR5A1;
3861 fWithoutAlpha := tfBGR5X1;
3862 fOpenGLFormat := tfBGR5A1;
3863 fRGBInverted := tfRGB5A1;
3872 fglFormat := GL_BGRA;
3873 fglInternalFormat := GL_RGB5_A1;
3874 fglDataFormat := GL_UNSIGNED_SHORT_5_5_5_1;
3877 constructor TfdA1BGR5.Create;
3881 fFormat := tfA1BGR5;
3882 fWithAlpha := tfA1BGR5;
3883 fWithoutAlpha := tfX1BGR5;
3884 fOpenGLFormat := tfA1BGR5;
3885 fRGBInverted := tfA1RGB5;
3894 fglFormat := GL_RGBA;
3895 fglInternalFormat := GL_RGB5_A1;
3896 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3899 constructor TfdBGRA8.Create;
3904 fWithAlpha := tfBGRA8;
3905 fWithoutAlpha := tfBGR8;
3906 fOpenGLFormat := tfBGRA8;
3907 fRGBInverted := tfRGBA8;
3916 fglFormat := GL_BGRA;
3917 fglInternalFormat := GL_RGBA8;
3918 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8;
3921 constructor TfdABGR8.Create;
3926 fWithAlpha := tfABGR8;
3927 fWithoutAlpha := tfBGR8;
3928 fOpenGLFormat := tfABGR8;
3929 fRGBInverted := tfARGB8;
3938 fglFormat := GL_RGBA;
3939 fglInternalFormat := GL_RGBA8;
3940 fglDataFormat := GL_UNSIGNED_INT_8_8_8_8_REV;
3943 constructor TfdBGR10A2.Create;
3947 fFormat := tfBGR10A2;
3948 fWithAlpha := tfBGR10A2;
3949 fWithoutAlpha := tfBGR10X2;
3950 fOpenGLFormat := tfBGR10A2;
3951 fRGBInverted := tfRGB10A2;
3960 fglFormat := GL_BGRA;
3961 fglInternalFormat := GL_RGB10_A2;
3962 fglDataFormat := GL_UNSIGNED_INT_10_10_10_2;
3965 constructor TfdA2BGR10.Create;
3969 fFormat := tfA2BGR10;
3970 fWithAlpha := tfA2BGR10;
3971 fWithoutAlpha := tfX2BGR10;
3972 fOpenGLFormat := tfA2BGR10;
3973 fRGBInverted := tfA2RGB10;
3982 fglFormat := GL_RGBA;
3983 fglInternalFormat := GL_RGB10_A2;
3984 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3987 constructor TfdBGRA16.Create;
3991 fFormat := tfBGRA16;
3992 fWithAlpha := tfBGRA16;
3993 fWithoutAlpha := tfBGR16;
3994 fOpenGLFormat := tfBGRA16;
3995 fRGBInverted := tfRGBA16;
4004 fglFormat := GL_RGBA; // reverse byte order to match little endianess
4005 fglInternalFormat := GL_RGBA16; // as if u interpret the 3 bytes as unsigned integer
4006 fglDataFormat := GL_UNSIGNED_SHORT;
4009 constructor TfdDepth16.Create;
4013 fFormat := tfDepth16;
4014 fWithoutAlpha := tfDepth16;
4015 fOpenGLFormat := tfDepth16;
4020 fglFormat := GL_DEPTH_COMPONENT;
4021 fglInternalFormat := GL_DEPTH_COMPONENT16;
4022 fglDataFormat := GL_UNSIGNED_SHORT;
4025 constructor TfdDepth24.Create;
4029 fFormat := tfDepth24;
4030 fWithoutAlpha := tfDepth24;
4031 fOpenGLFormat := tfDepth24;
4032 fRange.r := $FFFFFF;
4033 fRange.g := $FFFFFF;
4034 fRange.b := $FFFFFF;
4035 fRange.a := $FFFFFF;
4036 fglFormat := GL_DEPTH_COMPONENT;
4037 fglInternalFormat := GL_DEPTH_COMPONENT24;
4038 fglDataFormat := GL_UNSIGNED_INT;
4041 constructor TfdDepth32.Create;
4045 fFormat := tfDepth32;
4046 fWithoutAlpha := tfDepth32;
4047 fOpenGLFormat := tfDepth32;
4048 fRange.r := $FFFFFFFF;
4049 fRange.g := $FFFFFFFF;
4050 fRange.b := $FFFFFFFF;
4051 fRange.a := $FFFFFFFF;
4052 fglFormat := GL_DEPTH_COMPONENT;
4053 fglInternalFormat := GL_DEPTH_COMPONENT32;
4054 fglDataFormat := GL_UNSIGNED_INT;
4057 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4058 //TfdS3tcDtx1RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4059 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4060 procedure TfdS3tcDtx1RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4062 raise EglBitmap.Create('mapping for compressed formats is not supported');
4065 procedure TfdS3tcDtx1RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4067 raise EglBitmap.Create('mapping for compressed formats is not supported');
4070 constructor TfdS3tcDtx1RGBA.Create;
4073 fFormat := tfS3tcDtx1RGBA;
4074 fWithAlpha := tfS3tcDtx1RGBA;
4075 fOpenGLFormat := tfS3tcDtx1RGBA;
4076 fUncompressed := tfRGB5A1;
4078 fIsCompressed := true;
4079 fglFormat := GL_COMPRESSED_RGBA;
4080 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
4081 fglDataFormat := GL_UNSIGNED_BYTE;
4084 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4085 //TfdS3tcDtx3RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4086 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4087 procedure TfdS3tcDtx3RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4089 raise EglBitmap.Create('mapping for compressed formats is not supported');
4092 procedure TfdS3tcDtx3RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4094 raise EglBitmap.Create('mapping for compressed formats is not supported');
4097 constructor TfdS3tcDtx3RGBA.Create;
4100 fFormat := tfS3tcDtx3RGBA;
4101 fWithAlpha := tfS3tcDtx3RGBA;
4102 fOpenGLFormat := tfS3tcDtx3RGBA;
4103 fUncompressed := tfRGBA8;
4105 fIsCompressed := true;
4106 fglFormat := GL_COMPRESSED_RGBA;
4107 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
4108 fglDataFormat := GL_UNSIGNED_BYTE;
4111 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4112 //TfdS3tcDtx5RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4113 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4114 procedure TfdS3tcDtx5RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4116 raise EglBitmap.Create('mapping for compressed formats is not supported');
4119 procedure TfdS3tcDtx5RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4121 raise EglBitmap.Create('mapping for compressed formats is not supported');
4124 constructor TfdS3tcDtx5RGBA.Create;
4127 fFormat := tfS3tcDtx3RGBA;
4128 fWithAlpha := tfS3tcDtx3RGBA;
4129 fOpenGLFormat := tfS3tcDtx3RGBA;
4130 fUncompressed := tfRGBA8;
4132 fIsCompressed := true;
4133 fglFormat := GL_COMPRESSED_RGBA;
4134 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
4135 fglDataFormat := GL_UNSIGNED_BYTE;
4138 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4139 //TglBitmapFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4140 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4141 class function TglBitmapFormatDescriptor.GetByFormat(const aInternalFormat: GLenum): TglBitmapFormatDescriptor;
4145 for f := Low(TglBitmapFormat) to High(TglBitmapFormat) do begin
4146 result := TFormatDescriptor.Get(f);
4147 if (result.glInternalFormat = aInternalFormat) then
4150 result := TFormatDescriptor.Get(tfEmpty);
4153 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4154 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4155 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4156 class procedure TFormatDescriptor.Init;
4158 if not Assigned(FormatDescriptorCS) then
4159 FormatDescriptorCS := TCriticalSection.Create;
4162 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4163 class function TFormatDescriptor.Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
4165 FormatDescriptorCS.Enter;
4167 result := FormatDescriptors[aFormat];
4168 if not Assigned(result) then begin
4169 result := FORMAT_DESCRIPTOR_CLASSES[aFormat].Create;
4170 FormatDescriptors[aFormat] := result;
4173 FormatDescriptorCS.Leave;
4177 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4178 class function TFormatDescriptor.GetAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
4180 result := Get(Get(aFormat).WithAlpha);
4183 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4184 class procedure TFormatDescriptor.Clear;
4188 FormatDescriptorCS.Enter;
4190 for f := low(FormatDescriptors) to high(FormatDescriptors) do
4191 FreeAndNil(FormatDescriptors[f]);
4193 FormatDescriptorCS.Leave;
4197 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4198 class procedure TFormatDescriptor.Finalize;
4201 FreeAndNil(FormatDescriptorCS);
4204 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4205 //TBitfieldFormat/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4206 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4207 procedure TbmpBitfieldFormat.SetRedMask(const aValue: QWord);
4209 Update(aValue, fRange.r, fShift.r);
4212 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4213 procedure TbmpBitfieldFormat.SetGreenMask(const aValue: QWord);
4215 Update(aValue, fRange.g, fShift.g);
4218 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4219 procedure TbmpBitfieldFormat.SetBlueMask(const aValue: QWord);
4221 Update(aValue, fRange.b, fShift.b);
4224 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4225 procedure TbmpBitfieldFormat.SetAlphaMask(const aValue: QWord);
4227 Update(aValue, fRange.a, fShift.a);
4230 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4231 procedure TbmpBitfieldFormat.Update(aMask: QWord; out aRange: Cardinal; out
4238 while (aMask > 0) and ((aMask and 1) = 0) do begin
4240 aMask := aMask shr 1;
4243 while (aMask > 0) do begin
4244 aRange := aRange shl 1;
4245 aMask := aMask shr 1;
4249 fPixelSize := Round(GetTopMostBit(RedMask or GreenMask or BlueMask or AlphaMask) / 8);
4252 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4253 procedure TbmpBitfieldFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4259 ((aPixel.Data.r and fRange.r) shl fShift.r) or
4260 ((aPixel.Data.g and fRange.g) shl fShift.g) or
4261 ((aPixel.Data.b and fRange.b) shl fShift.b) or
4262 ((aPixel.Data.a and fRange.a) shl fShift.a);
4263 s := Round(fPixelSize);
4266 2: PWord(aData)^ := data;
4267 4: PCardinal(aData)^ := data;
4268 8: PQWord(aData)^ := data;
4270 raise EglBitmap.CreateFmt('invalid pixel size: %.1f', [fPixelSize]);
4275 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4276 procedure TbmpBitfieldFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4281 s := Round(fPixelSize);
4284 2: data := PWord(aData)^;
4285 4: data := PCardinal(aData)^;
4286 8: data := PQWord(aData)^;
4288 raise EglBitmap.CreateFmt('invalid pixel size: %.1f', [fPixelSize]);
4291 aPixel.Data.arr[i] := (data shr fShift.arr[i]) and fRange.arr[i];
4295 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4296 //TColorTableFormat///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4297 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4298 procedure TbmpColorTableFormat.CreateColorTable;
4302 if not (Format in [tfLuminance4, tfLuminance8, tfR3G3B2]) then
4303 raise EglBitmap.Create(UNSUPPORTED_FORMAT);
4305 if (Format = tfLuminance4) then
4306 SetLength(fColorTable, 16)
4308 SetLength(fColorTable, 256);
4312 for i := 0 to High(fColorTable) do begin
4313 fColorTable[i].r := 16 * i;
4314 fColorTable[i].g := 16 * i;
4315 fColorTable[i].b := 16 * i;
4316 fColorTable[i].a := 0;
4321 for i := 0 to High(fColorTable) do begin
4322 fColorTable[i].r := i;
4323 fColorTable[i].g := i;
4324 fColorTable[i].b := i;
4325 fColorTable[i].a := 0;
4330 for i := 0 to High(fColorTable) do begin
4331 fColorTable[i].r := Round(((i shr Shift.r) and Range.r) / Range.r * 255);
4332 fColorTable[i].g := Round(((i shr Shift.g) and Range.g) / Range.g * 255);
4333 fColorTable[i].b := Round(((i shr Shift.b) and Range.b) / Range.b * 255);
4334 fColorTable[i].a := 0;
4340 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4341 procedure TbmpColorTableFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
4345 if not (Format in [tfLuminance4, tfLuminance8, tfR3G3B2]) then
4346 raise EglBitmap.Create(UNSUPPORTED_FORMAT);
4350 if (aMapData = nil) then
4352 d := LuminanceWeight(aPixel) and Range.r;
4353 aData^ := aData^ or (d shl (4 - {%H-}PtrUInt(aMapData)));
4354 inc(PByte(aMapData), 4);
4355 if ({%H-}PtrUInt(aMapData) >= 8) then begin
4362 aData^ := LuminanceWeight(aPixel) and Range.r;
4368 ((aPixel.Data.r and Range.r) shl Shift.r) or
4369 ((aPixel.Data.g and Range.g) shl Shift.g) or
4370 ((aPixel.Data.b and Range.b) shl Shift.b));
4376 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4377 procedure TbmpColorTableFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
4384 s := Trunc(fPixelSize);
4385 f := fPixelSize - s;
4386 bits := Round(8 * f);
4388 0: idx := (aData^ shr (8 - bits - {%H-}PtrInt(aMapData))) and ((1 shl bits) - 1);
4390 2: idx := PWord(aData)^;
4391 4: idx := PCardinal(aData)^;
4392 8: idx := PQWord(aData)^;
4394 raise EglBitmap.CreateFmt('invalid pixel size: %.3f', [fPixelSize]);
4396 if (idx >= Length(fColorTable)) then
4397 raise EglBitmap.CreateFmt('invalid color index: %d', [idx]);
4398 with fColorTable[idx] do begin
4404 inc(PByte(aMapData), bits);
4405 if ({%H-}PtrUInt(aMapData) >= 8) then begin
4407 dec(PByte(aMapData), 8);
4412 destructor TbmpColorTableFormat.Destroy;
4414 SetLength(fColorTable, 0);
4418 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4419 //TglBitmap - Helper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4420 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4421 procedure glBitmapConvertPixel(var aPixel: TglBitmapPixelData; const aSourceFD, aDestFD: TFormatDescriptor);
4425 for i := 0 to 3 do begin
4426 if (aSourceFD.Range.arr[i] <> aDestFD.Range.arr[i]) then begin
4427 if (aSourceFD.Range.arr[i] > 0) then
4428 aPixel.Data.arr[i] := Round(aPixel.Data.arr[i] / aSourceFD.Range.arr[i] * aDestFD.Range.arr[i])
4430 aPixel.Data.arr[i] := 0;
4435 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4436 procedure glBitmapConvertCopyFunc(var aFuncRec: TglBitmapFunctionRec);
4438 with aFuncRec do begin
4439 if (Source.Range.r > 0) then
4440 Dest.Data.r := Source.Data.r;
4441 if (Source.Range.g > 0) then
4442 Dest.Data.g := Source.Data.g;
4443 if (Source.Range.b > 0) then
4444 Dest.Data.b := Source.Data.b;
4445 if (Source.Range.a > 0) then
4446 Dest.Data.a := Source.Data.a;
4450 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4451 procedure glBitmapConvertCalculateRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
4455 with aFuncRec do begin
4457 if (Source.Range.arr[i] > 0) then
4458 Dest.Data.arr[i] := Round(Dest.Range.arr[i] * Source.Data.arr[i] / Source.Range.arr[i]);
4463 TShiftData = packed record
4465 0: (r, g, b, a: SmallInt);
4466 1: (arr: array[0..3] of SmallInt);
4468 PShiftData = ^TShiftData;
4470 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4471 procedure glBitmapConvertShiftRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
4477 if (Source.Range.arr[i] > 0) then
4478 Dest.Data.arr[i] := Source.Data.arr[i] shr PShiftData(Args)^.arr[i];
4481 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4482 procedure glBitmapInvertFunc(var aFuncRec: TglBitmapFunctionRec);
4484 with aFuncRec do begin
4485 Dest.Data := Source.Data;
4486 if ({%H-}PtrUInt(Args) and $1 > 0) then begin
4487 Dest.Data.r := Dest.Data.r xor Dest.Range.r;
4488 Dest.Data.g := Dest.Data.g xor Dest.Range.g;
4489 Dest.Data.b := Dest.Data.b xor Dest.Range.b;
4491 if ({%H-}PtrUInt(Args) and $2 > 0) then begin
4492 Dest.Data.a := Dest.Data.a xor Dest.Range.a;
4497 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4498 procedure glBitmapFillWithColorFunc(var aFuncRec: TglBitmapFunctionRec);
4502 with aFuncRec do begin
4504 Dest.Data.arr[i] := PglBitmapPixelData(Args)^.Data.arr[i];
4508 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4509 procedure glBitmapAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4513 with FuncRec do begin
4514 if (FuncRec.Args = nil) then begin //source has no alpha
4516 Source.Data.r / Source.Range.r * ALPHA_WEIGHT_R +
4517 Source.Data.g / Source.Range.g * ALPHA_WEIGHT_G +
4518 Source.Data.b / Source.Range.b * ALPHA_WEIGHT_B;
4519 Dest.Data.a := Round(Dest.Range.a * Temp);
4521 Dest.Data.a := Round(Source.Data.a / Source.Range.a * Dest.Range.a);
4525 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4526 procedure glBitmapColorKeyAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4528 PglBitmapPixelData = ^TglBitmapPixelData;
4530 with FuncRec do begin
4531 Dest.Data.r := Source.Data.r;
4532 Dest.Data.g := Source.Data.g;
4533 Dest.Data.b := Source.Data.b;
4535 with PglBitmapPixelData(Args)^ do
4536 if ((Dest.Data.r <= Data.r) and (Dest.Data.r >= Range.r) and
4537 (Dest.Data.g <= Data.g) and (Dest.Data.g >= Range.g) and
4538 (Dest.Data.b <= Data.b) and (Dest.Data.b >= Range.b)) then
4541 Dest.Data.a := Dest.Range.a;
4545 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4546 procedure glBitmapValueAlphaFunc(var FuncRec: TglBitmapFunctionRec);
4548 with FuncRec do begin
4549 Dest.Data.r := Source.Data.r;
4550 Dest.Data.g := Source.Data.g;
4551 Dest.Data.b := Source.Data.b;
4552 Dest.Data.a := PCardinal(Args)^;
4556 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4557 procedure SwapRGB(aData: PByte; aWidth: Integer; const aHasAlpha: Boolean);
4560 TRGBPix = array [0..2] of byte;
4564 while aWidth > 0 do begin
4565 Temp := PRGBPix(aData)^[0];
4566 PRGBPix(aData)^[0] := PRGBPix(aData)^[2];
4567 PRGBPix(aData)^[2] := Temp;
4577 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4578 //TglBitmap - PROTECTED///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4579 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4580 function TglBitmap.GetFormatDesc: TglBitmapFormatDescriptor;
4582 result := TFormatDescriptor.Get(Format);
4585 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4586 function TglBitmap.GetWidth: Integer;
4588 if (ffX in fDimension.Fields) then
4589 result := fDimension.X
4594 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4595 function TglBitmap.GetHeight: Integer;
4597 if (ffY in fDimension.Fields) then
4598 result := fDimension.Y
4603 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4604 function TglBitmap.GetFileWidth: Integer;
4606 result := Max(1, Width);
4609 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4610 function TglBitmap.GetFileHeight: Integer;
4612 result := Max(1, Height);
4615 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4616 procedure TglBitmap.SetCustomData(const aValue: Pointer);
4618 if fCustomData = aValue then
4620 fCustomData := aValue;
4623 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4624 procedure TglBitmap.SetCustomName(const aValue: String);
4626 if fCustomName = aValue then
4628 fCustomName := aValue;
4631 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4632 procedure TglBitmap.SetCustomNameW(const aValue: WideString);
4634 if fCustomNameW = aValue then
4636 fCustomNameW := aValue;
4639 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4640 procedure TglBitmap.SetFreeDataOnDestroy(const aValue: Boolean);
4642 if fFreeDataOnDestroy = aValue then
4644 fFreeDataOnDestroy := aValue;
4647 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4648 procedure TglBitmap.SetDeleteTextureOnFree(const aValue: Boolean);
4650 if fDeleteTextureOnFree = aValue then
4652 fDeleteTextureOnFree := aValue;
4655 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4656 procedure TglBitmap.SetFormat(const aValue: TglBitmapFormat);
4658 if fFormat = aValue then
4660 if TFormatDescriptor.Get(Format).PixelSize <> TFormatDescriptor.Get(aValue).PixelSize then
4661 raise EglBitmapUnsupportedFormat.Create(Format);
4662 SetDataPointer(fData, aValue, Width, Height); //be careful, Data could be freed by this method
4665 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4666 procedure TglBitmap.SetFreeDataAfterGenTexture(const aValue: Boolean);
4668 if fFreeDataAfterGenTexture = aValue then
4670 fFreeDataAfterGenTexture := aValue;
4673 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4674 procedure TglBitmap.SetID(const aValue: Cardinal);
4676 if fID = aValue then
4681 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4682 procedure TglBitmap.SetMipMap(const aValue: TglBitmapMipMap);
4684 if fMipMap = aValue then
4689 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4690 procedure TglBitmap.SetTarget(const aValue: Cardinal);
4692 if fTarget = aValue then
4697 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4698 procedure TglBitmap.SetAnisotropic(const aValue: Integer);
4700 MaxAnisotropic: Integer;
4702 fAnisotropic := aValue;
4703 if (ID > 0) then begin
4704 if GL_EXT_texture_filter_anisotropic then begin
4705 if fAnisotropic > 0 then begin
4707 glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @MaxAnisotropic);
4708 if aValue > MaxAnisotropic then
4709 fAnisotropic := MaxAnisotropic;
4710 glTexParameteri(Target, GL_TEXTURE_MAX_ANISOTROPY_EXT, fAnisotropic);
4718 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4719 procedure TglBitmap.CreateID;
4722 glDeleteTextures(1, @fID);
4723 glGenTextures(1, @fID);
4727 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4728 procedure TglBitmap.SetupParameters(out aBuildWithGlu: Boolean);
4730 // Set Up Parameters
4731 SetWrap(fWrapS, fWrapT, fWrapR);
4732 SetFilter(fFilterMin, fFilterMag);
4733 SetAnisotropic(fAnisotropic);
4734 SetBorderColor(fBorderColor[0], fBorderColor[1], fBorderColor[2], fBorderColor[3]);
4736 if (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
4737 SetSwizzle(fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
4739 // Mip Maps Generation Mode
4740 aBuildWithGlu := false;
4741 if (MipMap = mmMipmap) then begin
4742 if (GL_VERSION_1_4 or GL_SGIS_generate_mipmap) then
4743 glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE)
4745 aBuildWithGlu := true;
4746 end else if (MipMap = mmMipmapGlu) then
4747 aBuildWithGlu := true;
4750 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4751 procedure TglBitmap.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
4752 const aWidth: Integer; const aHeight: Integer);
4756 if (Data <> aData) then begin
4757 if (Assigned(Data)) then
4762 if not Assigned(fData) then begin
4766 FillChar(fDimension, SizeOf(fDimension), 0);
4767 if aWidth <> -1 then begin
4768 fDimension.Fields := fDimension.Fields + [ffX];
4769 fDimension.X := aWidth;
4772 if aHeight <> -1 then begin
4773 fDimension.Fields := fDimension.Fields + [ffY];
4774 fDimension.Y := aHeight;
4777 s := TFormatDescriptor.Get(aFormat).PixelSize;
4779 fPixelSize := Ceil(s);
4780 fRowSize := Ceil(s * aWidth);
4784 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4785 function TglBitmap.FlipHorz: Boolean;
4790 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4791 function TglBitmap.FlipVert: Boolean;
4796 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4797 //TglBitmap - PUBLIC//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4798 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4799 procedure TglBitmap.AfterConstruction;
4801 inherited AfterConstruction;
4805 fIsResident := false;
4807 fMipMap := glBitmapDefaultMipmap;
4808 fFreeDataAfterGenTexture := glBitmapGetDefaultFreeDataAfterGenTexture;
4809 fDeleteTextureOnFree := glBitmapGetDefaultDeleteTextureOnFree;
4811 glBitmapGetDefaultFilter (fFilterMin, fFilterMag);
4812 glBitmapGetDefaultTextureWrap(fWrapS, fWrapT, fWrapR);
4813 glBitmapGetDefaultSwizzle (fSwizzle[0], fSwizzle[1], fSwizzle[2], fSwizzle[3]);
4816 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4817 procedure TglBitmap.BeforeDestruction;
4821 if fFreeDataOnDestroy then begin
4823 SetDataPointer(NewData, tfEmpty); //be careful, Data could be freed by this method
4825 if (fID > 0) and fDeleteTextureOnFree then
4826 glDeleteTextures(1, @fID);
4827 inherited BeforeDestruction;
4830 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4831 procedure TglBitmap.PrepareResType(var aResource: String; var aResType: PChar);
4835 if not Assigned(aResType) then begin
4836 TempPos := Pos('.', aResource);
4837 aResType := PChar(UpperCase(Copy(aResource, TempPos + 1, Length(aResource) - TempPos)));
4838 aResource := UpperCase(Copy(aResource, 0, TempPos -1));
4842 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4843 procedure TglBitmap.LoadFromFile(const aFilename: String);
4847 if not FileExists(aFilename) then
4848 raise EglBitmap.Create('file does not exist: ' + aFilename);
4849 fFilename := aFilename;
4850 fs := TFileStream.Create(fFilename, fmOpenRead);
4859 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4860 procedure TglBitmap.LoadFromStream(const aStream: TStream);
4862 {$IFDEF GLB_SUPPORT_PNG_READ}
4863 if not LoadPNG(aStream) then
4865 {$IFDEF GLB_SUPPORT_JPEG_READ}
4866 if not LoadJPEG(aStream) then
4868 if not LoadDDS(aStream) then
4869 if not LoadTGA(aStream) then
4870 if not LoadBMP(aStream) then
4871 raise EglBitmap.Create('LoadFromStream - Couldn''t load Stream. It''s possible to be an unknow Streamtype.');
4874 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4875 procedure TglBitmap.LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
4876 const aFormat: TglBitmapFormat; const aArgs: Pointer);
4881 size := TFormatDescriptor.Get(aFormat).GetSize(aSize);
4882 GetMem(tmpData, size);
4884 FillChar(tmpData^, size, #$FF);
4885 SetDataPointer(tmpData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
4887 if Assigned(tmpData) then
4891 AddFunc(Self, aFunc, false, aFormat, aArgs);
4894 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4895 procedure TglBitmap.LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar);
4897 rs: TResourceStream;
4899 PrepareResType(aResource, aResType);
4900 rs := TResourceStream.Create(aInstance, aResource, aResType);
4908 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4909 procedure TglBitmap.LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
4911 rs: TResourceStream;
4913 rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
4921 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4922 procedure TglBitmap.SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
4926 fs := TFileStream.Create(aFileName, fmCreate);
4929 SaveToStream(fs, aFileType);
4935 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4936 procedure TglBitmap.SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType);
4939 {$IFDEF GLB_SUPPORT_PNG_WRITE}
4940 ftPNG: SavePNG(aStream);
4942 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
4943 ftJPEG: SaveJPEG(aStream);
4945 ftDDS: SaveDDS(aStream);
4946 ftTGA: SaveTGA(aStream);
4947 ftBMP: SaveBMP(aStream);
4951 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4952 function TglBitmap.AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer): Boolean;
4954 result := AddFunc(Self, aFunc, aCreateTemp, Format, aArgs);
4957 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4958 function TglBitmap.AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
4959 const aFormat: TglBitmapFormat; const aArgs: Pointer): Boolean;
4961 DestData, TmpData, SourceData: pByte;
4962 TempHeight, TempWidth: Integer;
4963 SourceFD, DestFD: TFormatDescriptor;
4964 SourceMD, DestMD: Pointer;
4966 FuncRec: TglBitmapFunctionRec;
4968 Assert(Assigned(Data));
4969 Assert(Assigned(aSource));
4970 Assert(Assigned(aSource.Data));
4973 if Assigned(aSource.Data) and ((aSource.Height > 0) or (aSource.Width > 0)) then begin
4974 SourceFD := TFormatDescriptor.Get(aSource.Format);
4975 DestFD := TFormatDescriptor.Get(aFormat);
4977 if (SourceFD.IsCompressed) then
4978 raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', SourceFD.Format);
4979 if (DestFD.IsCompressed) then
4980 raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', DestFD.Format);
4982 // inkompatible Formats so CreateTemp
4983 if (SourceFD.PixelSize <> DestFD.PixelSize) then
4984 aCreateTemp := true;
4987 TempHeight := Max(1, aSource.Height);
4988 TempWidth := Max(1, aSource.Width);
4990 FuncRec.Sender := Self;
4991 FuncRec.Args := aArgs;
4994 if aCreateTemp then begin
4995 GetMem(TmpData, DestFD.GetSize(TempWidth, TempHeight));
4996 DestData := TmpData;
5001 SourceFD.PreparePixel(FuncRec.Source);
5002 DestFD.PreparePixel (FuncRec.Dest);
5004 SourceMD := SourceFD.CreateMappingData;
5005 DestMD := DestFD.CreateMappingData;
5007 FuncRec.Size := aSource.Dimension;
5008 FuncRec.Position.Fields := FuncRec.Size.Fields;
5011 SourceData := aSource.Data;
5012 FuncRec.Position.Y := 0;
5013 while FuncRec.Position.Y < TempHeight do begin
5014 FuncRec.Position.X := 0;
5015 while FuncRec.Position.X < TempWidth do begin
5016 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
5018 DestFD.Map(FuncRec.Dest, DestData, DestMD);
5019 inc(FuncRec.Position.X);
5021 inc(FuncRec.Position.Y);
5024 // Updating Image or InternalFormat
5026 SetDataPointer(TmpData, aFormat, aSource.Width, aSource.Height) //be careful, Data could be freed by this method
5027 else if (aFormat <> fFormat) then
5032 SourceFD.FreeMappingData(SourceMD);
5033 DestFD.FreeMappingData(DestMD);
5036 if aCreateTemp and Assigned(TmpData) then
5044 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5045 function TglBitmap.AssignToSurface(out aSurface: PSDL_Surface): Boolean;
5047 Row, RowSize: Integer;
5048 SourceData, TmpData: PByte;
5050 FormatDesc: TFormatDescriptor;
5052 function GetRowPointer(Row: Integer): pByte;
5054 result := aSurface.pixels;
5055 Inc(result, Row * RowSize);
5061 FormatDesc := TFormatDescriptor.Get(Format);
5062 if FormatDesc.IsCompressed then
5063 raise EglBitmapUnsupportedFormat.Create(Format);
5065 if Assigned(Data) then begin
5066 case Trunc(FormatDesc.PixelSize) of
5072 raise EglBitmapUnsupportedFormat.Create(Format);
5075 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, TempDepth,
5076 FormatDesc.RedMask, FormatDesc.GreenMask, FormatDesc.BlueMask, FormatDesc.AlphaMask);
5078 RowSize := FormatDesc.GetSize(FileWidth, 1);
5080 for Row := 0 to FileHeight-1 do begin
5081 TmpData := GetRowPointer(Row);
5082 if Assigned(TmpData) then begin
5083 Move(SourceData^, TmpData^, RowSize);
5084 inc(SourceData, RowSize);
5091 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5092 function TglBitmap.AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
5094 pSource, pData, pTempData: PByte;
5095 Row, RowSize, TempWidth, TempHeight: Integer;
5096 IntFormat: TglBitmapFormat;
5097 FormatDesc: TFormatDescriptor;
5099 function GetRowPointer(Row: Integer): pByte;
5101 result := aSurface^.pixels;
5102 Inc(result, Row * RowSize);
5107 if (Assigned(aSurface)) then begin
5108 with aSurface^.format^ do begin
5109 for IntFormat := High(TglBitmapFormat) to Low(TglBitmapFormat) do begin
5110 FormatDesc := TFormatDescriptor.Get(IntFormat);
5111 if (FormatDesc.MaskMatch(RMask, GMask, BMask, AMask)) then
5114 if (IntFormat = tfEmpty) then
5115 raise EglBitmapException.Create('AssignFromSurface - Invalid Pixelformat.');
5118 TempWidth := aSurface^.w;
5119 TempHeight := aSurface^.h;
5120 RowSize := FormatDesc.GetSize(TempWidth, 1);
5121 GetMem(pData, TempHeight * RowSize);
5124 for Row := 0 to TempHeight -1 do begin
5125 pSource := GetRowPointer(Row);
5126 if (Assigned(pSource)) then begin
5127 Move(pSource^, pTempData^, RowSize);
5128 Inc(pTempData, RowSize);
5131 SetDataPointer(pData, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
5134 if Assigned(pData) then
5141 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5142 function TglBitmap.AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
5144 Row, Col, AlphaInterleave: Integer;
5145 pSource, pDest: PByte;
5147 function GetRowPointer(Row: Integer): pByte;
5149 result := aSurface.pixels;
5150 Inc(result, Row * Width);
5155 if Assigned(Data) then begin
5156 if Format in [tfAlpha8, tfLuminance8Alpha8, tfBGRA8, tfRGBA8] then begin
5157 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, 8, $FF, $FF, $FF, 0);
5159 AlphaInterleave := 0;
5162 AlphaInterleave := 1;
5164 AlphaInterleave := 3;
5168 for Row := 0 to Height -1 do begin
5169 pDest := GetRowPointer(Row);
5170 if Assigned(pDest) then begin
5171 for Col := 0 to Width -1 do begin
5172 Inc(pSource, AlphaInterleave);
5184 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5185 function TglBitmap.AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
5189 bmp := TglBitmap2D.Create;
5191 bmp.AssignFromSurface(aSurface);
5192 result := AddAlphaFromGlBitmap(bmp, aFunc, aArgs);
5200 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5201 function CreateGrayPalette: HPALETTE;
5206 GetMem(Pal, SizeOf(TLogPalette) + (SizeOf(TPaletteEntry) * 256));
5208 Pal.palVersion := $300;
5209 Pal.palNumEntries := 256;
5211 for Idx := 0 to Pal.palNumEntries - 1 do begin
5212 Pal.palPalEntry[Idx].peRed := Idx;
5213 Pal.palPalEntry[Idx].peGreen := Idx;
5214 Pal.palPalEntry[Idx].peBlue := Idx;
5215 Pal.palPalEntry[Idx].peFlags := 0;
5217 Result := CreatePalette(Pal^);
5221 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5222 function TglBitmap.AssignToBitmap(const aBitmap: TBitmap): Boolean;
5225 pSource, pData: PByte;
5228 if Assigned(Data) then begin
5229 if Assigned(aBitmap) then begin
5230 aBitmap.Width := Width;
5231 aBitmap.Height := Height;
5234 tfAlpha8, tfLuminance8: begin
5235 aBitmap.PixelFormat := pf8bit;
5236 aBitmap.Palette := CreateGrayPalette;
5239 aBitmap.PixelFormat := pf15bit;
5241 aBitmap.PixelFormat := pf16bit;
5243 aBitmap.PixelFormat := pf24bit;
5245 aBitmap.PixelFormat := pf32bit;
5247 raise EglBitmap.Create('AssignToBitmap - Invalid Pixelformat.');
5251 for Row := 0 to FileHeight -1 do begin
5252 pData := aBitmap.Scanline[Row];
5253 Move(pSource^, pData^, fRowSize);
5254 Inc(pSource, fRowSize);
5255 if (Format in [tfRGB8, tfRGBA8]) then // swap RGB(A) to BGR(A)
5256 SwapRGB(pData, FileWidth, Format = tfRGBA8);
5263 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5264 function TglBitmap.AssignFromBitmap(const aBitmap: TBitmap): Boolean;
5266 pSource, pData, pTempData: PByte;
5267 Row, RowSize, TempWidth, TempHeight: Integer;
5268 IntFormat: TglBitmapFormat;
5272 if (Assigned(aBitmap)) then begin
5273 case aBitmap.PixelFormat of
5275 IntFormat := tfLuminance8;
5277 IntFormat := tfRGB5A1;
5279 IntFormat := tfR5G6B5;
5281 IntFormat := tfBGR8;
5283 IntFormat := tfBGRA8;
5285 raise EglBitmap.Create('AssignFromBitmap - Invalid Pixelformat.');
5288 TempWidth := aBitmap.Width;
5289 TempHeight := aBitmap.Height;
5290 RowSize := TFormatDescriptor.Get(IntFormat).GetSize(TempWidth, 1);
5291 GetMem(pData, TempHeight * RowSize);
5294 for Row := 0 to TempHeight -1 do begin
5295 pSource := aBitmap.Scanline[Row];
5296 if (Assigned(pSource)) then begin
5297 Move(pSource^, pTempData^, RowSize);
5298 Inc(pTempData, RowSize);
5301 SetDataPointer(pData, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
5304 if Assigned(pData) then
5311 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5312 function TglBitmap.AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
5314 Row, Col, AlphaInterleave: Integer;
5315 pSource, pDest: PByte;
5319 if Assigned(Data) then begin
5320 if (Format in [tfAlpha8, tfLuminance8Alpha8, tfRGBA8, tfBGRA8]) then begin
5321 if Assigned(aBitmap) then begin
5322 aBitmap.PixelFormat := pf8bit;
5323 aBitmap.Palette := CreateGrayPalette;
5324 aBitmap.Width := Width;
5325 aBitmap.Height := Height;
5329 AlphaInterleave := 1;
5331 AlphaInterleave := 3;
5333 AlphaInterleave := 0;
5339 for Row := 0 to Height -1 do begin
5340 pDest := aBitmap.Scanline[Row];
5341 if Assigned(pDest) then begin
5342 for Col := 0 to Width -1 do begin
5343 Inc(pSource, AlphaInterleave);
5356 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5357 function TglBitmap.AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5361 tex := TglBitmap2D.Create;
5363 tex.AssignFromBitmap(ABitmap);
5364 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
5371 {$IFDEF GLB_LAZARUS}
5372 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5373 function TglBitmap.AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
5375 rid: TRawImageDescription;
5376 FormatDesc: TFormatDescriptor;
5379 if not Assigned(aImage) or (Format = tfEmpty) then
5381 FormatDesc := TFormatDescriptor.Get(Format);
5382 if FormatDesc.IsCompressed then
5385 FillChar(rid{%H-}, SizeOf(rid), 0);
5387 tfAlpha4, tfAlpha8, tfAlpha16,
5388 tfLuminance4, tfLuminance8, tfLuminance16,
5389 tfLuminance4Alpha4, tfLuminance8Alpha8, tfLuminance12Alpha4, tfLuminance16Alpha16]) then
5390 rid.Format := ricfGray
5392 rid.Format := ricfRGBA;
5395 rid.Height := Height;
5396 rid.Depth := CountSetBits(FormatDesc.RedMask or FormatDesc.GreenMask or FormatDesc.BlueMask or FormatDesc.AlphaMask);
5397 rid.BitOrder := riboBitsInOrder;
5398 rid.ByteOrder := riboLSBFirst;
5399 rid.LineOrder := riloTopToBottom;
5400 rid.LineEnd := rileTight;
5401 rid.BitsPerPixel := Round(8 * FormatDesc.PixelSize);
5402 rid.RedPrec := CountSetBits(FormatDesc.Range.r);
5403 rid.GreenPrec := CountSetBits(FormatDesc.Range.g);
5404 rid.BluePrec := CountSetBits(FormatDesc.Range.b);
5405 rid.AlphaPrec := CountSetBits(FormatDesc.Range.a);
5406 rid.RedShift := FormatDesc.Shift.r;
5407 rid.GreenShift := FormatDesc.Shift.g;
5408 rid.BlueShift := FormatDesc.Shift.b;
5409 rid.AlphaShift := FormatDesc.Shift.a;
5411 rid.MaskBitsPerPixel := 0;
5412 rid.PaletteColorCount := 0;
5414 aImage.DataDescription := rid;
5417 Move(Data^, aImage.PixelData^, FormatDesc.GetSize(Dimension));
5422 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5423 function TglBitmap.AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
5426 FormatDesc: TFormatDescriptor;
5431 procedure CopyConvert;
5433 bfFormat: TbmpBitfieldFormat;
5434 pSourceLine, pDestLine: PByte;
5435 pSourceMD, pDestMD: Pointer;
5437 pixel: TglBitmapPixelData;
5439 bfFormat := TbmpBitfieldFormat.Create;
5440 with aImage.DataDescription do begin
5441 bfFormat.RedMask := ((1 shl RedPrec) - 1) shl RedShift;
5442 bfFormat.GreenMask := ((1 shl GreenPrec) - 1) shl GreenShift;
5443 bfFormat.BlueMask := ((1 shl BluePrec) - 1) shl BlueShift;
5444 bfFormat.AlphaMask := ((1 shl AlphaPrec) - 1) shl AlphaShift;
5445 bfFormat.PixelSize := BitsPerPixel / 8;
5447 pSourceMD := bfFormat.CreateMappingData;
5448 pDestMD := FormatDesc.CreateMappingData;
5450 for y := 0 to aImage.Height-1 do begin
5451 pSourceLine := aImage.PixelData + y {%H-}* aImage.DataDescription.BytesPerLine;
5452 pDestLine := ImageData + y * Round(FormatDesc.PixelSize * aImage.Width);
5453 for x := 0 to aImage.Width-1 do begin
5454 bfFormat.Unmap(pSourceLine, pixel, pSourceMD);
5455 FormatDesc.Map(pixel, pDestLine, pDestMD);
5459 FormatDesc.FreeMappingData(pDestMD);
5460 bfFormat.FreeMappingData(pSourceMD);
5467 if not Assigned(aImage) then
5469 for f := High(f) downto Low(f) do begin
5470 FormatDesc := TFormatDescriptor.Get(f);
5471 with aImage.DataDescription do
5472 if FormatDesc.MaskMatch(
5473 (QWord(1 shl RedPrec )-1) shl RedShift,
5474 (QWord(1 shl GreenPrec)-1) shl GreenShift,
5475 (QWord(1 shl BluePrec )-1) shl BlueShift,
5476 (QWord(1 shl AlphaPrec)-1) shl AlphaShift) then
5480 if (f = tfEmpty) then
5484 (Round(FormatDesc.PixelSize * 8) = aImage.DataDescription.Depth) and
5485 (aImage.DataDescription.BitsPerPixel = aImage.DataDescription.Depth);
5487 ImageSize := FormatDesc.GetSize(aImage.Width, aImage.Height);
5488 ImageData := GetMem(ImageSize);
5491 Move(aImage.PixelData^, ImageData^, ImageSize)
5494 SetDataPointer(ImageData, f, aImage.Width, aImage.Height); //be careful, Data could be freed by this method
5496 if Assigned(ImageData) then
5504 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5505 function TglBitmap.AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
5507 rid: TRawImageDescription;
5508 FormatDesc: TFormatDescriptor;
5509 Pixel: TglBitmapPixelData;
5515 if not Assigned(aImage) or (Format = tfEmpty) then
5517 FormatDesc := TFormatDescriptor.Get(Format);
5518 if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
5521 FillChar(rid{%H-}, SizeOf(rid), 0);
5522 rid.Format := ricfGray;
5524 rid.Height := Height;
5525 rid.Depth := CountSetBits(FormatDesc.Range.a);
5526 rid.BitOrder := riboBitsInOrder;
5527 rid.ByteOrder := riboLSBFirst;
5528 rid.LineOrder := riloTopToBottom;
5529 rid.LineEnd := rileTight;
5530 rid.BitsPerPixel := 8 * Ceil(rid.Depth / 8);
5531 rid.RedPrec := CountSetBits(FormatDesc.Range.a);
5536 rid.GreenShift := 0;
5538 rid.AlphaShift := 0;
5540 rid.MaskBitsPerPixel := 0;
5541 rid.PaletteColorCount := 0;
5543 aImage.DataDescription := rid;
5546 srcMD := FormatDesc.CreateMappingData;
5548 FormatDesc.PreparePixel(Pixel);
5550 dst := aImage.PixelData;
5551 for y := 0 to Height-1 do
5552 for x := 0 to Width-1 do begin
5553 FormatDesc.Unmap(src, Pixel, srcMD);
5554 case rid.BitsPerPixel of
5556 dst^ := Pixel.Data.a;
5560 PWord(dst)^ := Pixel.Data.a;
5564 PByteArray(dst)^[0] := PByteArray(@Pixel.Data.a)^[0];
5565 PByteArray(dst)^[1] := PByteArray(@Pixel.Data.a)^[1];
5566 PByteArray(dst)^[2] := PByteArray(@Pixel.Data.a)^[2];
5570 PCardinal(dst)^ := Pixel.Data.a;
5574 raise EglBitmapUnsupportedFormat.Create(Format);
5578 FormatDesc.FreeMappingData(srcMD);
5583 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5584 function TglBitmap.AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5588 tex := TglBitmap2D.Create;
5590 tex.AssignFromLazIntfImage(aImage);
5591 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
5598 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5599 function TglBitmap.AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar;
5600 const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5602 rs: TResourceStream;
5604 PrepareResType(aResource, aResType);
5605 rs := TResourceStream.Create(aInstance, aResource, aResType);
5607 result := AddAlphaFromStream(rs, aFunc, aArgs);
5613 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5614 function TglBitmap.AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
5615 const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5617 rs: TResourceStream;
5619 rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
5621 result := AddAlphaFromStream(rs, aFunc, aArgs);
5627 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5628 function TglBitmap.AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5630 if TFormatDescriptor.Get(Format).IsCompressed then
5631 raise EglBitmapUnsupportedFormat.Create(Format);
5632 result := AddFunc(Self, aFunc, false, TFormatDescriptor.Get(Format).WithAlpha, aArgs);
5635 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5636 function TglBitmap.AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5640 FS := TFileStream.Create(aFileName, fmOpenRead);
5642 result := AddAlphaFromStream(FS, aFunc, aArgs);
5648 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5649 function TglBitmap.AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5653 tex := TglBitmap2D.Create(aStream);
5655 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
5661 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5662 function TglBitmap.AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5664 DestData, DestData2, SourceData: pByte;
5665 TempHeight, TempWidth: Integer;
5666 SourceFD, DestFD: TFormatDescriptor;
5667 SourceMD, DestMD, DestMD2: Pointer;
5669 FuncRec: TglBitmapFunctionRec;
5673 Assert(Assigned(Data));
5674 Assert(Assigned(aBitmap));
5675 Assert(Assigned(aBitmap.Data));
5677 if ((aBitmap.Width = Width) and (aBitmap.Height = Height)) then begin
5678 result := ConvertTo(TFormatDescriptor.Get(Format).WithAlpha);
5680 SourceFD := TFormatDescriptor.Get(aBitmap.Format);
5681 DestFD := TFormatDescriptor.Get(Format);
5683 if not Assigned(aFunc) then begin
5684 aFunc := glBitmapAlphaFunc;
5685 FuncRec.Args := {%H-}Pointer(SourceFD.HasAlpha);
5687 FuncRec.Args := aArgs;
5690 TempHeight := aBitmap.FileHeight;
5691 TempWidth := aBitmap.FileWidth;
5693 FuncRec.Sender := Self;
5694 FuncRec.Size := Dimension;
5695 FuncRec.Position.Fields := FuncRec.Size.Fields;
5699 SourceData := aBitmap.Data;
5702 SourceFD.PreparePixel(FuncRec.Source);
5703 DestFD.PreparePixel (FuncRec.Dest);
5705 SourceMD := SourceFD.CreateMappingData;
5706 DestMD := DestFD.CreateMappingData;
5707 DestMD2 := DestFD.CreateMappingData;
5709 FuncRec.Position.Y := 0;
5710 while FuncRec.Position.Y < TempHeight do begin
5711 FuncRec.Position.X := 0;
5712 while FuncRec.Position.X < TempWidth do begin
5713 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
5714 DestFD.Unmap (DestData, FuncRec.Dest, DestMD);
5716 DestFD.Map(FuncRec.Dest, DestData2, DestMD2);
5717 inc(FuncRec.Position.X);
5719 inc(FuncRec.Position.Y);
5722 SourceFD.FreeMappingData(SourceMD);
5723 DestFD.FreeMappingData(DestMD);
5724 DestFD.FreeMappingData(DestMD2);
5729 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5730 function TglBitmap.AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte): Boolean;
5732 result := AddAlphaFromColorKeyFloat(aRed / $FF, aGreen / $FF, aBlue / $FF, aDeviation / $FF);
5735 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5736 function TglBitmap.AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal): Boolean;
5738 PixelData: TglBitmapPixelData;
5740 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5741 result := AddAlphaFromColorKeyFloat(
5742 aRed / PixelData.Range.r,
5743 aGreen / PixelData.Range.g,
5744 aBlue / PixelData.Range.b,
5745 aDeviation / Max(PixelData.Range.r, Max(PixelData.Range.g, PixelData.Range.b)));
5748 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5749 function TglBitmap.AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single): Boolean;
5751 values: array[0..2] of Single;
5754 PixelData: TglBitmapPixelData;
5756 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5757 with PixelData do begin
5759 values[1] := aGreen;
5762 for i := 0 to 2 do begin
5763 tmp := Trunc(Range.arr[i] * aDeviation);
5764 Data.arr[i] := Min(Range.arr[i], Trunc(Range.arr[i] * values[i] + tmp));
5765 Range.arr[i] := Max(0, Trunc(Range.arr[i] * values[i] - tmp));
5770 result := AddAlphaFromFunc(glBitmapColorKeyAlphaFunc, @PixelData);
5773 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5774 function TglBitmap.AddAlphaFromValue(const aAlpha: Byte): Boolean;
5776 result := AddAlphaFromValueFloat(aAlpha / $FF);
5779 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5780 function TglBitmap.AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
5782 PixelData: TglBitmapPixelData;
5784 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5785 result := AddAlphaFromValueFloat(aAlpha / PixelData.Range.a);
5788 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5789 function TglBitmap.AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
5791 PixelData: TglBitmapPixelData;
5793 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5795 Data.a := Min(Range.a, Max(0, Round(Range.a * aAlpha)));
5796 result := AddAlphaFromFunc(glBitmapValueAlphaFunc, @PixelData.Data.a);
5799 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5800 function TglBitmap.RemoveAlpha: Boolean;
5802 FormatDesc: TFormatDescriptor;
5805 FormatDesc := TFormatDescriptor.Get(Format);
5806 if Assigned(Data) then begin
5807 if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
5808 raise EglBitmapUnsupportedFormat.Create(Format);
5809 result := ConvertTo(FormatDesc.WithoutAlpha);
5813 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5814 function TglBitmap.Clone: TglBitmap;
5821 Temp := (ClassType.Create as TglBitmap);
5823 // copy texture data if assigned
5824 if Assigned(Data) then begin
5825 Size := TFormatDescriptor.Get(Format).GetSize(fDimension);
5826 GetMem(TempPtr, Size);
5828 Move(Data^, TempPtr^, Size);
5829 Temp.SetDataPointer(TempPtr, Format, Width, Height); //be careful, Data could be freed by this method
5831 if Assigned(TempPtr) then
5837 Temp.SetDataPointer(TempPtr, Format, Width, Height); //be careful, Data could be freed by this method
5842 Temp.fTarget := Target;
5843 Temp.fFormat := Format;
5844 Temp.fMipMap := MipMap;
5845 Temp.fAnisotropic := Anisotropic;
5846 Temp.fBorderColor := fBorderColor;
5847 Temp.fDeleteTextureOnFree := DeleteTextureOnFree;
5848 Temp.fFreeDataAfterGenTexture := FreeDataAfterGenTexture;
5849 Temp.fFilterMin := fFilterMin;
5850 Temp.fFilterMag := fFilterMag;
5851 Temp.fWrapS := fWrapS;
5852 Temp.fWrapT := fWrapT;
5853 Temp.fWrapR := fWrapR;
5854 Temp.fFilename := fFilename;
5855 Temp.fCustomName := fCustomName;
5856 Temp.fCustomNameW := fCustomNameW;
5857 Temp.fCustomData := fCustomData;
5866 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5867 function TglBitmap.ConvertTo(const aFormat: TglBitmapFormat): Boolean;
5869 SourceFD, DestFD: TFormatDescriptor;
5870 SourcePD, DestPD: TglBitmapPixelData;
5871 ShiftData: TShiftData;
5873 function DataIsIdentical: Boolean;
5876 (SourceFD.RedMask = DestFD.RedMask) and
5877 (SourceFD.GreenMask = DestFD.GreenMask) and
5878 (SourceFD.BlueMask = DestFD.BlueMask) and
5879 (SourceFD.AlphaMask = DestFD.AlphaMask);
5882 function CanCopyDirect: Boolean;
5885 ((SourcePD.Range.r = DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
5886 ((SourcePD.Range.g = DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
5887 ((SourcePD.Range.b = DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
5888 ((SourcePD.Range.a = DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
5891 function CanShift: Boolean;
5894 ((SourcePD.Range.r >= DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
5895 ((SourcePD.Range.g >= DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
5896 ((SourcePD.Range.b >= DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
5897 ((SourcePD.Range.a >= DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
5900 function GetShift(aSource, aDest: Cardinal) : ShortInt;
5903 while (aSource > aDest) and (aSource > 0) do begin
5905 aSource := aSource shr 1;
5910 if (aFormat <> fFormat) and (aFormat <> tfEmpty) then begin
5911 SourceFD := TFormatDescriptor.Get(Format);
5912 DestFD := TFormatDescriptor.Get(aFormat);
5914 if DataIsIdentical then begin
5920 SourceFD.PreparePixel(SourcePD);
5921 DestFD.PreparePixel (DestPD);
5923 if CanCopyDirect then
5924 result := AddFunc(Self, glBitmapConvertCopyFunc, false, aFormat)
5925 else if CanShift then begin
5926 ShiftData.r := GetShift(SourcePD.Range.r, DestPD.Range.r);
5927 ShiftData.g := GetShift(SourcePD.Range.g, DestPD.Range.g);
5928 ShiftData.b := GetShift(SourcePD.Range.b, DestPD.Range.b);
5929 ShiftData.a := GetShift(SourcePD.Range.a, DestPD.Range.a);
5930 result := AddFunc(Self, glBitmapConvertShiftRGBAFunc, false, aFormat, @ShiftData);
5932 result := AddFunc(Self, glBitmapConvertCalculateRGBAFunc, false, aFormat);
5937 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5938 procedure TglBitmap.Invert(const aUseRGB: Boolean; const aUseAlpha: Boolean);
5940 if aUseRGB or aUseAlpha then
5941 AddFunc(glBitmapInvertFunc, false, {%H-}Pointer(
5942 ((Byte(aUseAlpha) and 1) shl 1) or
5943 (Byte(aUseRGB) and 1) ));
5946 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5947 procedure TglBitmap.SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
5949 fBorderColor[0] := aRed;
5950 fBorderColor[1] := aGreen;
5951 fBorderColor[2] := aBlue;
5952 fBorderColor[3] := aAlpha;
5953 if (ID > 0) then begin
5955 glTexParameterfv(Target, GL_TEXTURE_BORDER_COLOR, @fBorderColor[0]);
5959 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5960 procedure TglBitmap.FreeData;
5965 SetDataPointer(TempPtr, tfEmpty); //be careful, Data could be freed by this method
5968 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5969 procedure TglBitmap.FillWithColor(const aRed, aGreen, aBlue: Byte;
5970 const aAlpha: Byte);
5972 FillWithColorFloat(aRed/$FF, aGreen/$FF, aBlue/$FF, aAlpha/$FF);
5975 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5976 procedure TglBitmap.FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal);
5978 PixelData: TglBitmapPixelData;
5980 TFormatDescriptor.GetAlpha(Format).PreparePixel(PixelData);
5982 aRed / PixelData.Range.r,
5983 aGreen / PixelData.Range.g,
5984 aBlue / PixelData.Range.b,
5985 aAlpha / PixelData.Range.a);
5988 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5989 procedure TglBitmap.FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single);
5991 PixelData: TglBitmapPixelData;
5993 TFormatDescriptor.Get(Format).PreparePixel(PixelData);
5994 with PixelData do begin
5995 Data.r := Max(0, Min(Range.r, Trunc(Range.r * aRed)));
5996 Data.g := Max(0, Min(Range.g, Trunc(Range.g * aGreen)));
5997 Data.b := Max(0, Min(Range.b, Trunc(Range.b * aBlue)));
5998 Data.a := Max(0, Min(Range.a, Trunc(Range.a * aAlpha)));
6000 AddFunc(glBitmapFillWithColorFunc, false, @PixelData);
6003 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6004 procedure TglBitmap.SetFilter(const aMin, aMag: GLenum);
6009 fFilterMin := GL_NEAREST;
6011 fFilterMin := GL_LINEAR;
6012 GL_NEAREST_MIPMAP_NEAREST:
6013 fFilterMin := GL_NEAREST_MIPMAP_NEAREST;
6014 GL_LINEAR_MIPMAP_NEAREST:
6015 fFilterMin := GL_LINEAR_MIPMAP_NEAREST;
6016 GL_NEAREST_MIPMAP_LINEAR:
6017 fFilterMin := GL_NEAREST_MIPMAP_LINEAR;
6018 GL_LINEAR_MIPMAP_LINEAR:
6019 fFilterMin := GL_LINEAR_MIPMAP_LINEAR;
6021 raise EglBitmap.Create('SetFilter - Unknow MIN filter.');
6027 fFilterMag := GL_NEAREST;
6029 fFilterMag := GL_LINEAR;
6031 raise EglBitmap.Create('SetFilter - Unknow MAG filter.');
6035 if (ID > 0) then begin
6037 glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, fFilterMag);
6039 if (MipMap = mmNone) or (Target = GL_TEXTURE_RECTANGLE) then begin
6041 GL_NEAREST, GL_LINEAR:
6042 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
6043 GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR:
6044 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6045 GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR:
6046 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6049 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
6053 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6054 procedure TglBitmap.SetWrap(const S: GLenum; const T: GLenum; const R: GLenum);
6056 procedure CheckAndSetWrap(const aValue: Cardinal; var aTarget: Cardinal);
6060 aTarget := GL_CLAMP;
6063 aTarget := GL_REPEAT;
6065 GL_CLAMP_TO_EDGE: begin
6066 if GL_VERSION_1_2 or GL_EXT_texture_edge_clamp then
6067 aTarget := GL_CLAMP_TO_EDGE
6069 aTarget := GL_CLAMP;
6072 GL_CLAMP_TO_BORDER: begin
6073 if GL_VERSION_1_3 or GL_ARB_texture_border_clamp then
6074 aTarget := GL_CLAMP_TO_BORDER
6076 aTarget := GL_CLAMP;
6079 GL_MIRRORED_REPEAT: begin
6080 if GL_VERSION_1_4 or GL_ARB_texture_mirrored_repeat or GL_IBM_texture_mirrored_repeat then
6081 aTarget := GL_MIRRORED_REPEAT
6083 raise EglBitmap.Create('SetWrap - Unsupported Texturewrap GL_MIRRORED_REPEAT (S).');
6086 raise EglBitmap.Create('SetWrap - Unknow Texturewrap');
6091 CheckAndSetWrap(S, fWrapS);
6092 CheckAndSetWrap(T, fWrapT);
6093 CheckAndSetWrap(R, fWrapR);
6095 if (ID > 0) then begin
6097 glTexParameteri(Target, GL_TEXTURE_WRAP_S, fWrapS);
6098 glTexParameteri(Target, GL_TEXTURE_WRAP_T, fWrapT);
6099 glTexParameteri(Target, GL_TEXTURE_WRAP_R, fWrapR);
6103 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6104 procedure TglBitmap.SetSwizzle(const r, g, b, a: GLenum);
6106 procedure CheckAndSetValue(const aValue: GLenum; const aIndex: Integer);
6108 if (aValue = GL_ZERO) or (aValue = GL_ONE) or (aValue = GL_ALPHA) or
6109 (aValue = GL_RED) or (aValue = GL_GREEN) or (aValue = GL_BLUE) then
6110 fSwizzle[aIndex] := aValue
6112 raise EglBitmap.Create('SetSwizzle - Unknow Swizle Value');
6116 if not (GL_ARB_texture_swizzle or GL_EXT_texture_swizzle or GL_VERSION_3_3) then
6117 raise EglBitmapNotSupported.Create('texture swizzle is not supported');
6118 CheckAndSetValue(r, 0);
6119 CheckAndSetValue(g, 1);
6120 CheckAndSetValue(b, 2);
6121 CheckAndSetValue(a, 3);
6123 if (ID > 0) then begin
6125 glTexParameteriv(Target, GL_TEXTURE_SWIZZLE_RGBA, PGLint(@fSwizzle[0]));
6129 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6130 procedure TglBitmap.Bind(const aEnableTextureUnit: Boolean);
6132 if aEnableTextureUnit then
6135 glBindTexture(Target, ID);
6138 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6139 procedure TglBitmap.Unbind(const aDisableTextureUnit: Boolean);
6141 if aDisableTextureUnit then
6143 glBindTexture(Target, 0);
6146 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6147 constructor TglBitmap.Create;
6149 if (ClassType = TglBitmap) then
6150 raise EglBitmap.Create('Don''t create TglBitmap directly. Use one of the deviated classes (TglBitmap2D) instead.');
6151 {$IFDEF GLB_NATIVE_OGL}
6152 glbReadOpenGLExtensions;
6155 fFormat := glBitmapGetDefaultFormat;
6156 fFreeDataOnDestroy := true;
6159 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6160 constructor TglBitmap.Create(const aFileName: String);
6163 LoadFromFile(aFileName);
6166 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6167 constructor TglBitmap.Create(const aStream: TStream);
6170 LoadFromStream(aStream);
6173 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6174 constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; aData: PByte);
6179 if not Assigned(aData) then begin
6180 ImageSize := TFormatDescriptor.Get(aFormat).GetSize(aSize);
6181 GetMem(aData, ImageSize);
6183 FillChar(aData^, ImageSize, #$FF);
6184 SetDataPointer(aData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
6186 if Assigned(aData) then
6191 SetDataPointer(aData, aFormat, aSize.X, aSize.Y); //be careful, Data could be freed by this method
6192 fFreeDataOnDestroy := false;
6196 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6197 constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer);
6200 LoadFromFunc(aSize, aFunc, aFormat, aArgs);
6203 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6204 constructor TglBitmap.Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar);
6207 LoadFromResource(aInstance, aResource, aResType);
6210 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6211 constructor TglBitmap.Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
6214 LoadFromResourceID(aInstance, aResourceID, aResType);
6217 {$IFDEF GLB_SUPPORT_PNG_READ}
6218 {$IF DEFINED(GLB_LAZ_PNG)}
6219 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6220 //PNG/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6221 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6222 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6225 PNG_MAGIC: String[MAGIC_LEN] = #$89#$50#$4E#$47#$0D#$0A#$1A#$0A;
6227 reader: TLazReaderPNG;
6228 intf: TLazIntfImage;
6230 magic: String[MAGIC_LEN];
6233 StreamPos := aStream.Position;
6235 SetLength(magic, MAGIC_LEN);
6236 aStream.Read(magic[1], MAGIC_LEN);
6237 aStream.Position := StreamPos;
6238 if (magic <> PNG_MAGIC) then begin
6243 intf := TLazIntfImage.Create(0, 0);
6244 reader := TLazReaderPNG.Create;
6246 reader.UpdateDescription := true;
6247 reader.ImageRead(aStream, intf);
6248 AssignFromLazIntfImage(intf);
6251 aStream.Position := StreamPos;
6260 {$ELSEIF DEFINED(GLB_SDL_IMAGE)}
6261 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6262 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6264 Surface: PSDL_Surface;
6268 RWops := glBitmapCreateRWops(aStream);
6270 if IMG_isPNG(RWops) > 0 then begin
6271 Surface := IMG_LoadPNG_RW(RWops);
6273 AssignFromSurface(Surface);
6276 SDL_FreeSurface(Surface);
6284 {$ELSEIF DEFINED(GLB_LIB_PNG)}
6285 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6286 procedure glBitmap_libPNG_read_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
6288 TStream(png_get_io_ptr(png)).Read(buffer^, size);
6291 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6292 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6295 signature: array [0..7] of byte;
6297 png_info: png_infop;
6299 TempHeight, TempWidth: Integer;
6300 Format: TglBitmapFormat;
6303 png_rows: array of pByte;
6304 Row, LineSize: Integer;
6308 if not init_libPNG then
6309 raise Exception.Create('LoadPNG - unable to initialize libPNG.');
6313 StreamPos := aStream.Position;
6314 aStream.Read(signature{%H-}, 8);
6315 aStream.Position := StreamPos;
6317 if png_check_sig(@signature, 8) <> 0 then begin
6319 png := png_create_read_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
6321 raise EglBitmapException.Create('LoadPng - couldn''t create read struct.');
6324 png_info := png_create_info_struct(png);
6325 if png_info = nil then begin
6326 png_destroy_read_struct(@png, nil, nil);
6327 raise EglBitmapException.Create('LoadPng - couldn''t create info struct.');
6330 // set read callback
6331 png_set_read_fn(png, aStream, glBitmap_libPNG_read_func);
6333 // read informations
6334 png_read_info(png, png_info);
6337 TempHeight := png_get_image_height(png, png_info);
6338 TempWidth := png_get_image_width(png, png_info);
6341 case png_get_color_type(png, png_info) of
6342 PNG_COLOR_TYPE_GRAY:
6343 Format := tfLuminance8;
6344 PNG_COLOR_TYPE_GRAY_ALPHA:
6345 Format := tfLuminance8Alpha8;
6348 PNG_COLOR_TYPE_RGB_ALPHA:
6351 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
6354 // cut upper 8 bit from 16 bit formats
6355 if png_get_bit_depth(png, png_info) > 8 then
6356 png_set_strip_16(png);
6358 // expand bitdepth smaller than 8
6359 if png_get_bit_depth(png, png_info) < 8 then
6360 png_set_expand(png);
6362 // allocating mem for scanlines
6363 LineSize := png_get_rowbytes(png, png_info);
6364 GetMem(png_data, TempHeight * LineSize);
6366 SetLength(png_rows, TempHeight);
6367 for Row := Low(png_rows) to High(png_rows) do begin
6368 png_rows[Row] := png_data;
6369 Inc(png_rows[Row], Row * LineSize);
6372 // read complete image into scanlines
6373 png_read_image(png, @png_rows[0]);
6376 png_read_end(png, png_info);
6378 // destroy read struct
6379 png_destroy_read_struct(@png, @png_info, nil);
6381 SetLength(png_rows, 0);
6384 SetDataPointer(png_data, Format, TempWidth, TempHeight); //be careful, Data could be freed by this method
6388 if Assigned(png_data) then
6398 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
6399 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6400 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
6405 Row, Col, PixSize, LineSize: Integer;
6406 NewImage, pSource, pDest, pAlpha: pByte;
6407 PngFormat: TglBitmapFormat;
6408 FormatDesc: TFormatDescriptor;
6411 PngHeader: String[8] = #137#80#78#71#13#10#26#10;
6416 StreamPos := aStream.Position;
6417 aStream.Read(Header[0], SizeOf(Header));
6418 aStream.Position := StreamPos;
6420 {Test if the header matches}
6421 if Header = PngHeader then begin
6422 Png := TPNGObject.Create;
6424 Png.LoadFromStream(aStream);
6426 case Png.Header.ColorType of
6428 PngFormat := tfLuminance8;
6429 COLOR_GRAYSCALEALPHA:
6430 PngFormat := tfLuminance8Alpha8;
6432 PngFormat := tfBGR8;
6434 PngFormat := tfBGRA8;
6436 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
6439 FormatDesc := TFormatDescriptor.Get(PngFormat);
6440 PixSize := Round(FormatDesc.PixelSize);
6441 LineSize := FormatDesc.GetSize(Png.Header.Width, 1);
6443 GetMem(NewImage, LineSize * Integer(Png.Header.Height));
6447 case Png.Header.ColorType of
6448 COLOR_RGB, COLOR_GRAYSCALE:
6450 for Row := 0 to Png.Height -1 do begin
6451 Move (Png.Scanline[Row]^, pDest^, LineSize);
6452 Inc(pDest, LineSize);
6455 COLOR_RGBALPHA, COLOR_GRAYSCALEALPHA:
6457 PixSize := PixSize -1;
6459 for Row := 0 to Png.Height -1 do begin
6460 pSource := Png.Scanline[Row];
6461 pAlpha := pByte(Png.AlphaScanline[Row]);
6463 for Col := 0 to Png.Width -1 do begin
6464 Move (pSource^, pDest^, PixSize);
6465 Inc(pSource, PixSize);
6466 Inc(pDest, PixSize);
6475 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
6478 SetDataPointer(NewImage, PngFormat, Png.Header.Width, Png.Header.Height); //be careful, Data could be freed by this method
6482 if Assigned(NewImage) then
6494 {$IFDEF GLB_SUPPORT_PNG_WRITE}
6495 {$IFDEF GLB_LIB_PNG}
6496 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6497 procedure glBitmap_libPNG_write_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
6499 TStream(png_get_io_ptr(png)).Write(buffer^, size);
6503 {$IF DEFINED(GLB_LAZ_PNG)}
6504 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6505 procedure TglBitmap.SavePNG(const aStream: TStream);
6507 png: TPortableNetworkGraphic;
6508 intf: TLazIntfImage;
6511 png := TPortableNetworkGraphic.Create;
6512 intf := TLazIntfImage.Create(0, 0);
6514 if not AssignToLazIntfImage(intf) then
6515 raise EglBitmap.Create('unable to create LazIntfImage from glBitmap');
6516 intf.GetRawImage(raw);
6517 png.LoadFromRawImage(raw, false);
6518 png.SaveToStream(aStream);
6525 {$ELSEIF DEFINED(GLB_LIB_PNG)}
6526 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6527 procedure TglBitmap.SavePNG(const aStream: TStream);
6530 png_info: png_infop;
6531 png_rows: array of pByte;
6535 FormatDesc: TFormatDescriptor;
6537 if not (ftPNG in FormatGetSupportedFiles(Format)) then
6538 raise EglBitmapUnsupportedFormat.Create(Format);
6540 if not init_libPNG then
6541 raise Exception.Create('unable to initialize libPNG.');
6545 tfAlpha8, tfLuminance8:
6546 ColorType := PNG_COLOR_TYPE_GRAY;
6548 ColorType := PNG_COLOR_TYPE_GRAY_ALPHA;
6550 ColorType := PNG_COLOR_TYPE_RGB;
6552 ColorType := PNG_COLOR_TYPE_RGBA;
6554 raise EglBitmapUnsupportedFormat.Create(Format);
6557 FormatDesc := TFormatDescriptor.Get(Format);
6558 LineSize := FormatDesc.GetSize(Width, 1);
6560 // creating array for scanline
6561 SetLength(png_rows, Height);
6563 for Row := 0 to Height - 1 do begin
6564 png_rows[Row] := Data;
6565 Inc(png_rows[Row], Row * LineSize)
6569 png := png_create_write_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
6571 raise EglBitmapException.Create('SavePng - couldn''t create write struct.');
6574 png_info := png_create_info_struct(png);
6575 if png_info = nil then begin
6576 png_destroy_write_struct(@png, nil);
6577 raise EglBitmapException.Create('SavePng - couldn''t create info struct.');
6580 // set read callback
6581 png_set_write_fn(png, aStream, glBitmap_libPNG_write_func, nil);
6584 png_set_compression_level(png, 6);
6586 if Format in [tfBGR8, tfBGRA8] then
6589 png_set_IHDR(png, png_info, Width, Height, 8, ColorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
6590 png_write_info(png, png_info);
6591 png_write_image(png, @png_rows[0]);
6592 png_write_end(png, png_info);
6593 png_destroy_write_struct(@png, @png_info);
6595 SetLength(png_rows, 0);
6602 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
6603 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6604 procedure TglBitmap.SavePNG(const aStream: TStream);
6608 pSource, pDest: pByte;
6609 X, Y, PixSize: Integer;
6610 ColorType: Cardinal;
6616 if not (ftPNG in FormatGetSupportedFiles (Format)) then
6617 raise EglBitmapUnsupportedFormat.Create(Format);
6620 tfAlpha8, tfLuminance8: begin
6621 ColorType := COLOR_GRAYSCALE;
6625 tfLuminance8Alpha8: begin
6626 ColorType := COLOR_GRAYSCALEALPHA;
6630 tfBGR8, tfRGB8: begin
6631 ColorType := COLOR_RGB;
6635 tfBGRA8, tfRGBA8: begin
6636 ColorType := COLOR_RGBALPHA;
6641 raise EglBitmapUnsupportedFormat.Create(Format);
6644 Png := TPNGObject.CreateBlank(ColorType, 8, Width, Height);
6648 for Y := 0 to Height -1 do begin
6649 pDest := png.ScanLine[Y];
6650 for X := 0 to Width -1 do begin
6651 Move(pSource^, pDest^, PixSize);
6652 Inc(pDest, PixSize);
6653 Inc(pSource, PixSize);
6655 png.AlphaScanline[Y]^[X] := pSource^;
6660 // convert RGB line to BGR
6661 if Format in [tfRGB8, tfRGBA8] then begin
6662 pTemp := png.ScanLine[Y];
6663 for X := 0 to Width -1 do begin
6664 Temp := pByteArray(pTemp)^[0];
6665 pByteArray(pTemp)^[0] := pByteArray(pTemp)^[2];
6666 pByteArray(pTemp)^[2] := Temp;
6673 Png.CompressionLevel := 6;
6674 Png.SaveToStream(aStream);
6682 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6683 //JPEG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6684 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6685 {$IFDEF GLB_LIB_JPEG}
6687 glBitmap_libJPEG_source_mgr_ptr = ^glBitmap_libJPEG_source_mgr;
6688 glBitmap_libJPEG_source_mgr = record
6689 pub: jpeg_source_mgr;
6692 SrcBuffer: array [1..4096] of byte;
6695 glBitmap_libJPEG_dest_mgr_ptr = ^glBitmap_libJPEG_dest_mgr;
6696 glBitmap_libJPEG_dest_mgr = record
6697 pub: jpeg_destination_mgr;
6699 DestStream: TStream;
6700 DestBuffer: array [1..4096] of byte;
6703 procedure glBitmap_libJPEG_error_exit(cinfo: j_common_ptr); cdecl;
6709 procedure glBitmap_libJPEG_output_message(cinfo: j_common_ptr); cdecl;
6715 procedure glBitmap_libJPEG_init_source(cinfo: j_decompress_ptr); cdecl;
6720 procedure glBitmap_libJPEG_term_source(cinfo: j_decompress_ptr); cdecl;
6726 procedure glBitmap_libJPEG_init_destination(cinfo: j_compress_ptr); cdecl;
6732 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6733 function glBitmap_libJPEG_fill_input_buffer(cinfo: j_decompress_ptr): boolean; cdecl;
6735 src: glBitmap_libJPEG_source_mgr_ptr;
6738 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
6740 bytes := src^.SrcStream.Read(src^.SrcBuffer[1], 4096);
6741 if (bytes <= 0) then begin
6742 src^.SrcBuffer[1] := $FF;
6743 src^.SrcBuffer[2] := JPEG_EOI;
6747 src^.pub.next_input_byte := @(src^.SrcBuffer[1]);
6748 src^.pub.bytes_in_buffer := bytes;
6753 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6754 procedure glBitmap_libJPEG_skip_input_data(cinfo: j_decompress_ptr; num_bytes: Longint); cdecl;
6756 src: glBitmap_libJPEG_source_mgr_ptr;
6758 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
6760 if num_bytes > 0 then begin
6761 // wanted byte isn't in buffer so set stream position and read buffer
6762 if num_bytes > src^.pub.bytes_in_buffer then begin
6763 src^.SrcStream.Position := src^.SrcStream.Position + num_bytes - src^.pub.bytes_in_buffer;
6764 src^.pub.fill_input_buffer(cinfo);
6766 // wanted byte is in buffer so only skip
6767 inc(src^.pub.next_input_byte, num_bytes);
6768 dec(src^.pub.bytes_in_buffer, num_bytes);
6773 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6774 function glBitmap_libJPEG_empty_output_buffer(cinfo: j_compress_ptr): boolean; cdecl;
6776 dest: glBitmap_libJPEG_dest_mgr_ptr;
6778 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
6780 if dest^.pub.free_in_buffer < Cardinal(Length(dest^.DestBuffer)) then begin
6781 // write complete buffer
6782 dest^.DestStream.Write(dest^.DestBuffer[1], SizeOf(dest^.DestBuffer));
6785 dest^.pub.next_output_byte := @dest^.DestBuffer[1];
6786 dest^.pub.free_in_buffer := Length(dest^.DestBuffer);
6792 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6793 procedure glBitmap_libJPEG_term_destination(cinfo: j_compress_ptr); cdecl;
6796 dest: glBitmap_libJPEG_dest_mgr_ptr;
6798 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
6800 for Idx := Low(dest^.DestBuffer) to High(dest^.DestBuffer) do begin
6801 // check for endblock
6802 if (Idx < High(dest^.DestBuffer)) and (dest^.DestBuffer[Idx] = $FF) and (dest^.DestBuffer[Idx +1] = JPEG_EOI) then begin
6804 dest^.DestStream.Write(dest^.DestBuffer[Idx], 2);
6809 dest^.DestStream.Write(dest^.DestBuffer[Idx], 1);
6814 {$IFDEF GLB_SUPPORT_JPEG_READ}
6815 {$IF DEFINED(GLB_LAZ_JPEG)}
6816 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6817 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6820 JPEG_MAGIC: String[MAGIC_LEN] = #$FF#$D8;
6822 intf: TLazIntfImage;
6823 reader: TFPReaderJPEG;
6825 magic: String[MAGIC_LEN];
6828 StreamPos := aStream.Position;
6830 SetLength(magic, MAGIC_LEN);
6831 aStream.Read(magic[1], MAGIC_LEN);
6832 aStream.Position := StreamPos;
6833 if (magic <> JPEG_MAGIC) then begin
6838 reader := TFPReaderJPEG.Create;
6839 intf := TLazIntfImage.Create(0, 0);
6841 intf.DataDescription := GetDescriptionFromDevice(0, 0, 0);
6842 reader.ImageRead(aStream, intf);
6843 AssignFromLazIntfImage(intf);
6846 aStream.Position := StreamPos;
6855 {$ELSEIF DEFINED(GLB_SDL_IMAGE)}
6856 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6857 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6859 Surface: PSDL_Surface;
6864 RWops := glBitmapCreateRWops(aStream);
6866 if IMG_isJPG(RWops) > 0 then begin
6867 Surface := IMG_LoadJPG_RW(RWops);
6869 AssignFromSurface(Surface);
6872 SDL_FreeSurface(Surface);
6880 {$ELSEIF DEFINED(GLB_LIB_JPEG)}
6881 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6882 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6885 Temp: array[0..1]of Byte;
6887 jpeg: jpeg_decompress_struct;
6888 jpeg_err: jpeg_error_mgr;
6890 IntFormat: TglBitmapFormat;
6892 TempHeight, TempWidth: Integer;
6897 FormatDesc: TFormatDescriptor;
6901 if not init_libJPEG then
6902 raise Exception.Create('LoadJPG - unable to initialize libJPEG.');
6905 // reading first two bytes to test file and set cursor back to begin
6906 StreamPos := aStream.Position;
6907 aStream.Read({%H-}Temp[0], 2);
6908 aStream.Position := StreamPos;
6910 // if Bitmap then read file.
6911 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
6912 FillChar(jpeg{%H-}, SizeOf(jpeg_decompress_struct), $00);
6913 FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
6916 jpeg.err := jpeg_std_error(@jpeg_err);
6917 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
6918 jpeg_err.output_message := glBitmap_libJPEG_output_message;
6920 // decompression struct
6921 jpeg_create_decompress(@jpeg);
6923 // allocation space for streaming methods
6924 jpeg.src := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_source_mgr));
6926 // seeting up custom functions
6927 with glBitmap_libJPEG_source_mgr_ptr(jpeg.src)^ do begin
6928 pub.init_source := glBitmap_libJPEG_init_source;
6929 pub.fill_input_buffer := glBitmap_libJPEG_fill_input_buffer;
6930 pub.skip_input_data := glBitmap_libJPEG_skip_input_data;
6931 pub.resync_to_restart := jpeg_resync_to_restart; // use default method
6932 pub.term_source := glBitmap_libJPEG_term_source;
6934 pub.bytes_in_buffer := 0; // forces fill_input_buffer on first read
6935 pub.next_input_byte := nil; // until buffer loaded
6937 SrcStream := aStream;
6940 // set global decoding state
6941 jpeg.global_state := DSTATE_START;
6943 // read header of jpeg
6944 jpeg_read_header(@jpeg, false);
6946 // setting output parameter
6947 case jpeg.jpeg_color_space of
6950 jpeg.out_color_space := JCS_GRAYSCALE;
6951 IntFormat := tfLuminance8;
6954 jpeg.out_color_space := JCS_RGB;
6955 IntFormat := tfRGB8;
6959 jpeg_start_decompress(@jpeg);
6961 TempHeight := jpeg.output_height;
6962 TempWidth := jpeg.output_width;
6964 FormatDesc := TFormatDescriptor.Get(IntFormat);
6966 // creating new image
6967 GetMem(pImage, FormatDesc.GetSize(TempWidth, TempHeight));
6971 for Row := 0 to TempHeight -1 do begin
6972 jpeg_read_scanlines(@jpeg, @pTemp, 1);
6973 Inc(pTemp, FormatDesc.GetSize(TempWidth, 1));
6976 // finish decompression
6977 jpeg_finish_decompress(@jpeg);
6979 // destroy decompression
6980 jpeg_destroy_decompress(@jpeg);
6982 SetDataPointer(pImage, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
6986 if Assigned(pImage) then
6996 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
6997 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6998 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
7003 Temp: array[0..1]of Byte;
7007 // reading first two bytes to test file and set cursor back to begin
7008 StreamPos := aStream.Position;
7009 aStream.Read(Temp[0], 2);
7010 aStream.Position := StreamPos;
7012 // if Bitmap then read file.
7013 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
7014 bmp := TBitmap.Create;
7016 jpg := TJPEGImage.Create;
7018 jpg.LoadFromStream(aStream);
7020 result := AssignFromBitmap(bmp);
7032 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
7033 {$IF DEFINED(GLB_LAZ_JPEG)}
7034 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7035 procedure TglBitmap.SaveJPEG(const aStream: TStream);
7038 intf: TLazIntfImage;
7041 jpeg := TJPEGImage.Create;
7042 intf := TLazIntfImage.Create(0, 0);
7044 if not AssignToLazIntfImage(intf) then
7045 raise EglBitmap.Create('unable to create LazIntfImage from glBitmap');
7046 intf.GetRawImage(raw);
7047 jpeg.LoadFromRawImage(raw, false);
7048 jpeg.SaveToStream(aStream);
7055 {$ELSEIF DEFINED(GLB_LIB_JPEG)}
7056 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7057 procedure TglBitmap.SaveJPEG(const aStream: TStream);
7059 jpeg: jpeg_compress_struct;
7060 jpeg_err: jpeg_error_mgr;
7062 pTemp, pTemp2: pByte;
7064 procedure CopyRow(pDest, pSource: pByte);
7068 for X := 0 to Width - 1 do begin
7069 pByteArray(pDest)^[0] := pByteArray(pSource)^[2];
7070 pByteArray(pDest)^[1] := pByteArray(pSource)^[1];
7071 pByteArray(pDest)^[2] := pByteArray(pSource)^[0];
7078 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
7079 raise EglBitmapUnsupportedFormat.Create(Format);
7081 if not init_libJPEG then
7082 raise Exception.Create('SaveJPG - unable to initialize libJPEG.');
7085 FillChar(jpeg{%H-}, SizeOf(jpeg_compress_struct), $00);
7086 FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
7089 jpeg.err := jpeg_std_error(@jpeg_err);
7090 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
7091 jpeg_err.output_message := glBitmap_libJPEG_output_message;
7093 // compression struct
7094 jpeg_create_compress(@jpeg);
7096 // allocation space for streaming methods
7097 jpeg.dest := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_dest_mgr));
7099 // seeting up custom functions
7100 with glBitmap_libJPEG_dest_mgr_ptr(jpeg.dest)^ do begin
7101 pub.init_destination := glBitmap_libJPEG_init_destination;
7102 pub.empty_output_buffer := glBitmap_libJPEG_empty_output_buffer;
7103 pub.term_destination := glBitmap_libJPEG_term_destination;
7105 pub.next_output_byte := @DestBuffer[1];
7106 pub.free_in_buffer := Length(DestBuffer);
7108 DestStream := aStream;
7111 // very important state
7112 jpeg.global_state := CSTATE_START;
7113 jpeg.image_width := Width;
7114 jpeg.image_height := Height;
7116 tfAlpha8, tfLuminance8: begin
7117 jpeg.input_components := 1;
7118 jpeg.in_color_space := JCS_GRAYSCALE;
7120 tfRGB8, tfBGR8: begin
7121 jpeg.input_components := 3;
7122 jpeg.in_color_space := JCS_RGB;
7126 jpeg_set_defaults(@jpeg);
7127 jpeg_set_quality(@jpeg, 95, true);
7128 jpeg_start_compress(@jpeg, true);
7131 if Format = tfBGR8 then
7132 GetMem(pTemp2, fRowSize)
7137 for Row := 0 to jpeg.image_height -1 do begin
7139 if Format = tfBGR8 then
7140 CopyRow(pTemp2, pTemp)
7145 jpeg_write_scanlines(@jpeg, @pTemp2, 1);
7146 inc(pTemp, fRowSize);
7150 if Format = tfBGR8 then
7153 jpeg_finish_compress(@jpeg);
7154 jpeg_destroy_compress(@jpeg);
7160 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
7161 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7162 procedure TglBitmap.SaveJPEG(const aStream: TStream);
7167 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
7168 raise EglBitmapUnsupportedFormat.Create(Format);
7170 Bmp := TBitmap.Create;
7172 Jpg := TJPEGImage.Create;
7174 AssignToBitmap(Bmp);
7175 if (Format in [tfAlpha8, tfLuminance8]) then begin
7176 Jpg.Grayscale := true;
7177 Jpg.PixelFormat := jf8Bit;
7180 Jpg.SaveToStream(aStream);
7191 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7192 //BMP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7193 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7200 BMP_COMP_BITFIELDS = 3;
7203 TBMPHeader = packed record
7208 bfOffBits: Cardinal;
7211 TBMPInfo = packed record
7217 biCompression: Cardinal;
7218 biSizeImage: Cardinal;
7219 biXPelsPerMeter: Longint;
7220 biYPelsPerMeter: Longint;
7221 biClrUsed: Cardinal;
7222 biClrImportant: Cardinal;
7225 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7226 function TglBitmap.LoadBMP(const aStream: TStream): Boolean;
7228 //////////////////////////////////////////////////////////////////////////////////////////////////
7229 function ReadInfo(out aInfo: TBMPInfo; out aMask: TglBitmapColorRec): TglBitmapFormat;
7232 aStream.Read(aInfo{%H-}, SizeOf(aInfo));
7233 FillChar(aMask{%H-}, SizeOf(aMask), 0);
7236 case aInfo.biCompression of
7238 BMP_COMP_RLE8: begin
7239 raise EglBitmap.Create('RLE compression is not supported');
7241 BMP_COMP_BITFIELDS: begin
7242 if (aInfo.biBitCount = 16) or (aInfo.biBitCount = 32) then begin
7243 aStream.Read(aMask.r, SizeOf(aMask.r));
7244 aStream.Read(aMask.g, SizeOf(aMask.g));
7245 aStream.Read(aMask.b, SizeOf(aMask.b));
7246 aStream.Read(aMask.a, SizeOf(aMask.a));
7248 raise EglBitmap.Create('Bitfields are only supported for 16bit and 32bit formats');
7252 //get suitable format
7253 case aInfo.biBitCount of
7254 8: result := tfLuminance8;
7255 16: result := tfX1RGB5;
7256 24: result := tfRGB8;
7257 32: result := tfXRGB8;
7261 function ReadColorTable(var aFormat: TglBitmapFormat; const aInfo: TBMPInfo): TbmpColorTableFormat;
7264 ColorTable: TbmpColorTable;
7267 if (aInfo.biBitCount >= 16) then
7269 aFormat := tfLuminance8;
7270 c := aInfo.biClrUsed;
7272 c := 1 shl aInfo.biBitCount;
7273 SetLength(ColorTable, c);
7274 for i := 0 to c-1 do begin
7275 aStream.Read(ColorTable[i], SizeOf(TbmpColorTableEnty));
7276 if (ColorTable[i].r <> ColorTable[i].g) or (ColorTable[i].g <> ColorTable[i].b) then
7280 result := TbmpColorTableFormat.Create;
7281 result.PixelSize := aInfo.biBitCount / 8;
7282 result.ColorTable := ColorTable;
7283 result.Range := glBitmapColorRec($FF, $FF, $FF, $00);
7286 //////////////////////////////////////////////////////////////////////////////////////////////////
7287 function CheckBitfields(var aFormat: TglBitmapFormat; const aMask: TglBitmapColorRec;
7288 const aInfo: TBMPInfo): TbmpBitfieldFormat;
7290 TmpFormat: TglBitmapFormat;
7291 FormatDesc: TFormatDescriptor;
7294 if (aMask.r <> 0) or (aMask.g <> 0) or (aMask.b <> 0) or (aMask.a <> 0) then begin
7295 for TmpFormat := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
7296 FormatDesc := TFormatDescriptor.Get(TmpFormat);
7297 if FormatDesc.MaskMatch(aMask.r, aMask.g, aMask.b, aMask.a) then begin
7298 aFormat := FormatDesc.Format;
7303 if (aMask.a = 0) and TFormatDescriptor.Get(aFormat).HasAlpha then
7304 aFormat := TFormatDescriptor.Get(aFormat).WithoutAlpha;
7305 if (aMask.a <> 0) and not TFormatDescriptor.Get(aFormat).HasAlpha then
7306 aFormat := TFormatDescriptor.Get(aFormat).WithAlpha;
7308 result := TbmpBitfieldFormat.Create;
7309 result.PixelSize := aInfo.biBitCount / 8;
7310 result.RedMask := aMask.r;
7311 result.GreenMask := aMask.g;
7312 result.BlueMask := aMask.b;
7313 result.AlphaMask := aMask.a;
7320 ImageSize, rbLineSize, wbLineSize, Padding, i: Integer;
7321 PaddingBuff: Cardinal;
7322 LineBuf, ImageData, TmpData: PByte;
7323 SourceMD, DestMD: Pointer;
7324 BmpFormat: TglBitmapFormat;
7327 Mask: TglBitmapColorRec;
7332 SpecialFormat: TFormatDescriptor;
7333 FormatDesc: TFormatDescriptor;
7335 //////////////////////////////////////////////////////////////////////////////////////////////////
7336 procedure SpecialFormatReadLine(aData: PByte; aLineBuf: PByte);
7339 Pixel: TglBitmapPixelData;
7341 aStream.Read(aLineBuf^, rbLineSize);
7342 SpecialFormat.PreparePixel(Pixel);
7343 for i := 0 to Info.biWidth-1 do begin
7344 SpecialFormat.Unmap(aLineBuf, Pixel, SourceMD);
7345 glBitmapConvertPixel(Pixel, SpecialFormat, FormatDesc);
7346 FormatDesc.Map(Pixel, aData, DestMD);
7352 BmpFormat := tfEmpty;
7353 SpecialFormat := nil;
7359 StartPos := aStream.Position;
7360 aStream.Read(Header{%H-}, SizeOf(Header));
7362 if Header.bfType = BMP_MAGIC then begin
7364 BmpFormat := ReadInfo(Info, Mask);
7365 SpecialFormat := ReadColorTable(BmpFormat, Info);
7366 if not Assigned(SpecialFormat) then
7367 SpecialFormat := CheckBitfields(BmpFormat, Mask, Info);
7368 aStream.Position := StartPos + Header.bfOffBits;
7370 if (BmpFormat <> tfEmpty) then begin
7371 FormatDesc := TFormatDescriptor.Get(BmpFormat);
7372 rbLineSize := Round(Info.biWidth * Info.biBitCount / 8); //ReadBuffer LineSize
7373 wbLineSize := Trunc(Info.biWidth * FormatDesc.PixelSize);
7374 Padding := (((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3) - rbLineSize;
7377 DestMD := FormatDesc.CreateMappingData;
7378 ImageSize := FormatDesc.GetSize(Info.biWidth, abs(Info.biHeight));
7379 GetMem(ImageData, ImageSize);
7380 if Assigned(SpecialFormat) then begin
7381 GetMem(LineBuf, rbLineSize); //tmp Memory for converting Bitfields
7382 SourceMD := SpecialFormat.CreateMappingData;
7387 FillChar(ImageData^, ImageSize, $FF);
7388 TmpData := ImageData;
7389 if (Info.biHeight > 0) then
7390 Inc(TmpData, wbLineSize * (Info.biHeight-1));
7391 for i := 0 to Abs(Info.biHeight)-1 do begin
7392 if Assigned(SpecialFormat) then
7393 SpecialFormatReadLine(TmpData, LineBuf) //if is special format read and convert data
7395 aStream.Read(TmpData^, wbLineSize); //else only read data
7396 if (Info.biHeight > 0) then
7397 dec(TmpData, wbLineSize)
7399 inc(TmpData, wbLineSize);
7400 aStream.Read(PaddingBuff{%H-}, Padding);
7402 SetDataPointer(ImageData, BmpFormat, Info.biWidth, abs(Info.biHeight)); //be careful, Data could be freed by this method
7405 if Assigned(LineBuf) then
7407 if Assigned(SourceMD) then
7408 SpecialFormat.FreeMappingData(SourceMD);
7409 FormatDesc.FreeMappingData(DestMD);
7412 if Assigned(ImageData) then
7417 raise EglBitmap.Create('LoadBMP - No suitable format found');
7419 aStream.Position := StartPos;
7423 FreeAndNil(SpecialFormat);
7426 else aStream.Position := StartPos;
7429 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7430 procedure TglBitmap.SaveBMP(const aStream: TStream);
7434 Converter: TFormatDescriptor;
7435 FormatDesc: TFormatDescriptor;
7436 SourceFD, DestFD: Pointer;
7437 pData, srcData, dstData, ConvertBuffer: pByte;
7439 Pixel: TglBitmapPixelData;
7440 ImageSize, wbLineSize, rbLineSize, Padding, LineIdx, PixelIdx: Integer;
7441 RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
7443 PaddingBuff: Cardinal;
7445 function GetLineWidth : Integer;
7447 result := ((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3;
7451 if not (ftBMP in FormatGetSupportedFiles(Format)) then
7452 raise EglBitmapUnsupportedFormat.Create(Format);
7455 FormatDesc := TFormatDescriptor.Get(Format);
7456 ImageSize := FormatDesc.GetSize(Dimension);
7458 FillChar(Header{%H-}, SizeOf(Header), 0);
7459 Header.bfType := BMP_MAGIC;
7460 Header.bfSize := SizeOf(Header) + SizeOf(Info) + ImageSize;
7461 Header.bfReserved1 := 0;
7462 Header.bfReserved2 := 0;
7463 Header.bfOffBits := SizeOf(Header) + SizeOf(Info);
7465 FillChar(Info{%H-}, SizeOf(Info), 0);
7466 Info.biSize := SizeOf(Info);
7467 Info.biWidth := Width;
7468 Info.biHeight := Height;
7470 Info.biCompression := BMP_COMP_RGB;
7471 Info.biSizeImage := ImageSize;
7476 Info.biBitCount := 4;
7477 Header.bfSize := Header.bfSize + 16 * SizeOf(Cardinal);
7478 Header.bfOffBits := Header.bfOffBits + 16 * SizeOf(Cardinal); //16 ColorTable entries
7479 Converter := TbmpColorTableFormat.Create;
7480 with (Converter as TbmpColorTableFormat) do begin
7483 Range := glBitmapColorRec($F, $F, $F, $0);
7488 tfR3G3B2, tfLuminance8: begin
7489 Info.biBitCount := 8;
7490 Header.bfSize := Header.bfSize + 256 * SizeOf(Cardinal);
7491 Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal); //256 ColorTable entries
7492 Converter := TbmpColorTableFormat.Create;
7493 with (Converter as TbmpColorTableFormat) do begin
7496 if (Format = tfR3G3B2) then begin
7497 Range := glBitmapColorRec($7, $7, $3, $0);
7498 Shift := glBitmapShiftRec(0, 3, 6, 0);
7500 Range := glBitmapColorRec($FF, $FF, $FF, $0);
7505 tfRGBX4, tfXRGB4, tfRGB5X1, tfX1RGB5, tfR5G6B5, tfRGB5A1, tfA1RGB5, tfRGBA4, tfARGB4,
7506 tfBGRX4, tfXBGR4, tfBGR5X1, tfX1BGR5, tfB5G6R5, tfBGR5A1, tfA1BGR5, tfBGRA4, tfABGR4: begin
7507 Info.biBitCount := 16;
7508 Info.biCompression := BMP_COMP_BITFIELDS;
7511 tfBGR8, tfRGB8: begin
7512 Info.biBitCount := 24;
7513 if (Format = tfRGB8) then
7514 Converter := TfdBGR8.Create; //use BGR8 Format Descriptor to Swap RGB Values
7517 tfRGB10X2, tfX2RGB10, tfRGB10A2, tfA2RGB10, tfRGBA8, tfARGB8,
7518 tfBGR10X2, tfX2BGR10, tfBGR10A2, tfA2BGR10, tfBGRA8, tfABGR8: begin
7519 Info.biBitCount := 32;
7520 Info.biCompression := BMP_COMP_BITFIELDS;
7523 raise EglBitmapUnsupportedFormat.Create(Format);
7525 Info.biXPelsPerMeter := 2835;
7526 Info.biYPelsPerMeter := 2835;
7529 if Info.biCompression = BMP_COMP_BITFIELDS then begin
7530 Header.bfSize := Header.bfSize + 4 * SizeOf(Cardinal);
7531 Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal);
7533 RedMask := FormatDesc.RedMask;
7534 GreenMask := FormatDesc.GreenMask;
7535 BlueMask := FormatDesc.BlueMask;
7536 AlphaMask := FormatDesc.AlphaMask;
7540 aStream.Write(Header, SizeOf(Header));
7541 aStream.Write(Info, SizeOf(Info));
7544 if Assigned(Converter) and (Converter is TbmpColorTableFormat) then
7545 with (Converter as TbmpColorTableFormat) do
7546 aStream.Write(ColorTable[0].b,
7547 SizeOf(TbmpColorTableEnty) * Length(ColorTable));
7550 if Info.biCompression = BMP_COMP_BITFIELDS then begin
7551 aStream.Write(RedMask, SizeOf(Cardinal));
7552 aStream.Write(GreenMask, SizeOf(Cardinal));
7553 aStream.Write(BlueMask, SizeOf(Cardinal));
7554 aStream.Write(AlphaMask, SizeOf(Cardinal));
7558 rbLineSize := Round(Info.biWidth * FormatDesc.PixelSize);
7559 wbLineSize := Round(Info.biWidth * Info.biBitCount / 8);
7560 Padding := GetLineWidth - wbLineSize;
7564 inc(pData, (Height-1) * rbLineSize);
7566 // prepare row buffer. But only for RGB because RGBA supports color masks
7567 // so it's possible to change color within the image.
7568 if Assigned(Converter) then begin
7569 FormatDesc.PreparePixel(Pixel);
7570 GetMem(ConvertBuffer, wbLineSize);
7571 SourceFD := FormatDesc.CreateMappingData;
7572 DestFD := Converter.CreateMappingData;
7574 ConvertBuffer := nil;
7577 for LineIdx := 0 to Height - 1 do begin
7579 if Assigned(Converter) then begin
7581 dstData := ConvertBuffer;
7582 for PixelIdx := 0 to Info.biWidth-1 do begin
7583 FormatDesc.Unmap(srcData, Pixel, SourceFD);
7584 glBitmapConvertPixel(Pixel, FormatDesc, Converter);
7585 Converter.Map(Pixel, dstData, DestFD);
7587 aStream.Write(ConvertBuffer^, wbLineSize);
7589 aStream.Write(pData^, rbLineSize);
7591 dec(pData, rbLineSize);
7592 if (Padding > 0) then
7593 aStream.Write(PaddingBuff, Padding);
7596 // destroy row buffer
7597 if Assigned(ConvertBuffer) then begin
7598 FormatDesc.FreeMappingData(SourceFD);
7599 Converter.FreeMappingData(DestFD);
7600 FreeMem(ConvertBuffer);
7604 if Assigned(Converter) then
7609 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7610 //TGA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7611 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7613 TTGAHeader = packed record
7617 //ColorMapSpec: Array[0..4] of Byte;
7618 ColorMapStart: Word;
7619 ColorMapLength: Word;
7620 ColorMapEntrySize: Byte;
7630 TGA_UNCOMPRESSED_RGB = 2;
7631 TGA_UNCOMPRESSED_GRAY = 3;
7632 TGA_COMPRESSED_RGB = 10;
7633 TGA_COMPRESSED_GRAY = 11;
7635 TGA_NONE_COLOR_TABLE = 0;
7637 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7638 function TglBitmap.LoadTGA(const aStream: TStream): Boolean;
7641 ImageData: System.PByte;
7642 StartPosition: Int64;
7643 PixelSize, LineSize: Integer;
7644 tgaFormat: TglBitmapFormat;
7645 FormatDesc: TFormatDescriptor;
7646 Counter: packed record
7648 low, high, dir: Integer;
7655 ////////////////////////////////////////////////////////////////////////////////////////
7656 procedure ReadUncompressed;
7659 buf, tmp1, tmp2: System.PByte;
7662 if (Counter.X.dir < 0) then
7663 GetMem(buf, LineSize);
7665 while (Counter.Y.low <> Counter.Y.high + counter.Y.dir) do begin
7667 inc(tmp1, (Counter.Y.low * LineSize)); //pointer to LineStart
7668 if (Counter.X.dir < 0) then begin //flip X
7669 aStream.Read(buf^, LineSize);
7671 inc(tmp2, LineSize - PixelSize); //pointer to last pixel in line
7672 for i := 0 to Header.Width-1 do begin //for all pixels in line
7673 for j := 0 to PixelSize-1 do begin //for all bytes in pixel
7678 dec(tmp2, 2*PixelSize); //move 2 backwards, because j-loop moved 1 forward
7681 aStream.Read(tmp1^, LineSize);
7682 inc(Counter.Y.low, Counter.Y.dir); //move to next line index
7685 if Assigned(buf) then
7690 ////////////////////////////////////////////////////////////////////////////////////////
7691 procedure ReadCompressed;
7693 /////////////////////////////////////////////////////////////////
7695 TmpData: System.PByte;
7696 LinePixelsRead: Integer;
7697 procedure CheckLine;
7699 if (LinePixelsRead >= Header.Width) then begin
7700 LinePixelsRead := 0;
7701 inc(Counter.Y.low, Counter.Y.dir); //next line index
7702 TmpData := ImageData;
7703 inc(TmpData, Counter.Y.low * LineSize); //set line
7704 if (Counter.X.dir < 0) then //if x flipped then
7705 inc(TmpData, LineSize - PixelSize); //set last pixel
7709 /////////////////////////////////////////////////////////////////
7712 CacheSize, CachePos: Integer;
7713 procedure CachedRead(out Buffer; Count: Integer);
7717 if (CachePos + Count > CacheSize) then begin
7718 //if buffer overflow save non read bytes
7720 if (CacheSize - CachePos > 0) then begin
7721 BytesRead := CacheSize - CachePos;
7722 Move(PByteArray(Cache)^[CachePos], Buffer{%H-}, BytesRead);
7723 inc(CachePos, BytesRead);
7726 //load cache from file
7727 CacheSize := Min(CACHE_SIZE, aStream.Size - aStream.Position);
7728 aStream.Read(Cache^, CacheSize);
7731 //read rest of requested bytes
7732 if (Count - BytesRead > 0) then begin
7733 Move(PByteArray(Cache)^[CachePos], TByteArray(Buffer)[BytesRead], Count - BytesRead);
7734 inc(CachePos, Count - BytesRead);
7737 //if no buffer overflow just read the data
7738 Move(PByteArray(Cache)^[CachePos], Buffer, Count);
7739 inc(CachePos, Count);
7743 procedure PixelToBuffer(const aData: PByte; var aBuffer: PByte);
7748 inc(aBuffer, Counter.X.dir);
7751 PWord(aBuffer)^ := PWord(aData)^;
7752 inc(aBuffer, 2 * Counter.X.dir);
7755 PByteArray(aBuffer)^[0] := PByteArray(aData)^[0];
7756 PByteArray(aBuffer)^[1] := PByteArray(aData)^[1];
7757 PByteArray(aBuffer)^[2] := PByteArray(aData)^[2];
7758 inc(aBuffer, 3 * Counter.X.dir);
7761 PCardinal(aBuffer)^ := PCardinal(aData)^;
7762 inc(aBuffer, 4 * Counter.X.dir);
7768 TotalPixelsToRead, TotalPixelsRead: Integer;
7770 buf: array [0..3] of Byte; //1 pixel is max 32bit long
7771 PixelRepeat: Boolean;
7772 PixelsToRead, PixelCount: Integer;
7777 TotalPixelsToRead := Header.Width * Header.Height;
7778 TotalPixelsRead := 0;
7779 LinePixelsRead := 0;
7781 GetMem(Cache, CACHE_SIZE);
7783 TmpData := ImageData;
7784 inc(TmpData, Counter.Y.low * LineSize); //set line
7785 if (Counter.X.dir < 0) then //if x flipped then
7786 inc(TmpData, LineSize - PixelSize); //set last pixel
7790 CachedRead(Temp, 1);
7791 PixelRepeat := (Temp and $80) > 0;
7792 PixelsToRead := (Temp and $7F) + 1;
7793 inc(TotalPixelsRead, PixelsToRead);
7796 CachedRead(buf[0], PixelSize);
7797 while (PixelsToRead > 0) do begin
7799 PixelCount := Min(Header.Width - LinePixelsRead, PixelsToRead); //max read to EOL or EOF
7800 while (PixelCount > 0) do begin
7801 if not PixelRepeat then
7802 CachedRead(buf[0], PixelSize);
7803 PixelToBuffer(@buf[0], TmpData);
7804 inc(LinePixelsRead);
7809 until (TotalPixelsRead >= TotalPixelsToRead);
7815 function IsGrayFormat: Boolean;
7817 result := Header.ImageType in [TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_GRAY];
7823 // reading header to test file and set cursor back to begin
7824 StartPosition := aStream.Position;
7825 aStream.Read(Header{%H-}, SizeOf(Header));
7827 // no colormapped files
7828 if (Header.ColorMapType = TGA_NONE_COLOR_TABLE) and (Header.ImageType in [
7829 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY]) then
7832 if Header.ImageID <> 0 then // skip image ID
7833 aStream.Position := aStream.Position + Header.ImageID;
7835 tgaFormat := tfEmpty;
7837 8: if IsGrayFormat then case (Header.ImageDesc and $F) of
7838 0: tgaFormat := tfLuminance8;
7839 8: tgaFormat := tfAlpha8;
7842 16: if IsGrayFormat then case (Header.ImageDesc and $F) of
7843 0: tgaFormat := tfLuminance16;
7844 8: tgaFormat := tfLuminance8Alpha8;
7845 end else case (Header.ImageDesc and $F) of
7846 0: tgaFormat := tfX1RGB5;
7847 1: tgaFormat := tfA1RGB5;
7848 4: tgaFormat := tfARGB4;
7851 24: if not IsGrayFormat then case (Header.ImageDesc and $F) of
7852 0: tgaFormat := tfRGB8;
7855 32: if not IsGrayFormat then case (Header.ImageDesc and $F) of
7856 2: tgaFormat := tfA2RGB10;
7857 8: tgaFormat := tfARGB8;
7861 if (tgaFormat = tfEmpty) then
7862 raise EglBitmap.Create('LoadTga - unsupported format');
7864 FormatDesc := TFormatDescriptor.Get(tgaFormat);
7865 PixelSize := FormatDesc.GetSize(1, 1);
7866 LineSize := FormatDesc.GetSize(Header.Width, 1);
7868 GetMem(ImageData, LineSize * Header.Height);
7871 if ((Header.ImageDesc and (1 shl 4)) > 0) then begin
7872 Counter.X.low := Header.Height-1;;
7873 Counter.X.high := 0;
7874 Counter.X.dir := -1;
7877 Counter.X.high := Header.Height-1;
7882 if ((Header.ImageDesc and (1 shl 5)) > 0) then begin
7884 Counter.Y.high := Header.Height-1;
7887 Counter.Y.low := Header.Height-1;;
7888 Counter.Y.high := 0;
7889 Counter.Y.dir := -1;
7893 case Header.ImageType of
7894 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY:
7896 TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY:
7900 SetDataPointer(ImageData, tgaFormat, Header.Width, Header.Height); //be careful, Data could be freed by this method
7903 if Assigned(ImageData) then
7908 aStream.Position := StartPosition;
7911 else aStream.Position := StartPosition;
7914 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7915 procedure TglBitmap.SaveTGA(const aStream: TStream);
7918 LineSize, Size, x, y: Integer;
7919 Pixel: TglBitmapPixelData;
7920 LineBuf, SourceData, DestData: PByte;
7921 SourceMD, DestMD: Pointer;
7922 FormatDesc: TFormatDescriptor;
7923 Converter: TFormatDescriptor;
7925 if not (ftTGA in FormatGetSupportedFiles(Format)) then
7926 raise EglBitmapUnsupportedFormat.Create(Format);
7929 FillChar(Header{%H-}, SizeOf(Header), 0);
7932 if (Format in [tfLuminance8, tfLuminance6Alpha2, tfLuminance4Alpha4, tfAlpha8,
7933 tfLuminance16, tfLuminance12Alpha4, tfLuminance8Alpha8]) then
7934 Header.ImageType := TGA_UNCOMPRESSED_GRAY
7936 Header.ImageType := TGA_UNCOMPRESSED_RGB;
7939 if (Format in [tfLuminance8, tfLuminance6Alpha2, tfLuminance4Alpha4, tfAlpha8]) then
7941 else if (Format in [tfLuminance16, tfLuminance12Alpha4, tfLuminance8Alpha8,
7942 tfRGB5X1, tfBGR5X1, tfRGB5A1, tfBGR5A1, tfRGBA4, tfBGRA4]) then
7944 else if (Format in [tfBGR8, tfRGB8]) then
7952 Header.ImageDesc := 1 and $F;
7953 tfRGB10A2, tfBGR10A2:
7954 Header.ImageDesc := 2 and $F;
7956 Header.ImageDesc := 4 and $F;
7957 tfAlpha8, tfLuminance8Alpha8, tfRGBA8, tfBGRA8:
7958 Header.ImageDesc := 8 and $F;
7961 Header.Width := Width;
7962 Header.Height := Height;
7963 Header.ImageDesc := Header.ImageDesc or $20; //flip y
7964 aStream.Write(Header, SizeOf(Header));
7966 // convert RGB(A) to BGR(A)
7968 FormatDesc := TFormatDescriptor.Get(Format);
7969 Size := FormatDesc.GetSize(Dimension);
7970 if Format in [tfRGB5X1, tfRGB5A1, tfRGBA4, tfRGB8, tfRGB10A2, tfRGBA8] then begin
7971 if (FormatDesc.RGBInverted = tfEmpty) then
7972 raise EglBitmap.Create('inverted RGB format is empty');
7973 Converter := TFormatDescriptor.Get(FormatDesc.RGBInverted);
7974 if not glBitmapColorRecCmp(Converter.Range, FormatDesc.Range) or
7975 (Converter.PixelSize <> FormatDesc.PixelSize) then
7976 raise EglBitmap.Create('invalid inverted RGB format');
7979 if Assigned(Converter) then begin
7980 LineSize := FormatDesc.GetSize(Width, 1);
7981 GetMem(LineBuf, LineSize);
7982 SourceMD := FormatDesc.CreateMappingData;
7983 DestMD := Converter.CreateMappingData;
7986 for y := 0 to Height-1 do begin
7987 DestData := LineBuf;
7988 for x := 0 to Width-1 do begin
7989 FormatDesc.Unmap(SourceData, Pixel, SourceMD);
7990 Converter.Map(Pixel, DestData, DestMD);
7992 aStream.Write(LineBuf^, LineSize);
7996 FormatDesc.FreeMappingData(SourceMD);
7997 FormatDesc.FreeMappingData(DestMD);
8000 aStream.Write(Data^, Size);
8003 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8004 //DDS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8005 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8007 DDS_MAGIC: Cardinal = $20534444;
8009 // DDS_header.dwFlags
8010 DDSD_CAPS = $00000001;
8011 DDSD_HEIGHT = $00000002;
8012 DDSD_WIDTH = $00000004;
8013 DDSD_PIXELFORMAT = $00001000;
8015 // DDS_header.sPixelFormat.dwFlags
8016 DDPF_ALPHAPIXELS = $00000001;
8017 DDPF_ALPHA = $00000002;
8018 DDPF_FOURCC = $00000004;
8019 DDPF_RGB = $00000040;
8020 DDPF_LUMINANCE = $00020000;
8022 // DDS_header.sCaps.dwCaps1
8023 DDSCAPS_TEXTURE = $00001000;
8025 // DDS_header.sCaps.dwCaps2
8026 DDSCAPS2_CUBEMAP = $00000200;
8028 D3DFMT_DXT1 = $31545844;
8029 D3DFMT_DXT3 = $33545844;
8030 D3DFMT_DXT5 = $35545844;
8033 TDDSPixelFormat = packed record
8037 dwRGBBitCount: Cardinal;
8038 dwRBitMask: Cardinal;
8039 dwGBitMask: Cardinal;
8040 dwBBitMask: Cardinal;
8041 dwABitMask: Cardinal;
8044 TDDSCaps = packed record
8048 dwReserved: Cardinal;
8051 TDDSHeader = packed record
8056 dwPitchOrLinearSize: Cardinal;
8058 dwMipMapCount: Cardinal;
8059 dwReserved: array[0..10] of Cardinal;
8060 PixelFormat: TDDSPixelFormat;
8062 dwReserved2: Cardinal;
8065 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8066 function TglBitmap.LoadDDS(const aStream: TStream): Boolean;
8069 Converter: TbmpBitfieldFormat;
8071 function GetDDSFormat: TglBitmapFormat;
8073 fd: TFormatDescriptor;
8075 Range: TglBitmapColorRec;
8079 with Header.PixelFormat do begin
8081 if ((dwFlags and DDPF_FOURCC) > 0) then begin
8082 case Header.PixelFormat.dwFourCC of
8083 D3DFMT_DXT1: result := tfS3tcDtx1RGBA;
8084 D3DFMT_DXT3: result := tfS3tcDtx3RGBA;
8085 D3DFMT_DXT5: result := tfS3tcDtx5RGBA;
8087 end else if ((dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE)) > 0) then begin
8089 if ((dwFlags and DDPF_LUMINANCE) = 0) then begin
8090 Range.r := dwRBitMask;
8091 Range.g := dwGBitMask;
8092 Range.b := dwBBitMask;
8094 Range.r := dwRBitMask;
8095 Range.g := dwRBitMask;
8096 Range.b := dwRBitMask;
8098 Range.a := dwABitMask;
8100 //find matching format
8101 for result := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
8102 fd := TFormatDescriptor.Get(result);
8103 if fd.MaskMatch(Range.r, Range.g, Range.b, Range.a) and
8104 (8 * fd.PixelSize = dwRGBBitCount) then
8108 //find format with same Range
8109 for i := 0 to 3 do begin
8110 while ((Range.arr[i] and 1) = 0) and (Range.arr[i] > 0) do
8111 Range.arr[i] := Range.arr[i] shr 1;
8113 for result := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
8114 fd := TFormatDescriptor.Get(result);
8117 if (fd.Range.arr[i] <> Range.arr[i]) then begin
8125 //no format with same range found -> use default
8126 if (result = tfEmpty) then begin
8127 if (dwABitMask > 0) then
8133 Converter := TbmpBitfieldFormat.Create;
8134 Converter.RedMask := dwRBitMask;
8135 Converter.GreenMask := dwGBitMask;
8136 Converter.BlueMask := dwBBitMask;
8137 Converter.AlphaMask := dwABitMask;
8138 Converter.PixelSize := dwRGBBitCount / 8;
8145 x, y, LineSize, RowSize, Magic: Cardinal;
8146 NewImage, TmpData, RowData, SrcData: System.PByte;
8147 SourceMD, DestMD: Pointer;
8148 Pixel: TglBitmapPixelData;
8149 ddsFormat: TglBitmapFormat;
8150 FormatDesc: TFormatDescriptor;
8155 StreamPos := aStream.Position;
8158 aStream.Read(Magic{%H-}, sizeof(Magic));
8159 if (Magic <> DDS_MAGIC) then begin
8160 aStream.Position := StreamPos;
8165 aStream.Read(Header{%H-}, sizeof(Header));
8166 if (Header.dwSize <> SizeOf(Header)) or
8167 ((Header.dwFlags and (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) <>
8168 (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) then
8170 aStream.Position := StreamPos;
8174 if ((Header.Caps.dwCaps1 and DDSCAPS2_CUBEMAP) > 0) then
8175 raise EglBitmap.Create('LoadDDS - CubeMaps are not supported');
8177 ddsFormat := GetDDSFormat;
8179 if (ddsFormat = tfEmpty) then
8180 raise EglBitmap.Create('LoadDDS - unsupported Pixelformat found.');
8182 FormatDesc := TFormatDescriptor.Get(ddsFormat);
8183 LineSize := Trunc(Header.dwWidth * FormatDesc.PixelSize);
8184 GetMem(NewImage, Header.dwHeight * LineSize);
8186 TmpData := NewImage;
8189 if Assigned(Converter) then begin
8190 RowSize := Round(Header.dwWidth * Header.PixelFormat.dwRGBBitCount / 8);
8191 GetMem(RowData, RowSize);
8192 SourceMD := Converter.CreateMappingData;
8193 DestMD := FormatDesc.CreateMappingData;
8195 for y := 0 to Header.dwHeight-1 do begin
8196 TmpData := NewImage;
8197 inc(TmpData, y * LineSize);
8199 aStream.Read(SrcData^, RowSize);
8200 for x := 0 to Header.dwWidth-1 do begin
8201 Converter.Unmap(SrcData, Pixel, SourceMD);
8202 glBitmapConvertPixel(Pixel, Converter, FormatDesc);
8203 FormatDesc.Map(Pixel, TmpData, DestMD);
8207 Converter.FreeMappingData(SourceMD);
8208 FormatDesc.FreeMappingData(DestMD);
8214 if ((Header.PixelFormat.dwFlags and DDPF_FOURCC) > 0) then begin
8215 RowSize := Header.dwPitchOrLinearSize div Header.dwWidth;
8216 for Y := 0 to Header.dwHeight-1 do begin
8217 aStream.Read(TmpData^, RowSize);
8218 Inc(TmpData, LineSize);
8223 if (Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE)) > 0 then begin
8224 RowSize := (Header.PixelFormat.dwRGBBitCount * Header.dwWidth) shr 3;
8225 for Y := 0 to Header.dwHeight-1 do begin
8226 aStream.Read(TmpData^, RowSize);
8227 Inc(TmpData, LineSize);
8230 raise EglBitmap.Create('LoadDDS - unsupported Pixelformat found.');
8232 SetDataPointer(NewImage, ddsFormat, Header.dwWidth, Header.dwHeight); //be careful, Data could be freed by this method
8235 if Assigned(NewImage) then
8240 FreeAndNil(Converter);
8244 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8245 procedure TglBitmap.SaveDDS(const aStream: TStream);
8248 FormatDesc: TFormatDescriptor;
8250 if not (ftDDS in FormatGetSupportedFiles(Format)) then
8251 raise EglBitmapUnsupportedFormat.Create(Format);
8253 FormatDesc := TFormatDescriptor.Get(Format);
8256 FillChar(Header{%H-}, SizeOf(Header), 0);
8257 Header.dwSize := SizeOf(Header);
8258 Header.dwFlags := DDSD_WIDTH or DDSD_HEIGHT or DDSD_CAPS or DDSD_PIXELFORMAT;
8260 Header.dwWidth := Max(1, Width);
8261 Header.dwHeight := Max(1, Height);
8264 Header.Caps.dwCaps1 := DDSCAPS_TEXTURE;
8267 Header.PixelFormat.dwSize := sizeof(Header);
8268 if (FormatDesc.IsCompressed) then begin
8269 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_FOURCC;
8271 tfS3tcDtx1RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT1;
8272 tfS3tcDtx3RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT3;
8273 tfS3tcDtx5RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT5;
8275 end else if (Format in [tfAlpha8, tfAlpha16]) then begin
8276 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHA;
8277 Header.PixelFormat.dwRGBBitCount := Round(FormatDesc.PixelSize * 8);
8278 Header.PixelFormat.dwABitMask := FormatDesc.AlphaMask;
8279 end else if (FormatDesc.RedMask = FormatDesc.GreenMask) and (FormatDesc.GreenMask = FormatDesc.BlueMask) then begin
8280 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_LUMINANCE;
8281 Header.PixelFormat.dwRGBBitCount := Round(FormatDesc.PixelSize * 8);
8282 Header.PixelFormat.dwRBitMask := FormatDesc.RedMask;
8283 Header.PixelFormat.dwABitMask := FormatDesc.AlphaMask;
8285 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_RGB;
8286 Header.PixelFormat.dwRGBBitCount := Round(FormatDesc.PixelSize * 8);
8287 Header.PixelFormat.dwRBitMask := FormatDesc.RedMask;
8288 Header.PixelFormat.dwGBitMask := FormatDesc.GreenMask;
8289 Header.PixelFormat.dwBBitMask := FormatDesc.BlueMask;
8290 Header.PixelFormat.dwABitMask := FormatDesc.AlphaMask;
8293 if (FormatDesc.HasAlpha) then
8294 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHAPIXELS;
8296 aStream.Write(DDS_MAGIC, sizeof(DDS_MAGIC));
8297 aStream.Write(Header, SizeOf(Header));
8298 aStream.Write(Data^, FormatDesc.GetSize(Dimension));
8301 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8302 //TglBitmap1D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8303 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8304 procedure TglBitmap1D.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
8305 const aWidth: Integer; const aHeight: Integer);
8310 if (aHeight > 1) then begin
8311 Size := TFormatDescriptor.Get(aFormat).GetSize(aWidth, 1);
8312 GetMem(pTemp, Size);
8314 Move(aData^, pTemp^, Size);
8323 inherited SetDataPointer(pTemp, aFormat, aWidth);
8326 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8327 function TglBitmap1D.FlipHorz: Boolean;
8330 pTempDest, pDest, pSource: PByte;
8332 result := inherited FlipHorz;
8333 if Assigned(Data) and not TFormatDescriptor.Get(Format).IsCompressed then begin
8335 GetMem(pDest, fRowSize);
8338 Inc(pTempDest, fRowSize);
8339 for Col := 0 to Width-1 do begin
8340 dec(pTempDest, fPixelSize); //dec before, because ptr is behind last byte of data
8341 Move(pSource^, pTempDest^, fPixelSize);
8342 Inc(pSource, fPixelSize);
8344 SetDataPointer(pDest, Format, Width); //be careful, Data could be freed by this method
8347 if Assigned(pDest) then
8354 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8355 procedure TglBitmap1D.UploadData(const aBuildWithGlu: Boolean);
8357 FormatDesc: TFormatDescriptor;
8360 FormatDesc := TFormatDescriptor.Get(Format);
8361 if FormatDesc.IsCompressed then begin
8362 if not Assigned(glCompressedTexImage1D) then
8363 raise EglBitmap.Create('compressed formats not supported by video adapter');
8364 glCompressedTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.GetSize(Width, 1), Data)
8365 end else if aBuildWithGlu then
8366 gluBuild1DMipmaps(Target, FormatDesc.glInternalFormat, Width, FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
8368 glTexImage1D(Target, 0, FormatDesc.glInternalFormat, Width, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
8371 if (FreeDataAfterGenTexture) then
8375 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8376 procedure TglBitmap1D.GenTexture(const aTestTextureSize: Boolean);
8378 BuildWithGlu, TexRec: Boolean;
8381 if Assigned(Data) then begin
8382 // Check Texture Size
8383 if (aTestTextureSize) then begin
8384 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
8386 if (Width > TexSize) then
8387 raise EglBitmapSizeToLarge.Create('TglBitmap1D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
8389 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and
8390 (Target = GL_TEXTURE_RECTANGLE);
8391 if not (IsPowerOfTwo(Width) or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
8392 raise EglBitmapNonPowerOfTwo.Create('TglBitmap1D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8396 SetupParameters(BuildWithGlu);
8397 UploadData(BuildWithGlu);
8398 glAreTexturesResident(1, @fID, @fIsResident);
8402 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8403 procedure TglBitmap1D.AfterConstruction;
8406 Target := GL_TEXTURE_1D;
8409 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8410 //TglBitmap2D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8411 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8412 function TglBitmap2D.GetScanline(const aIndex: Integer): Pointer;
8414 if (aIndex >= Low(fLines)) and (aIndex <= High(fLines)) then
8415 result := fLines[aIndex]
8420 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8421 procedure TglBitmap2D.SetDataPointer(var aData: PByte; const aFormat: TglBitmapFormat;
8422 const aWidth: Integer; const aHeight: Integer);
8424 Idx, LineWidth: Integer;
8426 inherited SetDataPointer(aData, aFormat, aWidth, aHeight);
8428 if not TFormatDescriptor.Get(aFormat).IsCompressed then begin
8430 if Assigned(Data) then begin
8431 SetLength(fLines, GetHeight);
8432 LineWidth := Trunc(GetWidth * TFormatDescriptor.Get(Format).PixelSize);
8434 for Idx := 0 to GetHeight-1 do begin
8435 fLines[Idx] := Data;
8436 Inc(fLines[Idx], Idx * LineWidth);
8439 else SetLength(fLines, 0);
8441 SetLength(fLines, 0);
8445 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8446 procedure TglBitmap2D.UploadData(const aTarget: GLenum; const aBuildWithGlu: Boolean);
8448 FormatDesc: TFormatDescriptor;
8450 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
8452 FormatDesc := TFormatDescriptor.Get(Format);
8453 if FormatDesc.IsCompressed then begin
8454 if not Assigned(glCompressedTexImage2D) then
8455 raise EglBitmap.Create('compressed formats not supported by video adapter');
8456 glCompressedTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0, FormatDesc.GetSize(fDimension), Data)
8457 end else if aBuildWithGlu then begin
8458 gluBuild2DMipmaps(aTarget, FormatDesc.Components, Width, Height,
8459 FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
8461 glTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0,
8462 FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
8466 if (FreeDataAfterGenTexture) then
8470 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8471 procedure TglBitmap2D.AfterConstruction;
8474 Target := GL_TEXTURE_2D;
8477 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8478 procedure TglBitmap2D.GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
8481 Size, w, h: Integer;
8482 FormatDesc: TFormatDescriptor;
8484 FormatDesc := TFormatDescriptor.Get(aFormat);
8485 if FormatDesc.IsCompressed then
8486 raise EglBitmapUnsupportedFormat.Create(aFormat);
8488 w := aRight - aLeft;
8489 h := aBottom - aTop;
8490 Size := FormatDesc.GetSize(w, h);
8493 glPixelStorei(GL_PACK_ALIGNMENT, 1);
8494 glReadPixels(aLeft, aTop, w, h, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
8495 SetDataPointer(Temp, aFormat, w, h); //be careful, Data could be freed by this method
8498 if Assigned(Temp) then
8504 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8505 procedure TglBitmap2D.GetDataFromTexture;
8508 TempWidth, TempHeight: Integer;
8509 TempIntFormat: GLint;
8510 IntFormat: TglBitmapFormat;
8511 FormatDesc: TFormatDescriptor;
8516 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_WIDTH, @TempWidth);
8517 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT, @TempHeight);
8518 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat);
8520 IntFormat := tfEmpty;
8521 FormatDesc := (TglBitmapFormatDescriptor.GetByFormat(TempIntFormat) as TFormatDescriptor);
8522 IntFormat := FormatDesc.Format;
8524 // Getting data from OpenGL
8525 FormatDesc := TFormatDescriptor.Get(IntFormat);
8526 GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight));
8528 if FormatDesc.IsCompressed then begin
8529 if not Assigned(glGetCompressedTexImage) then
8530 raise EglBitmap.Create('compressed formats not supported by video adapter');
8531 glGetCompressedTexImage(Target, 0, Temp)
8533 glGetTexImage(Target, 0, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
8534 SetDataPointer(Temp, IntFormat, TempWidth, TempHeight); //be careful, Data could be freed by this method
8536 if Assigned(Temp) then
8542 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8543 procedure TglBitmap2D.GenTexture(const aTestTextureSize: Boolean);
8545 BuildWithGlu, PotTex, TexRec: Boolean;
8548 if Assigned(Data) then begin
8549 // Check Texture Size
8550 if (aTestTextureSize) then begin
8551 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
8553 if ((Height > TexSize) or (Width > TexSize)) then
8554 raise EglBitmapSizeToLarge.Create('TglBitmap2D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
8556 PotTex := IsPowerOfTwo(Height) and IsPowerOfTwo(Width);
8557 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and (Target = GL_TEXTURE_RECTANGLE);
8558 if not (PotTex or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
8559 raise EglBitmapNonPowerOfTwo.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8563 SetupParameters(BuildWithGlu);
8564 UploadData(Target, BuildWithGlu);
8565 glAreTexturesResident(1, @fID, @fIsResident);
8569 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8570 function TglBitmap2D.FlipHorz: Boolean;
8573 TempDestData, DestData, SourceData: PByte;
8576 result := inherited FlipHorz;
8577 if Assigned(Data) then begin
8579 ImgSize := Height * fRowSize;
8580 GetMem(DestData, ImgSize);
8582 TempDestData := DestData;
8583 Dec(TempDestData, fRowSize + fPixelSize);
8584 for Row := 0 to Height -1 do begin
8585 Inc(TempDestData, fRowSize * 2);
8586 for Col := 0 to Width -1 do begin
8587 Move(SourceData^, TempDestData^, fPixelSize);
8588 Inc(SourceData, fPixelSize);
8589 Dec(TempDestData, fPixelSize);
8592 SetDataPointer(DestData, Format, Width, Height); //be careful, Data could be freed by this method
8595 if Assigned(DestData) then
8602 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8603 function TglBitmap2D.FlipVert: Boolean;
8606 TempDestData, DestData, SourceData: PByte;
8608 result := inherited FlipVert;
8609 if Assigned(Data) then begin
8611 GetMem(DestData, Height * fRowSize);
8613 TempDestData := DestData;
8614 Inc(TempDestData, Width * (Height -1) * fPixelSize);
8615 for Row := 0 to Height -1 do begin
8616 Move(SourceData^, TempDestData^, fRowSize);
8617 Dec(TempDestData, fRowSize);
8618 Inc(SourceData, fRowSize);
8620 SetDataPointer(DestData, Format, Width, Height); //be careful, Data could be freed by this method
8623 if Assigned(DestData) then
8630 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8631 //TglBitmap2D - ToNormalMap///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8632 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8634 TMatrixItem = record
8639 PglBitmapToNormalMapRec = ^TglBitmapToNormalMapRec;
8640 TglBitmapToNormalMapRec = Record
8642 Heights: array of Single;
8643 MatrixU : array of TMatrixItem;
8644 MatrixV : array of TMatrixItem;
8648 ONE_OVER_255 = 1 / 255;
8650 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8651 procedure glBitmapToNormalMapPrepareFunc(var FuncRec: TglBitmapFunctionRec);
8655 with FuncRec do begin
8657 Source.Data.r * LUMINANCE_WEIGHT_R +
8658 Source.Data.g * LUMINANCE_WEIGHT_G +
8659 Source.Data.b * LUMINANCE_WEIGHT_B;
8660 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Val * ONE_OVER_255;
8664 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8665 procedure glBitmapToNormalMapPrepareAlphaFunc(var FuncRec: TglBitmapFunctionRec);
8668 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Source.Data.a * ONE_OVER_255;
8671 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8672 procedure glBitmapToNormalMapFunc (var FuncRec: TglBitmapFunctionRec);
8674 TVec = Array[0..2] of Single;
8681 function GetHeight(X, Y: Integer): Single;
8683 with FuncRec do begin
8684 X := Max(0, Min(Size.X -1, X));
8685 Y := Max(0, Min(Size.Y -1, Y));
8686 result := PglBitmapToNormalMapRec(Args)^.Heights[Y * Size.X + X];
8691 with FuncRec do begin
8692 with PglBitmapToNormalMapRec(Args)^ do begin
8694 for Idx := Low(MatrixU) to High(MatrixU) do
8695 du := du + GetHeight(Position.X + MatrixU[Idx].X, Position.Y + MatrixU[Idx].Y) * MatrixU[Idx].W;
8698 for Idx := Low(MatrixU) to High(MatrixU) do
8699 dv := dv + GetHeight(Position.X + MatrixV[Idx].X, Position.Y + MatrixV[Idx].Y) * MatrixV[Idx].W;
8701 Vec[0] := -du * Scale;
8702 Vec[1] := -dv * Scale;
8707 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
8708 if Len <> 0 then begin
8709 Vec[0] := Vec[0] * Len;
8710 Vec[1] := Vec[1] * Len;
8711 Vec[2] := Vec[2] * Len;
8715 Dest.Data.r := Trunc((Vec[0] + 1) * 127.5);
8716 Dest.Data.g := Trunc((Vec[1] + 1) * 127.5);
8717 Dest.Data.b := Trunc((Vec[2] + 1) * 127.5);
8721 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8722 procedure TglBitmap2D.ToNormalMap(const aFunc: TglBitmapNormalMapFunc; const aScale: Single; const aUseAlpha: Boolean);
8724 Rec: TglBitmapToNormalMapRec;
8726 procedure SetEntry (var Matrix: array of TMatrixItem; Index, X, Y: Integer; W: Single);
8728 if (Index >= Low(Matrix)) and (Index <= High(Matrix)) then begin
8729 Matrix[Index].X := X;
8730 Matrix[Index].Y := Y;
8731 Matrix[Index].W := W;
8736 if TFormatDescriptor.Get(Format).IsCompressed then
8737 raise EglBitmapUnsupportedFormat.Create(Format);
8739 if aScale > 100 then
8741 else if aScale < -100 then
8744 Rec.Scale := aScale;
8746 SetLength(Rec.Heights, Width * Height);
8750 SetLength(Rec.MatrixU, 2);
8751 SetEntry(Rec.MatrixU, 0, -1, 0, -0.5);
8752 SetEntry(Rec.MatrixU, 1, 1, 0, 0.5);
8754 SetLength(Rec.MatrixV, 2);
8755 SetEntry(Rec.MatrixV, 0, 0, 1, 0.5);
8756 SetEntry(Rec.MatrixV, 1, 0, -1, -0.5);
8760 SetLength(Rec.MatrixU, 6);
8761 SetEntry(Rec.MatrixU, 0, -1, 1, -1.0);
8762 SetEntry(Rec.MatrixU, 1, -1, 0, -2.0);
8763 SetEntry(Rec.MatrixU, 2, -1, -1, -1.0);
8764 SetEntry(Rec.MatrixU, 3, 1, 1, 1.0);
8765 SetEntry(Rec.MatrixU, 4, 1, 0, 2.0);
8766 SetEntry(Rec.MatrixU, 5, 1, -1, 1.0);
8768 SetLength(Rec.MatrixV, 6);
8769 SetEntry(Rec.MatrixV, 0, -1, 1, 1.0);
8770 SetEntry(Rec.MatrixV, 1, 0, 1, 2.0);
8771 SetEntry(Rec.MatrixV, 2, 1, 1, 1.0);
8772 SetEntry(Rec.MatrixV, 3, -1, -1, -1.0);
8773 SetEntry(Rec.MatrixV, 4, 0, -1, -2.0);
8774 SetEntry(Rec.MatrixV, 5, 1, -1, -1.0);
8778 SetLength(Rec.MatrixU, 6);
8779 SetEntry(Rec.MatrixU, 0, -1, 1, -1/6);
8780 SetEntry(Rec.MatrixU, 1, -1, 0, -1/6);
8781 SetEntry(Rec.MatrixU, 2, -1, -1, -1/6);
8782 SetEntry(Rec.MatrixU, 3, 1, 1, 1/6);
8783 SetEntry(Rec.MatrixU, 4, 1, 0, 1/6);
8784 SetEntry(Rec.MatrixU, 5, 1, -1, 1/6);
8786 SetLength(Rec.MatrixV, 6);
8787 SetEntry(Rec.MatrixV, 0, -1, 1, 1/6);
8788 SetEntry(Rec.MatrixV, 1, 0, 1, 1/6);
8789 SetEntry(Rec.MatrixV, 2, 1, 1, 1/6);
8790 SetEntry(Rec.MatrixV, 3, -1, -1, -1/6);
8791 SetEntry(Rec.MatrixV, 4, 0, -1, -1/6);
8792 SetEntry(Rec.MatrixV, 5, 1, -1, -1/6);
8796 SetLength(Rec.MatrixU, 20);
8797 SetEntry(Rec.MatrixU, 0, -2, 2, -1 / 16);
8798 SetEntry(Rec.MatrixU, 1, -1, 2, -1 / 10);
8799 SetEntry(Rec.MatrixU, 2, 1, 2, 1 / 10);
8800 SetEntry(Rec.MatrixU, 3, 2, 2, 1 / 16);
8801 SetEntry(Rec.MatrixU, 4, -2, 1, -1 / 10);
8802 SetEntry(Rec.MatrixU, 5, -1, 1, -1 / 8);
8803 SetEntry(Rec.MatrixU, 6, 1, 1, 1 / 8);
8804 SetEntry(Rec.MatrixU, 7, 2, 1, 1 / 10);
8805 SetEntry(Rec.MatrixU, 8, -2, 0, -1 / 2.8);
8806 SetEntry(Rec.MatrixU, 9, -1, 0, -0.5);
8807 SetEntry(Rec.MatrixU, 10, 1, 0, 0.5);
8808 SetEntry(Rec.MatrixU, 11, 2, 0, 1 / 2.8);
8809 SetEntry(Rec.MatrixU, 12, -2, -1, -1 / 10);
8810 SetEntry(Rec.MatrixU, 13, -1, -1, -1 / 8);
8811 SetEntry(Rec.MatrixU, 14, 1, -1, 1 / 8);
8812 SetEntry(Rec.MatrixU, 15, 2, -1, 1 / 10);
8813 SetEntry(Rec.MatrixU, 16, -2, -2, -1 / 16);
8814 SetEntry(Rec.MatrixU, 17, -1, -2, -1 / 10);
8815 SetEntry(Rec.MatrixU, 18, 1, -2, 1 / 10);
8816 SetEntry(Rec.MatrixU, 19, 2, -2, 1 / 16);
8818 SetLength(Rec.MatrixV, 20);
8819 SetEntry(Rec.MatrixV, 0, -2, 2, 1 / 16);
8820 SetEntry(Rec.MatrixV, 1, -1, 2, 1 / 10);
8821 SetEntry(Rec.MatrixV, 2, 0, 2, 0.25);
8822 SetEntry(Rec.MatrixV, 3, 1, 2, 1 / 10);
8823 SetEntry(Rec.MatrixV, 4, 2, 2, 1 / 16);
8824 SetEntry(Rec.MatrixV, 5, -2, 1, 1 / 10);
8825 SetEntry(Rec.MatrixV, 6, -1, 1, 1 / 8);
8826 SetEntry(Rec.MatrixV, 7, 0, 1, 0.5);
8827 SetEntry(Rec.MatrixV, 8, 1, 1, 1 / 8);
8828 SetEntry(Rec.MatrixV, 9, 2, 1, 1 / 16);
8829 SetEntry(Rec.MatrixV, 10, -2, -1, -1 / 16);
8830 SetEntry(Rec.MatrixV, 11, -1, -1, -1 / 8);
8831 SetEntry(Rec.MatrixV, 12, 0, -1, -0.5);
8832 SetEntry(Rec.MatrixV, 13, 1, -1, -1 / 8);
8833 SetEntry(Rec.MatrixV, 14, 2, -1, -1 / 10);
8834 SetEntry(Rec.MatrixV, 15, -2, -2, -1 / 16);
8835 SetEntry(Rec.MatrixV, 16, -1, -2, -1 / 10);
8836 SetEntry(Rec.MatrixV, 17, 0, -2, -0.25);
8837 SetEntry(Rec.MatrixV, 18, 1, -2, -1 / 10);
8838 SetEntry(Rec.MatrixV, 19, 2, -2, -1 / 16);
8843 if aUseAlpha and TFormatDescriptor.Get(Format).HasAlpha then
8844 AddFunc(glBitmapToNormalMapPrepareAlphaFunc, false, @Rec)
8846 AddFunc(glBitmapToNormalMapPrepareFunc, false, @Rec);
8847 AddFunc(glBitmapToNormalMapFunc, false, @Rec);
8849 SetLength(Rec.Heights, 0);
8853 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8854 //TglBitmapCubeMap////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8855 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8856 procedure TglBitmapCubeMap.GenTexture(const aTestTextureSize: Boolean);
8858 Assert(false, 'TglBitmapCubeMap.GenTexture - Don''t call GenTextures directly.');
8861 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8862 procedure TglBitmapCubeMap.AfterConstruction;
8866 if not (GL_VERSION_1_3 or GL_ARB_texture_cube_map or GL_EXT_texture_cube_map) then
8867 raise EglBitmap.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
8870 Target := GL_TEXTURE_CUBE_MAP;
8871 fGenMode := GL_REFLECTION_MAP;
8874 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8875 procedure TglBitmapCubeMap.GenerateCubeMap(const aCubeTarget: Cardinal; const aTestTextureSize: Boolean);
8877 BuildWithGlu: Boolean;
8880 if (aTestTextureSize) then begin
8881 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, @TexSize);
8883 if (Height > TexSize) or (Width > TexSize) then
8884 raise EglBitmapSizeToLarge.Create('TglBitmapCubeMap.GenTexture - The size for the Cubemap is to large. It''s may be not conform with the Hardware.');
8886 if not ((IsPowerOfTwo(Height) and IsPowerOfTwo(Width)) or GL_VERSION_2_0 or GL_ARB_texture_non_power_of_two) then
8887 raise EglBitmapNonPowerOfTwo.Create('TglBitmapCubeMap.GenTexture - Cubemaps dosn''t support non power of two texture.');
8892 SetupParameters(BuildWithGlu);
8893 UploadData(aCubeTarget, BuildWithGlu);
8896 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8897 procedure TglBitmapCubeMap.Bind(const aEnableTexCoordsGen: Boolean; const aEnableTextureUnit: Boolean);
8899 inherited Bind (aEnableTextureUnit);
8900 if aEnableTexCoordsGen then begin
8901 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, fGenMode);
8902 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, fGenMode);
8903 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, fGenMode);
8904 glEnable(GL_TEXTURE_GEN_S);
8905 glEnable(GL_TEXTURE_GEN_T);
8906 glEnable(GL_TEXTURE_GEN_R);
8910 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8911 procedure TglBitmapCubeMap.Unbind(const aDisableTexCoordsGen: Boolean; const aDisableTextureUnit: Boolean);
8913 inherited Unbind(aDisableTextureUnit);
8914 if aDisableTexCoordsGen then begin
8915 glDisable(GL_TEXTURE_GEN_S);
8916 glDisable(GL_TEXTURE_GEN_T);
8917 glDisable(GL_TEXTURE_GEN_R);
8921 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8922 //TglBitmapNormalMap//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8923 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8925 TVec = Array[0..2] of Single;
8926 TglBitmapNormalMapGetVectorFunc = procedure (out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8928 PglBitmapNormalMapRec = ^TglBitmapNormalMapRec;
8929 TglBitmapNormalMapRec = record
8931 Func: TglBitmapNormalMapGetVectorFunc;
8934 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8935 procedure glBitmapNormalMapPosX(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8937 aVec[0] := aHalfSize;
8938 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8939 aVec[2] := - (aPosition.X + 0.5 - aHalfSize);
8942 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8943 procedure glBitmapNormalMapNegX(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8945 aVec[0] := - aHalfSize;
8946 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8947 aVec[2] := aPosition.X + 0.5 - aHalfSize;
8950 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8951 procedure glBitmapNormalMapPosY(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8953 aVec[0] := aPosition.X + 0.5 - aHalfSize;
8954 aVec[1] := aHalfSize;
8955 aVec[2] := aPosition.Y + 0.5 - aHalfSize;
8958 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8959 procedure glBitmapNormalMapNegY(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8961 aVec[0] := aPosition.X + 0.5 - aHalfSize;
8962 aVec[1] := - aHalfSize;
8963 aVec[2] := - (aPosition.Y + 0.5 - aHalfSize);
8966 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8967 procedure glBitmapNormalMapPosZ(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8969 aVec[0] := aPosition.X + 0.5 - aHalfSize;
8970 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8971 aVec[2] := aHalfSize;
8974 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8975 procedure glBitmapNormalMapNegZ(out aVec: TVec; const aPosition: TglBitmapPixelPosition; const aHalfSize: Integer);
8977 aVec[0] := - (aPosition.X + 0.5 - aHalfSize);
8978 aVec[1] := - (aPosition.Y + 0.5 - aHalfSize);
8979 aVec[2] := - aHalfSize;
8982 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8983 procedure glBitmapNormalMapFunc(var FuncRec: TglBitmapFunctionRec);
8989 with FuncRec do begin
8990 with PglBitmapNormalMapRec(Args)^ do begin
8991 Func(Vec, Position, HalfSize);
8994 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
8995 if Len <> 0 then begin
8996 Vec[0] := Vec[0] * Len;
8997 Vec[1] := Vec[1] * Len;
8998 Vec[2] := Vec[2] * Len;
9001 // Scale Vector and AddVectro
9002 Vec[0] := Vec[0] * 0.5 + 0.5;
9003 Vec[1] := Vec[1] * 0.5 + 0.5;
9004 Vec[2] := Vec[2] * 0.5 + 0.5;
9009 Dest.Data.arr[i] := Round(Vec[i] * 255);
9013 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9014 procedure TglBitmapNormalMap.AfterConstruction;
9017 fGenMode := GL_NORMAL_MAP;
9020 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9021 procedure TglBitmapNormalMap.GenerateNormalMap(const aSize: Integer; const aTestTextureSize: Boolean);
9023 Rec: TglBitmapNormalMapRec;
9024 SizeRec: TglBitmapPixelPosition;
9026 Rec.HalfSize := aSize div 2;
9027 FreeDataAfterGenTexture := false;
9029 SizeRec.Fields := [ffX, ffY];
9034 Rec.Func := glBitmapNormalMapPosX;
9035 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8, @Rec);
9036 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X, aTestTextureSize);
9039 Rec.Func := glBitmapNormalMapNegX;
9040 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8, @Rec);
9041 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, aTestTextureSize);
9044 Rec.Func := glBitmapNormalMapPosY;
9045 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8, @Rec);
9046 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, aTestTextureSize);
9049 Rec.Func := glBitmapNormalMapNegY;
9050 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8, @Rec);
9051 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, aTestTextureSize);
9054 Rec.Func := glBitmapNormalMapPosZ;
9055 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8, @Rec);
9056 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, aTestTextureSize);
9059 Rec.Func := glBitmapNormalMapNegZ;
9060 LoadFromFunc(SizeRec, glBitmapNormalMapFunc, tfBGR8, @Rec);
9061 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, aTestTextureSize);
9066 glBitmapSetDefaultFormat (tfEmpty);
9067 glBitmapSetDefaultMipmap (mmMipmap);
9068 glBitmapSetDefaultFilter (GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
9069 glBitmapSetDefaultWrap (GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
9070 glBitmapSetDefaultSwizzle(GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA);
9072 glBitmapSetDefaultFreeDataAfterGenTexture(true);
9073 glBitmapSetDefaultDeleteTextureOnFree (true);
9075 TFormatDescriptor.Init;
9077 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
9078 OpenGLInitialized := false;
9079 InitOpenGLCS := TCriticalSection.Create;
9083 TFormatDescriptor.Finalize;
9085 {$IFDEF GLB_NATIVE_OGL}
9086 if Assigned(GL_LibHandle) then
9087 glbFreeLibrary(GL_LibHandle);
9089 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
9090 if Assigned(GLU_LibHandle) then
9091 glbFreeLibrary(GLU_LibHandle);
9092 FreeAndNil(InitOpenGLCS);