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/)
8 ------------------------------------------------------------
9 The contents of this file are used with permission, subject to
10 the Mozilla Public License Version 1.1 (the "License"); you may
11 not use this file except in compliance with the License. You may
12 obtain a copy of the License at
13 http://www.mozilla.org/MPL/MPL-1.1.html
14 ------------------------------------------------------------
16 ------------------------------------------------------------
19 - The define GLB_DELPHI dosn't check versions anymore. If you say you are using delphi
20 then it's your problem if that isn't true. This prevents the unit for incompatibility
21 with newer versions of Delphi.
22 - Problems with D2009+ resolved (Thanks noeska and all i forgot)
23 - GetPixel isn't set if you are loading textures inside the constructor (Thanks Wilson)
25 - AddAlphaFromglBitmap used the custom pointer instead the imagedatapointer (Thanks Wilson)
26 - Additional Datapointer for functioninterface now has the name CustomData
28 - AssigneAlphaToBitmap overwrites his own palette (Thanks Wilson)
29 - If you load an texture from an file the property Filename will be set to the name of the file
30 - Three new properties to attach custom data to the Texture objects
31 - CustomName (free for use string)
32 - CustomNameW (free for use widestring)
33 - CustomDataPointer (free for use pointer to attach other objects or complex structures)
35 - RLE TGAs loaded much faster
37 - fixed some problem with reading RLE TGAs.
39 - function clone now only copys data if it's assigned and now it also copies the ID
40 - it seems that lazarus dont like comments in comments.
42 - It's possible to set the id of the texture
43 - define GLB_NO_NATIVE_GL deactivated by default
45 - Now supports the following libraries
49 - Linux compatibillity via free pascal compatibility (delphi sources optional)
50 - BMPs now loaded manuel
52 - Property DataPtr now has the name Data
53 - Functions are more flexible between RGB(A) and BGR(A). RGB can be saved as Bitmap and will be saved as BGR
54 - Unused Depth removed
55 - Function FreeData to freeing image data added
57 - ImageID flag of TGAs was ignored. (Thanks Zwoetzen)
59 - Function SetBorderColor implemented (only used by opengl if wrap is set to GL_CLAMP_TO_BORDER)
60 - Function AddAlphaFromValue implemented to use an fixed Value as Alphachannel
61 - Function ReadOpenGLExtension is now only intern
63 - pngimage now disabled by default like all other versions.
65 - Setting up an anisotropic filter of 0 isnt allowed by nvidia (Thanks Ogridi)
67 - Fixed some Problem with Delphi 5
68 - Now uses the newest version of pngimage. Makes saving pngs much easier.
70 - Property IsCompressed and Size removed. Not really supported by Spec (Thanks Ogridi)
72 - Internal Format ifDepth8 added
73 - function GrabScreen now supports all uncompressed formats
75 - AddAlphaFromglBitmap implemented
77 - LoadFromResource and LoadFromResourceId now needs an Instance and an ResourceType (for ID)
79 - Width, Height and Depth internal changed to TglBitmapPixelPosition.
80 property Width, Height, Depth are still existing and new property Dimension are avail
82 - Added native OpenGL Support. Breaking the dglOpenGL "barrier".
84 - Added function GrabScreen to class TglBitmap2D
86 - Added support to Save images
87 - Added function Clone to Clone Instance
89 - Functions now works with Cardinals for each channel. Up to 32 Bits per channel.
91 - Several speed optimizations
93 - Internal structure change. Loading of TGA, PNG and DDS improved.
94 Data, format and size will now set directly with SetDataPtr.
95 - AddFunc now works with all Types of Images and Formats
96 - Some Funtions moved to Baseclass TglBitmap
98 - Added Support to decompress DXT3 and DXT5 compressed Images.
99 - Added Mapping to convert data from one format into an other.
101 - Added method ConvertTo in Class TglBitmap2D. Method allows to convert every
102 supported Input format (supported by GetPixel) into any uncompresed Format
103 - Added Support to decompress DXT1 compressed Images.
104 - SwapColors replaced by ConvertTo
106 - Added Support for compressed DDSs
107 - Added new internal formats (DXT1, DXT3, DXT5)
109 - Parameter Components renamed to InternalFormat
111 - Some AllocMem replaced with GetMem (little speed change)
112 - better exception handling. Better protection from memory leaks.
114 - Added support for Direct Draw Surfaces (.DDS) (uncompressed images only)
115 - Added new internal formats (RGB8, RGBA8, RGBA4, RGB5A1, RGB10A2, R5G6B5)
117 - Added support for Grayscale textures
118 - Added internal formats (Alpha, Luminance, LuminanceAlpha, BGR8, BGRA8)
120 - Added support for GL_VERSION_2_0
121 - Added support for GL_EXT_texture_filter_anisotropic
123 - Function FillWithColor fills the Image with one Color
124 - Function LoadNormalMap added
126 - ToNormalMap allows to Create an NormalMap from the Alphachannel
127 - ToNormalMap now supports Sobel (nmSobel) function.
129 - support for RLE Compressed RGB TGAs added
131 - Class TglBitmapNormalMap added to support Normalmap generation
132 - Added function ToNormalMap in class TglBitmap2D to genereate normal maps from textures.
133 3 Filters are supported. (4 Samples, 3x3 and 5x5)
135 - Method LoadCubeMapClass removed
136 - LoadCubeMap returnvalue is now the Texture paramter. Such as LoadTextures
137 - virtual abstract method GenTexture in class TglBitmap now is protected
139 - now support DescriptionFlag in LoadTga. Allows vertical flipped images to be loaded as normal
141 - little enhancement for IsPowerOfTwo
142 - TglBitmap1D.GenTexture now tests NPOT Textures
144 - some little name changes. All properties or function with Texture in name are
145 now without texture in name. We have allways texture so we dosn't name it.
147 - GenTexture now tests if texture is NPOT and NPOT-Texture are supported or
148 TextureTarget is GL_TEXTURE_RECTANGLE. Else it raised an exception.
150 - added support for GL_ARB_texture_rectangle, GL_EXT_texture_rectangle and GL_NV_texture_rectangle
152 - Function Unbind added
153 - call of SetFilter or SetTextureWrap if TextureID exists results in setting properties to opengl texture.
155 - class TglBitmapCubeMap added (allows to Create Cubemaps)
157 - Added Support for PNG Images. (http://pngdelphi.sourceforge.net/)
158 To Enable png's use the define pngimage
160 - New Functioninterface added
161 - Function GetPixel added
163 - Property BuildMipMaps renamed to MipMap
165 - property Name removed.
166 - BuildMipMaps is now a set of 3 values. None, GluBuildMipmaps and SGIS_generate_mipmap
168 - property name added. Only used in glForms!
170 - property FreeDataAfterGenTexture is now available as default (default = true)
171 - BuildMipmaps now implemented in TglBitmap1D (i've forgotten it)
172 - function MoveMemory replaced with function Move (little speed change)
173 - several calculations stored in variables (little speed change)
175 - property BuildMipsMaps added (default = true)
176 if BuildMipMaps isn't set GenTextures uses glTexImage[12]D else it use gluBuild[12]dMipmaps
177 - property FreeDataAfterGenTexture added (default = true)
178 if FreeDataAfterGenTexture is set the texturedata were deleted after the texture was generated.
179 - parameter DisableOtherTextureUnits of Bind removed
180 - parameter FreeDataAfterGeneration of GenTextures removed
182 - TglBitmap dosn't delete data if class was destroyed (fixed)
184 - Bind now enables TextureUnits (by params)
185 - GenTextures can leave data (by param)
186 - LoadTextures now optimal
188 - Performance optimization in AddFunc
189 - procedure Bind moved to subclasses
190 - Added new Class TglBitmap1D to support real OpenGL 1D Textures
192 - Texturefilter and texturewrap now also as defaults
193 Minfilter = GL_LINEAR_MIPMAP_LINEAR
194 Magfilter = GL_LINEAR
195 Wrap(str) = GL_CLAMP_TO_EDGE
196 - Added new format tfCompressed to create a compressed texture.
197 - propertys IsCompressed, TextureSize and IsResident added
198 IsCompressed and TextureSize only contains data from level 0
200 - Added function AddFunc to add PerPixelEffects to Image
201 - LoadFromFunc now based on AddFunc
202 - Invert now based on AddFunc
203 - SwapColors now based on AddFunc
205 - Added function FlipHorz
207 - Added function LaodFromFunc to create images with function
208 - Added function FlipVert
209 - Added internal format RGB(A) if GL_EXT_bgra or OpenGL 1.2 isn't supported
211 - Added Alphafunctions to calculate alpha per function
212 - Added Alpha from ColorKey using alphafunctions
214 - First full functionally Version of glBitmap
215 - Support for 24Bit and 32Bit TGA Pictures added
217 - begin of programming
218 ***********************************************************}
221 // Please uncomment the defines below to configure the glBitmap to your preferences.
222 // If you have configured the unit you can uncomment the warning above.
223 {$MESSAGE warn 'Hey. I''m the glBitmap.pas and i need to be configured. My master tell me your preferences! ;)'}
225 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
226 // Preferences ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
227 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
228 // activate to enable build-in OpenGL support with statically linked methods
229 // use dglOpenGL.pas if not enabled
230 {.$DEFINE GLB_NATIVE_OGL_STATIC}
232 // activate to enable build-in OpenGL support with dynamically linked methods
233 // use dglOpenGL.pas if not enabled
234 {.$DEFINE GLB_NATIVE_OGL_DYNAMIC}
237 // activate to enable the support for SDL_surfaces
240 // activate to enable the support for TBitmap from Delphi (not lazarus)
241 {.$DEFINE GLB_DELPHI}
243 // activate to enable the support for TLazIntfImage from Lazarus
244 {.$DEFINE GLB_LAZARUS}
247 // activate to enable the support of SDL_image to load files. (READ ONLY)
248 // If you enable SDL_image all other libraries will be ignored!
249 {.$DEFINE GLB_SDL_IMAGE}
253 // activate to enable png support with the unit pngimage -> http://pngdelphi.sourceforge.net/
254 // if you enable pngimage the libPNG will be ignored
255 {.$DEFINE GLB_PNGIMAGE}
257 // activate to use the libPNG -> http://www.libpng.org/
258 // You will need an aditional header -> http://www.opengl24.de/index.php?cat=header&file=libpng
259 {.$DEFINE GLB_LIB_PNG}
263 // if you enable delphi jpegs the libJPEG will be ignored
264 {.$DEFINE GLB_DELPHI_JPEG}
266 // activate to use the libJPEG -> http://www.ijg.org/
267 // You will need an aditional header -> http://www.opengl24.de/index.php?cat=header&file=libjpeg
268 {.$DEFINE GLB_LIB_JPEG}
271 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
272 // PRIVATE: do not change anything! //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
273 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
289 {$IF DEFINED(WIN32) or DEFINED(WIN64) or DEFINED(WINDOWS)}
291 {$ELSEIF DEFINED(LINUX)}
295 // native OpenGL Support
296 {$IF DEFINED(GLB_NATIVE_OGL_STATIC) OR DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
297 {$DEFINE GLB_NATIVE_OGL}
300 // checking define combinations
302 {$IFDEF GLB_SDL_IMAGE}
304 {$MESSAGE warn 'SDL_image won''t work without SDL. SDL will be activated.'}
307 {$IFDEF GLB_PNGIMAGE}
308 {$MESSAGE warn 'The unit pngimage will be ignored because you are using SDL_image.'}
309 {$undef GLB_PNGIMAGE}
311 {$IFDEF GLB_DELPHI_JPEG}
312 {$MESSAGE warn 'The unit JPEG will be ignored because you are using SDL_image.'}
313 {$undef GLB_DELPHI_JPEG}
316 {$MESSAGE warn 'The library libPNG will be ignored because you are using SDL_image.'}
319 {$IFDEF GLB_LIB_JPEG}
320 {$MESSAGE warn 'The library libJPEG will be ignored because you are using SDL_image.'}
321 {$undef GLB_LIB_JPEG}
324 {$DEFINE GLB_SUPPORT_PNG_READ}
325 {$DEFINE GLB_SUPPORT_JPEG_READ}
329 {$IFDEF GLB_PNGIMAGE}
331 {$MESSAGE warn 'The library libPNG will be ignored if you are using pngimage.'}
335 {$DEFINE GLB_SUPPORT_PNG_READ}
336 {$DEFINE GLB_SUPPORT_PNG_WRITE}
341 {$DEFINE GLB_SUPPORT_PNG_READ}
342 {$DEFINE GLB_SUPPORT_PNG_WRITE}
346 {$IFDEF GLB_DELPHI_JPEG}
347 {$IFDEF GLB_LIB_JPEG}
348 {$MESSAGE warn 'The library libJPEG will be ignored if you are using the unit JPEG.'}
349 {$undef GLB_LIB_JPEG}
352 {$DEFINE GLB_SUPPORT_JPEG_READ}
353 {$DEFINE GLB_SUPPORT_JPEG_WRITE}
357 {$IFDEF GLB_LIB_JPEG}
358 {$DEFINE GLB_SUPPORT_JPEG_READ}
359 {$DEFINE GLB_SUPPORT_JPEG_WRITE}
363 {$IF DEFINED(GLB_NATIVE_OGL_STATIC) AND DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
364 {$MESSAGE warn 'GLB_NATIVE_OGL_STATIC will be ignored because you enabled GLB_NATIVE_OGL_DYNAMIC'}
378 {$IFNDEF GLB_NATIVE_OGL} dglOpenGL, {$ENDIF}
379 {$IF DEFINED(GLB_WIN) AND
380 DEFINED(GLB_NATIVE_OGL)} windows, {$IFEND}
382 {$IFDEF GLB_SDL} SDL, {$ENDIF}
383 {$IFDEF GLB_LAZARUS} IntfGraphics, GraphType, {$ENDIF}
384 {$IFDEF GLB_DELPHI} Dialogs, Graphics, {$ENDIF}
386 {$IFDEF GLB_SDL_IMAGE} SDL_image, {$ENDIF}
388 {$IFDEF GLB_PNGIMAGE} pngimage, {$ENDIF}
389 {$IFDEF GLB_LIB_PNG} libPNG, {$ENDIF}
391 {$IFDEF GLB_DELPHI_JPEG} JPEG, {$ENDIF}
392 {$IFDEF GLB_LIB_JPEG} libJPEG, {$ENDIF}
396 {$IFDEF GLB_NATIVE_OGL}
402 GL_EXTENSIONS = $1F03;
404 GL_TEXTURE_1D = $0DE0;
405 GL_TEXTURE_2D = $0DE1;
406 GL_TEXTURE_RECTANGLE = $84F5;
408 GL_TEXTURE_WIDTH = $1000;
409 GL_TEXTURE_HEIGHT = $1001;
410 GL_TEXTURE_INTERNAL_FORMAT = $1003;
418 GL_LUMINANCE = $1909;
419 GL_LUMINANCE4 = $803F;
420 GL_LUMINANCE8 = $8040;
421 GL_LUMINANCE12 = $8041;
422 GL_LUMINANCE16 = $8042;
424 GL_LUMINANCE_ALPHA = $190A;
425 GL_LUMINANCE4_ALPHA4 = $8043;
426 GL_LUMINANCE6_ALPHA2 = $8044;
427 GL_LUMINANCE8_ALPHA8 = $8045;
428 GL_LUMINANCE12_ALPHA4 = $8046;
429 GL_LUMINANCE12_ALPHA12 = $8047;
430 GL_LUMINANCE16_ALPHA16 = $8048;
453 GL_DEPTH_COMPONENT = $1902;
454 GL_DEPTH_COMPONENT16 = $81A5;
455 GL_DEPTH_COMPONENT24 = $81A6;
456 GL_DEPTH_COMPONENT32 = $81A7;
458 GL_COMPRESSED_RGB = $84ED;
459 GL_COMPRESSED_RGBA = $84EE;
460 GL_COMPRESSED_RGB_S3TC_DXT1_EXT = $83F0;
461 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = $83F1;
462 GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = $83F2;
463 GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = $83F3;
465 GL_UNSIGNED_BYTE = $1401;
466 GL_UNSIGNED_BYTE_3_3_2 = $8032;
467 GL_UNSIGNED_BYTE_2_3_3_REV = $8362;
469 GL_UNSIGNED_SHORT = $1403;
470 GL_UNSIGNED_SHORT_5_6_5 = $8363;
471 GL_UNSIGNED_SHORT_4_4_4_4 = $8033;
472 GL_UNSIGNED_SHORT_5_5_5_1 = $8034;
473 GL_UNSIGNED_SHORT_5_6_5_REV = $8364;
474 GL_UNSIGNED_SHORT_4_4_4_4_REV = $8365;
475 GL_UNSIGNED_SHORT_1_5_5_5_REV = $8366;
477 GL_UNSIGNED_INT = $1405;
478 GL_UNSIGNED_INT_8_8_8_8 = $8035;
479 GL_UNSIGNED_INT_10_10_10_2 = $8036;
480 GL_UNSIGNED_INT_8_8_8_8_REV = $8367;
481 GL_UNSIGNED_INT_2_10_10_10_REV = $8368;
484 GL_TEXTURE_MAG_FILTER = $2800;
485 GL_TEXTURE_MIN_FILTER = $2801;
487 GL_NEAREST_MIPMAP_NEAREST = $2700;
488 GL_NEAREST_MIPMAP_LINEAR = $2702;
490 GL_LINEAR_MIPMAP_NEAREST = $2701;
491 GL_LINEAR_MIPMAP_LINEAR = $2703;
494 GL_TEXTURE_WRAP_S = $2802;
495 GL_TEXTURE_WRAP_T = $2803;
496 GL_TEXTURE_WRAP_R = $8072;
499 GL_CLAMP_TO_EDGE = $812F;
500 GL_CLAMP_TO_BORDER = $812D;
501 GL_MIRRORED_REPEAT = $8370;
504 GL_GENERATE_MIPMAP = $8191;
505 GL_TEXTURE_BORDER_COLOR = $1004;
506 GL_MAX_TEXTURE_SIZE = $0D33;
507 GL_PACK_ALIGNMENT = $0D05;
508 GL_UNPACK_ALIGNMENT = $0CF5;
510 GL_TEXTURE_MAX_ANISOTROPY_EXT = $84FE;
511 GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = $84FF;
513 {$IF DEFINED(GLB_WIN)}
514 libglu = 'glu32.dll';
515 libopengl = 'opengl32.dll';
516 {$ELSEIF DEFINED(GLB_LINUX)}
517 libglu = 'libGLU.so.1';
518 libopengl = 'libGL.so.1';
522 GLboolean = BYTEBOOL;
530 PGLboolean = ^GLboolean;
535 TglCompressedTexImage1D = procedure(target: GLenum; level: GLint; internalformat: GLenum; width: GLsizei; border: GLint; imageSize: GLsizei; const data: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
536 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}
537 TglGetCompressedTexImage = procedure(target: GLenum; level: GLint; img: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
539 {$IF DEFINED(GLB_WIN)}
540 TwglGetProcAddress = function (ProcName: PAnsiChar): Pointer; stdcall;
541 {$ELSEIF DEFINED(GLB_LINUX)}
542 TglXGetProcAddress = function(ProcName: PAnsiChar): Pointer; cdecl;
543 TglXGetProcAddressARB = function(const name: PAnsiChar): pointer; cdecl;
546 {$IF DEFINED(GLB_NATIVE_OGL_DYNAMIC)}
547 TglEnable = procedure(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
548 TglDisable = procedure(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
550 TglGetString = function(name: GLenum): PAnsiChar; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
551 TglGetIntegerv = procedure(pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
553 TglTexParameteri = procedure(target: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
554 TglTexParameterfv = procedure(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
555 TglGetTexParameteriv = procedure(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
556 TglGetTexParameterfv = procedure(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
557 TglGetTexLevelParameteriv = procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
558 TglGetTexLevelParameterfv = procedure(target: GLenum; level: GLint; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
560 TglGenTextures = procedure(n: GLsizei; textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
561 TglBindTexture = procedure(target: GLenum; texture: GLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
562 TglDeleteTextures = procedure(n: GLsizei; const textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
564 TglAreTexturesResident = function(n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
565 TglReadPixels = procedure(x: GLint; y: GLint; width: GLsizei; height: GLsizei; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
566 TglPixelStorei = procedure(pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
568 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}
569 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}
570 TglGetTexImage = procedure(target: GLenum; level: GLint; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
572 TgluBuild1DMipmaps = function(target: GLEnum; components, width: GLint; format, atype: GLEnum; const data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
573 TgluBuild2DMipmaps = function(target: GLEnum; components, width, height: GLint; format, atype: GLEnum; const Data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF}
575 {$ELSEIF DEFINED(GLB_NATIVE_OGL_STATIC)}
576 procedure glEnable(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
577 procedure glDisable(cap: GLenum); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
579 function glGetString(name: GLenum): PAnsiChar; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
580 procedure glGetIntegerv(pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
582 procedure glTexParameteri(target: GLenum; pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
583 procedure glTexParameterfv(target: GLenum; pname: GLenum; const params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
584 procedure glGetTexParameteriv(target: GLenum; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
585 procedure glGetTexParameterfv(target: GLenum; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
586 procedure glGetTexLevelParameteriv(target: GLenum; level: GLint; pname: GLenum; params: PGLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
587 procedure glGetTexLevelParameterfv(target: GLenum; level: GLint; pname: GLenum; params: PGLfloat); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
589 procedure glGenTextures(n: GLsizei; textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
590 procedure glBindTexture(target: GLenum; texture: GLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
591 procedure glDeleteTextures(n: GLsizei; const textures: PGLuint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
593 function glAreTexturesResident(n: GLsizei; const textures: PGLuint; residences: PGLboolean): GLboolean; {$IFDEF DGL_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
594 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;
595 procedure glPixelStorei(pname: GLenum; param: GLint); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
597 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;
598 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;
599 procedure glGetTexImage(target: GLenum; level: GLint; format: GLenum; _type: GLenum; pixels: PGLvoid); {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libopengl;
601 function gluBuild1DMipmaps(target: GLEnum; components, width: GLint; format, atype: GLEnum; const data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libglu;
602 function gluBuild2DMipmaps(target: GLEnum; components, width, height: GLint; format, atype: GLEnum; const Data: Pointer): GLint; {$IFDEF GLB_WIN}stdcall; {$ELSE}cdecl; {$ENDIF} external libglu;
611 GL_SGIS_generate_mipmap,
613 GL_ARB_texture_border_clamp,
614 GL_ARB_texture_mirrored_repeat,
615 GL_ARB_texture_rectangle,
616 GL_ARB_texture_non_power_of_two,
618 GL_IBM_texture_mirrored_repeat,
620 GL_NV_texture_rectangle,
622 GL_EXT_texture_edge_clamp,
623 GL_EXT_texture_rectangle,
624 GL_EXT_texture_filter_anisotropic: Boolean;
626 glCompressedTexImage1D: TglCompressedTexImage1D;
627 glCompressedTexImage2D: TglCompressedTexImage2D;
628 glGetCompressedTexImage: TglGetCompressedTexImage;
630 {$IF DEFINED(GLB_WIN)}
631 wglGetProcAddress: TwglGetProcAddress;
632 {$ELSEIF DEFINED(GLB_LINUX)}
633 glXGetProcAddress: TglXGetProcAddress;
634 glXGetProcAddressARB: TglXGetProcAddress;
637 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
639 glDisable: TglDisable;
641 glGetString: TglGetString;
642 glGetIntegerv: TglGetIntegerv;
644 glTexParameteri: TglTexParameteri;
645 glTexParameterfv: TglTexParameterfv;
646 glGetTexParameteriv: TglGetTexParameteriv;
647 glGetTexParameterfv: TglGetTexParameterfv;
648 glGetTexLevelParameteriv: TglGetTexLevelParameteriv;
649 glGetTexLevelParameterfv: TglGetTexLevelParameterfv;
651 glGenTextures: TglGenTextures;
652 glBindTexture: TglBindTexture;
653 glDeleteTextures: TglDeleteTextures;
655 glAreTexturesResident: TglAreTexturesResident;
656 glReadPixels: TglReadPixels;
657 glPixelStorei: TglPixelStorei;
659 glTexImage1D: TglTexImage1D;
660 glTexImage2D: TglTexImage2D;
661 glGetTexImage: TglGetTexImage;
663 gluBuild1DMipmaps: TgluBuild1DMipmaps;
664 gluBuild2DMipmaps: TgluBuild2DMipmaps;
669 ////////////////////////////////////////////////////////////////////////////////////////////////////
671 tfEmpty = 0, //must be smallest value!
687 tfLuminance12Alpha12,
688 tfLuminance16Alpha16,
732 TglBitmapFileType = (
733 {$IFDEF GLB_SUPPORT_PNG_WRITE} ftPNG, {$ENDIF}
734 {$IFDEF GLB_SUPPORT_JPEG_WRITE}ftJPEG, {$ENDIF}
738 TglBitmapFileTypes = set of TglBitmapFileType;
745 TglBitmapNormalMapFunc = (
751 ////////////////////////////////////////////////////////////////////////////////////////////////////
752 EglBitmapException = class(Exception);
753 EglBitmapSizeToLargeException = class(EglBitmapException);
754 EglBitmapNonPowerOfTwoException = class(EglBitmapException);
755 EglBitmapUnsupportedFormat = class(EglBitmapException)
756 constructor Create(const aFormat: TglBitmapFormat); overload;
757 constructor Create(const aMsg: String; const aFormat: TglBitmapFormat); overload;
760 ////////////////////////////////////////////////////////////////////////////////////////////////////
761 TglBitmapColorRec = packed record
763 0: (r, g, b, a: Cardinal);
764 1: (arr: array[0..3] of Cardinal);
767 TglBitmapPixelData = packed record
768 Data, Range: TglBitmapColorRec;
769 Format: TglBitmapFormat;
771 PglBitmapPixelData = ^TglBitmapPixelData;
773 ////////////////////////////////////////////////////////////////////////////////////////////////////
774 TglBitmapPixelPositionFields = set of (ffX, ffY);
775 TglBitmapPixelPosition = record
776 Fields : TglBitmapPixelPositionFields;
781 ////////////////////////////////////////////////////////////////////////////////////////////////////
783 TglBitmapFunctionRec = record
785 Size: TglBitmapPixelPosition;
786 Position: TglBitmapPixelPosition;
787 Source: TglBitmapPixelData;
788 Dest: TglBitmapPixelData;
791 TglBitmapFunction = procedure(var FuncRec: TglBitmapFunctionRec);
793 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
798 fAnisotropic: Integer;
799 fDeleteTextureOnFree: Boolean;
800 fFreeDataAfterGenTexture: Boolean;
802 fIsResident: Boolean;
803 fBorderColor: array[0..3] of Single;
805 fDimension: TglBitmapPixelPosition;
806 fMipMap: TglBitmapMipMap;
807 fFormat: TglBitmapFormat;
814 fFilterMin: Cardinal;
815 fFilterMag: Cardinal;
825 fCustomNameW: WideString;
826 fCustomData: Pointer;
829 function GetWidth: Integer; virtual;
830 function GetHeight: Integer; virtual;
832 function GetFileWidth: Integer; virtual;
833 function GetFileHeight: Integer; virtual;
836 procedure SetCustomData(const aValue: Pointer);
837 procedure SetCustomName(const aValue: String);
838 procedure SetCustomNameW(const aValue: WideString);
839 procedure SetDeleteTextureOnFree(const aValue: Boolean);
840 procedure SetFormat(const aValue: TglBitmapFormat);
841 procedure SetFreeDataAfterGenTexture(const aValue: Boolean);
842 procedure SetID(const aValue: Cardinal);
843 procedure SetMipMap(const aValue: TglBitmapMipMap);
844 procedure SetTarget(const aValue: Cardinal);
845 procedure SetAnisotropic(const aValue: Integer);
848 procedure SetupParameters(out aBuildWithGlu: Boolean);
849 procedure SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
850 const aWidth: Integer = -1; const aHeight: Integer = -1); virtual;
851 procedure GenTexture(const aTestTextureSize: Boolean = true); virtual; abstract;
853 function FlipHorz: Boolean; virtual;
854 function FlipVert: Boolean; virtual;
856 property Width: Integer read GetWidth;
857 property Height: Integer read GetHeight;
859 property FileWidth: Integer read GetFileWidth;
860 property FileHeight: Integer read GetFileHeight;
863 property ID: Cardinal read fID write SetID;
864 property Target: Cardinal read fTarget write SetTarget;
865 property Format: TglBitmapFormat read fFormat write SetFormat;
866 property MipMap: TglBitmapMipMap read fMipMap write SetMipMap;
867 property Anisotropic: Integer read fAnisotropic write SetAnisotropic;
869 property Filename: String read fFilename;
870 property CustomName: String read fCustomName write SetCustomName;
871 property CustomNameW: WideString read fCustomNameW write SetCustomNameW;
872 property CustomData: Pointer read fCustomData write SetCustomData;
874 property DeleteTextureOnFree: Boolean read fDeleteTextureOnFree write SetDeleteTextureOnFree;
875 property FreeDataAfterGenTexture: Boolean read fFreeDataAfterGenTexture write SetFreeDataAfterGenTexture;
877 property Dimension: TglBitmapPixelPosition read fDimension;
878 property Data: PByte read fData;
879 property IsResident: Boolean read fIsResident;
881 procedure AfterConstruction; override;
882 procedure BeforeDestruction; override;
884 procedure PrepareResType(var aResource: String; var aResType: PChar);
887 procedure LoadFromFile(const aFilename: String);
888 procedure LoadFromStream(const aStream: TStream); virtual;
889 procedure LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
890 const aFormat: TglBitmapFormat; const aArgs: Pointer = nil);
891 procedure LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil);
892 procedure LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
895 procedure SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
896 procedure SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType); virtual;
899 function AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer = nil): Boolean; overload;
900 function AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
901 const aFormat: TglBitmapFormat; const aArgs: Pointer = nil): Boolean; overload;
905 function AssignToSurface(out aSurface: PSDL_Surface): Boolean;
906 function AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
907 function AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
908 function AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil;
909 const aArgs: Pointer = nil): Boolean;
913 function AssignToBitmap(const aBitmap: TBitmap): Boolean;
914 function AssignFromBitmap(const aBitmap: TBitmap): Boolean;
915 function AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
916 function AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction = nil;
917 const aArgs: Pointer = nil): Boolean;
921 function AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
922 function AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
923 function AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
924 function AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction = nil;
925 const aArgs: Pointer = nil): Boolean;
928 function AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar = nil;
929 const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
930 function AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
931 const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
933 function AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer = nil): Boolean; virtual;
934 function AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
935 function AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
936 function AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
938 function AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte = 0): Boolean;
939 function AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal = 0): Boolean;
940 function AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single = 0): Boolean;
942 function AddAlphaFromValue(const aAlpha: Byte): Boolean;
943 function AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
944 function AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
946 function RemoveAlpha: Boolean; virtual;
949 function Clone: TglBitmap;
950 function ConvertTo(const aFormat: TglBitmapFormat): Boolean; virtual;
951 procedure Invert(const aUseRGB: Boolean = true; const aUseAlpha: Boolean = false);
952 procedure SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
956 procedure FillWithColor(const aRed, aGreen, aBlue: Byte; const aAlpha: Byte = 255);
957 procedure FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal = $FFFFFFFF);
958 procedure FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha : Single = 1);
961 procedure SetFilter(const aMin, aMag: Cardinal);
963 const S: Cardinal = GL_CLAMP_TO_EDGE;
964 const T: Cardinal = GL_CLAMP_TO_EDGE;
965 const R: Cardinal = GL_CLAMP_TO_EDGE);
967 procedure Bind(const aEnableTextureUnit: Boolean = true); virtual;
968 procedure Unbind(const aDisableTextureUnit: Boolean = true); virtual;
971 constructor Create; overload;
972 constructor Create(const aFileName: String); overload;
973 constructor Create(const aStream: TStream); overload;
974 constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat); overload;
975 constructor Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat; const aFunc: TglBitmapFunction; const aArgs: Pointer = nil); overload;
976 constructor Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar = nil); overload;
977 constructor Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar); overload;
979 {$IFDEF GLB_SUPPORT_PNG_READ} function LoadPNG(const aStream: TStream): Boolean; virtual; {$ENDIF}
980 {$ifdef GLB_SUPPORT_PNG_WRITE} procedure SavePNG(const aStream: TStream); virtual; {$ENDIF}
982 {$IFDEF GLB_SUPPORT_JPEG_READ} function LoadJPEG(const aStream: TStream): Boolean; virtual; {$ENDIF}
983 {$IFDEF GLB_SUPPORT_JPEG_WRITE} procedure SaveJPEG(const aStream: TStream); virtual; {$ENDIF}
985 function LoadBMP(const aStream: TStream): Boolean; virtual;
986 procedure SaveBMP(const aStream: TStream); virtual;
988 function LoadTGA(const aStream: TStream): Boolean; virtual;
989 procedure SaveTGA(const aStream: TStream); virtual;
991 function LoadDDS(const aStream: TStream): Boolean; virtual;
992 procedure SaveDDS(const aStream: TStream); virtual;
995 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
996 TglBitmap2D = class(TglBitmap)
999 fLines: array of PByte;
1001 function GetScanline(const aIndex: Integer): Pointer;
1002 procedure SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
1003 const aWidth: Integer = - 1; const aHeight: Integer = - 1); override;
1004 procedure UploadData(const aTarget: Cardinal; const aBuildWithGlu: Boolean);
1008 property Scanline[const aIndex: Integer]: Pointer read GetScanline;
1010 procedure AfterConstruction; override;
1012 procedure GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
1013 procedure GetDataFromTexture;
1014 procedure GenTexture(const aTestTextureSize: Boolean = true); override;
1016 function FlipHorz: Boolean; override;
1017 function FlipVert: Boolean; override;
1019 procedure ToNormalMap(const aFunc: TglBitmapNormalMapFunc = nm3x3;
1020 const aScale: Single = 2; const aUseAlpha: Boolean = false);
1024 TglBitmapCubeMap = class(TglBitmap2D)
1029 procedure GenTexture(TestTextureSize: Boolean = true); reintroduce;
1031 procedure AfterConstruction; override;
1033 procedure GenerateCubeMap(CubeTarget: Cardinal; TestTextureSize: Boolean = true);
1035 procedure Unbind(DisableTexCoordsGen: Boolean = true; DisableTextureUnit: Boolean = true); reintroduce; virtual;
1036 procedure Bind(EnableTexCoordsGen: Boolean = true; EnableTextureUnit: Boolean = true); reintroduce; virtual;
1040 TglBitmapNormalMap = class(TglBitmapCubeMap)
1042 procedure AfterConstruction; override;
1044 procedure GenerateNormalMap(Size: Integer = 32; TestTextureSize: Boolean = true);
1048 TglBitmap1D = class(TglBitmap)
1050 procedure GetPixel1DUnmap(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
1052 procedure SetDataPointer(Data: pByte; Format: TglBitmapInternalFormat; Width: Integer = -1; Height: Integer = -1); override;
1053 procedure UploadData (Target, Format, InternalFormat, Typ: Cardinal; BuildWithGlu: Boolean);
1058 procedure AfterConstruction; override;
1061 function FlipHorz: Boolean; override;
1064 procedure GenTexture(TestTextureSize: Boolean = true); override;
1069 NULL_SIZE: TglBitmapPixelPosition = (Fields: []; X: 0; Y: 0);
1071 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
1072 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
1073 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
1074 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
1075 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
1076 procedure glBitmapSetDefaultWrap(
1077 const S: Cardinal = GL_CLAMP_TO_EDGE;
1078 const T: Cardinal = GL_CLAMP_TO_EDGE;
1079 const R: Cardinal = GL_CLAMP_TO_EDGE);
1081 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
1082 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
1083 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
1084 function glBitmapGetDefaultFormat: TglBitmapFormat;
1085 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
1086 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
1088 function glBitmapPosition(X: Integer = -1; Y: Integer = -1): TglBitmapPixelPosition;
1089 function glBitmapColorRec(const r, g, b, a: Cardinal): TglBitmapColorRec;
1090 function glBitmapColorRecCmp(const r1, r2: TglBitmapColorRec): Boolean;
1093 glBitmapDefaultDeleteTextureOnFree: Boolean;
1094 glBitmapDefaultFreeDataAfterGenTextures: Boolean;
1095 glBitmapDefaultFormat: TglBitmapFormat;
1096 glBitmapDefaultMipmap: TglBitmapMipMap;
1097 glBitmapDefaultFilterMin: Cardinal;
1098 glBitmapDefaultFilterMag: Cardinal;
1099 glBitmapDefaultWrapS: Cardinal;
1100 glBitmapDefaultWrapT: Cardinal;
1101 glBitmapDefaultWrapR: Cardinal;
1104 function CreateGrayPalette: HPALETTE;
1110 Math, syncobjs, typinfo;
1114 QWord = System.UInt64;
1121 ////////////////////////////////////////////////////////////////////////////////////////////////////
1122 TShiftRec = packed record
1124 0: (r, g, b, a: Byte);
1125 1: (arr: array[0..3] of Byte);
1128 TFormatDescriptor = class(TObject)
1130 function GetRedMask: QWord;
1131 function GetGreenMask: QWord;
1132 function GetBlueMask: QWord;
1133 function GetAlphaMask: QWord;
1135 fFormat: TglBitmapFormat;
1136 fWithAlpha: TglBitmapFormat;
1137 fWithoutAlpha: TglBitmapFormat;
1138 fRGBInverted: TglBitmapFormat;
1139 fUncompressed: TglBitmapFormat;
1141 fIsCompressed: Boolean;
1143 fRange: TglBitmapColorRec;
1146 fglFormat: Cardinal;
1147 fglInternalFormat: Cardinal;
1148 fglDataFormat: Cardinal;
1150 function GetComponents: Integer; virtual;
1152 property Format: TglBitmapFormat read fFormat;
1153 property WithAlpha: TglBitmapFormat read fWithAlpha;
1154 property WithoutAlpha: TglBitmapFormat read fWithoutAlpha;
1155 property RGBInverted: TglBitmapFormat read fRGBInverted;
1156 property Components: Integer read GetComponents;
1157 property PixelSize: Single read fPixelSize;
1158 property IsCompressed: Boolean read fIsCompressed;
1160 property glFormat: Cardinal read fglFormat;
1161 property glInternalFormat: Cardinal read fglInternalFormat;
1162 property glDataFormat: Cardinal read fglDataFormat;
1164 property Range: TglBitmapColorRec read fRange;
1165 property Shift: TShiftRec read fShift;
1167 property RedMask: QWord read GetRedMask;
1168 property GreenMask: QWord read GetGreenMask;
1169 property BlueMask: QWord read GetBlueMask;
1170 property AlphaMask: QWord read GetAlphaMask;
1172 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); virtual; abstract;
1173 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); virtual; abstract;
1175 function GetSize(const aSize: TglBitmapPixelPosition): Integer; overload; virtual;
1176 function GetSize(const aWidth, aHeight: Integer): Integer; overload; virtual;
1178 function CreateMappingData: Pointer; virtual;
1179 procedure FreeMappingData(var aMappingData: Pointer); virtual;
1181 function IsEmpty: Boolean; virtual;
1182 function HasAlpha: Boolean; virtual;
1183 function MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: QWord): Boolean; virtual;
1185 procedure PreparePixel(out aPixel: TglBitmapPixelData); virtual;
1187 constructor Create; virtual;
1189 class procedure Init;
1190 class function Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
1191 class function GetWithAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
1192 class procedure Clear;
1193 class procedure Finalize;
1195 TFormatDescriptorClass = class of TFormatDescriptor;
1197 TfdEmpty = class(TFormatDescriptor);
1199 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1200 TfdAlpha_UB1 = class(TFormatDescriptor) //1* unsigned byte
1201 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1202 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1203 constructor Create; override;
1206 TfdLuminance_UB1 = class(TFormatDescriptor) //1* unsigned byte
1207 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1208 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1209 constructor Create; override;
1212 TfdUniversal_UB1 = class(TFormatDescriptor) //1* unsigned byte
1213 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1214 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1215 constructor Create; override;
1218 TfdLuminanceAlpha_UB2 = class(TfdLuminance_UB1) //2* unsigned byte
1219 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1220 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1221 constructor Create; override;
1224 TfdRGB_UB3 = class(TFormatDescriptor) //3* unsigned byte
1225 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1226 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1227 constructor Create; override;
1230 TfdBGR_UB3 = class(TFormatDescriptor) //3* unsigned byte (inverse)
1231 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1232 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1233 constructor Create; override;
1236 TfdRGBA_UB4 = class(TfdRGB_UB3) //4* unsigned byte
1237 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1238 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1239 constructor Create; override;
1242 TfdBGRA_UB4 = class(TfdBGR_UB3) //4* unsigned byte (inverse)
1243 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1244 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1245 constructor Create; override;
1248 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1249 TfdAlpha_US1 = class(TFormatDescriptor) //1* unsigned short
1250 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1251 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1252 constructor Create; override;
1255 TfdLuminance_US1 = class(TFormatDescriptor) //1* unsigned short
1256 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1257 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1258 constructor Create; override;
1261 TfdUniversal_US1 = class(TFormatDescriptor) //1* unsigned short
1262 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1263 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1264 constructor Create; override;
1267 TfdDepth_US1 = class(TFormatDescriptor) //1* unsigned short
1268 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1269 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1270 constructor Create; override;
1273 TfdLuminanceAlpha_US2 = class(TfdLuminance_US1) //2* unsigned short
1274 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1275 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1276 constructor Create; override;
1279 TfdRGB_US3 = class(TFormatDescriptor) //3* unsigned short
1280 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1281 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1282 constructor Create; override;
1285 TfdBGR_US3 = class(TFormatDescriptor) //3* unsigned short (inverse)
1286 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1287 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1288 constructor Create; override;
1291 TfdRGBA_US4 = class(TfdRGB_US3) //4* unsigned short
1292 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1293 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1294 constructor Create; override;
1297 TfdBGRA_US4 = class(TfdBGR_US3) //4* unsigned short (inverse)
1298 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1299 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1300 constructor Create; override;
1303 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1304 TfdUniversal_UI1 = class(TFormatDescriptor) //1* unsigned int
1305 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1306 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1307 constructor Create; override;
1310 TfdDepth_UI1 = class(TFormatDescriptor) //1* unsigned int
1311 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1312 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1313 constructor Create; override;
1316 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1317 TfdAlpha4 = class(TfdAlpha_UB1)
1318 constructor Create; override;
1321 TfdAlpha8 = class(TfdAlpha_UB1)
1322 constructor Create; override;
1325 TfdAlpha12 = class(TfdAlpha_US1)
1326 constructor Create; override;
1329 TfdAlpha16 = class(TfdAlpha_US1)
1330 constructor Create; override;
1333 TfdLuminance4 = class(TfdLuminance_UB1)
1334 constructor Create; override;
1337 TfdLuminance8 = class(TfdLuminance_UB1)
1338 constructor Create; override;
1341 TfdLuminance12 = class(TfdLuminance_US1)
1342 constructor Create; override;
1345 TfdLuminance16 = class(TfdLuminance_US1)
1346 constructor Create; override;
1349 TfdLuminance4Alpha4 = class(TfdLuminanceAlpha_UB2)
1350 constructor Create; override;
1353 TfdLuminance6Alpha2 = class(TfdLuminanceAlpha_UB2)
1354 constructor Create; override;
1357 TfdLuminance8Alpha8 = class(TfdLuminanceAlpha_UB2)
1358 constructor Create; override;
1361 TfdLuminance12Alpha4 = class(TfdLuminanceAlpha_US2)
1362 constructor Create; override;
1365 TfdLuminance12Alpha12 = class(TfdLuminanceAlpha_US2)
1366 constructor Create; override;
1369 TfdLuminance16Alpha16 = class(TfdLuminanceAlpha_US2)
1370 constructor Create; override;
1373 TfdR3G3B2 = class(TfdUniversal_UB1)
1374 constructor Create; override;
1377 TfdRGB4 = class(TfdUniversal_US1)
1378 constructor Create; override;
1381 TfdR5G6B5 = class(TfdUniversal_US1)
1382 constructor Create; override;
1385 TfdRGB5 = class(TfdUniversal_US1)
1386 constructor Create; override;
1389 TfdRGB8 = class(TfdRGB_UB3)
1390 constructor Create; override;
1393 TfdRGB10 = class(TfdUniversal_UI1)
1394 constructor Create; override;
1397 TfdRGB12 = class(TfdRGB_US3)
1398 constructor Create; override;
1401 TfdRGB16 = class(TfdRGB_US3)
1402 constructor Create; override;
1405 TfdRGBA2 = class(TfdRGBA_UB4)
1406 constructor Create; override;
1409 TfdRGBA4 = class(TfdUniversal_US1)
1410 constructor Create; override;
1413 TfdRGB5A1 = class(TfdUniversal_US1)
1414 constructor Create; override;
1417 TfdRGBA8 = class(TfdRGBA_UB4)
1418 constructor Create; override;
1421 TfdRGB10A2 = class(TfdUniversal_UI1)
1422 constructor Create; override;
1425 TfdRGBA12 = class(TfdRGBA_US4)
1426 constructor Create; override;
1429 TfdRGBA16 = class(TfdRGBA_US4)
1430 constructor Create; override;
1433 TfdBGR4 = class(TfdUniversal_US1)
1434 constructor Create; override;
1437 TfdB5G6R5 = class(TfdUniversal_US1)
1438 constructor Create; override;
1441 TfdBGR5 = class(TfdUniversal_US1)
1442 constructor Create; override;
1445 TfdBGR8 = class(TfdBGR_UB3)
1446 constructor Create; override;
1449 TfdBGR10 = class(TfdUniversal_UI1)
1450 constructor Create; override;
1453 TfdBGR12 = class(TfdBGR_US3)
1454 constructor Create; override;
1457 TfdBGR16 = class(TfdBGR_US3)
1458 constructor Create; override;
1461 TfdBGRA2 = class(TfdBGRA_UB4)
1462 constructor Create; override;
1465 TfdBGRA4 = class(TfdUniversal_US1)
1466 constructor Create; override;
1469 TfdBGR5A1 = class(TfdUniversal_US1)
1470 constructor Create; override;
1473 TfdBGRA8 = class(TfdBGRA_UB4)
1474 constructor Create; override;
1477 TfdBGR10A2 = class(TfdUniversal_UI1)
1478 constructor Create; override;
1481 TfdBGRA12 = class(TfdBGRA_US4)
1482 constructor Create; override;
1485 TfdBGRA16 = class(TfdBGRA_US4)
1486 constructor Create; override;
1489 TfdDepth16 = class(TfdDepth_US1)
1490 constructor Create; override;
1493 TfdDepth24 = class(TfdDepth_UI1)
1494 constructor Create; override;
1497 TfdDepth32 = class(TfdDepth_UI1)
1498 constructor Create; override;
1501 TfdS3tcDtx1RGBA = class(TFormatDescriptor)
1502 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1503 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1504 constructor Create; override;
1507 TfdS3tcDtx3RGBA = class(TFormatDescriptor)
1508 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1509 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1510 constructor Create; override;
1513 TfdS3tcDtx5RGBA = class(TFormatDescriptor)
1514 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1515 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1516 constructor Create; override;
1519 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1520 TbmpBitfieldFormat = class(TFormatDescriptor)
1522 procedure SetRedMask (const aValue: QWord);
1523 procedure SetGreenMask(const aValue: QWord);
1524 procedure SetBlueMask (const aValue: QWord);
1525 procedure SetAlphaMask(const aValue: QWord);
1527 procedure Update(aMask: QWord; out aRange: Cardinal; out aShift: Byte);
1529 property RedMask: QWord read GetRedMask write SetRedMask;
1530 property GreenMask: QWord read GetGreenMask write SetGreenMask;
1531 property BlueMask: QWord read GetBlueMask write SetBlueMask;
1532 property AlphaMask: QWord read GetAlphaMask write SetAlphaMask;
1534 property PixelSize: Single read fPixelSize write fPixelSize;
1536 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1537 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1540 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1541 TbmpColorTableEnty = packed record
1544 TbmpColorTable = array of TbmpColorTableEnty;
1545 TbmpColorTableFormat = class(TFormatDescriptor)
1547 fColorTable: TbmpColorTable;
1549 property PixelSize: Single read fPixelSize write fPixelSize;
1550 property ColorTable: TbmpColorTable read fColorTable write fColorTable;
1551 property Range: TglBitmapColorRec read fRange write fRange;
1552 property Shift: TShiftRec read fShift write fShift;
1553 property Format: TglBitmapFormat read fFormat write fFormat;
1555 procedure CreateColorTable;
1557 procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
1558 procedure Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
1559 destructor Destroy; override;
1563 LUMINANCE_WEIGHT_R = 0.30;
1564 LUMINANCE_WEIGHT_G = 0.59;
1565 LUMINANCE_WEIGHT_B = 0.11;
1567 ALPHA_WEIGHT_R = 0.30;
1568 ALPHA_WEIGHT_G = 0.59;
1569 ALPHA_WEIGHT_B = 0.11;
1571 DEPTH_WEIGHT_R = 0.333333333;
1572 DEPTH_WEIGHT_G = 0.333333333;
1573 DEPTH_WEIGHT_B = 0.333333333;
1575 UNSUPPORTED_FORMAT = 'the given format isn''t supported by this function.';
1577 FORMAT_DESCRIPTOR_CLASSES: array[TglBitmapFormat] of TFormatDescriptorClass = (
1590 TfdLuminance4Alpha4,
1591 TfdLuminance6Alpha2,
1592 TfdLuminance8Alpha8,
1593 TfdLuminance12Alpha4,
1594 TfdLuminance12Alpha12,
1595 TfdLuminance16Alpha16,
1640 FormatDescriptorCS: TCriticalSection;
1641 FormatDescriptors: array[TglBitmapFormat] of TFormatDescriptor;
1643 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1644 constructor EglBitmapUnsupportedFormat.Create(const aFormat: TglBitmapFormat);
1646 inherited Create('unsupported format: ' + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
1649 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1650 constructor EglBitmapUnsupportedFormat.Create(const aMsg: String; const aFormat: TglBitmapFormat);
1652 inherited Create(aMsg + GetEnumName(TypeInfo(TglBitmapFormat), Integer(aFormat)));
1655 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1656 function glBitmapPosition(X, Y: Integer): TglBitmapPixelPosition;
1658 result.Fields := [];
1661 result.Fields := result.Fields + [ffX];
1663 result.Fields := result.Fields + [ffY];
1665 result.X := Max(0, X);
1666 result.Y := Max(0, Y);
1669 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1670 function glBitmapColorRec(const r, g, b, a: Cardinal): TglBitmapColorRec;
1678 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1679 function glBitmapColorRecCmp(const r1, r2: TglBitmapColorRec): Boolean;
1684 for i := 0 to high(r1.arr) do
1685 if (r1.arr[i] <> r2.arr[i]) then
1690 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1691 function glBitmapShiftRec(const r, g, b, a: Byte): TShiftRec;
1699 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1700 function FormatGetSupportedFiles(const aFormat: TglBitmapFormat): TglBitmapFileTypes;
1709 tfR3G3B2, tfLuminance8,
1712 tfRGB4, tfRGB5, tfR5G6B5, tfRGB5A1, tfRGBA4,
1713 tfBGR4, tfBGR5, tfB5G6R5, tfBGR5A1, tfBGRA4,
1719 tfRGB10, tfRGB10A2, tfRGBA8,
1720 tfBGR10, tfBGR10A2, tfBGRA8]) then
1721 result := result + [ftBMP];
1725 tfLuminance8, tfAlpha8,
1728 tfLuminance16, tfLuminance8Alpha8,
1729 tfRGB5, tfRGB5A1, tfRGBA4,
1730 tfBGR5, tfBGR5A1, tfBGRA4,
1736 tfRGB10A2, tfRGBA8, tfBGR10A2, tfBGRA8]) then
1737 result := result + [ftTGA];
1741 tfAlpha8, tfLuminance8, tfLuminance4Alpha4, tfLuminance6Alpha2,
1742 tfR3G3B2, tfRGBA2, tfBGRA2,
1745 tfAlpha16, tfLuminance16, tfLuminance8Alpha8, tfLuminance12Alpha4,
1746 tfRGB4, tfR5G6B5, tfRGB5, tfRGBA4, tfRGB5A1,
1747 tfBGR4, tfB5G6R5, tfBGR5, tfBGRA4, tfBGR5A1,
1753 tfLuminance16Alpha16,
1758 tfS3tcDtx1RGBA, tfS3tcDtx3RGBA, tfS3tcDtx5RGBA]) then
1759 result := result + [ftDDS];
1761 {$IFDEF GLB_SUPPORT_PNG_WRITE}
1763 tfAlpha8, tfLuminance8, tfLuminance8Alpha8,
1765 tfBGR8, tfBGRA8] then
1766 result := result + [ftPNG];
1769 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
1770 if aFormat in [tfAlpha8, tfLuminance8, tfRGB8, tfBGR8] then
1771 result := result + [ftJPEG];
1775 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1776 function IsPowerOfTwo(aNumber: Integer): Boolean;
1778 while (aNumber and 1) = 0 do
1779 aNumber := aNumber shr 1;
1780 result := aNumber = 1;
1783 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1784 function GetTopMostBit(aBitSet: QWord): Integer;
1787 while aBitSet > 0 do begin
1789 aBitSet := aBitSet shr 1;
1793 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1794 function CountSetBits(aBitSet: QWord): Integer;
1797 while aBitSet > 0 do begin
1798 if (aBitSet and 1) = 1 then
1800 aBitSet := aBitSet shr 1;
1804 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1805 function LuminanceWeight(const aPixel: TglBitmapPixelData): Cardinal;
1808 LUMINANCE_WEIGHT_R * aPixel.Data.r +
1809 LUMINANCE_WEIGHT_G * aPixel.Data.g +
1810 LUMINANCE_WEIGHT_B * aPixel.Data.b);
1813 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1814 function DepthWeight(const aPixel: TglBitmapPixelData): Cardinal;
1817 DEPTH_WEIGHT_R * aPixel.Data.r +
1818 DEPTH_WEIGHT_G * aPixel.Data.g +
1819 DEPTH_WEIGHT_B * aPixel.Data.b);
1822 {$IFDEF GLB_NATIVE_OGL}
1823 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1824 //OpenGLInitialization///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1825 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1827 GL_LibHandle: Pointer = nil;
1829 function glbGetProcAddress(aProcName: PChar; aLibHandle: Pointer = nil): Pointer;
1831 if not Assigned(aLibHandle) then
1832 aLibHandle := GL_LibHandle;
1834 {$IF DEFINED(GLB_WIN)}
1835 result := GetProcAddress({%H-}HMODULE(aLibHandle), aProcName);
1836 if Assigned(result) then
1839 if Assigned(wglGetProcAddress) then
1840 result := wglGetProcAddress(aProcName);
1841 {$ELSEIF DEFINED(GLB_LINUX)}
1842 if Assigned(glXGetProcAddress) then begin
1843 result := glXGetProcAddress(aProcName);
1844 if Assigned(result) then
1848 if Assigned(glXGetProcAddressARB) then begin
1849 result := glXGetProcAddressARB(aProcName);
1850 if Assigned(result) then
1854 result := dlsym(aLibHandle, aProcName);
1856 if not Assigned(result) then
1857 raise EglBitmapException.Create('unable to load procedure form library: ' + aProcName);
1860 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
1862 GLU_LibHandle: Pointer = nil;
1863 OpenGLInitialized: Boolean;
1864 InitOpenGLCS: TCriticalSection;
1866 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1867 procedure glbInitOpenGL;
1869 ////////////////////////////////////////////////////////////////////////////////
1870 function glbLoadLibrary(const aName: PChar): Pointer;
1872 {$IF DEFINED(GLB_WIN)}
1873 result := {%H-}Pointer(LoadLibrary(aName));
1874 {$ELSEIF DEFINED(GLB_LINUX)}
1875 result := dlopen(Name, RTLD_LAZY);
1881 ////////////////////////////////////////////////////////////////////////////////
1882 function glbFreeLibrary(const aLibHandle: Pointer): Boolean;
1885 if not Assigned(aLibHandle) then
1888 {$IF DEFINED(GLB_WIN)}
1889 Result := FreeLibrary({%H-}HINST(aLibHandle));
1890 {$ELSEIF DEFINED(GLB_LINUX)}
1891 Result := dlclose(aLibHandle) = 0;
1896 if Assigned(GL_LibHandle) then
1897 glbFreeLibrary(GL_LibHandle);
1899 if Assigned(GLU_LibHandle) then
1900 glbFreeLibrary(GLU_LibHandle);
1902 GL_LibHandle := glbLoadLibrary(libopengl);
1903 if not Assigned(GL_LibHandle) then
1904 raise EglBitmapException.Create('unable to load library: ' + libopengl);
1906 GLU_LibHandle := glbLoadLibrary(libglu);
1907 if not Assigned(GLU_LibHandle) then
1908 raise EglBitmapException.Create('unable to load library: ' + libglu);
1911 {$IF DEFINED(GLB_WIN)}
1912 wglGetProcAddress := glbGetProcAddress('wglGetProcAddress');
1913 {$ELSEIF DEFINED(GLB_LINUX)}
1914 glXGetProcAddress := glbGetProcAddress('glXGetProcAddress');
1915 glXGetProcAddressARB := glbGetProcAddress('glXGetProcAddressARB');
1918 glEnable := glbGetProcAddress('glEnable');
1919 glDisable := glbGetProcAddress('glDisable');
1920 glGetString := glbGetProcAddress('glGetString');
1921 glGetIntegerv := glbGetProcAddress('glGetIntegerv');
1922 glTexParameteri := glbGetProcAddress('glTexParameteri');
1923 glTexParameterfv := glbGetProcAddress('glTexParameterfv');
1924 glGetTexParameteriv := glbGetProcAddress('glGetTexParameteriv');
1925 glGetTexParameterfv := glbGetProcAddress('glGetTexParameterfv');
1926 glGetTexLevelParameteriv := glbGetProcAddress('glGetTexLevelParameteriv');
1927 glGetTexLevelParameterfv := glbGetProcAddress('glGetTexLevelParameterfv');
1928 glGenTextures := glbGetProcAddress('glGenTextures');
1929 glBindTexture := glbGetProcAddress('glBindTexture');
1930 glDeleteTextures := glbGetProcAddress('glDeleteTextures');
1931 glAreTexturesResident := glbGetProcAddress('glAreTexturesResident');
1932 glReadPixels := glbGetProcAddress('glReadPixels');
1933 glPixelStorei := glbGetProcAddress('glPixelStorei');
1934 glTexImage1D := glbGetProcAddress('glTexImage1D');
1935 glTexImage2D := glbGetProcAddress('glTexImage2D');
1936 glGetTexImage := glbGetProcAddress('glGetTexImage');
1938 gluBuild1DMipmaps := glbGetProcAddress('gluBuild1DMipmaps', GLU_LibHandle);
1939 gluBuild2DMipmaps := glbGetProcAddress('gluBuild2DMipmaps', GLU_LibHandle);
1941 glbFreeLibrary(GL_LibHandle);
1942 glbFreeLibrary(GLU_LibHandle);
1947 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1948 procedure glbReadOpenGLExtensions;
1951 MajorVersion, MinorVersion: Integer;
1953 ///////////////////////////////////////////////////////////////////////////////////////////
1954 procedure TrimVersionString(aBuffer: AnsiString; out aMajor, aMinor: Integer);
1961 Separator := Pos(AnsiString('.'), aBuffer);
1962 if (Separator > 1) and (Separator < Length(aBuffer)) and
1963 (aBuffer[Separator - 1] in ['0'..'9']) and
1964 (aBuffer[Separator + 1] in ['0'..'9']) then begin
1967 while (Separator > 0) and (aBuffer[Separator] in ['0'..'9']) do
1970 Delete(aBuffer, 1, Separator);
1971 Separator := Pos(AnsiString('.'), aBuffer) + 1;
1973 while (Separator <= Length(aBuffer)) and (AnsiChar(aBuffer[Separator]) in ['0'..'9']) do
1976 Delete(aBuffer, Separator, 255);
1977 Separator := Pos(AnsiString('.'), aBuffer);
1979 aMajor := StrToInt(Copy(String(aBuffer), 1, Separator - 1));
1980 aMinor := StrToInt(Copy(String(aBuffer), Separator + 1, 1));
1984 ///////////////////////////////////////////////////////////////////////////////////////////
1985 function CheckExtension(const Extension: AnsiString): Boolean;
1989 ExtPos := Pos(Extension, Buffer);
1990 result := ExtPos > 0;
1992 result := ((ExtPos + Length(Extension) - 1) = Length(Buffer)) or not (Buffer[ExtPos + Length(Extension)] in ['_', 'A'..'Z', 'a'..'z']);
1996 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
1999 if not OpenGLInitialized then begin
2001 OpenGLInitialized := true;
2009 Buffer := glGetString(GL_VERSION);
2010 TrimVersionString(Buffer, MajorVersion, MinorVersion);
2012 GL_VERSION_1_2 := false;
2013 GL_VERSION_1_3 := false;
2014 GL_VERSION_1_4 := false;
2015 GL_VERSION_2_0 := false;
2016 if MajorVersion = 1 then begin
2017 if MinorVersion >= 2 then
2018 GL_VERSION_1_2 := true;
2020 if MinorVersion >= 3 then
2021 GL_VERSION_1_3 := true;
2023 if MinorVersion >= 4 then
2024 GL_VERSION_1_4 := true;
2025 end else if MajorVersion >= 2 then begin
2026 GL_VERSION_1_2 := true;
2027 GL_VERSION_1_3 := true;
2028 GL_VERSION_1_4 := true;
2029 GL_VERSION_2_0 := true;
2033 Buffer := glGetString(GL_EXTENSIONS);
2034 GL_ARB_texture_border_clamp := CheckExtension('GL_ARB_texture_border_clamp');
2035 GL_ARB_texture_non_power_of_two := CheckExtension('GL_ARB_texture_non_power_of_two');
2036 GL_ARB_texture_rectangle := CheckExtension('GL_ARB_texture_rectangle');
2037 GL_ARB_texture_mirrored_repeat := CheckExtension('GL_ARB_texture_mirrored_repeat');
2038 GL_EXT_texture_edge_clamp := CheckExtension('GL_EXT_texture_edge_clamp');
2039 GL_EXT_texture_filter_anisotropic := CheckExtension('GL_EXT_texture_filter_anisotropic');
2040 GL_EXT_texture_rectangle := CheckExtension('GL_EXT_texture_rectangle');
2041 GL_NV_texture_rectangle := CheckExtension('GL_NV_texture_rectangle');
2042 GL_IBM_texture_mirrored_repeat := CheckExtension('GL_IBM_texture_mirrored_repeat');
2043 GL_SGIS_generate_mipmap := CheckExtension('GL_SGIS_generate_mipmap');
2045 if GL_VERSION_1_3 then begin
2046 glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1D');
2047 glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2D');
2048 glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImage');
2050 glCompressedTexImage1D := glbGetProcAddress('glCompressedTexImage1DARB');
2051 glCompressedTexImage2D := glbGetProcAddress('glCompressedTexImage2DARB');
2052 glGetCompressedTexImage := glbGetProcAddress('glGetCompressedTexImageARB');
2059 function CreateGrayPalette: HPALETTE;
2064 GetMem(Pal, SizeOf(TLogPalette) + (SizeOf(TPaletteEntry) * 256));
2066 Pal.palVersion := $300;
2067 Pal.palNumEntries := 256;
2070 {$DEFINE GLB_TEMPRANGECHECK}
2074 for Idx := 0 to 256 - 1 do begin
2075 Pal.palPalEntry[Idx].peRed := Idx;
2076 Pal.palPalEntry[Idx].peGreen := Idx;
2077 Pal.palPalEntry[Idx].peBlue := Idx;
2078 Pal.palPalEntry[Idx].peFlags := 0;
2081 {$IFDEF GLB_TEMPRANGECHECK}
2082 {$UNDEF GLB_TEMPRANGECHECK}
2086 result := CreatePalette(Pal^);
2093 {$IFDEF GLB_SDL_IMAGE}
2094 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2095 // SDL Image Helper /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2096 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2097 function glBitmapRWseek(context: PSDL_RWops; offset: Integer; whence: Integer): Integer; cdecl;
2099 result := TStream(context^.unknown.data1).Seek(offset, whence);
2102 function glBitmapRWread(context: PSDL_RWops; Ptr: Pointer; size: Integer; maxnum : Integer): Integer; cdecl;
2104 result := TStream(context^.unknown.data1).Read(Ptr^, size * maxnum);
2107 function glBitmapRWwrite(context: PSDL_RWops; Ptr: Pointer; size: Integer; num: Integer): Integer; cdecl;
2109 result := TStream(context^.unknown.data1).Write(Ptr^, size * num);
2112 function glBitmapRWclose(context: PSDL_RWops): Integer; cdecl;
2117 function glBitmapCreateRWops(Stream: TStream): PSDL_RWops;
2119 result := SDL_AllocRW;
2121 if result = nil then
2122 raise EglBitmapException.Create('glBitmapCreateRWops - SDL_AllocRW failed.');
2124 result^.seek := glBitmapRWseek;
2125 result^.read := glBitmapRWread;
2126 result^.write := glBitmapRWwrite;
2127 result^.close := glBitmapRWclose;
2128 result^.unknown.data1 := Stream;
2132 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2133 procedure glBitmapSetDefaultDeleteTextureOnFree(const aDeleteTextureOnFree: Boolean);
2135 glBitmapDefaultDeleteTextureOnFree := aDeleteTextureOnFree;
2138 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2139 procedure glBitmapSetDefaultFreeDataAfterGenTexture(const aFreeData: Boolean);
2141 glBitmapDefaultFreeDataAfterGenTextures := aFreeData;
2144 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2145 procedure glBitmapSetDefaultMipmap(const aValue: TglBitmapMipMap);
2147 glBitmapDefaultMipmap := aValue;
2150 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2151 procedure glBitmapSetDefaultFormat(const aFormat: TglBitmapFormat);
2153 glBitmapDefaultFormat := aFormat;
2156 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2157 procedure glBitmapSetDefaultFilter(const aMin, aMag: Integer);
2159 glBitmapDefaultFilterMin := aMin;
2160 glBitmapDefaultFilterMag := aMag;
2163 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2164 procedure glBitmapSetDefaultWrap(const S: Cardinal = GL_CLAMP_TO_EDGE; const T: Cardinal = GL_CLAMP_TO_EDGE; const R: Cardinal = GL_CLAMP_TO_EDGE);
2166 glBitmapDefaultWrapS := S;
2167 glBitmapDefaultWrapT := T;
2168 glBitmapDefaultWrapR := R;
2171 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2172 function glBitmapGetDefaultDeleteTextureOnFree: Boolean;
2174 result := glBitmapDefaultDeleteTextureOnFree;
2177 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2178 function glBitmapGetDefaultFreeDataAfterGenTexture: Boolean;
2180 result := glBitmapDefaultFreeDataAfterGenTextures;
2183 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2184 function glBitmapGetDefaultMipmap: TglBitmapMipMap;
2186 result := glBitmapDefaultMipmap;
2189 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2190 function glBitmapGetDefaultFormat: TglBitmapFormat;
2192 result := glBitmapDefaultFormat;
2195 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2196 procedure glBitmapGetDefaultFilter(var aMin, aMag: Cardinal);
2198 aMin := glBitmapDefaultFilterMin;
2199 aMag := glBitmapDefaultFilterMag;
2202 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2203 procedure glBitmapGetDefaultTextureWrap(var S, T, R: Cardinal);
2205 S := glBitmapDefaultWrapS;
2206 T := glBitmapDefaultWrapT;
2207 R := glBitmapDefaultWrapR;
2210 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2211 //TglBitmapFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2212 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2213 function TFormatDescriptor.GetRedMask: QWord;
2215 result := fRange.r shl fShift.r;
2218 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2219 function TFormatDescriptor.GetGreenMask: QWord;
2221 result := fRange.g shl fShift.g;
2224 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2225 function TFormatDescriptor.GetBlueMask: QWord;
2227 result := fRange.b shl fShift.b;
2230 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2231 function TFormatDescriptor.GetAlphaMask: QWord;
2233 result := fRange.a shl fShift.a;
2236 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2237 function TFormatDescriptor.GetComponents: Integer;
2243 if (fRange.arr[i] > 0) then
2247 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2248 function TFormatDescriptor.GetSize(const aSize: TglBitmapPixelPosition): Integer;
2252 if (ffX in aSize.Fields) or (ffY in aSize.Fields) then begin
2253 w := Max(1, aSize.X);
2254 h := Max(1, aSize.Y);
2255 result := GetSize(w, h);
2260 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2261 function TFormatDescriptor.GetSize(const aWidth, aHeight: Integer): Integer;
2264 if (aWidth <= 0) or (aHeight <= 0) then
2266 result := Ceil(aWidth * aHeight * fPixelSize);
2269 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2270 function TFormatDescriptor.CreateMappingData: Pointer;
2275 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2276 procedure TFormatDescriptor.FreeMappingData(var aMappingData: Pointer);
2281 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2282 function TFormatDescriptor.IsEmpty: Boolean;
2284 result := (fFormat = tfEmpty);
2287 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2288 function TFormatDescriptor.HasAlpha: Boolean;
2290 result := (fRange.a > 0);
2293 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2294 function TFormatDescriptor.MaskMatch(const aRedMask, aGreenMask, aBlueMask, aAlphaMask: QWord): Boolean;
2297 if (aRedMask = 0) and (aGreenMask = 0) and (aBlueMask = 0) and (aAlphaMask = 0) then
2298 raise EglBitmapException.Create('FormatCheckFormat - All Masks are 0');
2299 if (aRedMask <> RedMask) then
2301 if (aGreenMask <> GreenMask) then
2303 if (aBlueMask <> BlueMask) then
2305 if (aAlphaMask <> AlphaMask) then
2310 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2311 procedure TFormatDescriptor.PreparePixel(out aPixel: TglBitmapPixelData);
2313 FillChar(aPixel{%H-}, SizeOf(aPixel), 0);
2314 aPixel.Data := fRange;
2315 aPixel.Range := fRange;
2316 aPixel.Format := fFormat;
2319 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2320 constructor TFormatDescriptor.Create;
2325 fWithAlpha := tfEmpty;
2326 fWithoutAlpha := tfEmpty;
2327 fRGBInverted := tfEmpty;
2328 fUncompressed := tfEmpty;
2330 fIsCompressed := false;
2333 fglInternalFormat := 0;
2336 FillChar(fRange, 0, SizeOf(fRange));
2337 FillChar(fShift, 0, SizeOf(fShift));
2340 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2341 //TfdAlpha_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2342 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2343 procedure TfdAlpha_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2345 aData^ := aPixel.Data.a;
2349 procedure TfdAlpha_UB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2354 aPixel.Data.a := aData^;
2358 constructor TfdAlpha_UB1.Create;
2363 fglFormat := GL_ALPHA;
2364 fglDataFormat := GL_UNSIGNED_BYTE;
2367 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2368 //TfdLuminance_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2369 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2370 procedure TfdLuminance_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2372 aData^ := LuminanceWeight(aPixel);
2376 procedure TfdLuminance_UB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2378 aPixel.Data.r := aData^;
2379 aPixel.Data.g := aData^;
2380 aPixel.Data.b := aData^;
2385 constructor TfdLuminance_UB1.Create;
2392 fglFormat := GL_LUMINANCE;
2393 fglDataFormat := GL_UNSIGNED_BYTE;
2396 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2397 //TfdUniversal_UB1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2398 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2399 procedure TfdUniversal_UB1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2405 if (fRange.arr[i] > 0) then
2406 aData^ := aData^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
2410 procedure TfdUniversal_UB1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2415 aPixel.Data.arr[i] := (aData^ shr fShift.arr[i]) and fRange.arr[i];
2419 constructor TfdUniversal_UB1.Create;
2425 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2426 //TfdLuminanceAlpha_UB2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2427 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2428 procedure TfdLuminanceAlpha_UB2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2430 inherited Map(aPixel, aData, aMapData);
2431 aData^ := aPixel.Data.a;
2435 procedure TfdLuminanceAlpha_UB2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2437 inherited Unmap(aData, aPixel, aMapData);
2438 aPixel.Data.a := aData^;
2442 constructor TfdLuminanceAlpha_UB2.Create;
2448 fglFormat := GL_LUMINANCE_ALPHA;
2449 fglDataFormat := GL_UNSIGNED_BYTE;
2452 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2453 //TfdRGB_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2454 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2455 procedure TfdRGB_UB3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2457 aData^ := aPixel.Data.r;
2459 aData^ := aPixel.Data.g;
2461 aData^ := aPixel.Data.b;
2465 procedure TfdRGB_UB3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2467 aPixel.Data.r := aData^;
2469 aPixel.Data.g := aData^;
2471 aPixel.Data.b := aData^;
2476 constructor TfdRGB_UB3.Create;
2486 fglFormat := GL_RGB;
2487 fglDataFormat := GL_UNSIGNED_BYTE;
2490 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2491 //TfdBGR_UB3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2492 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2493 procedure TfdBGR_UB3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2495 aData^ := aPixel.Data.b;
2497 aData^ := aPixel.Data.g;
2499 aData^ := aPixel.Data.r;
2503 procedure TfdBGR_UB3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2505 aPixel.Data.b := aData^;
2507 aPixel.Data.g := aData^;
2509 aPixel.Data.r := aData^;
2514 constructor TfdBGR_UB3.Create;
2523 fglFormat := GL_BGR;
2524 fglDataFormat := GL_UNSIGNED_BYTE;
2527 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2528 //TdfRGBA_UB4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2529 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2530 procedure TfdRGBA_UB4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2532 inherited Map(aPixel, aData, aMapData);
2533 aData^ := aPixel.Data.a;
2537 procedure TfdRGBA_UB4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2539 inherited Unmap(aData, aPixel, aMapData);
2540 aPixel.Data.a := aData^;
2544 constructor TfdRGBA_UB4.Create;
2550 fglFormat := GL_RGBA;
2551 fglDataFormat := GL_UNSIGNED_BYTE;
2554 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2555 //TfdBGRA_UB4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2556 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2557 procedure TfdBGRA_UB4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2559 inherited Map(aPixel, aData, aMapData);
2560 aData^ := aPixel.Data.a;
2564 procedure TfdBGRA_UB4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2566 inherited Unmap(aData, aPixel, aMapData);
2567 aPixel.Data.a := aData^;
2571 constructor TfdBGRA_UB4.Create;
2577 fglFormat := GL_BGRA;
2578 fglDataFormat := GL_UNSIGNED_BYTE;
2581 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2582 //TfdAlpha_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2583 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2584 procedure TfdAlpha_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2586 PWord(aData)^ := aPixel.Data.a;
2590 procedure TfdAlpha_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2595 aPixel.Data.a := PWord(aData)^;
2599 constructor TfdAlpha_US1.Create;
2604 fglFormat := GL_ALPHA;
2605 fglDataFormat := GL_UNSIGNED_SHORT;
2608 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2609 //TfdLuminance_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2610 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2611 procedure TfdLuminance_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2613 PWord(aData)^ := LuminanceWeight(aPixel);
2617 procedure TfdLuminance_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2619 aPixel.Data.r := PWord(aData)^;
2620 aPixel.Data.g := PWord(aData)^;
2621 aPixel.Data.b := PWord(aData)^;
2626 constructor TfdLuminance_US1.Create;
2633 fglFormat := GL_LUMINANCE;
2634 fglDataFormat := GL_UNSIGNED_SHORT;
2637 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2638 //TfdUniversal_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2639 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2640 procedure TfdUniversal_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2646 if (fRange.arr[i] > 0) then
2647 PWord(aData)^ := PWord(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
2651 procedure TfdUniversal_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2656 aPixel.Data.arr[i] := (PWord(aData)^ shr fShift.arr[i]) and fRange.arr[i];
2660 constructor TfdUniversal_US1.Create;
2666 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2667 //TfdDepth_US1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2668 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2669 procedure TfdDepth_US1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2671 PWord(aData)^ := DepthWeight(aPixel);
2675 procedure TfdDepth_US1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2677 aPixel.Data.r := PWord(aData)^;
2678 aPixel.Data.g := PWord(aData)^;
2679 aPixel.Data.b := PWord(aData)^;
2684 constructor TfdDepth_US1.Create;
2691 fglFormat := GL_DEPTH_COMPONENT;
2692 fglDataFormat := GL_UNSIGNED_SHORT;
2695 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2696 //TfdLuminanceAlpha_US2///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2697 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2698 procedure TfdLuminanceAlpha_US2.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2700 inherited Map(aPixel, aData, aMapData);
2701 PWord(aData)^ := aPixel.Data.a;
2705 procedure TfdLuminanceAlpha_US2.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2707 inherited Unmap(aData, aPixel, aMapData);
2708 aPixel.Data.a := PWord(aData)^;
2712 constructor TfdLuminanceAlpha_US2.Create;
2718 fglFormat := GL_LUMINANCE_ALPHA;
2719 fglDataFormat := GL_UNSIGNED_SHORT;
2722 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2723 //TfdRGB_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2724 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2725 procedure TfdRGB_US3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2727 PWord(aData)^ := aPixel.Data.r;
2729 PWord(aData)^ := aPixel.Data.g;
2731 PWord(aData)^ := aPixel.Data.b;
2735 procedure TfdRGB_US3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2737 aPixel.Data.r := PWord(aData)^;
2739 aPixel.Data.g := PWord(aData)^;
2741 aPixel.Data.b := PWord(aData)^;
2746 constructor TfdRGB_US3.Create;
2756 fglFormat := GL_RGB;
2757 fglDataFormat := GL_UNSIGNED_SHORT;
2760 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2761 //TfdBGR_US3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2762 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2763 procedure TfdBGR_US3.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2765 PWord(aData)^ := aPixel.Data.b;
2767 PWord(aData)^ := aPixel.Data.g;
2769 PWord(aData)^ := aPixel.Data.r;
2773 procedure TfdBGR_US3.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2775 aPixel.Data.b := PWord(aData)^;
2777 aPixel.Data.g := PWord(aData)^;
2779 aPixel.Data.r := PWord(aData)^;
2784 constructor TfdBGR_US3.Create;
2794 fglFormat := GL_BGR;
2795 fglDataFormat := GL_UNSIGNED_SHORT;
2798 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2799 //TfdRGBA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2800 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2801 procedure TfdRGBA_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2803 inherited Map(aPixel, aData, aMapData);
2804 PWord(aData)^ := aPixel.Data.a;
2808 procedure TfdRGBA_US4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2810 inherited Unmap(aData, aPixel, aMapData);
2811 aPixel.Data.a := PWord(aData)^;
2815 constructor TfdRGBA_US4.Create;
2821 fglFormat := GL_RGBA;
2822 fglDataFormat := GL_UNSIGNED_SHORT;
2825 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2826 //TfdBGRA_US4/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2827 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2828 procedure TfdBGRA_US4.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2830 inherited Map(aPixel, aData, aMapData);
2831 PWord(aData)^ := aPixel.Data.a;
2835 procedure TfdBGRA_US4.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2837 inherited Unmap(aData, aPixel, aMapData);
2838 aPixel.Data.a := PWord(aData)^;
2842 constructor TfdBGRA_US4.Create;
2848 fglFormat := GL_BGRA;
2849 fglDataFormat := GL_UNSIGNED_SHORT;
2852 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2853 //TfdUniversal_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2854 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2855 procedure TfdUniversal_UI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2859 PCardinal(aData)^ := 0;
2861 if (fRange.arr[i] > 0) then
2862 PCardinal(aData)^ := PCardinal(aData)^ or ((aPixel.Data.arr[i] and fRange.arr[i]) shl fShift.arr[i]);
2866 procedure TfdUniversal_UI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2871 aPixel.Data.arr[i] := (PCardinal(aData)^ shr fShift.arr[i]) and fRange.arr[i];
2875 constructor TfdUniversal_UI1.Create;
2881 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2882 //TfdDepth_UI1////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2883 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2884 procedure TfdDepth_UI1.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
2886 PCardinal(aData)^ := DepthWeight(aPixel);
2890 procedure TfdDepth_UI1.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
2892 aPixel.Data.r := PCardinal(aData)^;
2893 aPixel.Data.g := PCardinal(aData)^;
2894 aPixel.Data.b := PCardinal(aData)^;
2899 constructor TfdDepth_UI1.Create;
2903 fRange.r := $FFFFFFFF;
2904 fRange.g := $FFFFFFFF;
2905 fRange.b := $FFFFFFFF;
2906 fglFormat := GL_DEPTH_COMPONENT;
2907 fglDataFormat := GL_UNSIGNED_INT;
2910 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2911 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2912 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2913 constructor TfdAlpha4.Create;
2916 fFormat := tfAlpha4;
2917 fWithAlpha := tfAlpha4;
2918 fglInternalFormat := GL_ALPHA4;
2921 constructor TfdAlpha8.Create;
2924 fFormat := tfAlpha8;
2925 fWithAlpha := tfAlpha8;
2926 fglInternalFormat := GL_ALPHA8;
2929 constructor TfdAlpha12.Create;
2932 fFormat := tfAlpha12;
2933 fWithAlpha := tfAlpha12;
2934 fglInternalFormat := GL_ALPHA12;
2937 constructor TfdAlpha16.Create;
2940 fFormat := tfAlpha16;
2941 fWithAlpha := tfAlpha16;
2942 fglInternalFormat := GL_ALPHA16;
2945 constructor TfdLuminance4.Create;
2948 fFormat := tfLuminance4;
2949 fWithAlpha := tfLuminance4Alpha4;
2950 fWithoutAlpha := tfLuminance4;
2951 fglInternalFormat := GL_LUMINANCE4;
2954 constructor TfdLuminance8.Create;
2957 fFormat := tfLuminance8;
2958 fWithAlpha := tfLuminance8Alpha8;
2959 fWithoutAlpha := tfLuminance8;
2960 fglInternalFormat := GL_LUMINANCE8;
2963 constructor TfdLuminance12.Create;
2966 fFormat := tfLuminance12;
2967 fWithAlpha := tfLuminance12Alpha12;
2968 fWithoutAlpha := tfLuminance12;
2969 fglInternalFormat := GL_LUMINANCE12;
2972 constructor TfdLuminance16.Create;
2975 fFormat := tfLuminance16;
2976 fWithAlpha := tfLuminance16Alpha16;
2977 fWithoutAlpha := tfLuminance16;
2978 fglInternalFormat := GL_LUMINANCE16;
2981 constructor TfdLuminance4Alpha4.Create;
2984 fFormat := tfLuminance4Alpha4;
2985 fWithAlpha := tfLuminance4Alpha4;
2986 fWithoutAlpha := tfLuminance4;
2987 fglInternalFormat := GL_LUMINANCE4_ALPHA4;
2990 constructor TfdLuminance6Alpha2.Create;
2993 fFormat := tfLuminance6Alpha2;
2994 fWithAlpha := tfLuminance6Alpha2;
2995 fWithoutAlpha := tfLuminance8;
2996 fglInternalFormat := GL_LUMINANCE6_ALPHA2;
2999 constructor TfdLuminance8Alpha8.Create;
3002 fFormat := tfLuminance8Alpha8;
3003 fWithAlpha := tfLuminance8Alpha8;
3004 fWithoutAlpha := tfLuminance8;
3005 fglInternalFormat := GL_LUMINANCE8_ALPHA8;
3008 constructor TfdLuminance12Alpha4.Create;
3011 fFormat := tfLuminance12Alpha4;
3012 fWithAlpha := tfLuminance12Alpha4;
3013 fWithoutAlpha := tfLuminance12;
3014 fglInternalFormat := GL_LUMINANCE12_ALPHA4;
3017 constructor TfdLuminance12Alpha12.Create;
3020 fFormat := tfLuminance12Alpha12;
3021 fWithAlpha := tfLuminance12Alpha12;
3022 fWithoutAlpha := tfLuminance12;
3023 fglInternalFormat := GL_LUMINANCE12_ALPHA12;
3026 constructor TfdLuminance16Alpha16.Create;
3029 fFormat := tfLuminance16Alpha16;
3030 fWithAlpha := tfLuminance16Alpha16;
3031 fWithoutAlpha := tfLuminance16;
3032 fglInternalFormat := GL_LUMINANCE16_ALPHA16;
3035 constructor TfdR3G3B2.Create;
3038 fFormat := tfR3G3B2;
3039 fWithAlpha := tfRGBA2;
3040 fWithoutAlpha := tfR3G3B2;
3047 fglFormat := GL_RGB;
3048 fglInternalFormat := GL_R3_G3_B2;
3049 fglDataFormat := GL_UNSIGNED_BYTE_2_3_3_REV;
3052 constructor TfdRGB4.Create;
3056 fWithAlpha := tfRGBA4;
3057 fWithoutAlpha := tfRGB4;
3058 fRGBInverted := tfBGR4;
3065 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3066 fglInternalFormat := GL_RGB4;
3067 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3070 constructor TfdR5G6B5.Create;
3073 fFormat := tfR5G6B5;
3074 fWithAlpha := tfRGBA4;
3075 fWithoutAlpha := tfR5G6B5;
3076 fRGBInverted := tfB5G6R5;
3083 fglFormat := GL_RGB;
3084 fglInternalFormat := GL_RGB565;
3085 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5_REV;
3088 constructor TfdRGB5.Create;
3092 fWithAlpha := tfRGB5A1;
3093 fWithoutAlpha := tfRGB5;
3094 fRGBInverted := tfBGR5;
3101 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3102 fglInternalFormat := GL_RGB5;
3103 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3106 constructor TfdRGB8.Create;
3110 fWithAlpha := tfRGBA8;
3111 fWithoutAlpha := tfRGB8;
3112 fRGBInverted := tfBGR8;
3113 fglInternalFormat := GL_RGB8;
3116 constructor TfdRGB10.Create;
3120 fWithAlpha := tfRGB10A2;
3121 fWithoutAlpha := tfRGB10;
3122 fRGBInverted := tfBGR10;
3129 fglFormat := GL_RGBA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3130 fglInternalFormat := GL_RGB10;
3131 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3134 constructor TfdRGB12.Create;
3138 fWithAlpha := tfRGBA12;
3139 fWithoutAlpha := tfRGB12;
3140 fRGBInverted := tfBGR12;
3141 fglInternalFormat := GL_RGB12;
3144 constructor TfdRGB16.Create;
3148 fWithAlpha := tfRGBA16;
3149 fWithoutAlpha := tfRGB16;
3150 fRGBInverted := tfBGR16;
3151 fglInternalFormat := GL_RGB16;
3154 constructor TfdRGBA2.Create;
3158 fWithAlpha := tfRGBA2;
3159 fWithoutAlpha := tfR3G3B2;
3160 fRGBInverted := tfBGRA2;
3161 fglInternalFormat := GL_RGBA2;
3164 constructor TfdRGBA4.Create;
3168 fWithAlpha := tfRGBA4;
3169 fWithoutAlpha := tfRGB4;
3170 fRGBInverted := tfBGRA4;
3179 fglFormat := GL_RGBA;
3180 fglInternalFormat := GL_RGBA4;
3181 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3184 constructor TfdRGB5A1.Create;
3187 fFormat := tfRGB5A1;
3188 fWithAlpha := tfRGB5A1;
3189 fWithoutAlpha := tfRGB5;
3190 fRGBInverted := tfBGR5A1;
3199 fglFormat := GL_RGBA;
3200 fglInternalFormat := GL_RGB5_A1;
3201 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3204 constructor TfdRGBA8.Create;
3208 fWithAlpha := tfRGBA8;
3209 fWithoutAlpha := tfRGB8;
3210 fRGBInverted := tfBGRA8;
3211 fglInternalFormat := GL_RGBA8;
3214 constructor TfdRGB10A2.Create;
3217 fFormat := tfRGB10A2;
3218 fWithAlpha := tfRGB10A2;
3219 fWithoutAlpha := tfRGB10;
3220 fRGBInverted := tfBGR10A2;
3229 fglFormat := GL_RGBA;
3230 fglInternalFormat := GL_RGB10_A2;
3231 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3234 constructor TfdRGBA12.Create;
3237 fFormat := tfRGBA12;
3238 fWithAlpha := tfRGBA12;
3239 fWithoutAlpha := tfRGB12;
3240 fRGBInverted := tfBGRA12;
3241 fglInternalFormat := GL_RGBA12;
3244 constructor TfdRGBA16.Create;
3247 fFormat := tfRGBA16;
3248 fWithAlpha := tfRGBA16;
3249 fWithoutAlpha := tfRGB16;
3250 fRGBInverted := tfBGRA16;
3251 fglInternalFormat := GL_RGBA16;
3254 constructor TfdBGR4.Create;
3259 fWithAlpha := tfBGRA4;
3260 fWithoutAlpha := tfBGR4;
3261 fRGBInverted := tfRGB4;
3270 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3271 fglInternalFormat := GL_RGB4;
3272 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3275 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3276 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3277 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3278 constructor TfdB5G6R5.Create;
3281 fFormat := tfB5G6R5;
3282 fWithAlpha := tfBGRA4;
3283 fWithoutAlpha := tfB5G6R5;
3284 fRGBInverted := tfR5G6B5;
3291 fglFormat := GL_RGB; //B5G6R5 is only possible as R5G6B5 -> use reverted dataformat
3292 fglInternalFormat := GL_RGB8;
3293 fglDataFormat := GL_UNSIGNED_SHORT_5_6_5;
3296 constructor TfdBGR5.Create;
3301 fWithAlpha := tfBGR5A1;
3302 fWithoutAlpha := tfBGR5;
3303 fRGBInverted := tfRGB5;
3312 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3313 fglInternalFormat := GL_RGB5;
3314 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3317 constructor TfdBGR8.Create;
3321 fWithAlpha := tfBGRA8;
3322 fWithoutAlpha := tfBGR8;
3323 fRGBInverted := tfRGB8;
3324 fglInternalFormat := GL_RGB8;
3327 constructor TfdBGR10.Create;
3331 fWithAlpha := tfBGR10A2;
3332 fWithoutAlpha := tfBGR10;
3333 fRGBInverted := tfRGB10;
3342 fglFormat := GL_BGRA; //GL_INVALID_OPERATION if not GL_BGRA or GL_RGBA
3343 fglInternalFormat := GL_RGB10;
3344 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3347 constructor TfdBGR12.Create;
3351 fWithAlpha := tfBGRA12;
3352 fWithoutAlpha := tfBGR12;
3353 fRGBInverted := tfRGB12;
3354 fglInternalFormat := GL_RGB12;
3357 constructor TfdBGR16.Create;
3361 fWithAlpha := tfBGRA16;
3362 fWithoutAlpha := tfBGR16;
3363 fRGBInverted := tfRGB16;
3364 fglInternalFormat := GL_RGB16;
3367 constructor TfdBGRA2.Create;
3371 fWithAlpha := tfBGRA4;
3372 fWithoutAlpha := tfBGR4;
3373 fRGBInverted := tfRGBA2;
3374 fglInternalFormat := GL_RGBA2;
3377 constructor TfdBGRA4.Create;
3381 fWithAlpha := tfBGRA4;
3382 fWithoutAlpha := tfBGR4;
3383 fRGBInverted := tfRGBA4;
3392 fglFormat := GL_BGRA;
3393 fglInternalFormat := GL_RGBA4;
3394 fglDataFormat := GL_UNSIGNED_SHORT_4_4_4_4_REV;
3397 constructor TfdBGR5A1.Create;
3400 fFormat := tfBGR5A1;
3401 fWithAlpha := tfBGR5A1;
3402 fWithoutAlpha := tfBGR5;
3403 fRGBInverted := tfRGB5A1;
3412 fglFormat := GL_BGRA;
3413 fglInternalFormat := GL_RGB5_A1;
3414 fglDataFormat := GL_UNSIGNED_SHORT_1_5_5_5_REV;
3417 constructor TfdBGRA8.Create;
3421 fWithAlpha := tfBGRA8;
3422 fWithoutAlpha := tfBGR8;
3423 fRGBInverted := tfRGBA8;
3424 fglInternalFormat := GL_RGBA8;
3427 constructor TfdBGR10A2.Create;
3430 fFormat := tfBGR10A2;
3431 fWithAlpha := tfBGR10A2;
3432 fWithoutAlpha := tfBGR10;
3433 fRGBInverted := tfRGB10A2;
3442 fglFormat := GL_BGRA;
3443 fglInternalFormat := GL_RGB10_A2;
3444 fglDataFormat := GL_UNSIGNED_INT_2_10_10_10_REV;
3447 constructor TfdBGRA12.Create;
3450 fFormat := tfBGRA12;
3451 fWithAlpha := tfBGRA12;
3452 fWithoutAlpha := tfBGR12;
3453 fRGBInverted := tfRGBA12;
3454 fglInternalFormat := GL_RGBA12;
3457 constructor TfdBGRA16.Create;
3460 fFormat := tfBGRA16;
3461 fWithAlpha := tfBGRA16;
3462 fWithoutAlpha := tfBGR16;
3463 fRGBInverted := tfRGBA16;
3464 fglInternalFormat := GL_RGBA16;
3467 constructor TfdDepth16.Create;
3470 fFormat := tfDepth16;
3471 fWithAlpha := tfEmpty;
3472 fWithoutAlpha := tfDepth16;
3473 fglInternalFormat := GL_DEPTH_COMPONENT16;
3476 constructor TfdDepth24.Create;
3479 fFormat := tfDepth24;
3480 fWithAlpha := tfEmpty;
3481 fWithoutAlpha := tfDepth24;
3482 fglInternalFormat := GL_DEPTH_COMPONENT24;
3485 constructor TfdDepth32.Create;
3488 fFormat := tfDepth32;
3489 fWithAlpha := tfEmpty;
3490 fWithoutAlpha := tfDepth32;
3491 fglInternalFormat := GL_DEPTH_COMPONENT32;
3494 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3495 //TfdS3tcDtx1RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3496 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3497 procedure TfdS3tcDtx1RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3499 raise EglBitmapException.Create('mapping for compressed formats is not supported');
3502 procedure TfdS3tcDtx1RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3504 raise EglBitmapException.Create('mapping for compressed formats is not supported');
3507 constructor TfdS3tcDtx1RGBA.Create;
3510 fFormat := tfS3tcDtx1RGBA;
3511 fWithAlpha := tfS3tcDtx1RGBA;
3512 fUncompressed := tfRGB5A1;
3514 fIsCompressed := true;
3515 fglFormat := GL_COMPRESSED_RGBA;
3516 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
3517 fglDataFormat := GL_UNSIGNED_BYTE;
3520 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3521 //TfdS3tcDtx3RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3522 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3523 procedure TfdS3tcDtx3RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3525 raise EglBitmapException.Create('mapping for compressed formats is not supported');
3528 procedure TfdS3tcDtx3RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3530 raise EglBitmapException.Create('mapping for compressed formats is not supported');
3533 constructor TfdS3tcDtx3RGBA.Create;
3536 fFormat := tfS3tcDtx3RGBA;
3537 fWithAlpha := tfS3tcDtx3RGBA;
3538 fUncompressed := tfRGBA8;
3540 fIsCompressed := true;
3541 fglFormat := GL_COMPRESSED_RGBA;
3542 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
3543 fglDataFormat := GL_UNSIGNED_BYTE;
3546 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3547 //TfdS3tcDtx5RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3548 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3549 procedure TfdS3tcDtx5RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3551 raise EglBitmapException.Create('mapping for compressed formats is not supported');
3554 procedure TfdS3tcDtx5RGBA.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3556 raise EglBitmapException.Create('mapping for compressed formats is not supported');
3559 constructor TfdS3tcDtx5RGBA.Create;
3562 fFormat := tfS3tcDtx3RGBA;
3563 fWithAlpha := tfS3tcDtx3RGBA;
3564 fUncompressed := tfRGBA8;
3566 fIsCompressed := true;
3567 fglFormat := GL_COMPRESSED_RGBA;
3568 fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
3569 fglDataFormat := GL_UNSIGNED_BYTE;
3572 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3573 //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3574 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3575 class procedure TFormatDescriptor.Init;
3577 if not Assigned(FormatDescriptorCS) then
3578 FormatDescriptorCS := TCriticalSection.Create;
3581 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3582 class function TFormatDescriptor.Get(const aFormat: TglBitmapFormat): TFormatDescriptor;
3584 FormatDescriptorCS.Enter;
3586 result := FormatDescriptors[aFormat];
3587 if not Assigned(result) then begin
3588 result := FORMAT_DESCRIPTOR_CLASSES[aFormat].Create;
3589 FormatDescriptors[aFormat] := result;
3592 FormatDescriptorCS.Leave;
3596 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3597 class function TFormatDescriptor.GetWithAlpha(const aFormat: TglBitmapFormat): TFormatDescriptor;
3599 result := Get(Get(aFormat).WithAlpha);
3602 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3603 class procedure TFormatDescriptor.Clear;
3607 FormatDescriptorCS.Enter;
3609 for f := low(FormatDescriptors) to high(FormatDescriptors) do
3610 FreeAndNil(FormatDescriptors[f]);
3612 FormatDescriptorCS.Leave;
3616 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3617 class procedure TFormatDescriptor.Finalize;
3620 FreeAndNil(FormatDescriptorCS);
3623 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3624 //TBitfieldFormat/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3625 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3626 procedure TbmpBitfieldFormat.SetRedMask(const aValue: QWord);
3628 Update(aValue, fRange.r, fShift.r);
3631 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3632 procedure TbmpBitfieldFormat.SetGreenMask(const aValue: QWord);
3634 Update(aValue, fRange.g, fShift.g);
3637 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3638 procedure TbmpBitfieldFormat.SetBlueMask(const aValue: QWord);
3640 Update(aValue, fRange.b, fShift.b);
3643 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3644 procedure TbmpBitfieldFormat.SetAlphaMask(const aValue: QWord);
3646 Update(aValue, fRange.a, fShift.a);
3649 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3650 procedure TbmpBitfieldFormat.Update(aMask: QWord; out aRange: Cardinal; out
3657 while (aMask > 0) and ((aMask and 1) = 0) do begin
3659 aMask := aMask shr 1;
3662 while (aMask > 0) do begin
3663 aRange := aRange shl 1;
3664 aMask := aMask shr 1;
3668 fPixelSize := Round(GetTopMostBit(RedMask or GreenMask or BlueMask or AlphaMask) / 8);
3671 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3672 procedure TbmpBitfieldFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3678 ((aPixel.Data.r and fRange.r) shl fShift.r) or
3679 ((aPixel.Data.g and fRange.g) shl fShift.g) or
3680 ((aPixel.Data.b and fRange.b) shl fShift.b) or
3681 ((aPixel.Data.a and fRange.a) shl fShift.a);
3682 s := Round(fPixelSize);
3685 2: PWord(aData)^ := data;
3686 4: PCardinal(aData)^ := data;
3687 8: PQWord(aData)^ := data;
3689 raise EglBitmapException.CreateFmt('invalid pixel size: %.1f', [fPixelSize]);
3694 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3695 procedure TbmpBitfieldFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3700 s := Round(fPixelSize);
3703 2: data := PWord(aData)^;
3704 4: data := PCardinal(aData)^;
3705 8: data := PQWord(aData)^;
3707 raise EglBitmapException.CreateFmt('invalid pixel size: %.1f', [fPixelSize]);
3710 aPixel.Data.arr[i] := (data shr fShift.arr[i]) and fRange.arr[i];
3714 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3715 //TColorTableFormat///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3716 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3717 procedure TbmpColorTableFormat.CreateColorTable;
3721 if not (Format in [tfLuminance4, tfLuminance8, tfR3G3B2]) then
3722 raise EglBitmapException.Create(UNSUPPORTED_FORMAT);
3724 if (Format = tfLuminance4) then
3725 SetLength(fColorTable, 16)
3727 SetLength(fColorTable, 256);
3731 for i := 0 to High(fColorTable) do begin
3732 fColorTable[i].r := 16 * i;
3733 fColorTable[i].g := 16 * i;
3734 fColorTable[i].b := 16 * i;
3735 fColorTable[i].a := 0;
3740 for i := 0 to High(fColorTable) do begin
3741 fColorTable[i].r := i;
3742 fColorTable[i].g := i;
3743 fColorTable[i].b := i;
3744 fColorTable[i].a := 0;
3749 for i := 0 to High(fColorTable) do begin
3750 fColorTable[i].r := Round(((i shr Shift.r) and Range.r) / Range.r * 255);
3751 fColorTable[i].g := Round(((i shr Shift.g) and Range.g) / Range.g * 255);
3752 fColorTable[i].b := Round(((i shr Shift.b) and Range.b) / Range.b * 255);
3753 fColorTable[i].a := 0;
3759 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3760 procedure TbmpColorTableFormat.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
3764 if not (Format in [tfLuminance4, tfLuminance8, tfR3G3B2]) then
3765 raise EglBitmapException.Create(UNSUPPORTED_FORMAT);
3769 if (aMapData = nil) then
3771 d := LuminanceWeight(aPixel) and Range.r;
3772 aData^ := aData^ or (d shl (4 - {%H-}PtrUInt(aMapData)));
3773 inc(PByte(aMapData), 4);
3774 if ({%H-}PtrUInt(aMapData) >= 8) then begin
3781 aData^ := LuminanceWeight(aPixel) and Range.r;
3787 ((aPixel.Data.r and Range.r) shl Shift.r) or
3788 ((aPixel.Data.g and Range.g) shl Shift.g) or
3789 ((aPixel.Data.b and Range.b) shl Shift.b));
3795 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3796 procedure TbmpColorTableFormat.Unmap(var aData: PByte; out aPixel: TglBitmapPixelData; var aMapData: Pointer);
3803 s := Trunc(fPixelSize);
3804 f := fPixelSize - s;
3805 bits := Round(8 * f);
3807 0: idx := (aData^ shr (8 - bits - {%H-}PtrInt(aMapData))) and ((1 shl bits) - 1);
3809 2: idx := PWord(aData)^;
3810 4: idx := PCardinal(aData)^;
3811 8: idx := PQWord(aData)^;
3813 raise EglBitmapException.CreateFmt('invalid pixel size: %.3f', [fPixelSize]);
3815 if (idx >= Length(fColorTable)) then
3816 raise EglBitmapException.CreateFmt('invalid color index: %d', [idx]);
3817 with fColorTable[idx] do begin
3823 inc(PByte(aMapData), bits);
3824 if ({%H-}PtrUInt(aMapData) >= 8) then begin
3826 dec(PByte(aMapData), 8);
3831 destructor TbmpColorTableFormat.Destroy;
3833 SetLength(fColorTable, 0);
3837 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3838 //TglBitmap - Helper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3839 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3840 procedure glBitmapConvertPixel(var aPixel: TglBitmapPixelData; const aSourceFD, aDestFD: TFormatDescriptor);
3844 for i := 0 to 3 do begin
3845 if (aSourceFD.Range.arr[i] <> aDestFD.Range.arr[i]) then begin
3846 if (aSourceFD.Range.arr[i] > 0) then
3847 aPixel.Data.arr[i] := Round(aPixel.Data.arr[i] / aSourceFD.Range.arr[i] * aDestFD.Range.arr[i])
3849 aPixel.Data.arr[i] := aDestFD.Range.arr[i];
3854 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3855 procedure glBitmapConvertCopyFunc(var aFuncRec: TglBitmapFunctionRec);
3857 with aFuncRec do begin
3858 if (Source.Range.r > 0) then
3859 Dest.Data.r := Source.Data.r;
3860 if (Source.Range.g > 0) then
3861 Dest.Data.g := Source.Data.g;
3862 if (Source.Range.b > 0) then
3863 Dest.Data.b := Source.Data.b;
3864 if (Source.Range.a > 0) then
3865 Dest.Data.a := Source.Data.a;
3869 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3870 procedure glBitmapConvertCalculateRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
3874 with aFuncRec do begin
3876 if (Source.Range.arr[i] > 0) then
3877 Dest.Data.arr[i] := Round(Dest.Range.arr[i] * Source.Data.arr[i] / Source.Range.arr[i]);
3882 TShiftData = packed record
3884 0: (r, g, b, a: SmallInt);
3885 1: (arr: array[0..3] of SmallInt);
3887 PShiftData = ^TShiftData;
3889 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3890 procedure glBitmapConvertShiftRGBAFunc(var aFuncRec: TglBitmapFunctionRec);
3896 if (Source.Range.arr[i] > 0) then
3897 Dest.Data.arr[i] := Source.Data.arr[i] shr PShiftData(Args)^.arr[i];
3900 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3901 procedure glBitmapInvertFunc(var aFuncRec: TglBitmapFunctionRec);
3903 with aFuncRec do begin
3904 Dest.Data := Source.Data;
3905 if ({%H-}PtrUInt(Args) and $1 > 0) then begin
3906 Dest.Data.r := Dest.Data.r xor Dest.Range.r;
3907 Dest.Data.g := Dest.Data.g xor Dest.Range.g;
3908 Dest.Data.b := Dest.Data.b xor Dest.Range.b;
3910 if ({%H-}PtrUInt(Args) and $2 > 0) then begin
3911 Dest.Data.a := Dest.Data.a xor Dest.Range.a;
3916 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3917 procedure glBitmapFillWithColorFunc(var aFuncRec: TglBitmapFunctionRec);
3921 with aFuncRec do begin
3923 Dest.Data.arr[i] := PglBitmapPixelData(Args)^.Data.arr[i];
3927 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3928 procedure glBitmapAlphaFunc(var FuncRec: TglBitmapFunctionRec);
3932 with FuncRec do begin
3933 if (FuncRec.Args = nil) then begin //source has no alpha
3935 Source.Data.r / Source.Range.r * ALPHA_WEIGHT_R +
3936 Source.Data.g / Source.Range.g * ALPHA_WEIGHT_G +
3937 Source.Data.b / Source.Range.b * ALPHA_WEIGHT_B;
3938 Dest.Data.a := Round(Dest.Range.a * Temp);
3940 Dest.Data.a := Round(Source.Data.a / Source.Range.a * Dest.Range.a);
3944 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3945 procedure glBitmapColorKeyAlphaFunc(var FuncRec: TglBitmapFunctionRec);
3947 PglBitmapPixelData = ^TglBitmapPixelData;
3949 with FuncRec do begin
3950 Dest.Data.r := Source.Data.r;
3951 Dest.Data.g := Source.Data.g;
3952 Dest.Data.b := Source.Data.b;
3954 with PglBitmapPixelData(Args)^ do
3955 if ((Dest.Data.r <= Data.r) and (Dest.Data.r >= Range.r) and
3956 (Dest.Data.g <= Data.g) and (Dest.Data.g >= Range.g) and
3957 (Dest.Data.b <= Data.b) and (Dest.Data.b >= Range.b)) then
3960 Dest.Data.a := Dest.Range.a;
3964 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3965 procedure glBitmapValueAlphaFunc(var FuncRec: TglBitmapFunctionRec);
3967 with FuncRec do begin
3968 Dest.Data.r := Source.Data.r;
3969 Dest.Data.g := Source.Data.g;
3970 Dest.Data.b := Source.Data.b;
3971 Dest.Data.a := PCardinal(Args)^;
3975 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3976 procedure SwapRGB(aData: PByte; aWidth: Integer; const aHasAlpha: Boolean);
3979 TRGBPix = array [0..2] of byte;
3983 while aWidth > 0 do begin
3984 Temp := PRGBPix(aData)^[0];
3985 PRGBPix(aData)^[0] := PRGBPix(aData)^[2];
3986 PRGBPix(aData)^[2] := Temp;
3996 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3997 //TglBitmap - PROTECTED///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3998 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3999 function TglBitmap.GetWidth: Integer;
4001 if (ffX in fDimension.Fields) then
4002 result := fDimension.X
4007 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4008 function TglBitmap.GetHeight: Integer;
4010 if (ffY in fDimension.Fields) then
4011 result := fDimension.Y
4016 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4017 function TglBitmap.GetFileWidth: Integer;
4019 result := Max(1, Width);
4022 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4023 function TglBitmap.GetFileHeight: Integer;
4025 result := Max(1, Height);
4028 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4029 procedure TglBitmap.SetCustomData(const aValue: Pointer);
4031 if fCustomData = aValue then
4033 fCustomData := aValue;
4036 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4037 procedure TglBitmap.SetCustomName(const aValue: String);
4039 if fCustomName = aValue then
4041 fCustomName := aValue;
4044 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4045 procedure TglBitmap.SetCustomNameW(const aValue: WideString);
4047 if fCustomNameW = aValue then
4049 fCustomNameW := aValue;
4052 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4053 procedure TglBitmap.SetDeleteTextureOnFree(const aValue: Boolean);
4055 if fDeleteTextureOnFree = aValue then
4057 fDeleteTextureOnFree := aValue;
4060 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4061 procedure TglBitmap.SetFormat(const aValue: TglBitmapFormat);
4063 if fFormat = aValue then
4065 if TFormatDescriptor.Get(Format).PixelSize <> TFormatDescriptor.Get(aValue).PixelSize then
4066 raise EglBitmapUnsupportedFormat.Create(Format);
4067 SetDataPointer(Data, aValue, Width, Height);
4070 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4071 procedure TglBitmap.SetFreeDataAfterGenTexture(const aValue: Boolean);
4073 if fFreeDataAfterGenTexture = aValue then
4075 fFreeDataAfterGenTexture := aValue;
4078 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4079 procedure TglBitmap.SetID(const aValue: Cardinal);
4081 if fID = aValue then
4086 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4087 procedure TglBitmap.SetMipMap(const aValue: TglBitmapMipMap);
4089 if fMipMap = aValue then
4094 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4095 procedure TglBitmap.SetTarget(const aValue: Cardinal);
4097 if fTarget = aValue then
4102 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4103 procedure TglBitmap.SetAnisotropic(const aValue: Integer);
4105 MaxAnisotropic: Integer;
4107 fAnisotropic := aValue;
4108 if (ID > 0) then begin
4109 if GL_EXT_texture_filter_anisotropic then begin
4110 if fAnisotropic > 0 then begin
4112 glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @MaxAnisotropic);
4113 if aValue > MaxAnisotropic then
4114 fAnisotropic := MaxAnisotropic;
4115 glTexParameteri(Target, GL_TEXTURE_MAX_ANISOTROPY_EXT, fAnisotropic);
4123 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4124 procedure TglBitmap.CreateID;
4127 glDeleteTextures(1, @fID);
4128 glGenTextures(1, @fID);
4132 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4133 procedure TglBitmap.SetupParameters(out aBuildWithGlu: Boolean);
4135 // Set Up Parameters
4136 SetWrap(fWrapS, fWrapT, fWrapR);
4137 SetFilter(fFilterMin, fFilterMag);
4138 SetAnisotropic(fAnisotropic);
4139 SetBorderColor(fBorderColor[0], fBorderColor[1], fBorderColor[2], fBorderColor[3]);
4141 // Mip Maps Generation Mode
4142 aBuildWithGlu := false;
4143 if (MipMap = mmMipmap) then begin
4144 if (GL_VERSION_1_4 or GL_SGIS_generate_mipmap) then
4145 glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE)
4147 aBuildWithGlu := true;
4148 end else if (MipMap = mmMipmapGlu) then
4149 aBuildWithGlu := true;
4152 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4153 procedure TglBitmap.SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
4154 const aWidth: Integer; const aHeight: Integer);
4158 if (Data <> aData) then begin
4159 if (Assigned(Data)) then
4164 FillChar(fDimension, SizeOf(fDimension), 0);
4165 if not Assigned(fData) then begin
4170 if aWidth <> -1 then begin
4171 fDimension.Fields := fDimension.Fields + [ffX];
4172 fDimension.X := aWidth;
4175 if aHeight <> -1 then begin
4176 fDimension.Fields := fDimension.Fields + [ffY];
4177 fDimension.Y := aHeight;
4180 s := TFormatDescriptor.Get(aFormat).PixelSize;
4182 fPixelSize := Ceil(s);
4183 fRowSize := Ceil(s * aWidth);
4187 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4188 function TglBitmap.FlipHorz: Boolean;
4193 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4194 function TglBitmap.FlipVert: Boolean;
4199 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4200 //TglBitmap - PUBLIC//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4201 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4202 procedure TglBitmap.AfterConstruction;
4204 inherited AfterConstruction;
4208 fIsResident := false;
4210 fFormat := glBitmapGetDefaultFormat;
4211 fMipMap := glBitmapDefaultMipmap;
4212 fFreeDataAfterGenTexture := glBitmapGetDefaultFreeDataAfterGenTexture;
4213 fDeleteTextureOnFree := glBitmapGetDefaultDeleteTextureOnFree;
4215 glBitmapGetDefaultFilter (fFilterMin, fFilterMag);
4216 glBitmapGetDefaultTextureWrap(fWrapS, fWrapT, fWrapR);
4219 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4220 procedure TglBitmap.BeforeDestruction;
4222 SetDataPointer(nil, tfEmpty);
4223 if (fID > 0) and fDeleteTextureOnFree then
4224 glDeleteTextures(1, @fID);
4225 inherited BeforeDestruction;
4228 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4229 procedure TglBitmap.PrepareResType(var aResource: String; var aResType: PChar);
4233 if not Assigned(aResType) then begin
4234 TempPos := Pos('.', aResource);
4235 aResType := PChar(UpperCase(Copy(aResource, TempPos + 1, Length(aResource) - TempPos)));
4236 aResource := UpperCase(Copy(aResource, 0, TempPos -1));
4240 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4241 procedure TglBitmap.LoadFromFile(const aFilename: String);
4245 if not FileExists(aFilename) then
4246 raise EglBitmapException.Create('file does not exist: ' + aFilename);
4247 fFilename := aFilename;
4248 fs := TFileStream.Create(fFilename, fmOpenRead);
4257 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4258 procedure TglBitmap.LoadFromStream(const aStream: TStream);
4260 {$IFDEF GLB_SUPPORT_PNG_READ}
4261 if not LoadPNG(aStream) then
4263 {$IFDEF GLB_SUPPORT_JPEG_READ}
4264 if not LoadJPEG(aStream) then
4266 if not LoadDDS(aStream) then
4267 if not LoadTGA(aStream) then
4268 if not LoadBMP(aStream) then
4269 raise EglBitmapException.Create('LoadFromStream - Couldn''t load Stream. It''s possible to be an unknow Streamtype.');
4272 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4273 procedure TglBitmap.LoadFromFunc(const aSize: TglBitmapPixelPosition; const aFunc: TglBitmapFunction;
4274 const aFormat: TglBitmapFormat; const aArgs: Pointer);
4279 size := TFormatDescriptor.Get(aFormat).GetSize(aSize);
4280 GetMem(tmpData, size);
4282 FillChar(tmpData^, size, #$FF);
4283 SetDataPointer(tmpData, aFormat, aSize.X, aSize.Y);
4288 AddFunc(Self, aFunc, false, Format, aArgs);
4291 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4292 procedure TglBitmap.LoadFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar);
4294 rs: TResourceStream;
4296 PrepareResType(aResource, aResType);
4297 rs := TResourceStream.Create(aInstance, aResource, aResType);
4305 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4306 procedure TglBitmap.LoadFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
4308 rs: TResourceStream;
4310 rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
4318 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4319 procedure TglBitmap.SaveToFile(const aFileName: String; const aFileType: TglBitmapFileType);
4323 fs := TFileStream.Create(aFileName, fmCreate);
4326 SaveToStream(fs, aFileType);
4332 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4333 procedure TglBitmap.SaveToStream(const aStream: TStream; const aFileType: TglBitmapFileType);
4336 {$IFDEF GLB_SUPPORT_PNG_WRITE}
4337 ftPNG: SavePNG(aStream);
4339 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
4340 ftJPEG: SaveJPEG(aStream);
4342 ftDDS: SaveDDS(aStream);
4343 ftTGA: SaveTGA(aStream);
4344 ftBMP: SaveBMP(aStream);
4348 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4349 function TglBitmap.AddFunc(const aFunc: TglBitmapFunction; const aCreateTemp: Boolean; const aArgs: Pointer): Boolean;
4351 result := AddFunc(Self, aFunc, aCreateTemp, Format, aArgs);
4354 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4355 function TglBitmap.AddFunc(const aSource: TglBitmap; const aFunc: TglBitmapFunction; aCreateTemp: Boolean;
4356 const aFormat: TglBitmapFormat; const aArgs: Pointer): Boolean;
4358 DestData, TmpData, SourceData: pByte;
4359 TempHeight, TempWidth: Integer;
4360 SourceFD, DestFD: TFormatDescriptor;
4361 SourceMD, DestMD: Pointer;
4363 FuncRec: TglBitmapFunctionRec;
4365 Assert(Assigned(Data));
4366 Assert(Assigned(aSource));
4367 Assert(Assigned(aSource.Data));
4370 if Assigned(aSource.Data) and ((aSource.Height > 0) or (aSource.Width > 0)) then begin
4371 SourceFD := TFormatDescriptor.Get(aSource.Format);
4372 DestFD := TFormatDescriptor.Get(aFormat);
4374 if (SourceFD.IsCompressed) then
4375 raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', SourceFD.Format);
4376 if (DestFD.IsCompressed) then
4377 raise EglBitmapUnsupportedFormat.Create('compressed formats are not supported: ', DestFD.Format);
4379 // inkompatible Formats so CreateTemp
4380 if (SourceFD.PixelSize <> DestFD.PixelSize) then
4381 aCreateTemp := true;
4384 TempHeight := Max(1, aSource.Height);
4385 TempWidth := Max(1, aSource.Width);
4387 FuncRec.Sender := Self;
4388 FuncRec.Args := aArgs;
4391 if aCreateTemp then begin
4392 GetMem(TmpData, DestFD.GetSize(TempWidth, TempHeight));
4393 DestData := TmpData;
4398 SourceFD.PreparePixel(FuncRec.Source);
4399 DestFD.PreparePixel (FuncRec.Dest);
4401 SourceMD := SourceFD.CreateMappingData;
4402 DestMD := DestFD.CreateMappingData;
4404 FuncRec.Size := aSource.Dimension;
4405 FuncRec.Position.Fields := FuncRec.Size.Fields;
4408 SourceData := aSource.Data;
4409 FuncRec.Position.Y := 0;
4410 while FuncRec.Position.Y < TempHeight do begin
4411 FuncRec.Position.X := 0;
4412 while FuncRec.Position.X < TempWidth do begin
4413 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
4415 DestFD.Map(FuncRec.Dest, DestData, DestMD);
4416 inc(FuncRec.Position.X);
4418 inc(FuncRec.Position.Y);
4421 // Updating Image or InternalFormat
4423 SetDataPointer(TmpData, aFormat, aSource.Width, aSource.Height)
4424 else if (aFormat <> fFormat) then
4429 SourceFD.FreeMappingData(SourceMD);
4430 DestFD.FreeMappingData(DestMD);
4441 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4442 function TglBitmap.AssignToSurface(out aSurface: PSDL_Surface): Boolean;
4444 Row, RowSize: Integer;
4445 SourceData, TmpData: PByte;
4447 FormatDesc: TFormatDescriptor;
4449 function GetRowPointer(Row: Integer): pByte;
4451 result := aSurface.pixels;
4452 Inc(result, Row * RowSize);
4458 FormatDesc := TFormatDescriptor.Get(Format);
4459 if FormatDesc.IsCompressed then
4460 raise EglBitmapUnsupportedFormat.Create(Format);
4462 if Assigned(Data) then begin
4463 case Trunc(FormatDesc.PixelSize) of
4469 raise EglBitmapUnsupportedFormat.Create(Format);
4472 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, TempDepth,
4473 FormatDesc.RedMask, FormatDesc.GreenMask, FormatDesc.BlueMask, FormatDesc.AlphaMask);
4475 RowSize := FormatDesc.GetSize(FileWidth, 1);
4477 for Row := 0 to FileHeight-1 do begin
4478 TmpData := GetRowPointer(Row);
4479 if Assigned(TmpData) then begin
4480 Move(SourceData^, TmpData^, RowSize);
4481 inc(SourceData, RowSize);
4488 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4489 function TglBitmap.AssignFromSurface(const aSurface: PSDL_Surface): Boolean;
4491 pSource, pData, pTempData: PByte;
4492 Row, RowSize, TempWidth, TempHeight: Integer;
4493 IntFormat: TglBitmapFormat;
4494 FormatDesc: TFormatDescriptor;
4496 function GetRowPointer(Row: Integer): pByte;
4498 result := aSurface^.pixels;
4499 Inc(result, Row * RowSize);
4504 if (Assigned(aSurface)) then begin
4505 with aSurface^.format^ do begin
4506 for IntFormat := High(TglBitmapFormat) to Low(TglBitmapFormat) do begin
4507 FormatDesc := TFormatDescriptor.Get(IntFormat);
4508 if (FormatDesc.MaskMatch(RMask, GMask, BMask, AMask)) then
4511 if (IntFormat = tfEmpty) then
4512 raise EglBitmapException.Create('AssignFromSurface - Invalid Pixelformat.');
4515 TempWidth := aSurface^.w;
4516 TempHeight := aSurface^.h;
4517 RowSize := FormatDesc.GetSize(TempWidth, 1);
4518 GetMem(pData, TempHeight * RowSize);
4521 for Row := 0 to TempHeight -1 do begin
4522 pSource := GetRowPointer(Row);
4523 if (Assigned(pSource)) then begin
4524 Move(pSource^, pTempData^, RowSize);
4525 Inc(pTempData, RowSize);
4528 SetDataPointer(pData, IntFormat, TempWidth, TempHeight);
4537 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4538 function TglBitmap.AssignAlphaToSurface(out aSurface: PSDL_Surface): Boolean;
4540 Row, Col, AlphaInterleave: Integer;
4541 pSource, pDest: PByte;
4543 function GetRowPointer(Row: Integer): pByte;
4545 result := aSurface.pixels;
4546 Inc(result, Row * Width);
4551 if Assigned(Data) then begin
4552 if Format in [tfAlpha8, tfLuminance8Alpha8, tfBGRA8, tfRGBA8] then begin
4553 aSurface := SDL_CreateRGBSurface(SDL_SWSURFACE, Width, Height, 8, $FF, $FF, $FF, 0);
4555 AlphaInterleave := 0;
4558 AlphaInterleave := 1;
4560 AlphaInterleave := 3;
4564 for Row := 0 to Height -1 do begin
4565 pDest := GetRowPointer(Row);
4566 if Assigned(pDest) then begin
4567 for Col := 0 to Width -1 do begin
4568 Inc(pSource, AlphaInterleave);
4580 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4581 function TglBitmap.AddAlphaFromSurface(const aSurface: PSDL_Surface; const aFunc: TglBitmapFunction = nil; const aArgs: Pointer = nil): Boolean;
4585 bmp := TglBitmap2D.Create;
4587 bmp.AssignFromSurface(aSurface);
4588 result := AddAlphaFromGlBitmap(bmp, aFunc, aArgs);
4596 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4597 function CreateGrayPalette: HPALETTE;
4602 GetMem(Pal, SizeOf(TLogPalette) + (SizeOf(TPaletteEntry) * 256));
4604 Pal.palVersion := $300;
4605 Pal.palNumEntries := 256;
4607 for Idx := 0 to Pal.palNumEntries - 1 do begin
4608 Pal.palPalEntry[Idx].peRed := Idx;
4609 Pal.palPalEntry[Idx].peGreen := Idx;
4610 Pal.palPalEntry[Idx].peBlue := Idx;
4611 Pal.palPalEntry[Idx].peFlags := 0;
4613 Result := CreatePalette(Pal^);
4617 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4618 function TglBitmap.AssignToBitmap(const aBitmap: TBitmap): Boolean;
4621 pSource, pData: PByte;
4624 if Assigned(Data) then begin
4625 if Assigned(aBitmap) then begin
4626 aBitmap.Width := Width;
4627 aBitmap.Height := Height;
4630 tfAlpha8, tfLuminance8: begin
4631 aBitmap.PixelFormat := pf8bit;
4632 aBitmap.Palette := CreateGrayPalette;
4635 aBitmap.PixelFormat := pf15bit;
4637 aBitmap.PixelFormat := pf16bit;
4639 aBitmap.PixelFormat := pf24bit;
4641 aBitmap.PixelFormat := pf32bit;
4643 raise EglBitmapException.Create('AssignToBitmap - Invalid Pixelformat.');
4647 for Row := 0 to FileHeight -1 do begin
4648 pData := aBitmap.Scanline[Row];
4649 Move(pSource^, pData^, fRowSize);
4650 Inc(pSource, fRowSize);
4651 if (Format in [tfRGB8, tfRGBA8]) then // swap RGB(A) to BGR(A)
4652 SwapRGB(pData, FileWidth, Format = tfRGBA8);
4659 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4660 function TglBitmap.AssignFromBitmap(const aBitmap: TBitmap): Boolean;
4662 pSource, pData, pTempData: PByte;
4663 Row, RowSize, TempWidth, TempHeight: Integer;
4664 IntFormat: TglBitmapFormat;
4668 if (Assigned(aBitmap)) then begin
4669 case aBitmap.PixelFormat of
4671 IntFormat := tfLuminance8;
4673 IntFormat := tfRGB5A1;
4675 IntFormat := tfR5G6B5;
4677 IntFormat := tfBGR8;
4679 IntFormat := tfBGRA8;
4681 raise EglBitmapException.Create('AssignFromBitmap - Invalid Pixelformat.');
4684 TempWidth := aBitmap.Width;
4685 TempHeight := aBitmap.Height;
4686 RowSize := TFormatDescriptor.Get(IntFormat).GetSize(TempWidth, 1);
4687 GetMem(pData, TempHeight * RowSize);
4690 for Row := 0 to TempHeight -1 do begin
4691 pSource := aBitmap.Scanline[Row];
4692 if (Assigned(pSource)) then begin
4693 Move(pSource^, pTempData^, RowSize);
4694 Inc(pTempData, RowSize);
4697 SetDataPointer(pData, IntFormat, TempWidth, TempHeight);
4706 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4707 function TglBitmap.AssignAlphaToBitmap(const aBitmap: TBitmap): Boolean;
4709 Row, Col, AlphaInterleave: Integer;
4710 pSource, pDest: PByte;
4714 if Assigned(Data) then begin
4715 if (Format in [tfAlpha8, tfLuminance8Alpha8, tfRGBA8, tfBGRA8]) then begin
4716 if Assigned(aBitmap) then begin
4717 aBitmap.PixelFormat := pf8bit;
4718 aBitmap.Palette := CreateGrayPalette;
4719 aBitmap.Width := Width;
4720 aBitmap.Height := Height;
4724 AlphaInterleave := 1;
4726 AlphaInterleave := 3;
4728 AlphaInterleave := 0;
4734 for Row := 0 to Height -1 do begin
4735 pDest := aBitmap.Scanline[Row];
4736 if Assigned(pDest) then begin
4737 for Col := 0 to Width -1 do begin
4738 Inc(pSource, AlphaInterleave);
4751 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4752 function TglBitmap.AddAlphaFromBitmap(const aBitmap: TBitmap; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
4756 tex := TglBitmap2D.Create;
4758 tex.AssignFromBitmap(ABitmap);
4759 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
4766 {$IFDEF GLB_LAZARUS}
4767 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4768 function TglBitmap.AssignToLazIntfImage(const aImage: TLazIntfImage): Boolean;
4770 rid: TRawImageDescription;
4771 FormatDesc: TFormatDescriptor;
4774 if not Assigned(aImage) or (Format = tfEmpty) then
4776 FormatDesc := TFormatDescriptor.Get(Format);
4777 if FormatDesc.IsCompressed then
4780 FillChar(rid{%H-}, SizeOf(rid), 0);
4782 tfAlpha4, tfAlpha8, tfAlpha12, tfAlpha16,
4783 tfLuminance4, tfLuminance8, tfLuminance12, tfLuminance16,
4784 tfLuminance4Alpha4, tfLuminance8Alpha8, tfLuminance12Alpha4, tfLuminance12Alpha12, tfLuminance16Alpha16]) then
4785 rid.Format := ricfGray
4787 rid.Format := ricfRGBA;
4790 rid.Height := Height;
4791 rid.Depth := CountSetBits(FormatDesc.Range.r or FormatDesc.Range.g or FormatDesc.Range.b or FormatDesc.Range.a);
4792 rid.BitOrder := riboBitsInOrder;
4793 rid.ByteOrder := riboLSBFirst;
4794 rid.LineOrder := riloTopToBottom;
4795 rid.LineEnd := rileTight;
4796 rid.BitsPerPixel := Round(8 * FormatDesc.PixelSize);
4797 rid.RedPrec := CountSetBits(FormatDesc.Range.r);
4798 rid.GreenPrec := CountSetBits(FormatDesc.Range.g);
4799 rid.BluePrec := CountSetBits(FormatDesc.Range.b);
4800 rid.AlphaPrec := CountSetBits(FormatDesc.Range.a);
4801 rid.RedShift := FormatDesc.Shift.r;
4802 rid.GreenShift := FormatDesc.Shift.g;
4803 rid.BlueShift := FormatDesc.Shift.b;
4804 rid.AlphaShift := FormatDesc.Shift.a;
4806 rid.MaskBitsPerPixel := 0;
4807 rid.PaletteColorCount := 0;
4809 aImage.DataDescription := rid;
4812 Move(Data^, aImage.PixelData^, FormatDesc.GetSize(Dimension));
4817 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4818 function TglBitmap.AssignFromLazIntfImage(const aImage: TLazIntfImage): Boolean;
4821 FormatDesc: TFormatDescriptor;
4826 if not Assigned(aImage) then
4828 for f := High(f) downto Low(f) do begin
4829 FormatDesc := TFormatDescriptor.Get(f);
4830 with aImage.DataDescription do
4831 if FormatDesc.MaskMatch(
4832 (QWord(1 shl RedPrec )-1) shl RedShift,
4833 (QWord(1 shl GreenPrec)-1) shl GreenShift,
4834 (QWord(1 shl BluePrec )-1) shl BlueShift,
4835 (QWord(1 shl AlphaPrec)-1) shl AlphaShift) then
4839 if (f = tfEmpty) then
4842 ImageSize := FormatDesc.GetSize(aImage.Width, aImage.Height);
4843 ImageData := GetMem(ImageSize);
4845 Move(aImage.PixelData^, ImageData^, (aImage.Width * aImage.Height * aImage.DataDescription.BitsPerPixel) shr 3);
4846 SetDataPointer(ImageData, f, aImage.Width, aImage.Height);
4855 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4856 function TglBitmap.AssignAlphaToLazIntfImage(const aImage: TLazIntfImage): Boolean;
4858 rid: TRawImageDescription;
4859 FormatDesc: TFormatDescriptor;
4860 Pixel: TglBitmapPixelData;
4866 if not Assigned(aImage) or (Format = tfEmpty) then
4868 FormatDesc := TFormatDescriptor.Get(Format);
4869 if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
4872 FillChar(rid{%H-}, SizeOf(rid), 0);
4873 rid.Format := ricfGray;
4875 rid.Height := Height;
4876 rid.Depth := CountSetBits(FormatDesc.Range.a);
4877 rid.BitOrder := riboBitsInOrder;
4878 rid.ByteOrder := riboLSBFirst;
4879 rid.LineOrder := riloTopToBottom;
4880 rid.LineEnd := rileTight;
4881 rid.BitsPerPixel := 8 * Ceil(rid.Depth / 8);
4882 rid.RedPrec := CountSetBits(FormatDesc.Range.a);
4887 rid.GreenShift := 0;
4889 rid.AlphaShift := 0;
4891 rid.MaskBitsPerPixel := 0;
4892 rid.PaletteColorCount := 0;
4894 aImage.DataDescription := rid;
4897 srcMD := FormatDesc.CreateMappingData;
4899 FormatDesc.PreparePixel(Pixel);
4901 dst := aImage.PixelData;
4902 for y := 0 to Height-1 do
4903 for x := 0 to Width-1 do begin
4904 FormatDesc.Unmap(src, Pixel, srcMD);
4905 case rid.BitsPerPixel of
4907 dst^ := Pixel.Data.a;
4911 PWord(dst)^ := Pixel.Data.a;
4915 PByteArray(dst)^[0] := PByteArray(@Pixel.Data.a)^[0];
4916 PByteArray(dst)^[1] := PByteArray(@Pixel.Data.a)^[1];
4917 PByteArray(dst)^[2] := PByteArray(@Pixel.Data.a)^[2];
4921 PCardinal(dst)^ := Pixel.Data.a;
4925 raise EglBitmapUnsupportedFormat.Create(Format);
4929 FormatDesc.FreeMappingData(srcMD);
4934 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4935 function TglBitmap.AddAlphaFromLazIntfImage(const aImage: TLazIntfImage; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
4939 tex := TglBitmap2D.Create;
4941 tex.AssignFromLazIntfImage(aImage);
4942 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
4949 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4950 function TglBitmap.AddAlphaFromResource(const aInstance: Cardinal; aResource: String; aResType: PChar;
4951 const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
4953 rs: TResourceStream;
4955 PrepareResType(aResource, aResType);
4956 rs := TResourceStream.Create(aInstance, aResource, aResType);
4958 result := AddAlphaFromStream(rs, aFunc, aArgs);
4964 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4965 function TglBitmap.AddAlphaFromResourceID(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar;
4966 const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
4968 rs: TResourceStream;
4970 rs := TResourceStream.CreateFromID(aInstance, aResourceID, aResType);
4972 result := AddAlphaFromStream(rs, aFunc, aArgs);
4978 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4979 function TglBitmap.AddAlphaFromFunc(const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
4981 if TFormatDescriptor.Get(Format).IsCompressed then
4982 raise EglBitmapUnsupportedFormat.Create(Format);
4983 result := AddFunc(Self, aFunc, false, TFormatDescriptor.Get(Format).WithAlpha, aArgs);
4986 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4987 function TglBitmap.AddAlphaFromFile(const aFileName: String; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
4991 FS := TFileStream.Create(FileName, fmOpenRead);
4993 result := AddAlphaFromStream(FS, aFunc, aArgs);
4999 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5000 function TglBitmap.AddAlphaFromStream(const aStream: TStream; const aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5004 tex := TglBitmap2D.Create(aStream);
5006 result := AddAlphaFromglBitmap(tex, aFunc, aArgs);
5012 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5013 function TglBitmap.AddAlphaFromGlBitmap(const aBitmap: TglBitmap; aFunc: TglBitmapFunction; const aArgs: Pointer): Boolean;
5015 DestData, DestData2, SourceData: pByte;
5016 TempHeight, TempWidth: Integer;
5017 SourceFD, DestFD: TFormatDescriptor;
5018 SourceMD, DestMD, DestMD2: Pointer;
5020 FuncRec: TglBitmapFunctionRec;
5024 Assert(Assigned(Data));
5025 Assert(Assigned(aBitmap));
5026 Assert(Assigned(aBitmap.Data));
5028 if ((aBitmap.Width = Width) and (aBitmap.Height = Height)) then begin
5029 result := ConvertTo(TFormatDescriptor.Get(Format).WithAlpha);
5031 SourceFD := TFormatDescriptor.Get(aBitmap.Format);
5032 DestFD := TFormatDescriptor.Get(Format);
5034 if not Assigned(aFunc) then begin
5035 aFunc := glBitmapAlphaFunc;
5036 FuncRec.Args := {%H-}Pointer(SourceFD.HasAlpha);
5038 FuncRec.Args := aArgs;
5041 TempHeight := aBitmap.FileHeight;
5042 TempWidth := aBitmap.FileWidth;
5044 FuncRec.Sender := Self;
5045 FuncRec.Size := Dimension;
5046 FuncRec.Position.Fields := FuncRec.Size.Fields;
5050 SourceData := aBitmap.Data;
5053 SourceFD.PreparePixel(FuncRec.Source);
5054 DestFD.PreparePixel (FuncRec.Dest);
5056 SourceMD := SourceFD.CreateMappingData;
5057 DestMD := DestFD.CreateMappingData;
5058 DestMD2 := DestFD.CreateMappingData;
5060 FuncRec.Position.Y := 0;
5061 while FuncRec.Position.Y < TempHeight do begin
5062 FuncRec.Position.X := 0;
5063 while FuncRec.Position.X < TempWidth do begin
5064 SourceFD.Unmap(SourceData, FuncRec.Source, SourceMD);
5065 DestFD.Unmap (DestData, FuncRec.Dest, DestMD);
5067 DestFD.Map(FuncRec.Dest, DestData2, DestMD2);
5068 inc(FuncRec.Position.X);
5070 inc(FuncRec.Position.Y);
5073 SourceFD.FreeMappingData(SourceMD);
5074 DestFD.FreeMappingData(DestMD);
5075 DestFD.FreeMappingData(DestMD2);
5080 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5081 function TglBitmap.AddAlphaFromColorKey(const aRed, aGreen, aBlue: Byte; const aDeviation: Byte): Boolean;
5083 result := AddAlphaFromColorKeyFloat(aRed / $FF, aGreen / $FF, aBlue / $FF, aDeviation / $FF);
5086 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5087 function TglBitmap.AddAlphaFromColorKeyRange(const aRed, aGreen, aBlue: Cardinal; const aDeviation: Cardinal): Boolean;
5089 PixelData: TglBitmapPixelData;
5091 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
5092 result := AddAlphaFromColorKeyFloat(
5093 aRed / PixelData.Range.r,
5094 aGreen / PixelData.Range.g,
5095 aBlue / PixelData.Range.b,
5096 aDeviation / Max(PixelData.Range.r, Max(PixelData.Range.g, PixelData.Range.b)));
5099 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5100 function TglBitmap.AddAlphaFromColorKeyFloat(const aRed, aGreen, aBlue: Single; const aDeviation: Single): Boolean;
5102 values: array[0..2] of Single;
5105 PixelData: TglBitmapPixelData;
5107 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
5108 with PixelData do begin
5110 values[1] := aGreen;
5113 for i := 0 to 2 do begin
5114 tmp := Trunc(Range.arr[i] * aDeviation);
5115 Data.arr[i] := Min(Range.arr[i], Trunc(Range.arr[i] * values[i] + tmp));
5116 Range.arr[i] := Max(0, Trunc(Range.arr[i] * values[i] - tmp));
5121 result := AddAlphaFromFunc(glBitmapColorKeyAlphaFunc, @PixelData);
5124 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5125 function TglBitmap.AddAlphaFromValue(const aAlpha: Byte): Boolean;
5127 result := AddAlphaFromValueFloat(aAlpha / $FF);
5130 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5131 function TglBitmap.AddAlphaFromValueRange(const aAlpha: Cardinal): Boolean;
5133 PixelData: TglBitmapPixelData;
5135 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
5136 result := AddAlphaFromValueFloat(aAlpha / PixelData.Range.a);
5139 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5140 function TglBitmap.AddAlphaFromValueFloat(const aAlpha: Single): Boolean;
5142 PixelData: TglBitmapPixelData;
5144 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
5146 Data.a := Min(Range.a, Max(0, Round(Range.a * aAlpha)));
5147 result := AddAlphaFromFunc(glBitmapValueAlphaFunc, @PixelData.Data.a);
5150 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5151 function TglBitmap.RemoveAlpha: Boolean;
5153 FormatDesc: TFormatDescriptor;
5156 FormatDesc := TFormatDescriptor.Get(Format);
5157 if Assigned(Data) then begin
5158 if FormatDesc.IsCompressed or not FormatDesc.HasAlpha then
5159 raise EglBitmapUnsupportedFormat.Create(Format);
5160 result := ConvertTo(FormatDesc.WithoutAlpha);
5164 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5165 function TglBitmap.Clone: TglBitmap;
5172 Temp := (ClassType.Create as TglBitmap);
5174 // copy texture data if assigned
5175 if Assigned(Data) then begin
5176 Size := TFormatDescriptor.Get(Format).GetSize(fDimension);
5177 GetMem(TempPtr, Size);
5179 Move(Data^, TempPtr^, Size);
5180 Temp.SetDataPointer(TempPtr, Format, Width, Height);
5186 Temp.SetDataPointer(nil, Format, Width, Height);
5190 Temp.fTarget := Target;
5191 Temp.fFormat := Format;
5192 Temp.fMipMap := MipMap;
5193 Temp.fAnisotropic := Anisotropic;
5194 Temp.fBorderColor := fBorderColor;
5195 Temp.fDeleteTextureOnFree := DeleteTextureOnFree;
5196 Temp.fFreeDataAfterGenTexture := FreeDataAfterGenTexture;
5197 Temp.fFilterMin := fFilterMin;
5198 Temp.fFilterMag := fFilterMag;
5199 Temp.fWrapS := fWrapS;
5200 Temp.fWrapT := fWrapT;
5201 Temp.fWrapR := fWrapR;
5202 Temp.fFilename := fFilename;
5203 Temp.fCustomName := fCustomName;
5204 Temp.fCustomNameW := fCustomNameW;
5205 Temp.fCustomData := fCustomData;
5214 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5215 function TglBitmap.ConvertTo(const aFormat: TglBitmapFormat): Boolean;
5217 SourceFD, DestFD: TFormatDescriptor;
5218 SourcePD, DestPD: TglBitmapPixelData;
5219 ShiftData: TShiftData;
5221 function CanCopyDirect: Boolean;
5224 ((SourcePD.Range.r = DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
5225 ((SourcePD.Range.g = DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
5226 ((SourcePD.Range.b = DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
5227 ((SourcePD.Range.a = DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
5230 function CanShift: Boolean;
5233 ((SourcePD.Range.r >= DestPD.Range.r) or (SourcePD.Range.r = 0) or (DestPD.Range.r = 0)) and
5234 ((SourcePD.Range.g >= DestPD.Range.g) or (SourcePD.Range.g = 0) or (DestPD.Range.g = 0)) and
5235 ((SourcePD.Range.b >= DestPD.Range.b) or (SourcePD.Range.b = 0) or (DestPD.Range.b = 0)) and
5236 ((SourcePD.Range.a >= DestPD.Range.a) or (SourcePD.Range.a = 0) or (DestPD.Range.a = 0));
5239 function GetShift(aSource, aDest: Cardinal) : ShortInt;
5242 while (aSource > aDest) and (aSource > 0) do begin
5244 aSource := aSource shr 1;
5249 if (aFormat <> fFormat) and (aFormat <> tfEmpty) then begin
5250 SourceFD := TFormatDescriptor.Get(Format);
5251 DestFD := TFormatDescriptor.Get(aFormat);
5253 SourceFD.PreparePixel(SourcePD);
5254 DestFD.PreparePixel (DestPD);
5256 if CanCopyDirect then
5257 result := AddFunc(Self, glBitmapConvertCopyFunc, false, aFormat)
5258 else if CanShift then begin
5259 ShiftData.r := GetShift(SourcePD.Range.r, DestPD.Range.r);
5260 ShiftData.g := GetShift(SourcePD.Range.g, DestPD.Range.g);
5261 ShiftData.b := GetShift(SourcePD.Range.b, DestPD.Range.b);
5262 ShiftData.a := GetShift(SourcePD.Range.a, DestPD.Range.a);
5263 result := AddFunc(Self, glBitmapConvertShiftRGBAFunc, false, aFormat, @ShiftData);
5265 result := AddFunc(Self, glBitmapConvertCalculateRGBAFunc, false, aFormat);
5270 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5271 procedure TglBitmap.Invert(const aUseRGB: Boolean; const aUseAlpha: Boolean);
5273 if aUseRGB or aUseAlpha then
5274 AddFunc(glBitmapInvertFunc, false, {%H-}Pointer(
5275 ((PtrInt(aUseAlpha) and 1) shl 1) or
5276 (PtrInt(aUseRGB) and 1) ));
5279 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5280 procedure TglBitmap.SetBorderColor(const aRed, aGreen, aBlue, aAlpha: Single);
5282 fBorderColor[0] := aRed;
5283 fBorderColor[1] := aGreen;
5284 fBorderColor[2] := aBlue;
5285 fBorderColor[3] := aAlpha;
5286 if (ID > 0) then begin
5288 glTexParameterfv(Target, GL_TEXTURE_BORDER_COLOR, @fBorderColor[0]);
5292 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5293 procedure TglBitmap.FreeData;
5295 SetDataPointer(nil, tfEmpty);
5298 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5299 procedure TglBitmap.FillWithColor(const aRed, aGreen, aBlue: Byte;
5300 const aAlpha: Byte);
5302 FillWithColorFloat(aRed/$FF, aGreen/$FF, aBlue/$FF, aAlpha/$FF);
5305 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5306 procedure TglBitmap.FillWithColorRange(const aRed, aGreen, aBlue: Cardinal; const aAlpha: Cardinal);
5308 PixelData: TglBitmapPixelData;
5310 TFormatDescriptor.GetWithAlpha(Format).PreparePixel(PixelData);
5312 aRed / PixelData.Range.r,
5313 aGreen / PixelData.Range.g,
5314 aBlue / PixelData.Range.b,
5315 aAlpha / PixelData.Range.a);
5318 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5319 procedure TglBitmap.FillWithColorFloat(const aRed, aGreen, aBlue: Single; const aAlpha: Single);
5321 PixelData: TglBitmapPixelData;
5323 TFormatDescriptor.Get(Format).PreparePixel(PixelData);
5324 with PixelData do begin
5325 Data.r := Max(0, Min(Range.r, Trunc(Range.r * aRed)));
5326 Data.g := Max(0, Min(Range.g, Trunc(Range.g * aGreen)));
5327 Data.b := Max(0, Min(Range.b, Trunc(Range.b * aBlue)));
5328 Data.a := Max(0, Min(Range.a, Trunc(Range.a * aAlpha)));
5330 AddFunc(glBitmapFillWithColorFunc, false, @PixelData);
5333 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5334 procedure TglBitmap.SetFilter(const aMin, aMag: Cardinal);
5339 fFilterMin := GL_NEAREST;
5341 fFilterMin := GL_LINEAR;
5342 GL_NEAREST_MIPMAP_NEAREST:
5343 fFilterMin := GL_NEAREST_MIPMAP_NEAREST;
5344 GL_LINEAR_MIPMAP_NEAREST:
5345 fFilterMin := GL_LINEAR_MIPMAP_NEAREST;
5346 GL_NEAREST_MIPMAP_LINEAR:
5347 fFilterMin := GL_NEAREST_MIPMAP_LINEAR;
5348 GL_LINEAR_MIPMAP_LINEAR:
5349 fFilterMin := GL_LINEAR_MIPMAP_LINEAR;
5351 raise EglBitmapException.Create('SetFilter - Unknow MIN filter.');
5357 fFilterMag := GL_NEAREST;
5359 fFilterMag := GL_LINEAR;
5361 raise EglBitmapException.Create('SetFilter - Unknow MAG filter.');
5365 if (ID > 0) then begin
5367 glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, fFilterMag);
5369 if (MipMap = mmNone) or (Target = GL_TEXTURE_RECTANGLE) then begin
5371 GL_NEAREST, GL_LINEAR:
5372 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
5373 GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR:
5374 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5375 GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR:
5376 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5379 glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, fFilterMin);
5383 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5384 procedure TglBitmap.SetWrap(const S: Cardinal; const T: Cardinal; const R: Cardinal);
5386 procedure CheckAndSetWrap(const aValue: Cardinal; var aTarget: Cardinal);
5390 aTarget := GL_CLAMP;
5393 aTarget := GL_REPEAT;
5395 GL_CLAMP_TO_EDGE: begin
5396 if GL_VERSION_1_2 or GL_EXT_texture_edge_clamp then
5397 aTarget := GL_CLAMP_TO_EDGE
5399 aTarget := GL_CLAMP;
5402 GL_CLAMP_TO_BORDER: begin
5403 if GL_VERSION_1_3 or GL_ARB_texture_border_clamp then
5404 aTarget := GL_CLAMP_TO_BORDER
5406 aTarget := GL_CLAMP;
5409 GL_MIRRORED_REPEAT: begin
5410 if GL_VERSION_1_4 or GL_ARB_texture_mirrored_repeat or GL_IBM_texture_mirrored_repeat then
5411 aTarget := GL_MIRRORED_REPEAT
5413 raise EglBitmapException.Create('SetWrap - Unsupported Texturewrap GL_MIRRORED_REPEAT (S).');
5416 raise EglBitmapException.Create('SetWrap - Unknow Texturewrap (S).');
5421 CheckAndSetWrap(S, fWrapS);
5422 CheckAndSetWrap(T, fWrapT);
5423 CheckAndSetWrap(R, fWrapR);
5425 if (ID > 0) then begin
5427 glTexParameteri(Target, GL_TEXTURE_WRAP_S, fWrapS);
5428 glTexParameteri(Target, GL_TEXTURE_WRAP_T, fWrapT);
5429 glTexParameteri(Target, GL_TEXTURE_WRAP_R, fWrapR);
5433 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5434 procedure TglBitmap.Bind(const aEnableTextureUnit: Boolean);
5436 if aEnableTextureUnit then
5439 glBindTexture(Target, ID);
5442 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5443 procedure TglBitmap.Unbind(const aDisableTextureUnit: Boolean);
5445 if aDisableTextureUnit then
5447 glBindTexture(Target, 0);
5450 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5451 constructor TglBitmap.Create;
5453 {$IFDEF GLB_NATIVE_OGL}
5454 glbReadOpenGLExtensions;
5456 if (ClassType = TglBitmap) then
5457 raise EglBitmapException.Create('Don''t create TglBitmap directly. Use one of the deviated classes (TglBitmap2D) instead.');
5461 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5462 constructor TglBitmap.Create(const aFileName: String);
5465 LoadFromFile(FileName);
5468 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5469 constructor TglBitmap.Create(const aStream: TStream);
5472 LoadFromStream(aStream);
5475 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5476 constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat);
5482 ImageSize := TFormatDescriptor.Get(aFormat).GetSize(aSize);
5483 GetMem(Image, ImageSize);
5485 FillChar(Image^, ImageSize, #$FF);
5486 SetDataPointer(Image, aFormat, aSize.X, aSize.Y);
5493 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5494 constructor TglBitmap.Create(const aSize: TglBitmapPixelPosition; const aFormat: TglBitmapFormat;
5495 const aFunc: TglBitmapFunction; const aArgs: Pointer);
5498 LoadFromFunc(aSize, aFunc, aFormat, aArgs);
5501 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5502 constructor TglBitmap.Create(const aInstance: Cardinal; const aResource: String; const aResType: PChar);
5505 LoadFromResource(aInstance, aResource, aResType);
5508 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5509 constructor TglBitmap.Create(const aInstance: Cardinal; const aResourceID: Integer; const aResType: PChar);
5512 LoadFromResourceID(aInstance, aResourceID, aResType);
5515 {$IFDEF GLB_SUPPORT_PNG_READ}
5516 {$IF DEFINED(GLB_SDL_IMAGE)}
5517 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5518 //PNG/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5519 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5520 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
5522 Surface: PSDL_Surface;
5526 RWops := glBitmapCreateRWops(aStream);
5528 if IMG_isPNG(RWops) > 0 then begin
5529 Surface := IMG_LoadPNG_RW(RWops);
5531 AssignFromSurface(Surface);
5534 SDL_FreeSurface(Surface);
5542 {$ELSEIF DEFINED(GLB_LIB_PNG)}
5543 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5544 procedure glBitmap_libPNG_read_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
5546 TStream(png_get_io_ptr(png)).Read(buffer^, size);
5549 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5550 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
5553 signature: array [0..7] of byte;
5555 png_info: png_infop;
5557 TempHeight, TempWidth: Integer;
5558 Format: TglBitmapFormat;
5561 png_rows: array of pByte;
5562 Row, LineSize: Integer;
5566 if not init_libPNG then
5567 raise Exception.Create('LoadPNG - unable to initialize libPNG.');
5571 StreamPos := aStream.Position;
5572 aStream.Read(signature{%H-}, 8);
5573 aStream.Position := StreamPos;
5575 if png_check_sig(@signature, 8) <> 0 then begin
5577 png := png_create_read_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
5579 raise EglBitmapException.Create('LoadPng - couldn''t create read struct.');
5582 png_info := png_create_info_struct(png);
5583 if png_info = nil then begin
5584 png_destroy_read_struct(@png, nil, nil);
5585 raise EglBitmapException.Create('LoadPng - couldn''t create info struct.');
5588 // set read callback
5589 png_set_read_fn(png, aStream, glBitmap_libPNG_read_func);
5591 // read informations
5592 png_read_info(png, png_info);
5595 TempHeight := png_get_image_height(png, png_info);
5596 TempWidth := png_get_image_width(png, png_info);
5599 case png_get_color_type(png, png_info) of
5600 PNG_COLOR_TYPE_GRAY:
5601 Format := tfLuminance8;
5602 PNG_COLOR_TYPE_GRAY_ALPHA:
5603 Format := tfLuminance8Alpha8;
5606 PNG_COLOR_TYPE_RGB_ALPHA:
5609 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
5612 // cut upper 8 bit from 16 bit formats
5613 if png_get_bit_depth(png, png_info) > 8 then
5614 png_set_strip_16(png);
5616 // expand bitdepth smaller than 8
5617 if png_get_bit_depth(png, png_info) < 8 then
5618 png_set_expand(png);
5620 // allocating mem for scanlines
5621 LineSize := png_get_rowbytes(png, png_info);
5622 GetMem(png_data, TempHeight * LineSize);
5624 SetLength(png_rows, TempHeight);
5625 for Row := Low(png_rows) to High(png_rows) do begin
5626 png_rows[Row] := png_data;
5627 Inc(png_rows[Row], Row * LineSize);
5630 // read complete image into scanlines
5631 png_read_image(png, @png_rows[0]);
5634 png_read_end(png, png_info);
5636 // destroy read struct
5637 png_destroy_read_struct(@png, @png_info, nil);
5639 SetLength(png_rows, 0);
5642 SetDataPointer(png_data, Format, TempWidth, TempHeight);
5655 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
5656 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5657 function TglBitmap.LoadPNG(const aStream: TStream): Boolean;
5662 Row, Col, PixSize, LineSize: Integer;
5663 NewImage, pSource, pDest, pAlpha: pByte;
5664 PngFormat: TglBitmapFormat;
5665 FormatDesc: TFormatDescriptor;
5668 PngHeader: String[8] = #137#80#78#71#13#10#26#10;
5673 StreamPos := aStream.Position;
5674 aStream.Read(Header[0], SizeOf(Header));
5675 aStream.Position := StreamPos;
5677 {Test if the header matches}
5678 if Header = PngHeader then begin
5679 Png := TPNGObject.Create;
5681 Png.LoadFromStream(aStream);
5683 case Png.Header.ColorType of
5685 PngFormat := tfLuminance8;
5686 COLOR_GRAYSCALEALPHA:
5687 PngFormat := tfLuminance8Alpha8;
5689 PngFormat := tfBGR8;
5691 PngFormat := tfBGRA8;
5693 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
5696 FormatDesc := TFormatDescriptor.Get(PngFormat);
5697 PixSize := Round(FormatDesc.PixelSize);
5698 LineSize := FormatDesc.GetSize(Png.Header.Width, 1);
5700 GetMem(NewImage, LineSize * Integer(Png.Header.Height));
5704 case Png.Header.ColorType of
5705 COLOR_RGB, COLOR_GRAYSCALE:
5707 for Row := 0 to Png.Height -1 do begin
5708 Move (Png.Scanline[Row]^, pDest^, LineSize);
5709 Inc(pDest, LineSize);
5712 COLOR_RGBALPHA, COLOR_GRAYSCALEALPHA:
5714 PixSize := PixSize -1;
5716 for Row := 0 to Png.Height -1 do begin
5717 pSource := Png.Scanline[Row];
5718 pAlpha := pByte(Png.AlphaScanline[Row]);
5720 for Col := 0 to Png.Width -1 do begin
5721 Move (pSource^, pDest^, PixSize);
5722 Inc(pSource, PixSize);
5723 Inc(pDest, PixSize);
5732 raise EglBitmapException.Create ('LoadPng - Unsupported Colortype found.');
5735 SetDataPointer(NewImage, PngFormat, Png.Header.Width, Png.Header.Height);
5750 {$IFDEF GLB_SUPPORT_PNG_WRITE}
5751 {$IFDEF GLB_LIB_PNG}
5752 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5753 procedure glBitmap_libPNG_write_func(png: png_structp; buffer: png_bytep; size: cardinal); cdecl;
5755 TStream(png_get_io_ptr(png)).Write(buffer^, size);
5759 {$IF DEFINED(GLB_LIB_PNG)}
5760 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5761 procedure TglBitmap.SavePNG(const aStream: TStream);
5764 png_info: png_infop;
5765 png_rows: array of pByte;
5769 FormatDesc: TFormatDescriptor;
5771 if not (ftPNG in FormatGetSupportedFiles(Format)) then
5772 raise EglBitmapUnsupportedFormat.Create(Format);
5774 if not init_libPNG then
5775 raise Exception.Create('unable to initialize libPNG.');
5779 tfAlpha8, tfLuminance8:
5780 ColorType := PNG_COLOR_TYPE_GRAY;
5782 ColorType := PNG_COLOR_TYPE_GRAY_ALPHA;
5784 ColorType := PNG_COLOR_TYPE_RGB;
5786 ColorType := PNG_COLOR_TYPE_RGBA;
5788 raise EglBitmapUnsupportedFormat.Create(Format);
5791 FormatDesc := TFormatDescriptor.Get(Format);
5792 LineSize := FormatDesc.GetSize(Width, 1);
5794 // creating array for scanline
5795 SetLength(png_rows, Height);
5797 for Row := 0 to Height - 1 do begin
5798 png_rows[Row] := Data;
5799 Inc(png_rows[Row], Row * LineSize)
5803 png := png_create_write_struct(PNG_LIBPNG_VER_STRING, nil, nil, nil);
5805 raise EglBitmapException.Create('SavePng - couldn''t create write struct.');
5808 png_info := png_create_info_struct(png);
5809 if png_info = nil then begin
5810 png_destroy_write_struct(@png, nil);
5811 raise EglBitmapException.Create('SavePng - couldn''t create info struct.');
5814 // set read callback
5815 png_set_write_fn(png, aStream, glBitmap_libPNG_write_func, nil);
5818 png_set_compression_level(png, 6);
5820 if Format in [tfBGR8, tfBGRA8] then
5823 png_set_IHDR(png, png_info, Width, Height, 8, ColorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
5824 png_write_info(png, png_info);
5825 png_write_image(png, @png_rows[0]);
5826 png_write_end(png, png_info);
5827 png_destroy_write_struct(@png, @png_info);
5829 SetLength(png_rows, 0);
5836 {$ELSEIF DEFINED(GLB_PNGIMAGE)}
5837 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5838 procedure TglBitmap.SavePNG(const aStream: TStream);
5842 pSource, pDest: pByte;
5843 X, Y, PixSize: Integer;
5844 ColorType: Cardinal;
5850 if not (ftPNG in FormatGetSupportedFiles (Format)) then
5851 raise EglBitmapUnsupportedFormat.Create(Format);
5854 tfAlpha8, tfLuminance8: begin
5855 ColorType := COLOR_GRAYSCALE;
5859 tfLuminance8Alpha8: begin
5860 ColorType := COLOR_GRAYSCALEALPHA;
5864 tfBGR8, tfRGB8: begin
5865 ColorType := COLOR_RGB;
5869 tfBGRA8, tfRGBA8: begin
5870 ColorType := COLOR_RGBALPHA;
5875 raise EglBitmapUnsupportedFormat.Create(Format);
5878 Png := TPNGObject.CreateBlank(ColorType, 8, Width, Height);
5882 for Y := 0 to Height -1 do begin
5883 pDest := png.ScanLine[Y];
5884 for X := 0 to Width -1 do begin
5885 Move(pSource^, pDest^, PixSize);
5886 Inc(pDest, PixSize);
5887 Inc(pSource, PixSize);
5889 png.AlphaScanline[Y]^[X] := pSource^;
5894 // convert RGB line to BGR
5895 if Format in [tfRGB8, tfRGBA8] then begin
5896 pTemp := png.ScanLine[Y];
5897 for X := 0 to Width -1 do begin
5898 Temp := pByteArray(pTemp)^[0];
5899 pByteArray(pTemp)^[0] := pByteArray(pTemp)^[2];
5900 pByteArray(pTemp)^[2] := Temp;
5907 Png.CompressionLevel := 6;
5908 Png.SaveToStream(aStream);
5916 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5917 //JPEG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5918 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5919 {$IFDEF GLB_LIB_JPEG}
5921 glBitmap_libJPEG_source_mgr_ptr = ^glBitmap_libJPEG_source_mgr;
5922 glBitmap_libJPEG_source_mgr = record
5923 pub: jpeg_source_mgr;
5926 SrcBuffer: array [1..4096] of byte;
5929 glBitmap_libJPEG_dest_mgr_ptr = ^glBitmap_libJPEG_dest_mgr;
5930 glBitmap_libJPEG_dest_mgr = record
5931 pub: jpeg_destination_mgr;
5933 DestStream: TStream;
5934 DestBuffer: array [1..4096] of byte;
5937 procedure glBitmap_libJPEG_error_exit(cinfo: j_common_ptr); cdecl;
5943 procedure glBitmap_libJPEG_output_message(cinfo: j_common_ptr); cdecl;
5949 procedure glBitmap_libJPEG_init_source(cinfo: j_decompress_ptr); cdecl;
5954 procedure glBitmap_libJPEG_term_source(cinfo: j_decompress_ptr); cdecl;
5960 procedure glBitmap_libJPEG_init_destination(cinfo: j_compress_ptr); cdecl;
5966 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5967 function glBitmap_libJPEG_fill_input_buffer(cinfo: j_decompress_ptr): boolean; cdecl;
5969 src: glBitmap_libJPEG_source_mgr_ptr;
5972 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
5974 bytes := src^.SrcStream.Read(src^.SrcBuffer[1], 4096);
5975 if (bytes <= 0) then begin
5976 src^.SrcBuffer[1] := $FF;
5977 src^.SrcBuffer[2] := JPEG_EOI;
5981 src^.pub.next_input_byte := @(src^.SrcBuffer[1]);
5982 src^.pub.bytes_in_buffer := bytes;
5987 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5988 procedure glBitmap_libJPEG_skip_input_data(cinfo: j_decompress_ptr; num_bytes: Longint); cdecl;
5990 src: glBitmap_libJPEG_source_mgr_ptr;
5992 src := glBitmap_libJPEG_source_mgr_ptr(cinfo^.src);
5994 if num_bytes > 0 then begin
5995 // wanted byte isn't in buffer so set stream position and read buffer
5996 if num_bytes > src^.pub.bytes_in_buffer then begin
5997 src^.SrcStream.Position := src^.SrcStream.Position + num_bytes - src^.pub.bytes_in_buffer;
5998 src^.pub.fill_input_buffer(cinfo);
6000 // wanted byte is in buffer so only skip
6001 inc(src^.pub.next_input_byte, num_bytes);
6002 dec(src^.pub.bytes_in_buffer, num_bytes);
6007 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6008 function glBitmap_libJPEG_empty_output_buffer(cinfo: j_compress_ptr): boolean; cdecl;
6010 dest: glBitmap_libJPEG_dest_mgr_ptr;
6012 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
6014 if dest^.pub.free_in_buffer < Cardinal(Length(dest^.DestBuffer)) then begin
6015 // write complete buffer
6016 dest^.DestStream.Write(dest^.DestBuffer[1], SizeOf(dest^.DestBuffer));
6019 dest^.pub.next_output_byte := @dest^.DestBuffer[1];
6020 dest^.pub.free_in_buffer := Length(dest^.DestBuffer);
6026 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6027 procedure glBitmap_libJPEG_term_destination(cinfo: j_compress_ptr); cdecl;
6030 dest: glBitmap_libJPEG_dest_mgr_ptr;
6032 dest := glBitmap_libJPEG_dest_mgr_ptr(cinfo^.dest);
6034 for Idx := Low(dest^.DestBuffer) to High(dest^.DestBuffer) do begin
6035 // check for endblock
6036 if (Idx < High(dest^.DestBuffer)) and (dest^.DestBuffer[Idx] = $FF) and (dest^.DestBuffer[Idx +1] = JPEG_EOI) then begin
6038 dest^.DestStream.Write(dest^.DestBuffer[Idx], 2);
6043 dest^.DestStream.Write(dest^.DestBuffer[Idx], 1);
6048 {$IFDEF GLB_SUPPORT_JPEG_READ}
6049 {$IF DEFINED(GLB_SDL_IMAGE)}
6050 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6051 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6053 Surface: PSDL_Surface;
6058 RWops := glBitmapCreateRWops(aStream);
6060 if IMG_isJPG(RWops) > 0 then begin
6061 Surface := IMG_LoadJPG_RW(RWops);
6063 AssignFromSurface(Surface);
6066 SDL_FreeSurface(Surface);
6074 {$ELSEIF DEFINED(GLB_LIB_JPEG)}
6075 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6076 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6079 Temp: array[0..1]of Byte;
6081 jpeg: jpeg_decompress_struct;
6082 jpeg_err: jpeg_error_mgr;
6084 IntFormat: TglBitmapFormat;
6086 TempHeight, TempWidth: Integer;
6091 FormatDesc: TFormatDescriptor;
6095 if not init_libJPEG then
6096 raise Exception.Create('LoadJPG - unable to initialize libJPEG.');
6099 // reading first two bytes to test file and set cursor back to begin
6100 StreamPos := aStream.Position;
6101 aStream.Read({%H-}Temp[0], 2);
6102 aStream.Position := StreamPos;
6104 // if Bitmap then read file.
6105 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
6106 FillChar(jpeg{%H-}, SizeOf(jpeg_decompress_struct), $00);
6107 FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
6110 jpeg.err := jpeg_std_error(@jpeg_err);
6111 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
6112 jpeg_err.output_message := glBitmap_libJPEG_output_message;
6114 // decompression struct
6115 jpeg_create_decompress(@jpeg);
6117 // allocation space for streaming methods
6118 jpeg.src := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_source_mgr));
6120 // seeting up custom functions
6121 with glBitmap_libJPEG_source_mgr_ptr(jpeg.src)^ do begin
6122 pub.init_source := glBitmap_libJPEG_init_source;
6123 pub.fill_input_buffer := glBitmap_libJPEG_fill_input_buffer;
6124 pub.skip_input_data := glBitmap_libJPEG_skip_input_data;
6125 pub.resync_to_restart := jpeg_resync_to_restart; // use default method
6126 pub.term_source := glBitmap_libJPEG_term_source;
6128 pub.bytes_in_buffer := 0; // forces fill_input_buffer on first read
6129 pub.next_input_byte := nil; // until buffer loaded
6131 SrcStream := aStream;
6134 // set global decoding state
6135 jpeg.global_state := DSTATE_START;
6137 // read header of jpeg
6138 jpeg_read_header(@jpeg, false);
6140 // setting output parameter
6141 case jpeg.jpeg_color_space of
6144 jpeg.out_color_space := JCS_GRAYSCALE;
6145 IntFormat := tfLuminance8;
6148 jpeg.out_color_space := JCS_RGB;
6149 IntFormat := tfRGB8;
6153 jpeg_start_decompress(@jpeg);
6155 TempHeight := jpeg.output_height;
6156 TempWidth := jpeg.output_width;
6158 FormatDesc := TFormatDescriptor.Get(IntFormat);
6160 // creating new image
6161 GetMem(pImage, FormatDesc.GetSize(TempWidth, TempHeight));
6165 for Row := 0 to TempHeight -1 do begin
6166 jpeg_read_scanlines(@jpeg, @pTemp, 1);
6167 Inc(pTemp, FormatDesc.GetSize(TempWidth, 1));
6170 // finish decompression
6171 jpeg_finish_decompress(@jpeg);
6173 // destroy decompression
6174 jpeg_destroy_decompress(@jpeg);
6176 SetDataPointer(pImage, IntFormat, TempWidth, TempHeight);
6189 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
6190 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6191 function TglBitmap.LoadJPEG(const aStream: TStream): Boolean;
6196 Temp: array[0..1]of Byte;
6200 // reading first two bytes to test file and set cursor back to begin
6201 StreamPos := aStream.Position;
6202 aStream.Read(Temp[0], 2);
6203 aStream.Position := StreamPos;
6205 // if Bitmap then read file.
6206 if ((Temp[0] = $FF) and (Temp[1] = $D8)) then begin
6207 bmp := TBitmap.Create;
6209 jpg := TJPEGImage.Create;
6211 jpg.LoadFromStream(aStream);
6213 result := AssignFromBitmap(bmp);
6225 {$IFDEF GLB_SUPPORT_JPEG_WRITE}
6226 {$IF DEFINED(GLB_LIB_JPEG)}
6227 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6228 procedure TglBitmap.SaveJPEG(const aStream: TStream);
6230 jpeg: jpeg_compress_struct;
6231 jpeg_err: jpeg_error_mgr;
6233 pTemp, pTemp2: pByte;
6235 procedure CopyRow(pDest, pSource: pByte);
6239 for X := 0 to Width - 1 do begin
6240 pByteArray(pDest)^[0] := pByteArray(pSource)^[2];
6241 pByteArray(pDest)^[1] := pByteArray(pSource)^[1];
6242 pByteArray(pDest)^[2] := pByteArray(pSource)^[0];
6249 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
6250 raise EglBitmapUnsupportedFormat.Create(Format);
6252 if not init_libJPEG then
6253 raise Exception.Create('SaveJPG - unable to initialize libJPEG.');
6256 FillChar(jpeg{%H-}, SizeOf(jpeg_compress_struct), $00);
6257 FillChar(jpeg_err{%H-}, SizeOf(jpeg_error_mgr), $00);
6260 jpeg.err := jpeg_std_error(@jpeg_err);
6261 jpeg_err.error_exit := glBitmap_libJPEG_error_exit;
6262 jpeg_err.output_message := glBitmap_libJPEG_output_message;
6264 // compression struct
6265 jpeg_create_compress(@jpeg);
6267 // allocation space for streaming methods
6268 jpeg.dest := jpeg.mem^.alloc_small(@jpeg, JPOOL_PERMANENT, SizeOf(glBitmap_libJPEG_dest_mgr));
6270 // seeting up custom functions
6271 with glBitmap_libJPEG_dest_mgr_ptr(jpeg.dest)^ do begin
6272 pub.init_destination := glBitmap_libJPEG_init_destination;
6273 pub.empty_output_buffer := glBitmap_libJPEG_empty_output_buffer;
6274 pub.term_destination := glBitmap_libJPEG_term_destination;
6276 pub.next_output_byte := @DestBuffer[1];
6277 pub.free_in_buffer := Length(DestBuffer);
6279 DestStream := aStream;
6282 // very important state
6283 jpeg.global_state := CSTATE_START;
6284 jpeg.image_width := Width;
6285 jpeg.image_height := Height;
6287 tfAlpha8, tfLuminance8: begin
6288 jpeg.input_components := 1;
6289 jpeg.in_color_space := JCS_GRAYSCALE;
6291 tfRGB8, tfBGR8: begin
6292 jpeg.input_components := 3;
6293 jpeg.in_color_space := JCS_RGB;
6297 jpeg_set_defaults(@jpeg);
6298 jpeg_set_quality(@jpeg, 95, true);
6299 jpeg_start_compress(@jpeg, true);
6302 if Format = tfBGR8 then
6303 GetMem(pTemp2, fRowSize)
6308 for Row := 0 to jpeg.image_height -1 do begin
6310 if Format = tfBGR8 then
6311 CopyRow(pTemp2, pTemp)
6316 jpeg_write_scanlines(@jpeg, @pTemp2, 1);
6317 inc(pTemp, fRowSize);
6321 if Format = tfBGR8 then
6324 jpeg_finish_compress(@jpeg);
6325 jpeg_destroy_compress(@jpeg);
6331 {$ELSEIF DEFINED(GLB_DELPHI_JPEG)}
6332 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6333 procedure TglBitmap.SaveJPEG(const aStream: TStream);
6338 if not (ftJPEG in FormatGetSupportedFiles(Format)) then
6339 raise EglBitmapUnsupportedFormat.Create(Format);
6341 Bmp := TBitmap.Create;
6343 Jpg := TJPEGImage.Create;
6345 AssignToBitmap(Bmp);
6346 if (Format in [tfAlpha8, tfLuminance8]) then begin
6347 Jpg.Grayscale := true;
6348 Jpg.PixelFormat := jf8Bit;
6351 Jpg.SaveToStream(aStream);
6362 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6363 //BMP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6364 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6371 BMP_COMP_BITFIELDS = 3;
6374 TBMPHeader = packed record
6379 bfOffBits: Cardinal;
6382 TBMPInfo = packed record
6388 biCompression: Cardinal;
6389 biSizeImage: Cardinal;
6390 biXPelsPerMeter: Longint;
6391 biYPelsPerMeter: Longint;
6392 biClrUsed: Cardinal;
6393 biClrImportant: Cardinal;
6396 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6397 function TglBitmap.LoadBMP(const aStream: TStream): Boolean;
6399 //////////////////////////////////////////////////////////////////////////////////////////////////
6400 function ReadInfo(out aInfo: TBMPInfo; out aMask: TglBitmapColorRec): TglBitmapFormat;
6403 aStream.Read(aInfo{%H-}, SizeOf(aInfo));
6404 FillChar(aMask{%H-}, SizeOf(aMask), 0);
6407 case aInfo.biCompression of
6409 BMP_COMP_RLE8: begin
6410 raise EglBitmapException.Create('RLE compression is not supported');
6412 BMP_COMP_BITFIELDS: begin
6413 if (aInfo.biBitCount = 16) or (aInfo.biBitCount = 32) then begin
6414 aStream.Read(aMask.r, SizeOf(aMask.r));
6415 aStream.Read(aMask.g, SizeOf(aMask.g));
6416 aStream.Read(aMask.b, SizeOf(aMask.b));
6417 aStream.Read(aMask.a, SizeOf(aMask.a));
6419 raise EglBitmapException.Create('Bitfields are only supported for 16bit and 32bit formats');
6423 //get suitable format
6424 case aInfo.biBitCount of
6425 8: result := tfLuminance8;
6426 16: result := tfBGR5;
6427 24: result := tfBGR8;
6428 32: result := tfBGRA8;
6432 function ReadColorTable(var aFormat: TglBitmapFormat; const aInfo: TBMPInfo): TbmpColorTableFormat;
6435 ColorTable: TbmpColorTable;
6438 if (aInfo.biBitCount >= 16) then
6440 aFormat := tfLuminance8;
6441 c := aInfo.biClrUsed;
6443 c := 1 shl aInfo.biBitCount;
6444 SetLength(ColorTable, c);
6445 for i := 0 to c-1 do begin
6446 aStream.Read(ColorTable[i], SizeOf(TbmpColorTableEnty));
6447 if (ColorTable[i].r <> ColorTable[i].g) or (ColorTable[i].g <> ColorTable[i].b) then
6451 result := TbmpColorTableFormat.Create;
6452 result.PixelSize := aInfo.biBitCount / 8;
6453 result.ColorTable := ColorTable;
6454 result.Range := glBitmapColorRec($FF, $FF, $FF, $00);
6457 //////////////////////////////////////////////////////////////////////////////////////////////////
6458 function CheckBitfields(var aFormat: TglBitmapFormat; const aMask: TglBitmapColorRec;
6459 const aInfo: TBMPInfo): TbmpBitfieldFormat;
6461 TmpFormat: TglBitmapFormat;
6462 FormatDesc: TFormatDescriptor;
6465 if (aMask.r <> 0) or (aMask.g <> 0) or (aMask.b <> 0) or (aMask.a <> 0) then begin
6466 for TmpFormat := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
6467 FormatDesc := TFormatDescriptor.Get(TmpFormat);
6468 if FormatDesc.MaskMatch(aMask.r, aMask.g, aMask.b, aMask.a) then begin
6469 aFormat := FormatDesc.Format;
6474 if (aMask.a = 0) and TFormatDescriptor.Get(aFormat).HasAlpha then
6475 aFormat := TFormatDescriptor.Get(aFormat).WithoutAlpha;
6476 if (aMask.a <> 0) and not TFormatDescriptor.Get(aFormat).HasAlpha then
6477 aFormat := TFormatDescriptor.Get(aFormat).WithAlpha;
6479 result := TbmpBitfieldFormat.Create;
6480 result.PixelSize := aInfo.biBitCount / 8;
6481 result.RedMask := aMask.r;
6482 result.GreenMask := aMask.g;
6483 result.BlueMask := aMask.b;
6484 result.AlphaMask := aMask.a;
6491 ImageSize, rbLineSize, wbLineSize, Padding, i: Integer;
6492 PaddingBuff: Cardinal;
6493 LineBuf, ImageData, TmpData: PByte;
6494 SourceMD, DestMD: Pointer;
6495 BmpFormat: TglBitmapFormat;
6498 Mask: TglBitmapColorRec;
6503 SpecialFormat: TFormatDescriptor;
6504 FormatDesc: TFormatDescriptor;
6506 //////////////////////////////////////////////////////////////////////////////////////////////////
6507 procedure SpecialFormatReadLine(aData: PByte; aLineBuf: PByte);
6510 Pixel: TglBitmapPixelData;
6512 aStream.Read(aLineBuf^, rbLineSize);
6513 SpecialFormat.PreparePixel(Pixel);
6514 for i := 0 to Info.biWidth-1 do begin
6515 SpecialFormat.Unmap(aLineBuf, Pixel, SourceMD);
6516 glBitmapConvertPixel(Pixel, SpecialFormat, FormatDesc);
6517 FormatDesc.Map(Pixel, aData, DestMD);
6523 BmpFormat := tfEmpty;
6524 SpecialFormat := nil;
6530 StartPos := aStream.Position;
6531 aStream.Read(Header{%H-}, SizeOf(Header));
6533 if Header.bfType = BMP_MAGIC then begin
6535 BmpFormat := ReadInfo(Info, Mask);
6536 SpecialFormat := ReadColorTable(BmpFormat, Info);
6537 if not Assigned(SpecialFormat) then
6538 SpecialFormat := CheckBitfields(BmpFormat, Mask, Info);
6539 aStream.Position := StartPos + Header.bfOffBits;
6541 if (BmpFormat <> tfEmpty) then begin
6542 FormatDesc := TFormatDescriptor.Get(BmpFormat);
6543 rbLineSize := Round(Info.biWidth * Info.biBitCount / 8); //ReadBuffer LineSize
6544 wbLineSize := Trunc(Info.biWidth * FormatDesc.PixelSize);
6545 Padding := (((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3) - rbLineSize;
6548 DestMD := FormatDesc.CreateMappingData;
6549 ImageSize := FormatDesc.GetSize(Info.biWidth, abs(Info.biHeight));
6550 GetMem(ImageData, ImageSize);
6551 if Assigned(SpecialFormat) then begin
6552 GetMem(LineBuf, rbLineSize); //tmp Memory for converting Bitfields
6553 SourceMD := SpecialFormat.CreateMappingData;
6558 FillChar(ImageData^, ImageSize, $FF);
6559 TmpData := ImageData;
6560 if (Info.biHeight > 0) then
6561 Inc(TmpData, wbLineSize * (Info.biHeight-1));
6562 for i := 0 to Abs(Info.biHeight)-1 do begin
6563 if Assigned(SpecialFormat) then
6564 SpecialFormatReadLine(TmpData, LineBuf) //if is special format read and convert data
6566 aStream.Read(TmpData^, wbLineSize); //else only read data
6567 if (Info.biHeight > 0) then
6568 dec(TmpData, wbLineSize)
6570 inc(TmpData, wbLineSize);
6571 aStream.Read(PaddingBuff{%H-}, Padding);
6573 SetDataPointer(ImageData, BmpFormat, Info.biWidth, abs(Info.biHeight));
6576 if Assigned(LineBuf) then
6578 if Assigned(SourceMD) then
6579 SpecialFormat.FreeMappingData(SourceMD);
6580 FormatDesc.FreeMappingData(DestMD);
6587 raise EglBitmapException.Create('LoadBMP - No suitable format found');
6589 aStream.Position := StartPos;
6593 FreeAndNil(SpecialFormat);
6596 else aStream.Position := StartPos;
6599 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6600 procedure TglBitmap.SaveBMP(const aStream: TStream);
6604 Converter: TbmpColorTableFormat;
6605 FormatDesc: TFormatDescriptor;
6606 SourceFD, DestFD: Pointer;
6607 pData, srcData, dstData, ConvertBuffer: pByte;
6609 Pixel: TglBitmapPixelData;
6610 ImageSize, wbLineSize, rbLineSize, Padding, LineIdx, PixelIdx: Integer;
6611 RedMask, GreenMask, BlueMask, AlphaMask: Cardinal;
6613 PaddingBuff: Cardinal;
6615 function GetLineWidth : Integer;
6617 result := ((Info.biWidth * Info.biBitCount + 31) and - 32) shr 3;
6621 if not (ftBMP in FormatGetSupportedFiles(Format)) then
6622 raise EglBitmapUnsupportedFormat.Create(Format);
6625 FormatDesc := TFormatDescriptor.Get(Format);
6626 ImageSize := FormatDesc.GetSize(Dimension);
6628 FillChar(Header{%H-}, SizeOf(Header), 0);
6629 Header.bfType := BMP_MAGIC;
6630 Header.bfSize := SizeOf(Header) + SizeOf(Info) + ImageSize;
6631 Header.bfReserved1 := 0;
6632 Header.bfReserved2 := 0;
6633 Header.bfOffBits := SizeOf(Header) + SizeOf(Info);
6635 FillChar(Info{%H-}, SizeOf(Info), 0);
6636 Info.biSize := SizeOf(Info);
6637 Info.biWidth := Width;
6638 Info.biHeight := Height;
6640 Info.biCompression := BMP_COMP_RGB;
6641 Info.biSizeImage := ImageSize;
6646 Info.biBitCount := 4;
6647 Header.bfSize := Header.bfSize + 16 * SizeOf(Cardinal);
6648 Header.bfOffBits := Header.bfOffBits + 16 * SizeOf(Cardinal); //16 ColorTable entries
6649 Converter := TbmpColorTableFormat.Create;
6650 Converter.PixelSize := 0.5;
6651 Converter.Format := Format;
6652 Converter.Range := glBitmapColorRec($F, $F, $F, $0);
6653 Converter.CreateColorTable;
6656 tfR3G3B2, tfLuminance8: begin
6657 Info.biBitCount := 8;
6658 Header.bfSize := Header.bfSize + 256 * SizeOf(Cardinal);
6659 Header.bfOffBits := Header.bfOffBits + 256 * SizeOf(Cardinal); //256 ColorTable entries
6660 Converter := TbmpColorTableFormat.Create;
6661 Converter.PixelSize := 1;
6662 Converter.Format := Format;
6663 if (Format = tfR3G3B2) then begin
6664 Converter.Range := glBitmapColorRec($7, $7, $3, $0);
6665 Converter.Shift := glBitmapShiftRec(0, 3, 6, 0);
6667 Converter.Range := glBitmapColorRec($FF, $FF, $FF, $0);
6668 Converter.CreateColorTable;
6671 tfRGB4, tfRGB5, tfR5G6B5, tfRGB5A1, tfRGBA4,
6672 tfBGR4, tfBGR5, tfB5G6R5, tfBGR5A1, tfBGRA4: begin
6673 Info.biBitCount := 16;
6674 Info.biCompression := BMP_COMP_BITFIELDS;
6677 tfBGR8, tfRGB8: begin
6678 Info.biBitCount := 24;
6681 tfRGB10, tfRGB10A2, tfRGBA8,
6682 tfBGR10, tfBGR10A2, tfBGRA8: begin
6683 Info.biBitCount := 32;
6684 Info.biCompression := BMP_COMP_BITFIELDS;
6687 raise EglBitmapUnsupportedFormat.Create(Format);
6689 Info.biXPelsPerMeter := 2835;
6690 Info.biYPelsPerMeter := 2835;
6693 if Info.biCompression = BMP_COMP_BITFIELDS then begin
6694 Header.bfSize := Header.bfSize + 4 * SizeOf(Cardinal);
6695 Header.bfOffBits := Header.bfOffBits + 4 * SizeOf(Cardinal);
6697 RedMask := FormatDesc.RedMask;
6698 GreenMask := FormatDesc.GreenMask;
6699 BlueMask := FormatDesc.BlueMask;
6700 AlphaMask := FormatDesc.AlphaMask;
6704 aStream.Write(Header, SizeOf(Header));
6705 aStream.Write(Info, SizeOf(Info));
6708 if Assigned(Converter) then
6709 aStream.Write(Converter.ColorTable[0].b,
6710 SizeOf(TbmpColorTableEnty) * Length(Converter.ColorTable));
6713 if Info.biCompression = BMP_COMP_BITFIELDS then begin
6714 aStream.Write(RedMask, SizeOf(Cardinal));
6715 aStream.Write(GreenMask, SizeOf(Cardinal));
6716 aStream.Write(BlueMask, SizeOf(Cardinal));
6717 aStream.Write(AlphaMask, SizeOf(Cardinal));
6721 rbLineSize := Round(Info.biWidth * FormatDesc.PixelSize);
6722 wbLineSize := Round(Info.biWidth * Info.biBitCount / 8);
6723 Padding := GetLineWidth - wbLineSize;
6727 inc(pData, (Height-1) * rbLineSize);
6729 // prepare row buffer. But only for RGB because RGBA supports color masks
6730 // so it's possible to change color within the image.
6731 if Assigned(Converter) then begin
6732 FormatDesc.PreparePixel(Pixel);
6733 GetMem(ConvertBuffer, wbLineSize);
6734 SourceFD := FormatDesc.CreateMappingData;
6735 DestFD := Converter.CreateMappingData;
6737 ConvertBuffer := nil;
6740 for LineIdx := 0 to Height - 1 do begin
6742 if Assigned(Converter) then begin
6744 dstData := ConvertBuffer;
6745 for PixelIdx := 0 to Info.biWidth-1 do begin
6746 FormatDesc.Unmap(srcData, Pixel, SourceFD);
6747 glBitmapConvertPixel(Pixel, FormatDesc, Converter);
6748 Converter.Map(Pixel, dstData, DestFD);
6750 aStream.Write(ConvertBuffer^, wbLineSize);
6752 aStream.Write(pData^, rbLineSize);
6754 dec(pData, rbLineSize);
6755 if (Padding > 0) then
6756 aStream.Write(PaddingBuff, Padding);
6759 // destroy row buffer
6760 if Assigned(ConvertBuffer) then begin
6761 FormatDesc.FreeMappingData(SourceFD);
6762 Converter.FreeMappingData(DestFD);
6763 FreeMem(ConvertBuffer);
6767 if Assigned(Converter) then
6772 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6773 //TGA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6774 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6776 TTGAHeader = packed record
6780 //ColorMapSpec: Array[0..4] of Byte;
6781 ColorMapStart: Word;
6782 ColorMapLength: Word;
6783 ColorMapEntrySize: Byte;
6793 TGA_UNCOMPRESSED_RGB = 2;
6794 TGA_UNCOMPRESSED_GRAY = 3;
6795 TGA_COMPRESSED_RGB = 10;
6796 TGA_COMPRESSED_GRAY = 11;
6798 TGA_NONE_COLOR_TABLE = 0;
6800 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6801 function TglBitmap.LoadTGA(const aStream: TStream): Boolean;
6804 ImageData: System.PByte;
6805 StartPosition: Int64;
6806 PixelSize, LineSize: Integer;
6807 tgaFormat: TglBitmapFormat;
6808 FormatDesc: TFormatDescriptor;
6809 Counter: packed record
6811 low, high, dir: Integer;
6818 ////////////////////////////////////////////////////////////////////////////////////////
6819 procedure ReadUncompressed;
6822 buf, tmp1, tmp2: System.PByte;
6825 if (Counter.X.dir < 0) then
6826 GetMem(buf, LineSize);
6828 while (Counter.Y.low <> Counter.Y.high + counter.Y.dir) do begin
6830 inc(tmp1, (Counter.Y.low * LineSize)); //pointer to LineStart
6831 if (Counter.X.dir < 0) then begin //flip X
6832 aStream.Read(buf^, LineSize);
6834 inc(tmp2, LineSize - PixelSize); //pointer to last pixel in line
6835 for i := 0 to Header.Width-1 do begin //for all pixels in line
6836 for j := 0 to PixelSize-1 do begin //for all bytes in pixel
6841 dec(tmp2, 2*PixelSize); //move 2 backwards, because j-loop moved 1 forward
6844 aStream.Read(tmp1^, LineSize);
6845 inc(Counter.Y.low, Counter.Y.dir); //move to next line index
6848 if Assigned(buf) then
6853 ////////////////////////////////////////////////////////////////////////////////////////
6854 procedure ReadCompressed;
6856 /////////////////////////////////////////////////////////////////
6858 TmpData: System.PByte;
6859 LinePixelsRead: Integer;
6860 procedure CheckLine;
6862 if (LinePixelsRead >= Header.Width) then begin
6863 LinePixelsRead := 0;
6864 inc(Counter.Y.low, Counter.Y.dir); //next line index
6865 TmpData := ImageData;
6866 inc(TmpData, Counter.Y.low * LineSize); //set line
6867 if (Counter.X.dir < 0) then //if x flipped then
6868 inc(TmpData, LineSize - PixelSize); //set last pixel
6872 /////////////////////////////////////////////////////////////////
6875 CacheSize, CachePos: Integer;
6876 procedure CachedRead(out Buffer; Count: Integer);
6880 if (CachePos + Count > CacheSize) then begin
6881 //if buffer overflow save non read bytes
6883 if (CacheSize - CachePos > 0) then begin
6884 BytesRead := CacheSize - CachePos;
6885 Move(PByteArray(Cache)^[CachePos], Buffer{%H-}, BytesRead);
6886 inc(CachePos, BytesRead);
6889 //load cache from file
6890 CacheSize := Min(CACHE_SIZE, aStream.Size - aStream.Position);
6891 aStream.Read(Cache^, CacheSize);
6894 //read rest of requested bytes
6895 if (Count - BytesRead > 0) then begin
6896 Move(PByteArray(Cache)^[CachePos], TByteArray(Buffer)[BytesRead], Count - BytesRead);
6897 inc(CachePos, Count - BytesRead);
6900 //if no buffer overflow just read the data
6901 Move(PByteArray(Cache)^[CachePos], Buffer, Count);
6902 inc(CachePos, Count);
6906 procedure PixelToBuffer(const aData: PByte; var aBuffer: PByte);
6911 inc(aBuffer, Counter.X.dir);
6914 PWord(aBuffer)^ := PWord(aData)^;
6915 inc(aBuffer, 2 * Counter.X.dir);
6918 PByteArray(aBuffer)^[0] := PByteArray(aData)^[0];
6919 PByteArray(aBuffer)^[1] := PByteArray(aData)^[1];
6920 PByteArray(aBuffer)^[2] := PByteArray(aData)^[2];
6921 inc(aBuffer, 3 * Counter.X.dir);
6924 PCardinal(aBuffer)^ := PCardinal(aData)^;
6925 inc(aBuffer, 4 * Counter.X.dir);
6931 TotalPixelsToRead, TotalPixelsRead: Integer;
6933 buf: array [0..3] of Byte; //1 pixel is max 32bit long
6934 PixelRepeat: Boolean;
6935 PixelsToRead, PixelCount: Integer;
6940 TotalPixelsToRead := Header.Width * Header.Height;
6941 TotalPixelsRead := 0;
6942 LinePixelsRead := 0;
6944 GetMem(Cache, CACHE_SIZE);
6946 TmpData := ImageData;
6947 inc(TmpData, Counter.Y.low * LineSize); //set line
6948 if (Counter.X.dir < 0) then //if x flipped then
6949 inc(TmpData, LineSize - PixelSize); //set last pixel
6953 CachedRead(Temp, 1);
6954 PixelRepeat := (Temp and $80) > 0;
6955 PixelsToRead := (Temp and $7F) + 1;
6956 inc(TotalPixelsRead, PixelsToRead);
6959 CachedRead(buf[0], PixelSize);
6960 while (PixelsToRead > 0) do begin
6962 PixelCount := Min(Header.Width - LinePixelsRead, PixelsToRead); //max read to EOL or EOF
6963 while (PixelCount > 0) do begin
6964 if not PixelRepeat then
6965 CachedRead(buf[0], PixelSize);
6966 PixelToBuffer(@buf[0], TmpData);
6967 inc(LinePixelsRead);
6972 until (TotalPixelsRead >= TotalPixelsToRead);
6978 function IsGrayFormat: Boolean;
6980 result := Header.ImageType in [TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_GRAY];
6986 // reading header to test file and set cursor back to begin
6987 StartPosition := aStream.Position;
6988 aStream.Read(Header{%H-}, SizeOf(Header));
6990 // no colormapped files
6991 if (Header.ColorMapType = TGA_NONE_COLOR_TABLE) and (Header.ImageType in [
6992 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY, TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY]) then
6995 if Header.ImageID <> 0 then // skip image ID
6996 aStream.Position := aStream.Position + Header.ImageID;
6998 tgaFormat := tfEmpty;
7000 8: if IsGrayFormat then case (Header.ImageDesc and $F) of
7001 0: tgaFormat := tfLuminance8;
7002 8: tgaFormat := tfAlpha8;
7005 16: if IsGrayFormat then case (Header.ImageDesc and $F) of
7006 0: tgaFormat := tfLuminance16;
7007 8: tgaFormat := tfLuminance8Alpha8;
7008 end else case (Header.ImageDesc and $F) of
7009 0: tgaFormat := tfBGR5;
7010 1: tgaFormat := tfBGR5A1;
7011 4: tgaFormat := tfBGRA4;
7014 24: if not IsGrayFormat then case (Header.ImageDesc and $F) of
7015 0: tgaFormat := tfBGR8;
7018 32: if not IsGrayFormat then case (Header.ImageDesc and $F) of
7019 2: tgaFormat := tfBGR10A2;
7020 8: tgaFormat := tfBGRA8;
7024 if (tgaFormat = tfEmpty) then
7025 raise EglBitmapException.Create('LoadTga - unsupported format');
7027 FormatDesc := TFormatDescriptor.Get(tgaFormat);
7028 PixelSize := FormatDesc.GetSize(1, 1);
7029 LineSize := FormatDesc.GetSize(Header.Width, 1);
7031 GetMem(ImageData, LineSize * Header.Height);
7034 if ((Header.ImageDesc and (1 shl 4)) > 0) then begin
7035 Counter.X.low := Header.Height-1;;
7036 Counter.X.high := 0;
7037 Counter.X.dir := -1;
7040 Counter.X.high := Header.Height-1;
7045 if ((Header.ImageDesc and (1 shl 5)) > 0) then begin
7047 Counter.Y.high := Header.Height-1;
7050 Counter.Y.low := Header.Height-1;;
7051 Counter.Y.high := 0;
7052 Counter.Y.dir := -1;
7056 case Header.ImageType of
7057 TGA_UNCOMPRESSED_RGB, TGA_UNCOMPRESSED_GRAY:
7059 TGA_COMPRESSED_RGB, TGA_COMPRESSED_GRAY:
7063 SetDataPointer(ImageData, tgaFormat, Header.Width, Header.Height);
7070 aStream.Position := StartPosition;
7073 else aStream.Position := StartPosition;
7076 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7077 procedure TglBitmap.SaveTGA(const aStream: TStream);
7080 LineSize, Size, x, y: Integer;
7081 Pixel: TglBitmapPixelData;
7082 LineBuf, SourceData, DestData: PByte;
7083 SourceMD, DestMD: Pointer;
7084 FormatDesc: TFormatDescriptor;
7085 Converter: TFormatDescriptor;
7087 if not (ftTGA in FormatGetSupportedFiles(Format)) then
7088 raise EglBitmapUnsupportedFormat.Create(Format);
7091 FillChar(Header{%H-}, SizeOf(Header), 0);
7094 if (Format in [tfLuminance8, tfLuminance6Alpha2, tfLuminance4Alpha4, tfAlpha8,
7095 tfLuminance16, tfLuminance12Alpha4, tfLuminance8Alpha8]) then
7096 Header.ImageType := TGA_UNCOMPRESSED_GRAY
7098 Header.ImageType := TGA_UNCOMPRESSED_RGB;
7101 if (Format in [tfLuminance8, tfLuminance6Alpha2, tfLuminance4Alpha4, tfAlpha8]) then
7103 else if (Format in [tfLuminance16, tfLuminance12Alpha4, tfLuminance8Alpha8,
7104 tfRGB5, tfBGR5, tfRGB5A1, tfBGR5A1, tfRGBA4, tfBGRA4]) then
7106 else if (Format in [tfBGR8, tfRGB8]) then
7114 Header.ImageDesc := 1 and $F;
7115 tfRGB10A2, tfBGR10A2:
7116 Header.ImageDesc := 2 and $F;
7118 Header.ImageDesc := 4 and $F;
7119 tfAlpha8, tfLuminance8Alpha8, tfRGBA8, tfBGRA8:
7120 Header.ImageDesc := 8 and $F;
7123 Header.Width := Width;
7124 Header.Height := Height;
7125 Header.ImageDesc := Header.ImageDesc or $20; //flip y
7126 aStream.Write(Header, SizeOf(Header));
7128 // convert RGB(A) to BGR(A)
7130 FormatDesc := TFormatDescriptor.Get(Format);
7131 Size := FormatDesc.GetSize(Dimension);
7132 if Format in [tfRGB5, tfRGB5A1, tfRGBA4, tfRGB8, tfRGB10A2, tfRGBA8] then begin
7133 if (FormatDesc.RGBInverted = tfEmpty) then
7134 raise EglBitmapException.Create('inverted RGB format is empty');
7135 Converter := TFormatDescriptor.Get(FormatDesc.RGBInverted);
7136 if not glBitmapColorRecCmp(Converter.Range, FormatDesc.Range) or
7137 (Converter.PixelSize <> FormatDesc.PixelSize) then
7138 raise EglBitmapException.Create('invalid inverted RGB format');
7141 if Assigned(Converter) then begin
7142 LineSize := FormatDesc.GetSize(Width, 1);
7143 GetMem(LineBuf, LineSize);
7144 SourceMD := FormatDesc.CreateMappingData;
7145 DestMD := Converter.CreateMappingData;
7148 for y := 0 to Height-1 do begin
7149 DestData := LineBuf;
7150 for x := 0 to Width-1 do begin
7151 FormatDesc.Unmap(SourceData, Pixel, SourceMD);
7152 Converter.Map(Pixel, DestData, DestMD);
7154 aStream.Write(LineBuf^, LineSize);
7158 FormatDesc.FreeMappingData(SourceMD);
7159 FormatDesc.FreeMappingData(DestMD);
7162 aStream.Write(Data^, Size);
7165 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7166 //DDS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7167 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7169 DDS_MAGIC: Cardinal = $20534444;
7171 // DDS_header.dwFlags
7172 DDSD_CAPS = $00000001;
7173 DDSD_HEIGHT = $00000002;
7174 DDSD_WIDTH = $00000004;
7175 DDSD_PIXELFORMAT = $00001000;
7177 // DDS_header.sPixelFormat.dwFlags
7178 DDPF_ALPHAPIXELS = $00000001;
7179 DDPF_ALPHA = $00000002;
7180 DDPF_FOURCC = $00000004;
7181 DDPF_RGB = $00000040;
7182 DDPF_LUMINANCE = $00020000;
7184 // DDS_header.sCaps.dwCaps1
7185 DDSCAPS_TEXTURE = $00001000;
7187 // DDS_header.sCaps.dwCaps2
7188 DDSCAPS2_CUBEMAP = $00000200;
7190 D3DFMT_DXT1 = $31545844;
7191 D3DFMT_DXT3 = $33545844;
7192 D3DFMT_DXT5 = $35545844;
7195 TDDSPixelFormat = packed record
7199 dwRGBBitCount: Cardinal;
7200 dwRBitMask: Cardinal;
7201 dwGBitMask: Cardinal;
7202 dwBBitMask: Cardinal;
7203 dwABitMask: Cardinal;
7206 TDDSCaps = packed record
7210 dwReserved: Cardinal;
7213 TDDSHeader = packed record
7218 dwPitchOrLinearSize: Cardinal;
7220 dwMipMapCount: Cardinal;
7221 dwReserved: array[0..10] of Cardinal;
7222 PixelFormat: TDDSPixelFormat;
7224 dwReserved2: Cardinal;
7227 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7228 function TglBitmap.LoadDDS(const aStream: TStream): Boolean;
7231 Converter: TbmpBitfieldFormat;
7233 function GetDDSFormat: TglBitmapFormat;
7235 fd: TFormatDescriptor;
7237 Range: TglBitmapColorRec;
7241 with Header.PixelFormat do begin
7243 if ((dwFlags and DDPF_FOURCC) > 0) then begin
7244 case Header.PixelFormat.dwFourCC of
7245 D3DFMT_DXT1: result := tfS3tcDtx1RGBA;
7246 D3DFMT_DXT3: result := tfS3tcDtx3RGBA;
7247 D3DFMT_DXT5: result := tfS3tcDtx5RGBA;
7249 end else if ((Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE)) > 0) then begin
7251 //find matching format
7252 for result := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
7253 fd := TFormatDescriptor.Get(result);
7254 if fd.MaskMatch(dwRBitMask, dwGBitMask, dwBBitMask, dwABitMask) and
7255 (8 * fd.PixelSize = dwRGBBitCount) then
7259 //find format with same Range
7260 Range.r := dwRBitMask;
7261 Range.g := dwGBitMask;
7262 Range.b := dwBBitMask;
7263 Range.a := dwABitMask;
7264 for i := 0 to 3 do begin
7265 while ((Range.arr[i] and 1) = 0) and (Range.arr[i] > 0) do
7266 Range.arr[i] := Range.arr[i] shr 1;
7268 for result := High(TglBitmapFormat) downto Low(TglBitmapFormat) do begin
7269 fd := TFormatDescriptor.Get(result);
7272 if (fd.Range.arr[i] <> Range.arr[i]) then begin
7280 //no format with same range found -> use default
7281 if (result = tfEmpty) then begin
7282 if (dwABitMask > 0) then
7288 Converter := TbmpBitfieldFormat.Create;
7289 Converter.RedMask := dwRBitMask;
7290 Converter.GreenMask := dwGBitMask;
7291 Converter.BlueMask := dwBBitMask;
7292 Converter.AlphaMask := dwABitMask;
7293 Converter.PixelSize := dwRGBBitCount / 8;
7300 x, y, LineSize, RowSize, Magic: Cardinal;
7301 NewImage, TmpData, RowData, SrcData: System.PByte;
7302 SourceMD, DestMD: Pointer;
7303 Pixel: TglBitmapPixelData;
7304 ddsFormat: TglBitmapFormat;
7305 FormatDesc: TFormatDescriptor;
7310 StreamPos := aStream.Position;
7313 aStream.Read(Magic{%H-}, sizeof(Magic));
7314 if (Magic <> DDS_MAGIC) then begin
7315 aStream.Position := StreamPos;
7320 aStream.Read(Header{%H-}, sizeof(Header));
7321 if (Header.dwSize <> SizeOf(Header)) or
7322 ((Header.dwFlags and (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) <>
7323 (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) then
7325 aStream.Position := StreamPos;
7329 if ((Header.Caps.dwCaps1 and DDSCAPS2_CUBEMAP) > 0) then
7330 raise EglBitmapException.Create('LoadDDS - CubeMaps are not supported');
7332 ddsFormat := GetDDSFormat;
7334 if (ddsFormat = tfEmpty) then
7335 raise EglBitmapException.Create('LoadDDS - unsupported Pixelformat found.');
7337 FormatDesc := TFormatDescriptor.Get(ddsFormat);
7338 LineSize := Trunc(Header.dwWidth * FormatDesc.PixelSize);
7339 GetMem(NewImage, Header.dwHeight * LineSize);
7341 TmpData := NewImage;
7344 if Assigned(Converter) then begin
7345 RowSize := Round(Header.dwWidth * Header.PixelFormat.dwRGBBitCount / 8);
7346 GetMem(RowData, RowSize);
7347 SourceMD := Converter.CreateMappingData;
7348 DestMD := FormatDesc.CreateMappingData;
7350 for y := 0 to Header.dwHeight-1 do begin
7351 TmpData := NewImage;
7352 inc(TmpData, y * LineSize);
7354 aStream.Read(SrcData^, RowSize);
7355 for x := 0 to Header.dwWidth-1 do begin
7356 Converter.Unmap(SrcData, Pixel, SourceMD);
7357 glBitmapConvertPixel(Pixel, Converter, FormatDesc);
7358 FormatDesc.Map(Pixel, TmpData, DestMD);
7362 Converter.FreeMappingData(SourceMD);
7363 FormatDesc.FreeMappingData(DestMD);
7369 if ((Header.PixelFormat.dwFlags and DDPF_FOURCC) > 0) then begin
7370 RowSize := Header.dwPitchOrLinearSize div Header.dwWidth;
7371 for Y := 0 to Header.dwHeight-1 do begin
7372 aStream.Read(TmpData^, RowSize);
7373 Inc(TmpData, LineSize);
7378 if (Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE)) > 0 then begin
7379 RowSize := (Header.PixelFormat.dwRGBBitCount * Header.dwWidth) shr 3;
7380 for Y := 0 to Header.dwHeight-1 do begin
7381 aStream.Read(TmpData^, RowSize);
7382 Inc(TmpData, LineSize);
7385 raise EglBitmapException.Create('LoadDDS - unsupported Pixelformat found.');
7387 SetDataPointer(NewImage, ddsFormat, Header.dwWidth, Header.dwHeight);
7394 FreeAndNil(Converter);
7398 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7399 procedure TglBitmap.SaveDDS(const aStream: TStream);
7402 FormatDesc: TFormatDescriptor;
7404 if not (ftDDS in FormatGetSupportedFiles(Format)) then
7405 raise EglBitmapUnsupportedFormat.Create(Format);
7407 FormatDesc := TFormatDescriptor.Get(Format);
7410 FillChar(Header{%H-}, SizeOf(Header), 0);
7411 Header.dwSize := SizeOf(Header);
7412 Header.dwFlags := DDSD_WIDTH or DDSD_HEIGHT or DDSD_CAPS or DDSD_PIXELFORMAT;
7414 Header.dwWidth := Max(1, Width);
7415 Header.dwHeight := Max(1, Height);
7418 Header.Caps.dwCaps1 := DDSCAPS_TEXTURE;
7421 Header.PixelFormat.dwSize := sizeof(Header);
7422 if (FormatDesc.IsCompressed) then begin
7423 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_FOURCC;
7425 tfS3tcDtx1RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT1;
7426 tfS3tcDtx3RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT3;
7427 tfS3tcDtx5RGBA: Header.PixelFormat.dwFourCC := D3DFMT_DXT5;
7429 end else if (Format in [tfAlpha8, tfAlpha16]) then begin
7430 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHA;
7431 Header.PixelFormat.dwRGBBitCount := Round(FormatDesc.PixelSize * 8);
7432 Header.PixelFormat.dwABitMask := FormatDesc.AlphaMask;
7433 end else if (FormatDesc.RedMask = FormatDesc.GreenMask) and (FormatDesc.GreenMask = FormatDesc.BlueMask) then begin
7434 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_LUMINANCE;
7435 Header.PixelFormat.dwRGBBitCount := Round(FormatDesc.PixelSize * 8);
7436 Header.PixelFormat.dwRBitMask := FormatDesc.RedMask;
7437 Header.PixelFormat.dwABitMask := FormatDesc.AlphaMask;
7439 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_RGB;
7440 Header.PixelFormat.dwRGBBitCount := Round(FormatDesc.PixelSize * 8);
7441 Header.PixelFormat.dwRBitMask := FormatDesc.RedMask;
7442 Header.PixelFormat.dwGBitMask := FormatDesc.GreenMask;
7443 Header.PixelFormat.dwBBitMask := FormatDesc.BlueMask;
7444 Header.PixelFormat.dwABitMask := FormatDesc.AlphaMask;
7447 if (FormatDesc.HasAlpha) then
7448 Header.PixelFormat.dwFlags := Header.PixelFormat.dwFlags or DDPF_ALPHAPIXELS;
7450 aStream.Write(DDS_MAGIC, sizeof(DDS_MAGIC));
7451 aStream.Write(Header, SizeOf(Header));
7452 aStream.Write(Data^, FormatDesc.GetSize(Dimension));
7455 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7456 //TglBitmap2D/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7457 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7458 function TglBitmap2D.GetScanline(const aIndex: Integer): Pointer;
7460 if (aIndex >= Low(fLines)) and (aIndex <= High(fLines)) then
7461 result := fLines[aIndex]
7466 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7467 procedure TglBitmap2D.SetDataPointer(const aData: PByte; const aFormat: TglBitmapFormat;
7468 const aWidth: Integer; const aHeight: Integer);
7470 Idx, LineWidth: Integer;
7472 inherited SetDataPointer(aData, aFormat, aWidth, aHeight);
7474 if not TFormatDescriptor.Get(aFormat).IsCompressed then begin
7476 if Assigned(Data) then begin
7477 SetLength(fLines, GetHeight);
7478 LineWidth := Trunc(GetWidth * TFormatDescriptor.Get(Format).PixelSize);
7480 for Idx := 0 to GetHeight-1 do begin
7481 fLines[Idx] := Data;
7482 Inc(fLines[Idx], Idx * LineWidth);
7485 else SetLength(fLines, 0);
7487 SetLength(fLines, 0);
7491 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7492 procedure TglBitmap2D.UploadData(const aTarget: Cardinal; const aBuildWithGlu: Boolean);
7494 FormatDesc: TFormatDescriptor;
7496 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
7498 FormatDesc := TFormatDescriptor.Get(Format);
7499 if FormatDesc.IsCompressed then begin
7500 glCompressedTexImage2D(Target, 0, FormatDesc.glInternalFormat, Width, Height, 0, FormatDesc.GetSize(fDimension), Data)
7501 end else if aBuildWithGlu then begin
7502 gluBuild2DMipmaps(aTarget, FormatDesc.Components, Width, Height,
7503 FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
7505 glTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0,
7506 FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
7510 if (FreeDataAfterGenTexture) then
7514 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7515 procedure TglBitmap2D.AfterConstruction;
7518 Target := GL_TEXTURE_2D;
7521 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7522 procedure TglBitmap2D.GrabScreen(const aTop, aLeft, aRight, aBottom: Integer; const aFormat: TglBitmapFormat);
7525 Size, w, h: Integer;
7526 FormatDesc: TFormatDescriptor;
7528 FormatDesc := TFormatDescriptor.Get(Format);
7529 if FormatDesc.IsCompressed then
7530 raise EglBitmapUnsupportedFormat.Create(Format);
7532 w := aRight - aLeft;
7533 h := aBottom - aTop;
7534 Size := FormatDesc.GetSize(w, h);
7537 glPixelStorei(GL_PACK_ALIGNMENT, 1);
7538 glReadPixels(aLeft, aTop, w, h, FormatDesc.glFormat, FormatDesc.glDataFormat, Temp);
7539 SetDataPointer(Temp, Format, w, h);
7547 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7548 procedure TglBitmap2D.GetDataFromTexture;
7551 TempWidth, TempHeight: Integer;
7552 TempIntFormat: Cardinal;
7553 IntFormat, f: TglBitmapFormat;
7554 FormatDesc: TFormatDescriptor;
7559 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_WIDTH, @TempWidth);
7560 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_HEIGHT, @TempHeight);
7561 glGetTexLevelParameteriv(Target, 0, GL_TEXTURE_INTERNAL_FORMAT, @TempIntFormat);
7563 IntFormat := tfEmpty;
7564 for f := Low(TglBitmapFormat) to High(TglBitmapFormat) do begin
7565 FormatDesc := TFormatDescriptor.Get(f);
7566 if (FormatDesc.glInternalFormat = TempIntFormat) then begin
7567 IntFormat := FormatDesc.Format;
7572 // Getting data from OpenGL
7573 FormatDesc := TFormatDescriptor.Get(IntFormat);
7574 GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight));
7576 if FormatDesc.IsCompressed then
7577 glGetCompressedTexImage(Target, 0, Temp)
7579 glGetTexImage(Target, 0, FormatDesc.glInternalFormat, FormatDesc.glDataFormat, Temp);
7580 SetDataPointer(Temp, IntFormat, TempWidth, TempHeight);
7587 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7588 procedure TglBitmap2D.GenTexture(const aTestTextureSize: Boolean);
7590 BuildWithGlu, PotTex, TexRec: Boolean;
7593 if Assigned(Data) then begin
7594 // Check Texture Size
7595 if (aTestTextureSize) then begin
7596 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
7598 if ((Height > TexSize) or (Width > TexSize)) then
7599 raise EglBitmapSizeToLargeException.Create('TglBitmap2D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
7601 PotTex := IsPowerOfTwo(Height) and IsPowerOfTwo(Width);
7602 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and (Target = GL_TEXTURE_RECTANGLE);
7604 if not (PotTex or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
7605 raise EglBitmapNonPowerOfTwoException.Create('TglBitmap2D.GenTexture - Rendercontex dosn''t support non power of two texture.');
7609 SetupParameters(BuildWithGlu);
7610 UploadData(Target, BuildWithGlu);
7611 glAreTexturesResident(1, @fID, @fIsResident);
7615 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7616 function TglBitmap2D.FlipHorz: Boolean;
7619 TempDestData, DestData, SourceData: PByte;
7622 result := inherited FlipHorz;
7623 if Assigned(Data) then begin
7625 ImgSize := Height * fRowSize;
7626 GetMem(DestData, ImgSize);
7628 TempDestData := DestData;
7629 Dec(TempDestData, fRowSize + fPixelSize);
7630 for Row := 0 to Height -1 do begin
7631 Inc(TempDestData, fRowSize * 2);
7632 for Col := 0 to Width -1 do begin
7633 Move(SourceData^, TempDestData^, fPixelSize);
7634 Inc(SourceData, fPixelSize);
7635 Dec(TempDestData, fPixelSize);
7638 SetDataPointer(DestData, Format);
7647 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7648 function TglBitmap2D.FlipVert: Boolean;
7651 TempDestData, DestData, SourceData: PByte;
7653 result := inherited FlipVert;
7654 if Assigned(Data) then begin
7656 GetMem(DestData, Height * fRowSize);
7658 TempDestData := DestData;
7659 Inc(TempDestData, Width * (Height -1) * fPixelSize);
7660 for Row := 0 to Height -1 do begin
7661 Move(SourceData^, TempDestData^, fRowSize);
7662 Dec(TempDestData, fRowSize);
7663 Inc(SourceData, fRowSize);
7665 SetDataPointer(DestData, Format);
7674 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7675 //TglBitmap2D - ToNormalMap///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7676 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7678 TMatrixItem = record
7683 PglBitmapToNormalMapRec = ^TglBitmapToNormalMapRec;
7684 TglBitmapToNormalMapRec = Record
7686 Heights: array of Single;
7687 MatrixU : array of TMatrixItem;
7688 MatrixV : array of TMatrixItem;
7692 ONE_OVER_255 = 1 / 255;
7694 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7695 procedure glBitmapToNormalMapPrepareFunc(var FuncRec: TglBitmapFunctionRec);
7699 with FuncRec do begin
7701 Source.Data.r * LUMINANCE_WEIGHT_R +
7702 Source.Data.g * LUMINANCE_WEIGHT_G +
7703 Source.Data.b * LUMINANCE_WEIGHT_B;
7704 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Val * ONE_OVER_255;
7708 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7709 procedure glBitmapToNormalMapPrepareAlphaFunc(var FuncRec: TglBitmapFunctionRec);
7712 PglBitmapToNormalMapRec(Args)^.Heights[Position.Y * Size.X + Position.X] := Source.Data.a * ONE_OVER_255;
7715 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7716 procedure glBitmapToNormalMapFunc (var FuncRec: TglBitmapFunctionRec);
7718 TVec = Array[0..2] of Single;
7725 function GetHeight(X, Y: Integer): Single;
7727 with FuncRec do begin
7728 X := Max(0, Min(Size.X -1, X));
7729 Y := Max(0, Min(Size.Y -1, Y));
7730 result := PglBitmapToNormalMapRec(Args)^.Heights[Y * Size.X + X];
7735 with FuncRec do begin
7736 with PglBitmapToNormalMapRec(Args)^ do begin
7738 for Idx := Low(MatrixU) to High(MatrixU) do
7739 du := du + GetHeight(Position.X + MatrixU[Idx].X, Position.Y + MatrixU[Idx].Y) * MatrixU[Idx].W;
7742 for Idx := Low(MatrixU) to High(MatrixU) do
7743 dv := dv + GetHeight(Position.X + MatrixV[Idx].X, Position.Y + MatrixV[Idx].Y) * MatrixV[Idx].W;
7745 Vec[0] := -du * Scale;
7746 Vec[1] := -dv * Scale;
7751 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
7752 if Len <> 0 then begin
7753 Vec[0] := Vec[0] * Len;
7754 Vec[1] := Vec[1] * Len;
7755 Vec[2] := Vec[2] * Len;
7759 Dest.Data.r := Trunc((Vec[0] + 1) * 127.5);
7760 Dest.Data.g := Trunc((Vec[1] + 1) * 127.5);
7761 Dest.Data.b := Trunc((Vec[2] + 1) * 127.5);
7765 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
7766 procedure TglBitmap2D.ToNormalMap(const aFunc: TglBitmapNormalMapFunc; const aScale: Single; const aUseAlpha: Boolean);
7768 Rec: TglBitmapToNormalMapRec;
7770 procedure SetEntry (var Matrix: array of TMatrixItem; Index, X, Y: Integer; W: Single);
7772 if (Index >= Low(Matrix)) and (Index <= High(Matrix)) then begin
7773 Matrix[Index].X := X;
7774 Matrix[Index].Y := Y;
7775 Matrix[Index].W := W;
7780 if TFormatDescriptor.Get(Format).IsCompressed then
7781 raise EglBitmapUnsupportedFormat.Create(Format);
7783 if aScale > 100 then
7785 else if aScale < -100 then
7788 Rec.Scale := aScale;
7790 SetLength(Rec.Heights, Width * Height);
7794 SetLength(Rec.MatrixU, 2);
7795 SetEntry(Rec.MatrixU, 0, -1, 0, -0.5);
7796 SetEntry(Rec.MatrixU, 1, 1, 0, 0.5);
7798 SetLength(Rec.MatrixV, 2);
7799 SetEntry(Rec.MatrixV, 0, 0, 1, 0.5);
7800 SetEntry(Rec.MatrixV, 1, 0, -1, -0.5);
7804 SetLength(Rec.MatrixU, 6);
7805 SetEntry(Rec.MatrixU, 0, -1, 1, -1.0);
7806 SetEntry(Rec.MatrixU, 1, -1, 0, -2.0);
7807 SetEntry(Rec.MatrixU, 2, -1, -1, -1.0);
7808 SetEntry(Rec.MatrixU, 3, 1, 1, 1.0);
7809 SetEntry(Rec.MatrixU, 4, 1, 0, 2.0);
7810 SetEntry(Rec.MatrixU, 5, 1, -1, 1.0);
7812 SetLength(Rec.MatrixV, 6);
7813 SetEntry(Rec.MatrixV, 0, -1, 1, 1.0);
7814 SetEntry(Rec.MatrixV, 1, 0, 1, 2.0);
7815 SetEntry(Rec.MatrixV, 2, 1, 1, 1.0);
7816 SetEntry(Rec.MatrixV, 3, -1, -1, -1.0);
7817 SetEntry(Rec.MatrixV, 4, 0, -1, -2.0);
7818 SetEntry(Rec.MatrixV, 5, 1, -1, -1.0);
7822 SetLength(Rec.MatrixU, 6);
7823 SetEntry(Rec.MatrixU, 0, -1, 1, -1/6);
7824 SetEntry(Rec.MatrixU, 1, -1, 0, -1/6);
7825 SetEntry(Rec.MatrixU, 2, -1, -1, -1/6);
7826 SetEntry(Rec.MatrixU, 3, 1, 1, 1/6);
7827 SetEntry(Rec.MatrixU, 4, 1, 0, 1/6);
7828 SetEntry(Rec.MatrixU, 5, 1, -1, 1/6);
7830 SetLength(Rec.MatrixV, 6);
7831 SetEntry(Rec.MatrixV, 0, -1, 1, 1/6);
7832 SetEntry(Rec.MatrixV, 1, 0, 1, 1/6);
7833 SetEntry(Rec.MatrixV, 2, 1, 1, 1/6);
7834 SetEntry(Rec.MatrixV, 3, -1, -1, -1/6);
7835 SetEntry(Rec.MatrixV, 4, 0, -1, -1/6);
7836 SetEntry(Rec.MatrixV, 5, 1, -1, -1/6);
7840 SetLength(Rec.MatrixU, 20);
7841 SetEntry(Rec.MatrixU, 0, -2, 2, -1 / 16);
7842 SetEntry(Rec.MatrixU, 1, -1, 2, -1 / 10);
7843 SetEntry(Rec.MatrixU, 2, 1, 2, 1 / 10);
7844 SetEntry(Rec.MatrixU, 3, 2, 2, 1 / 16);
7845 SetEntry(Rec.MatrixU, 4, -2, 1, -1 / 10);
7846 SetEntry(Rec.MatrixU, 5, -1, 1, -1 / 8);
7847 SetEntry(Rec.MatrixU, 6, 1, 1, 1 / 8);
7848 SetEntry(Rec.MatrixU, 7, 2, 1, 1 / 10);
7849 SetEntry(Rec.MatrixU, 8, -2, 0, -1 / 2.8);
7850 SetEntry(Rec.MatrixU, 9, -1, 0, -0.5);
7851 SetEntry(Rec.MatrixU, 10, 1, 0, 0.5);
7852 SetEntry(Rec.MatrixU, 11, 2, 0, 1 / 2.8);
7853 SetEntry(Rec.MatrixU, 12, -2, -1, -1 / 10);
7854 SetEntry(Rec.MatrixU, 13, -1, -1, -1 / 8);
7855 SetEntry(Rec.MatrixU, 14, 1, -1, 1 / 8);
7856 SetEntry(Rec.MatrixU, 15, 2, -1, 1 / 10);
7857 SetEntry(Rec.MatrixU, 16, -2, -2, -1 / 16);
7858 SetEntry(Rec.MatrixU, 17, -1, -2, -1 / 10);
7859 SetEntry(Rec.MatrixU, 18, 1, -2, 1 / 10);
7860 SetEntry(Rec.MatrixU, 19, 2, -2, 1 / 16);
7862 SetLength(Rec.MatrixV, 20);
7863 SetEntry(Rec.MatrixV, 0, -2, 2, 1 / 16);
7864 SetEntry(Rec.MatrixV, 1, -1, 2, 1 / 10);
7865 SetEntry(Rec.MatrixV, 2, 0, 2, 0.25);
7866 SetEntry(Rec.MatrixV, 3, 1, 2, 1 / 10);
7867 SetEntry(Rec.MatrixV, 4, 2, 2, 1 / 16);
7868 SetEntry(Rec.MatrixV, 5, -2, 1, 1 / 10);
7869 SetEntry(Rec.MatrixV, 6, -1, 1, 1 / 8);
7870 SetEntry(Rec.MatrixV, 7, 0, 1, 0.5);
7871 SetEntry(Rec.MatrixV, 8, 1, 1, 1 / 8);
7872 SetEntry(Rec.MatrixV, 9, 2, 1, 1 / 16);
7873 SetEntry(Rec.MatrixV, 10, -2, -1, -1 / 16);
7874 SetEntry(Rec.MatrixV, 11, -1, -1, -1 / 8);
7875 SetEntry(Rec.MatrixV, 12, 0, -1, -0.5);
7876 SetEntry(Rec.MatrixV, 13, 1, -1, -1 / 8);
7877 SetEntry(Rec.MatrixV, 14, 2, -1, -1 / 10);
7878 SetEntry(Rec.MatrixV, 15, -2, -2, -1 / 16);
7879 SetEntry(Rec.MatrixV, 16, -1, -2, -1 / 10);
7880 SetEntry(Rec.MatrixV, 17, 0, -2, -0.25);
7881 SetEntry(Rec.MatrixV, 18, 1, -2, -1 / 10);
7882 SetEntry(Rec.MatrixV, 19, 2, -2, -1 / 16);
7887 if aUseAlpha and TFormatDescriptor.Get(Format).HasAlpha then
7888 AddFunc(glBitmapToNormalMapPrepareAlphaFunc, false, @Rec)
7890 AddFunc(glBitmapToNormalMapPrepareFunc, false, @Rec);
7891 AddFunc(glBitmapToNormalMapFunc, false, @Rec);
7893 SetLength(Rec.Heights, 0);
7906 procedure TglBitmap1D.SetDataPointer(Data: pByte; Format: TglBitmapInternalFormat; Width, Height: Integer);
7911 if Height > 1 then begin
7912 // extract first line of the data
7913 Size := FormatGetImageSize(glBitmapPosition(Width), Format);
7914 GetMem(pTemp, Size);
7916 Move(Data^, pTemp^, Size);
7923 inherited SetDataPointer(pTemp, Format, Width);
7925 if FormatIsUncompressed(Format) then begin
7926 fUnmapFunc := FormatGetUnMapFunc(Format);
7927 fGetPixelFunc := GetPixel1DUnmap;
7932 procedure TglBitmap1D.GetPixel1DUnmap(const Pos: TglBitmapPixelPosition; var Pixel: TglBitmapPixelData);
7937 Inc(pTemp, Pos.X * fPixelSize);
7939 fUnmapFunc(pTemp, Pixel);
7943 function TglBitmap1D.FlipHorz: Boolean;
7946 pTempDest, pDest, pSource: pByte;
7948 result := inherited FlipHorz;
7950 if Assigned(Data) and FormatIsUncompressed(InternalFormat) then begin
7953 GetMem(pDest, fRowSize);
7957 Inc(pTempDest, fRowSize);
7958 for Col := 0 to Width -1 do begin
7959 Move(pSource^, pTempDest^, fPixelSize);
7961 Inc(pSource, fPixelSize);
7962 Dec(pTempDest, fPixelSize);
7965 SetDataPointer(pDest, InternalFormat);
7975 procedure TglBitmap1D.UploadData (Target, Format, InternalFormat, Typ: Cardinal; BuildWithGlu: Boolean);
7978 if Self.InternalFormat in [ifDXT1, ifDXT3, ifDXT5] then
7979 glCompressedTexImage1D(Target, 0, InternalFormat, Width, 0, Trunc(Width * FormatGetSize(Self.InternalFormat)), Data)
7983 if BuildWithGlu then
7984 gluBuild1DMipmaps(Target, InternalFormat, Width, Format, Typ, Data)
7986 glTexImage1D(Target, 0, InternalFormat, Width, 0, Format, Typ, Data);
7989 if (FreeDataAfterGenTexture) then
7994 procedure TglBitmap1D.GenTexture(TestTextureSize: Boolean);
7996 BuildWithGlu, TexRec: Boolean;
7997 glFormat, glInternalFormat, glType: Cardinal;
8000 if Assigned(Data) then begin
8001 // Check Texture Size
8002 if (TestTextureSize) then begin
8003 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @TexSize);
8005 if (Width > TexSize) then
8006 raise EglBitmapSizeToLargeException.Create('TglBitmap1D.GenTexture - The size for the texture is to large. It''s may be not conform with the Hardware.');
8008 TexRec := (GL_ARB_texture_rectangle or GL_EXT_texture_rectangle or GL_NV_texture_rectangle) and
8009 (Target = GL_TEXTURE_RECTANGLE_ARB);
8011 if not (IsPowerOfTwo (Width) or GL_ARB_texture_non_power_of_two or GL_VERSION_2_0 or TexRec) then
8012 raise EglBitmapNonPowerOfTwoException.Create('TglBitmap1D.GenTexture - Rendercontex dosn''t support non power of two texture.');
8017 SetupParameters(BuildWithGlu);
8018 SelectFormat(InternalFormat, glFormat, glInternalFormat, glType);
8020 UploadData(Target, glFormat, glInternalFormat, glType, BuildWithGlu);
8023 glAreTexturesResident(1, @fID, @fIsResident);
8028 procedure TglBitmap1D.AfterConstruction;
8032 Target := GL_TEXTURE_1D;
8036 { TglBitmapCubeMap }
8038 procedure TglBitmapCubeMap.AfterConstruction;
8042 if not (GL_VERSION_1_3 or GL_ARB_texture_cube_map or GL_EXT_texture_cube_map) then
8043 raise EglBitmapException.Create('TglBitmapCubeMap.AfterConstruction - CubeMaps are unsupported.');
8045 SetWrap; // set all to GL_CLAMP_TO_EDGE
8046 Target := GL_TEXTURE_CUBE_MAP;
8047 fGenMode := GL_REFLECTION_MAP;
8051 procedure TglBitmapCubeMap.Bind(EnableTexCoordsGen, EnableTextureUnit: Boolean);
8053 inherited Bind (EnableTextureUnit);
8055 if EnableTexCoordsGen then begin
8056 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, fGenMode);
8057 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, fGenMode);
8058 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, fGenMode);
8059 glEnable(GL_TEXTURE_GEN_S);
8060 glEnable(GL_TEXTURE_GEN_T);
8061 glEnable(GL_TEXTURE_GEN_R);
8066 procedure TglBitmapCubeMap.GenerateCubeMap(CubeTarget: Cardinal; TestTextureSize: Boolean);
8068 glFormat, glInternalFormat, glType: Cardinal;
8069 BuildWithGlu: Boolean;
8072 // Check Texture Size
8073 if (TestTextureSize) then begin
8074 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, @TexSize);
8076 if ((Height > TexSize) or (Width > TexSize)) then
8077 raise EglBitmapSizeToLargeException.Create('TglBitmapCubeMap.GenTexture - The size for the Cubemap is to large. It''s may be not conform with the Hardware.');
8079 if not ((IsPowerOfTwo (Height) and IsPowerOfTwo (Width)) or GL_VERSION_2_0 or GL_ARB_texture_non_power_of_two) then
8080 raise EglBitmapNonPowerOfTwoException.Create('TglBitmapCubeMap.GenTexture - Cubemaps dosn''t support non power of two texture.');
8084 if ID = 0 then begin
8086 SetupParameters(BuildWithGlu);
8089 SelectFormat(InternalFormat, glFormat, glInternalFormat, glType);
8091 UploadData (CubeTarget, glFormat, glInternalFormat, glType, BuildWithGlu);
8095 procedure TglBitmapCubeMap.GenTexture(TestTextureSize: Boolean);
8097 Assert(false, 'TglBitmapCubeMap.GenTexture - Don''t call GenTextures directly.');
8101 procedure TglBitmapCubeMap.Unbind(DisableTexCoordsGen,
8102 DisableTextureUnit: Boolean);
8104 inherited Unbind (DisableTextureUnit);
8106 if DisableTexCoordsGen then begin
8107 glDisable(GL_TEXTURE_GEN_S);
8108 glDisable(GL_TEXTURE_GEN_T);
8109 glDisable(GL_TEXTURE_GEN_R);
8114 { TglBitmapNormalMap }
8117 TVec = Array[0..2] of Single;
8118 TglBitmapNormalMapGetVectorFunc = procedure (var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
8120 PglBitmapNormalMapRec = ^TglBitmapNormalMapRec;
8121 TglBitmapNormalMapRec = record
8123 Func: TglBitmapNormalMapGetVectorFunc;
8127 procedure glBitmapNormalMapPosX(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
8130 Vec[1] := - (Position.Y + 0.5 - HalfSize);
8131 Vec[2] := - (Position.X + 0.5 - HalfSize);
8135 procedure glBitmapNormalMapNegX(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
8137 Vec[0] := - HalfSize;
8138 Vec[1] := - (Position.Y + 0.5 - HalfSize);
8139 Vec[2] := Position.X + 0.5 - HalfSize;
8143 procedure glBitmapNormalMapPosY(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
8145 Vec[0] := Position.X + 0.5 - HalfSize;
8147 Vec[2] := Position.Y + 0.5 - HalfSize;
8151 procedure glBitmapNormalMapNegY(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
8153 Vec[0] := Position.X + 0.5 - HalfSize;
8154 Vec[1] := - HalfSize;
8155 Vec[2] := - (Position.Y + 0.5 - HalfSize);
8159 procedure glBitmapNormalMapPosZ(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
8161 Vec[0] := Position.X + 0.5 - HalfSize;
8162 Vec[1] := - (Position.Y + 0.5 - HalfSize);
8167 procedure glBitmapNormalMapNegZ(var Vec: TVec; const Position: TglBitmapPixelPosition; const HalfSize: Integer);
8169 Vec[0] := - (Position.X + 0.5 - HalfSize);
8170 Vec[1] := - (Position.Y + 0.5 - HalfSize);
8171 Vec[2] := - HalfSize;
8175 procedure glBitmapNormalMapFunc(var FuncRec: TglBitmapFunctionRec);
8180 with FuncRec do begin
8181 with PglBitmapNormalMapRec (CustomData)^ do begin
8182 Func(Vec, Position, HalfSize);
8185 Len := 1 / Sqrt(Sqr(Vec[0]) + Sqr(Vec[1]) + Sqr(Vec[2]));
8186 if Len <> 0 then begin
8187 Vec[0] := Vec[0] * Len;
8188 Vec[1] := Vec[1] * Len;
8189 Vec[2] := Vec[2] * Len;
8192 // Scale Vector and AddVectro
8193 Vec[0] := Vec[0] * 0.5 + 0.5;
8194 Vec[1] := Vec[1] * 0.5 + 0.5;
8195 Vec[2] := Vec[2] * 0.5 + 0.5;
8199 Dest.Red := Round(Vec[0] * 255);
8200 Dest.Green := Round(Vec[1] * 255);
8201 Dest.Blue := Round(Vec[2] * 255);
8206 procedure TglBitmapNormalMap.AfterConstruction;
8210 fGenMode := GL_NORMAL_MAP;
8214 procedure TglBitmapNormalMap.GenerateNormalMap(Size: Integer;
8215 TestTextureSize: Boolean);
8217 Rec: TglBitmapNormalMapRec;
8218 SizeRec: TglBitmapPixelPosition;
8220 Rec.HalfSize := Size div 2;
8222 FreeDataAfterGenTexture := false;
8224 SizeRec.Fields := [ffX, ffY];
8229 Rec.Func := glBitmapNormalMapPosX;
8230 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
8231 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X, TestTextureSize);
8234 Rec.Func := glBitmapNormalMapNegX;
8235 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
8236 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, TestTextureSize);
8239 Rec.Func := glBitmapNormalMapPosY;
8240 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
8241 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, TestTextureSize);
8244 Rec.Func := glBitmapNormalMapNegY;
8245 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
8246 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, TestTextureSize);
8249 Rec.Func := glBitmapNormalMapPosZ;
8250 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
8251 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, TestTextureSize);
8254 Rec.Func := glBitmapNormalMapNegZ;
8255 LoadFromFunc (SizeRec, glBitmapNormalMapFunc, ifBGR8, @Rec);
8256 GenerateCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, TestTextureSize);
8261 glBitmapSetDefaultFormat(tfEmpty);
8262 glBitmapSetDefaultMipmap(mmMipmap);
8263 glBitmapSetDefaultFilter(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
8264 glBitmapSetDefaultWrap (GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
8266 glBitmapSetDefaultFreeDataAfterGenTexture(true);
8267 glBitmapSetDefaultDeleteTextureOnFree (true);
8269 TFormatDescriptor.Init;
8271 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
8272 OpenGLInitialized := false;
8273 InitOpenGLCS := TCriticalSection.Create;
8277 TFormatDescriptor.Finalize;
8279 {$IFDEF GLB_NATIVE_OGL_DYNAMIC}
8280 FreeAndNil(InitOpenGLCS);